任务块
可以通过block关键字,将多个任务组合到一起
可以将整个block任务组,一起控制是否要执行
# 如果test组中的主机系统发行版是RedHat,则安装并启动httpd
[root@control ansible]# vim block1.yml
---
- name: block tasks
hosts: test
tasks:
- name: define a group of tasks
block:
- name: install httpd # 通过yum安装httpd
yum:
name: httpd
state: present
- name: start httpd # 通过service启动httpd服务
service:
name: httpd
state: started
enabled: yes
when: ansible_distribution=="RedHat" # 条件为真才会执行上面的任务
[root@control ansible]# ansible-playbook block1.yml
rescue和always
block和rescue、always联合使用:
- block中的任务都成功,rescue中的任务不执行
- block中的任务出现失败(failed),rescue中的任务执行
- block中的任务不管怎么样,always中的任务总是执行
[root@control ansible]# vim block2.yml
---
- name: block test
hosts: test
tasks:
- name: block / rescue / always test1
block:
- name: touch a file
file:
path: /tmp/test1.txt
state: touch
rescue:
- name: touch file test2.txt
file:
path: /tmp/test2.txt
state: touch
always:
- name: touch file test3.txt
file:
path: /tmp/test3.txt
state: touch
# 执行playbook node1上将会出现/tmp/test1.txt和/tmp/test3.txt
[root@control ansible]# ansible-playbook block2.yml
[root@node1 ~]# ls /tmp/test*.txt
/tmp/test1.txt /tmp/test3.txt
# 修改上面的playbook,使block中的任务出错
[root@node1 ~]# rm -f /tmp/test*.txt
[root@control ansible]# vim block2.yml
---
- name: block test
hosts: test
tasks:
- name: block / rescue / always test1
block:
- name: touch a file
file:
path: /tmp/abcd/test11.txt
state: touch
rescue:
- name: touch file test22.txt
file:
path: /tmp/test22.txt
state: touch
always:
- name: touch file test33.txt
file:
path: /tmp/test33.txt
state: touch
# 因为node1上没有/tmp/abcd目录,所以block中的任务失败。但是playbook不再崩溃,而是执行rescue中的任务。always中的任务总是执行
[root@control ansible]# ansible-playbook block2.yml
[root@node1 ~]# ls /tmp/test*.txt
/tmp/test22.txt /tmp/test33.txt
loop循环
相当于shell中for循环
ansible中循环用到的变量名是固定的,叫item
# 在test组中的主机上创建5个目录/tmp/{aaa,bbb,ccc,ddd,eee}
[root@control ansible]# vim loop1.yml
---
- name: use loop
hosts: test
tasks:
- name: create directory
file:
path: /tmp/{{item}}
state: directory
loop: [aaa,bbb,ccc,ddd,eee]
# 上面写法,也可以改为:
---
- name: use loop
hosts: test
tasks:
- name: create directory
file:
path: /tmp/{{item}}
state: directory
loop:
- aaa
- bbb
- ccc
- ddd
- eee
[root@control ansible]# ansible-playbook loop1.yml
# 使用复杂变量。创建zhangsan用户,密码是123;创建lisi用户,密码是456
# item是固定的,用于表示循环中的变量
# 循环时,loop中每个-后面的内容作为一个整体赋值给item。
# loop中{}中的内容是自己定义的,写法为key:val
# 取值时使用句点表示。如下例中取出用户名就是{{item.uname}}
[root@control ansible]# vim loop_user.yml
---
- name: create users
hosts: test
tasks:
- name: create multiple users
user:
name: "{{item.uname}}"
password: "{{item.upass|password_hash('sha512')}}"
loop:
- {"uname": "zhangsan", "upass": "123"}
- {"uname": "lisi", "upass": "456"}
[root@control ansible]# ansible-playbook loop_user.yml
sudo命令
- 一般用于普通用户执行需要root权限的命令
- 在node1上配置zhangsan拥有sudo权限
# 如果没有zhangsan,手工创建
[root@node1 ~]# visudo # 将会打开vi,在尾部追加以下一行
zhangsan ALL=(ALL) ALL
# 中间的ALL=(ALL)在集中认证的域环境中才有效,单机忽略即可
# zhangsan是用户名,最后的ALL表示zhangsan可以以管理员的身份执行所有命令
# 切换成zhangsan用户,执行命令
[root@node1 ~]# su - zhangsan
[zhangsan@node1 ~]$ useradd wangwu # 失败,因为还是张三身份
[zhangsan@node1 ~]$ sudo useradd wangwu # 以管理员身份执行
... ...
[sudo] password for zhangsan: # 输入zhangsan的密码,不是root
# 配置lisi不输入密码可以直接运行sudo
[root@node1 ~]# visudo # 在最后追加一行
lisi ALL=(ALL) NOPASSWD: ALL
# 切换成lisi运行
[root@node1 ~]# su - lisi
[lisi@node1 ~]$ ls /root/ # 没权限
ls: cannot open directory '/root/': Permission denied
[lisi@node1 ~]$ sudo ls /root/ # 成功运行,无需输入密码
a3.txt anaconda-ks.cfg