一:ansible-playbook的基本语法
#编写以下yaml文件
[root@supervisor yaml]# cat /etc/ansible/yaml/test.yml
---
- hosts: all
remote_user: root
tasks:
- name: 安装ntpdate,wget,lrzsz
yum: state=present name=ntpdate,wget,lrzsz
- name: 创建web目录
shell: mkdir -p /data/cache
- name: 安装httpd
yum: state=present name=httpd
notify:
- Start httpd
handlers:
- name: Start httpd
service: state=restarted name=httpd enabled=yes
- hosts: centos7
remote_user: root
tasks:
- name: 安装net工具
yum: state=present name=net-tools
#检查语法是否正确
[root@supervisor yaml]# ansible-playbook -i /etc/ansible/hosts /etc/ansible/yaml/test.yml --syntax-check
playbook: /etc/ansible/yaml/test.yml
#执行playbook
[root@supervisor yaml]# ansible-playbook test.yml
PLAY [all] **********************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [192.168.1.182]
ok: [192.168.1.183]
ok: [192.168.1.184]
ok: [192.168.1.181]
ok: [192.168.1.185]
ok: [192.168.1.186]
TASK [安装ntpdate,wget,lrzsz] *****************************************************************************************************************************************************************************************************************
changed: [192.168.1.184]
changed: [192.168.1.182]
changed: [192.168.1.185]
changed: [192.168.1.181]
changed: [192.168.1.183]
changed: [192.168.1.186]
TASK [创建web目录] ******************************************************************************************************************************************************************************************************************************
[WARNING]: Consider using the file module with state=directory rather than running mkdir. If you need to use command because file is insufficient you can add warn=False to this command task or set command_warnings=False in ansible.cfg #这里提示对文件操作用file模块
to get rid of this message.
changed: [192.168.1.184]
changed: [192.168.1.183]
changed: [192.168.1.181]
changed: [192.168.1.182]
changed: [192.168.1.185]
changed: [192.168.1.186]
TASK [安装httpd] ******************************************************************************************************************************************************************************************************************************
changed: [192.168.1.185]
changed: [192.168.1.183]
changed: [192.168.1.184]
changed: [192.168.1.181]
changed: [192.168.1.182]
changed: [192.168.1.186]
RUNNING HANDLER [Start httpd] ***************************************************************************************************************************************************************************************************************
changed: [192.168.1.183]
changed: [192.168.1.181]
changed: [192.168.1.185]
changed: [192.168.1.184]
changed: [192.168.1.182]
changed: [192.168.1.186]
PLAY [centos7] ******************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [192.168.1.182]
ok: [192.168.1.184]
ok: [192.168.1.186]
TASK [安装net工具] ******************************************************************************************************************************************************************************************************************************
changed: [192.168.1.186]
changed: [192.168.1.182]
changed: [192.168.1.184]
PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.1.181 : ok=5 changed=4 unreachable=0 failed=0
192.168.1.182 : ok=7 changed=5 unreachable=0 failed=0
192.168.1.183 : ok=5 changed=4 unreachable=0 failed=0
192.168.1.184 : ok=7 changed=5 unreachable=0 failed=0
192.168.1.185 : ok=5 changed=4 unreachable=0 failed=0
192.168.1.186 : ok=7 changed=5 unreachable=0 failed=0
#yml文件说明
第一行:---类似于解释器如同shell的/bin/bash
第二行:- hosts:all 指定对那些主机进行操作
第三行:remote_user 指定执行用户
第四行:tasks 任务
第五行至第十行:可以有多个任务,- name任务的描述下边是具体任务内容
第十一行:norify和handlers配合使用,指定连锁动作
可以有多个hosts,多个tasks多个notify和handlers
二:ansible-playbook定义变量
ansible-playbook设置变量有以下五种方式:
1:hosts主机清单定义
2:vars 设置
3:vars_file 设置变量文件
4:vars_prompt 手动输入
5:setup 获取变量
============================================hosts主机清单
[root@supervisor yaml]# cat /etc/ansible/hosts #主机清单
[centos6]
192.168.1.181
192.168.1.183
192.168.1.185
[centos7]
192.168.1.182
192.168.1.184
192.168.1.186
[centos:children]
centos6
centos7
[centos:vars] #定义变量
port=8080
#使用变量
[root@supervisor yaml]# cat test
{{port}}
[root@supervisor yaml]# cat debug.yml
---
- hosts: centos
gather_facts: no
tasks:
- name: print port
template: src=test dest=/tmp/test_debug
#执行结果
[root@supervisor yaml]# ansible centos -m shell -a "cat /tmp/test_debug"
192.168.1.185 | SUCCESS | rc=0 >>
8080
192.168.1.182 | SUCCESS | rc=0 >>
8080
192.168.1.184 | SUCCESS | rc=0 >>
8080
192.168.1.183 | SUCCESS | rc=0 >>
8080
192.168.1.181 | SUCCESS | rc=0 >>
8080
192.168.1.186 | SUCCESS | rc=0 >>
8080
============================================vars
比如需要在远程主机创建目录和文件,可以用vars在playbook中定义变量
---
- hosts: centos6
remote_user: root
vars:
directory: /root/test
file: /root/test/haha
tasks:
- name: 创建目录
shell: "mkdir {{directory}}"
- name: 创建文件
shell: "touch {{file}}"
============================================vars_file
同时如果变量比较多,我们可以写在文件中,然后调用该文件。用于往远程主机传递变量
[root@supervisor yaml]# cat variables_file #定义变量的文件
name: lisi
passwd: 123456
[root@supervisor yaml]# cat test #调用变量的文件
{{name}}
{{passwd}}
[root@supervisor yaml]# cat test2.yml
---
- hosts: centos7
remote_user: root
vars_files:
- variables_file
tasks:
- name: 复制文件 #传递变量(和copy模块类似)
template: src=test dest=/root/test.file
#远程主机检查
[root@supervisor yaml]# ansible centos7 -a "cat /root/test.file"
192.168.1.184 | SUCCESS | rc=0 >>
lisi
123456
192.168.1.182 | SUCCESS | rc=0 >>
lisi
123456
192.168.1.186 | SUCCESS | rc=0 >>
lisi
123456
============================================vars_prompt
这个是手动输入变量,比如我们创建一个用户的时候,手动输入密码
[root@supervisor yaml]# cat test3.yml
---
- hosts: all
remote_user: root
vars_prompt:
- name: users
prompt: 输入用户名
- name: passwd
prompt: 输入密码
private: no #指定是否隐藏输入,默认为隐藏(yes)
tasks:
- name: 上传变量文件
template: src=test dest=/root/test.txt
[root@supervisor yaml]# cat test #变量文件
{{users}}
{{passwd}}
#执行状态
[root@supervisor yaml]# ansible-playbook test3.yml
输入用户名:
输入密码: zhangsan
......
#执行结果
[root@supervisor yaml]# ansible all -a "cat /root/test.txt"
192.168.1.186 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.184 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.182 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.183 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.181 | SUCCESS | rc=0 >>
zhangsan
zhangsan
============================================setup方法
比如我们根据setup的信息,获取每个主机的IP地址和根分区的大小,如下
注意取值
[root@supervisor yaml]# cat test4.yml
---
- hosts: all
remote_user: root
tasks:
- name: 上传变量文件
template: src=test dest=/root/test.txt
[root@supervisor yaml]# cat test
{{ansible_virbr0.ipv4.address}}
{{ansible_mounts[0].size_total/1024/1024/1024}}
ansible-playbook设置变量有以下四种方式:
1:vars 设置
2:vars_file 设置变量文件
3:vars_prompt 手动输入
4:setup 获取变量
============================================vars
比如需要在远程主机创建目录和文件,可以用vars在playbook中定义变量
---
- hosts: centos6
remote_user: root
vars:
directory: /root/test
file: /root/test/haha
tasks:
- name: 创建目录
shell: "mkdir {{directory}}"
- name: 创建文件
shell: "touch {{file}}"
============================================vars_file
同时如果变量比较多,我们可以写在文件中,然后调用该文件。用于往远程主机传递变量
[root@supervisor yaml]# cat variables_file #定义变量的文件
name: lisi
passwd: 123456
[root@supervisor yaml]# cat test #调用变量的文件
{{name}}
{{passwd}}
[root@supervisor yaml]# cat test2.yml
---
- hosts: centos7
remote_user: root
vars_files:
- variables_file
tasks:
- name: 复制文件 #传递变量(和copy模块类似)
template: src=test dest=/root/test.file
#远程主机检查
[root@supervisor yaml]# ansible centos7 -a "cat /root/test.file"
192.168.1.184 | SUCCESS | rc=0 >>
lisi
123456
192.168.1.182 | SUCCESS | rc=0 >>
lisi
123456
192.168.1.186 | SUCCESS | rc=0 >>
lisi
123456
============================================vars_prompt
这个是手动输入变量,比如我们创建一个用户的时候,手动输入密码
[root@supervisor yaml]# cat test3.yml
---
- hosts: all
remote_user: root
vars_prompt:
- name: users
prompt: 输入用户名
- name: passwd
prompt: 输入密码
private: no #指定是否隐藏输入,默认为隐藏(yes)
tasks:
- name: 上传变量文件
template: src=test dest=/root/test.txt
[root@supervisor yaml]# cat test #变量文件
{{users}}
{{passwd}}
#执行状态
[root@supervisor yaml]# ansible-playbook test3.yml
输入用户名:
输入密码: zhangsan
......
#执行结果
[root@supervisor yaml]# ansible all -a "cat /root/test.txt"
192.168.1.186 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.184 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.182 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.183 | SUCCESS | rc=0 >>
zhangsan
zhangsan
192.168.1.181 | SUCCESS | rc=0 >>
zhangsan
zhangsan
============================================setup方法
比如我们根据setup的信息,获取每个主机的IP地址和根分区的大小,如下
注意取值
[root@supervisor yaml]# cat test4.yml
---
- hosts: all
remote_user: root
gather_facts: True #(这一项表明是否执行setup模块,默认为执行,False为不执行)
tasks:
- name: 上传变量文件
template: src=test dest=/root/test.txt
[root@supervisor yaml]# cat test
{{ansible_virbr0.ipv4.address}}
{{ansible_mounts[0].size_total/1024/1024/1024}}
#执行结果
[root@centos6.9_1 ~]# cat test.txt
192.168.122.1
8.28001785278
三:ansible-playbook的role(角色)
角色就是将一个playbook分开写,角色定义两种方式,如下
#方式1(安装httpd服务)
[root@supervisor ansible]# pwd
/etc/ansible
[root@supervisor ansible]# tree httpd
httpd
├── roles
│ └── httpd
│ └── tasks
│ └── main.yml
└── selt.yml
[root@supervisor ansible]# cat httpd/selt.yml #主接口文件
---
- hosts: all
gather_facts: no
remote_user: root
roles:
- httpd
[root@supervisor ansible]# cat httpd/roles/httpd/tasks/main.yml #任务文件
---
- name: 安装httpd
yum: state=present name=httpd
- name: 配置开机启动项
shell: echo "/usr/sbin/httpd" >> /etc/rc.local
- name: 启动httpd
service: state=started name=httpd enabled=yes
#方式2(安装httpd服务,推荐使用此方式)
[root@supervisor httpd]# pwd
/etc/ansible/yaml/httpd
[root@supervisor httpd]# ls
handlers.yml selt.yml tasks.yml varsfile.yml
[root@supervisor httpd]# cat selt.yml #主接口文件
---
- hosts: all
remote_user: root
gather_facts: no
vars_files:
- varsfile.yml #变量文件
tasks:
- include: tasks.yml #任务文件
handlers:
- include: handlers.yml #连锁动作文件
[root@supervisor httpd]# cat varsfile.yml #变量文件
server_name: http
port: 80
[root@supervisor httpd]# cat tasks.yml #任务文件
---
- name: 安装httpd
yum: state=present name=httpd
- name: 准备启动配置
shell: echo "/usr/sbin/httpd" >> /etc/rc.local
- name: 上传变量文件
template: src=varsfile.yml dest=/root/varsfile
notify: started httpd
[root@supervisor httpd]# cat handlers.yml #连锁动作文件
---
- name: started httpd
service: name=httpd state=started enabled=yes
四:playbook常用模块
======================================template模块
[root@supervisor yaml]# cat test_template.yml
---
- hosts: all
remote_user: root
gather_facts: no
vars_files:
- variables_file
tasks:
- name: 上传变量文件 #template支持变量
template: src=test_file dest=/root/test_file
- name: copy复制 #copy不支持变量
copy: src=test_file dest=/root/test_file1
#template执行
[root@supervisor yaml]# ansible all -m shell -a "cat /root/test_file"
192.168.1.181 | SUCCESS | rc=0 >>
lisi
123456
#copy执行结果
[root@supervisor yaml]# ansible all -m shell -a "cat /root/test_file1"
192.168.1.182 | SUCCESS | rc=0 >>
{{name}}
{{passwd}}
======================================set_fact模块
可以计算变量同时也可以设置新的变量(可以根据setup获取值)
[root@supervisor yaml]# ansible all -m setup |grep "ansible_memtotal_mb"
"ansible_memtotal_mb": 490,
"ansible_memtotal_mb": 490,
"ansible_memtotal_mb": 488,
"ansible_memtotal_mb": 488,
"ansible_memtotal_mb": 488,
"ansible_memtotal_mb": 490,
[root@supervisor yaml]# cat test_set_fact.yml
---
- hosts: all
remote_user: root
tasks:
- name: 设置变量
set_fact: port="{{ansible_memtotal_mb/2}}"
- name: 复制文件
template: src=test_set.conf dest=/root/
[root@supervisor yaml]# cat test_set.conf
port={{port|default(1003)}} #可以设置默认值
======================================debug模块
打印信息
[root@supervisor yaml]# cat debug.yml
---
- hosts: centos
gather_facts: no
vars:
port: 9090
tasks:
- name: print port
debug: msg="{{port}}"
[root@supervisor yaml]# ansible-playbook debug.yml
[WARNING]: Found variable using reserved name: port
PLAY [centos] *******************************************************************************************************************************************************************************************************************************
TASK [print port] ***************************************************************************************************************************************************************************************************************************
ok: [192.168.1.181] => {
"msg": 9090
}
ok: [192.168.1.183] => {
"msg": 9090
}
ok: [192.168.1.182] => {
"msg": 9090
}
ok: [192.168.1.185] => {
"msg": 9090
}
ok: [192.168.1.184] => {
"msg": 9090
}
ok: [192.168.1.186] => {
"msg": 9090
}
五:ansible-playbook的register
register的用处就是比如有两个任务,第二个任务需要第一个任务中的变量
[root@supervisor yaml]# cat register.yml
---
- hosts: all
gather_facts: no
tasks:
- name: 获取主机名
shell: hostname
register: host #定义变量
- name: 打印变量
debug: msg={{host}}
#获取结果
ok: [192.168.1.182] => {
"msg": {
"changed": true,
"cmd": "hostname",
"delta": "0:00:00.074242",
"end": "2018-08-27 21:29:21.502808",
"failed": false,
"rc": 0,
"start": "2018-08-27 21:29:21.428566",
"stderr": "",
"stderr_lines": [],
"stdout": "centos7.4_1", #这里才是真正的变量(需要把yml文件里的host改为host.stdout)
"stdout_lines": [
"centos7.4_1"
]
}
}
#如下
ok: [192.168.1.181] => {
"msg": "centos6.9_1"
}
==========================比如我们获取到内存大小然后写入文件
[root@supervisor yaml]# cat register2.yml
---
- hosts: all
gather_facts: no
tasks:
- name: 获取机器负载
shell: uptime
register: info
- name: 写入文件
shell: echo "{{info.stdout}}" > cpu.txt
[root@supervisor yaml]# ansible all -m shell -a "cat cpu.txt"
192.168.1.184 | SUCCESS | rc=0 >>
21:34:13 up 16 min, 2 users, load average: 0.01, 0.06, 0.07
192.168.1.182 | SUCCESS | rc=0 >>
21:34:14 up 37 min, 2 users, load average: 0.01, 0.05, 0.05
192.168.1.183 | SUCCESS | rc=0 >>
21:35:22 up 37 min, 2 users, load average: 0.16, 0.03, 0.01
192.168.1.181 | SUCCESS | rc=0 >>
21:35:23 up 37 min, 2 users, load average: 0.23, 0.06, 0.02
192.168.1.185 | SUCCESS | rc=0 >>
09:35:23 up 37 min, 2 users, load average: 0.08, 0.02, 0.01
192.168.1.186 | SUCCESS | rc=0 >>
21:34:16 up 16 min, 2 users, load average: 0.05, 0.12, 0.12
六:playbook的条件判断以及循环
=============================================================================基本循环
比如我们需要创建很多个用户,我们可以利用循环
[root@supervisor yaml]# cat loops.yml
---
- hosts: all
gather_facts: no
vars_prompt:
- name: passwd
prompt:
tasks:
- name: 批量创建用户
#注意:item是固定语法
user: state=present name="{{item}}" password={{passwd}}
with_items:
- zhuangzhuang
- zhuangzhuang1
- zhuangzhuang2
- zhuangzhuang3
#执行过程
[root@supervisor yaml]# ansible-playbook loops.yml
input for passwd: #这里提示输入密码(必须是加密的)
PLAY [all] **********************************************************************************************************************************************************************************************************************************
TASK [批量创建用户] *******************************************************************************************************************************************************************************************************************************
changed: [192.168.1.186] => (item=zhuangzhuang)
changed: [192.168.1.184] => (item=zhuangzhuang)
changed: [192.168.1.182] => (item=zhuangzhuang)
changed: [192.168.1.186] => (item=zhuangzhuang1)
changed: [192.168.1.183] => (item=zhuangzhuang)
changed: [192.168.1.184] => (item=zhuangzhuang1)
changed: [192.168.1.182] => (item=zhuangzhuang1)
changed: [192.168.1.181] => (item=zhuangzhuang)
changed: [192.168.1.186] => (item=zhuangzhuang2)
changed: [192.168.1.183] => (item=zhuangzhuang1)
changed: [192.168.1.184] => (item=zhuangzhuang2)
changed: [192.168.1.186] => (item=zhuangzhuang3)
changed: [192.168.1.181] => (item=zhuangzhuang1)
changed: [192.168.1.182] => (item=zhuangzhuang2)
changed: [192.168.1.184] => (item=zhuangzhuang3)
changed: [192.168.1.183] => (item=zhuangzhuang2)
changed: [192.168.1.182] => (item=zhuangzhuang3)
changed: [192.168.1.181] => (item=zhuangzhuang2)
changed: [192.168.1.183] => (item=zhuangzhuang3)
changed: [192.168.1.185] => (item=zhuangzhuang)
changed: [192.168.1.181] => (item=zhuangzhuang3)
changed: [192.168.1.185] => (item=zhuangzhuang1)
changed: [192.168.1.185] => (item=zhuangzhuang2)
changed: [192.168.1.185] => (item=zhuangzhuang3)
PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.1.181 : ok=1 changed=1 unreachable=0 failed=0
192.168.1.182 : ok=1 changed=1 unreachable=0 failed=0
192.168.1.183 : ok=1 changed=1 unreachable=0 failed=0
192.168.1.184 : ok=1 changed=1 unreachable=0 failed=0
192.168.1.185 : ok=1 changed=1 unreachable=0 failed=0
192.168.1.186 : ok=1 changed=1 unreachable=0 failed=0
#结果
[root@supervisor yaml]# ansible all -m shell -a "cat /etc/passwd|grep '^zhuangzhuang'"
192.168.1.182 | SUCCESS | rc=0 >>
zhuangzhuang:x:1002:1002::/home/zhuangzhuang:/bin/bash
zhuangzhuang1:x:1003:1003::/home/zhuangzhuang1:/bin/bash
zhuangzhuang2:x:1004:1004::/home/zhuangzhuang2:/bin/bash
zhuangzhuang3:x:1005:1005::/home/zhuangzhuang3:/bin/bash
=============================================================================when条件判断
#######################################单一判断
[root@supervisor yaml]# cat when.yml
---
- hosts: all
gather_facts: True
remote_user: root
ignore_errors: yes
tasks:
- name: 判断IP地址是否是192.168.1.182,如果是则创建一个文件
shell: touch /mnt/{{ansible_all_ipv4_addresses[0]}}.txt
when: ansible_all_ipv4_addresses[0] == "192.168.1.182"
注意:不满足条件的会跳过
########################################结合循环判断
#判断ip是否是循环中的IP,如果是则创建文件
[root@supervisor yaml]# cat when2.yml
---
- hosts: all
gather_facts: True
remote_user: root
tasks:
- name: 判断IP是否是182,如果是则创建一个文件
shell: touch /mnt/{{ansible_all_ipv4_addresses[0]}}.txt
when: ansible_all_ipv4_addresses[0] == "{{item}}"
with_items:
- 192.168.1.182
- 192.168.1.183
- 192.168.1.184
- 192.168.1.185
########################################逻辑与
#判断主机IP是否是192.168.1.192并且主机名是否是centos7.4_1,如果是则创建文件
#注意:when条件判断的时候引用变量不需要{{}}
[root@supervisor yaml]# cat when3.yml
---
- hosts: all
ignore_errors: yes
gather_facts: yes
remote_user: root
tasks:
- name: 获取主机名
shell: hostname
register: host
- name: 逻辑与的判断
shell: touch /mnt/{{ansible_all_ipv4_addresses[0]}}.txt
when:
- ansible_all_ipv4_addresses[0] == "192.168.1.182"
- host.stdout == "centos7.4_1"
来源:oschina
链接:https://my.oschina.net/u/4064859/blog/2999740