所谓的Ansible模块,其实基本上都是Python脚本,只不过Ansible会通过SSH连接将其上传到被控制主机并运行。
需要注意的是,在Ansible中,强调也给很重要的概念:**幂等性(idempotency)**,也就是说,无论进行多少次部署,最终得到的系统都是完全一样的。这点在DevOps中就显得格为重要,只有有了这种保证,我们才能放心的把系统安装,配置等工作交给这些自动化软件。Ansible的很多模块都具有幂等性。
准备工作
为了方便后续使用,建议在当前目录下添加:ansible.cfg及inventory。(不推荐添加默认inventory文件/etc/ansible/hosts)
ansible.cfg:
[defaults]
remote_user=ubuntu
inventory = /home/lcoding/tutorials/ansible/inventory
inventory:
[dev]
xxx.xxx.xxx.xxx
默认command模块
需要注意,command模块是Ansible的默认模块。如果不指定,则会默认使用此模块。
比如运行:
ansible all -a "ifconfig"
代表要在远程被控主机上运行ifconfig这个命令。由于我在本地安装了ifconfig,但在远程没有安装ifconfig,因此其运行结果为:
xxx.xxx.xxx.xxx | FAILED | rc=2 >>
[Errno 2] No such file or directory: b'ifconfig'
注意:Command模块和Shell模块的最大区别就是Command模块并不启动Shell,因此无法执行Shell的内置命令和特性,比如管道和重定向等。
但需要注意的是,无论是shell,还是command模块,都不要运行交互性的命令,比如vi。
copy模块
这个模块用于将文件从本地复制到目标机器。其常用参数:
- src
- dest
- backup: 是否对目标文件进行备份
- owner: 目标文件所有者
- group: 目标文件所有组
- mode: 目标文件的访问权限
例如:
ansible all -m copy -a "src=/tmp/test.conf dest=/tmp/test2.conf"
cron模块
用于管理远程被控制主机上的Cron服务。
debug模块
可以用于输出变量的值,比如:
ansible dev -m debug -a "var=user" -e "user=lcoding"
ansible dev -m debug -a "msg='user is {{user}}'" -e "user=lcoding"
fetch模块
把远程主机文件复制到本机。
file模块
用于管理远程被控主机上的文件,例如创建文件,目录,连接,修改权限与属性等。
state参数:
- absent: 删除文件
- touch: 如果文件不存在,创建空文件
- file:文件
- directory: 目录
- link: 链接文件
例如:创建一个文件:
ansible dev -m file -a "path=/tmp/demo.txt state=touch"
创建一个目录:
ansible dev -m file -a "path=/tmp/demo state=directory"
lineinfile模块
可以修改单个文件的单行内容。
script模块
将本地的一个脚本在被控制机器上执行:
ansible dev -m script -a "./test.sh"
执行命令之前,test.sh会被复制到被控主机的临时目录。在命令执行完之后,test.sh会被自动删除。
setup模块
可用于查看被控主机的信息
ansible dev -m setup
shell模块
通过shell模块及管道操作符查看前面创建的test.conf文件:
> ansible all -m shell -a "ls /tmp | grep conf"
YOUR_IP | CHANGED | rc=0 >>
test.conf
查看远程主机的进程数:
> ansible all -m shell -a "ps aux | wc -l"
xxx.xxx.xxx.xxx | CHANGED | rc=0 >>
180
但需要注意的是,无论是shell,还是command模块,都不要运行交互性的命令,比如vi。
给Shell模块传递多个参数
ansible all -m shell -a "chdir=/tmp touch test.txt"
creates/removes参数
- creates:当文件存在时,不执行shell命令
- removes:当文件不存在时,不执行shell命令
例如:只有当目标主机上没有SSH密钥时,创建新密钥:
> ansible dev -m shell -a "ssh-keygen -f ~/.ssh/id_rsa -N creates=~/.ssh/id_rsa"
xxx.xxx.xxx.xxx | SUCCESS | rc=0 >>
skipped, since /home/ubuntu/.ssh/id_rsa exists Did not run command since '/home/ubuntu/.ssh/id_rsa' exists
再比如说,如果没有安装unzip命令,就跳过解压过程:
ansible dev -m shell -a "unzip demo.zip removes=/bin/unzip"
systemd模块
例如在被控机上启动sshd服务:
ansible all -m systemd -a "name=sshd state=started"
template模块
这里使用Jinjia2格式作为文件模板并可以进行文档内变量的替换。
user及group模块
注意:在创建用户及组的时候,要注意运行该命令用户的权限。默认用户可以在文件:~/.ansible.cfg 中进行配置。
user模块
可用参数:
- comment
- create_home=yes/no: 是否在创建用户时同时创建该用户的home目录
- home
- name
- group/groups
- password: 加密后的密码
- uid
- update_password: 是否更新密码
需要注意的是密码的使用,需要进行加密:
ansible dev -m user -a "name=u1 password={{'12345'|password_hash('sha512')}}"
将用户添加到sudoers组中以便执行一些特殊命令
这里可以使用 lineinfile 模块授权lcoding可以运行systemctl命令:
ansible all -m lineinfile -a "path=/etc/sudoers line='lcoding ALL=(ALL) /usr/bin/systemctl'"
授权lcoding用户可以无需密码远程执行所有命令:
ansible all -m lineinfile -a "path=/etc/sudoers line='lcoding ALL=(ALL) NOPASSWD:ALL'"
group模块
创建组:
ansible dev -m group -a "name=devgroup"
可选参数还有:
- system=yes/no: 是否为系统组
- state=present/absent: 创建或删除