Ansible循环与判断
一、Ansible循环
1.with_items迭代列表
当Linux中依次需要安装多个软件包时,可以使用with_items迭代功能进行实现。
# 安装 httpd smaba smaba-client --- - name: install hosts: all tasks: - name: install httpd smaba smaba-client yum: name: "{{ item }}" state: present with_items: - httpd - smaba - smaba-client # with_items可以使用loop代替
2.with_dict迭代字典
item.key对应是字典的键,item.value对应是字典的值
--- - name: test hosts: all tasks: - name: debug debug: msg: "{{ item.key }} & {{ item.value }}" with_dict: address: 1 netmask: 2 gateway: 3 # 结果为 address & 1 netmask & 2 gateway & 3
3.with_fileglob迭代文件
当拷贝多个文件到受控主机上时,可以使用。
# 拷贝本机/tmp/中所有.sh结尾和.py结尾的文件到node1的/tmp/中 --- - name: test hosts: node1 tasks: - name: cp file copy: src: "{{ item }}" dest: /tmp/ with_fileglob: - /tmp/*.sh - /tmp/*.py
4.with_lines迭代行
with_lines可以将命令行的输出结果按行迭代。
# 查找本机/home/student/ansible/中所有的/.yml结尾的文件,并将这些文件拷贝到主机node1的/tmp/中 --- - name: test hosts: node1 tasks: - name: cp file copy: src: "{{ item }}" dest: /tmp/ with_lines: - find /home/student/ansible/ -name "*.yml"
5.with_nested嵌套迭代
例如:a、b、c与1、2、3连接组合
--- - name: test hosts: node1 tasks: - name: debug debug: msg: "{{ item[0] }} & {{ item[1] }}" with_nested: - [a,b,c] - [1,2,3]
6.with_sequence排序列
start:是从什么开始
stride:每隔多少
end:结束
# 在主机node1中显示1、3、5、7、9 --- - name: test hosts: node1 tasks: - name: debug debug: var: item with_sequence: start=1 end=10 stride=2
7.with_random_choice随机获得列表中的一个值
--- - name: test hosts: node1 tasks: - name: debug debug: msg: "{{item}}" with_random_choice: - 1 - 2 - a - b - c
8.过滤器
# 字符相关过滤器 upper # 将字符串转换成纯大写 lower # 将字符串转换成纯小写 trim # 将字符串的首尾空格去掉,可以去掉多个空格 length # 求字符串的长度,与count等效 capitalize # 将字符串首字母大写,之后的所有字母纯小写 first # 返回字符串的第一个字符 last # 返回字符串的最后一个字符 center(width=30) # 将字符串居中,并设置长度为30,长度不足,字符串两边用空格补全 list # 将字符串转换成列表,每个字符作为一个元素 shuffle # 洗牌,即将字符串转换成列表,每个字符作为一个元素,并且随机打乱顺序 # 数字操作有关的过滤器 int # 将对应的值转换成int类型,如果无法转换,默认返回0 float # 将对应的值转换成浮点型,如果无法转换,默认返回'0.0' abs # 获取对应数值的绝对值 round # 四舍五入 round(5) # 取小数点后5位 random # 随机返回一个随机数,random(start=5)从5开始 random(step=3) # 返回一个随机数,这个随机数是3的倍数 random(start=5,step=3) # 返回一个随机数,从5开始,步长为3,例如{{ 15 | random(start=5,step=3) }},返回的随机数只可能是5、8、11、14 # 文件或目录类过滤器 hash('sha1') # 使用sha1算法对字符串进行哈希 hash('md5') # 使用md5算法对字符串进行哈希 checksum # 获取到字符串的校验和,与md5哈希值一致 password_hash('sha256') # 使用sha256算法对字符串进行哈希,哈希过程中会生成随机"盐",以便无法直接对比出原值 password_hash('sha256','mysalt') # 使用sha256算法对字符串进行哈希,并使用指定的字符串作为"盐" password_hash('sha512') # 使用sha512算法对字符串进行哈希,哈希过程中会生成随机"盐",以便无法直接对比出原值 password_hash('sha512','ebzL.U5cjaHe55KK') # 使用sha512算法对字符串进行哈希,并使用指定的字符串作为"盐"
--- - name: test hosts: node1 vars: testvar: "abc123ABC 666" testvar1: " abc " tasks: - name: debug1 debug: msg: "{{ testvar | upper }}" - name: debug2 debug: msg: "{{ testvar | lower }}" - name: debug3 debug: msg: "{{ testvar1 | trim }}" - name: debug4 debug: msg: "{{ testvar1 | length }}" - name: debug5 debug: msg: "{{ testvar | capitalize }}" - name: debug6 debug: msg: "{{ testvar | first }}" - name: debug7 debug: msg: "{{ testvar | last }}" - name: debug7 debug: msg: "{{ testvar | shuffle }}" - name: debug8 debug: msg: "{{ testvar | list }}"
二、Ansible判断
when关键字
判断运算符
== # 等于 != # 不等 > < >= <= and or not is in
每次执行完一个任务,不管成功与失败,都会将执行的结果进行注册,可以使用这个注册的变量来when
判断变量
Defined # 判断变量是否已经定义,已定义则返回真 Undefined # 判断变量是否已经定义,未定义则返回真 None # 判断变量值是否为空,如果变量已经定义,但是变量值为空,则返回真
判断执行结果
Success/successed # 通过任务的返回信息判断执行状态,任务执行成功返回真 Failure/failed # 通过执行任务的返回信息判断执行状态,任务执行失败返回真 Change/changed # 通过任务的返回信息判断执行状态,任务返回状态为changed返回真 Skip/skipped # 通过任务的返回信息判断执行状态,当任务没有满足条件,而被跳过执行,则返回真
判断路径
# 判断均对ansible主机中的路径,与目标主机无关 file # 判断路径是否是一个文件 directory # 判断路径是否是一个目录 link # 判断路径是否是一个软连接 mount # 判断路径是否是一个挂载点 exists # 判断路径是否存在
判断字符串
# 该判断字符串中的字母大小写,字符串中的数字与其他字符不影响判断 upper # 判断包含字母的字符串中的字母是否为纯大写 lower # 判断包含字母的字符串中的字母是否为纯小写
其他判断
string # 判断对象是否是一个字符串 number # 判断对象是否是一个数字
block/rescue/always
如果block执行失败,则执行rescue,无论是block还是rescue执行失败还是成功,在最后都执行always
判断与错误处理
fail模块可用于中断剧本,但我们一般是不会无故中断,除非在满足条件的情况下可以中断,经常和when一起用
--- - name: test hosts: node1 tasks: - name: shell shell: cmd: echo 'this is a string for testing--error' register: return_value - name: fail fail: msg: Conditions established,Interrupt running playbook when: "'error' in return_value.stdout" - name: debug debug: msg: I never execute,because the playbook has stopped
三、练习
练习1
创建一个名为/etc/ansible/lv.yml 的playbook,它将在所有受管节点上运行以执行下列任务:
创建符合以下要求的逻辑卷:
逻辑卷创建在research卷组中
逻辑卷名称为data
逻辑卷大小为1500MiB
使用ext4文件系统格式化逻辑卷
如果无法创建请求的逻辑卷大小,应显示错误消息Could not create logical volume of that size,并且应改为使用大小 800MiB。
如果卷组research 不存在 ,应显示错误消息Volume group does not exist。
不要以任何方式挂载逻辑卷
前提:在node1、node2上添加一块硬盘,然后新建卷组
Node1的卷组大小为2G 卷组名为research
Node2的卷组大小为1G 卷组名为research
--- - name: test hosts: all tasks: - name: create lv block: - name: create lv 1500M lvol: vg: research lv: data size: 1500 rescue: - name: output debug: msg: Could not create logical volume of that size - name: create lv 800M lvol: vg: research lv: data size: 800 always: - name: filesystem filesystem: dev: /dev/research/data fstype: ext4 when: "'research' in ansible_lvm.vgs" - name: research not exists debug: msg: Volume group does not exist when: "'research' not in ansible_lvm.vgs"
练习2
从 http://ansible.example.com/materials/newhosts.j2 下载模板文件 完成该模板文件,用来生成新主机清单(主机的显示顺序没有要求),结构如下:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.122.10 node1.example.com node1 192.168.122.20 node2.example.com node2 192.168.122.30 node3.example.com node3 192.168.122.40 node4.example.com node4 192.168.122.50 node5.example.com node5
创建剧本/home/student/ansible/newhosts.yml,它将使用上述模板在 test01 主机组的主机上 生成文件/etc/newhosts。
1.ansible主机下载模板文件
# ansible主机下载模板文件 [student@master ansible]$ curl -O http://ansible.example.com/materials/newhosts.j2
2.修改newhosts.j2文件
vim newhosts.j2 # 在后面写 {% for i in groups.all %} {{ hostvars[i].ansible_default_ipv4.address }} {{ hostvars[i].ansible_fqdn }} {{ hostvars[i].ansible_hostname }} {% endfor %} # groups.all为所有受控主机 # hostvars为主机变量
3.编写剧本/home/student/ansible/newhosts.yml
--- # 先获取所有主机的事实变量 - name: test hosts: all - name: test1 hosts: test01 tasks: - name: aa template: src: /home/student/ansible/newhosts.j2 dest: /etc/newhosts
4.验证
[student@master ansible]$ ansible test01 -m shell -a 'cat /etc/newhosts'
练习3
编写剧本修改远程文件内容 创建剧本 /home/student/ansible/newissue.yml,满足下列要求: 1)在所有清单主机上运行,替换/etc/issue 的内容 2)对于 test01 主机组中的主机,/etc/issue 文件内容为 test01 3)对于 test02 主机组中的主机,/etc/issue 文件内容为 test02 4)对于 web 主机组中的主机,/etc/issue 文件内容为 Webserver
--- - name: test hosts: all tasks: - name: copy copy: content: | {% if 'test01' in group_names %} test01 {% elif 'test02' in group_names %} test02 {% elif 'web' in group_names %} Webserver {% endif %} dest: /etc/issue
验证
[student@master ansible]$ ansible all -m shell -a 'cat /etc/issue'