目录
Ansible的Loop循环
简单的Loop循环
数组列表方式的Loop循环
字典方式的Loop循环
基于外部变量的Loop循环
Ansible的When判断
通过魔法变量、事实变量作为条件
通过剧本执行结果的变量来作为条件
Ansible处理程序
Ansible处理失败任务
处理失败任务ignore_errors
强制执行失败的任务对应的处理程序force_handlers
指定任务失败的条件failed_when
通过Ansible块block处理错误任务
Ansible的Loop循环
在playbook中使用循环语句,可以批量的执行任务(例如批量创建用户、批量安装应用等)
在loop关键字中定义要循环的元素列表,然后通过固定变量名为item来依次提取loop中的元素列表
简单的Loop循环
创建用户admin1和admin2
---
- name: create users with loop
hosts: web
tasks:
- name: create user
user:
name: "{{ item }}"
loop:
- admin1
- admin2
数组列表方式的Loop循环
创建普通用户admin1,系统用户admin2
---
- name: create users with loop
hosts: web
tasks:
- name: create user
user:
name: "{{ item.user }}"
group: "{{ item.shell }}"
loop:
- user: admin1
shell: /bin/bash
- user: admin2
shell: /sbin/nologin
字典方式的Loop循环
创建普通用户admin1,系统用户admin2
---
- name: create users with loop
hosts: web
tasks:
- name: create user
user:
name: "{{ item.name }}"
shell: "{{ item.shell }}"
loop:
- { name: "admin1" , shell: "/bin/bash" }
- { name: "admin2" , shell: "/sbin/nologin" }
基于外部变量的Loop循环
创建普通用户admin1,系统用户admin2
定义变量文件
vim user.yml
users:
- name: admin1
shell: /bin/bash
- name: admin2
shell: /sbin/nologin
定义剧本
vim create_user.yml
---
- name: create users with loop
hosts: web
vars_files:
- user.yml
tasks:
- name: create user
user:
name: "{{ item.name }}"
shell: "{{ item.shell }}"
state: present
loop: "{{ user }}"
Ansible的When判断
可以通过when关键字来定义判断语句,只有这个判断语句成功了才会执行此模块任务,不满足条件就不执行
When判断语句格式
when: 跟上判断表达式
比较运算符
== 两边是否相等
!= 两边是否不相等
: 比较大小,左边的值大于右边的值为真
< 比较大小,左边的值小于右边的值为真
= 比较大小,左边的值大于等于右边的值为真
<= 比较大小,左边的值小于等于右边的值为真
逻辑运算符
and 逻辑与;都满足才成功
or 逻辑或;只要有一个条件满足,就成功
not 逻辑否;对表达式进行取反
() 将其多个表达式组合到一起(组合内的所有表达式要同时满足)
通过魔法变量、事实变量作为条件
如果主机属于资产清单中web主机组中的主机,则安装httpd(invenrtory_hostname为魔法变量)
--- - name: yum hosts: all tasks: - name: install httpd yum: name: httpd state: latest when: inventory_hostname in groups.web
如果主机存在IPv4地址,则安装httpd(ansible_facts为事实变量)
--- - name: yum hosts: all tasks: - name: install httpd yum: name: httpd state: latest when: ansible_facts['default_ipv4']['address'] is defined
通过剧本执行结果的变量来作为条件
以rc变量举例子
当通过剧本安装软件包时,执行结果中会有rc变量,rc变量有0和1两种值
如果rc=0,表示此安装包已经存在或之前不存在但是安装成功
如果rc=1,表示此安装包不存在,安装失败
可以通过register关键字来将执行结果定义到某个变量中,然后再提取出此变量中rc变量对应的值来作为判断条件(也可以通过debug模块将执行结果显示出来)
安装httpd,并显示执行结果;如果主机上已经存在httpd,则删除httpd --- - name: install hosts: all tasks: - name: install httpd yum: name: httpd state: present register: result - name: debug debug: var: result - name: renove httpd yum: name: httpd state: absent when: result.rc == 0
Ansible处理程序
Ansible处理程序是指响应其他任务而触发的任务,触发的任务就为处理程序
只有当响应任务在被管理节点执行并生效后(执行结果为黄色),才会触发处理程序;并且处理程序是在playbook中所有任务完成后才会运行
handlers元素
handlers元素属于和tasks同级的列表,作用是定义处理程序
等待tasks中任务执行的结果为changed(黄色)时触发notify,然后调用handlers下的此notify所对应的任务
notify元素
notify元素作为handlers的触发器,在tasks中的某段代码中定义,与模块并列
实例
当httpd和phpinfo安装成功后,开启httpd和phpinfo服务 --- - name: httpd hosts: web tasks: - name: install httpd yum: name: httpd state: present notify: - start httpd handlers: - name: start httpd service: name: httpd state: started
注意事项
handler执行的顺序只与playbook定义的顺序有关,与handler配置的notify的顺序无关
handlers中的- name的名字需要与notify定义的名字一致
处理程序只有在使用notify语句调用时才会被触发
处理程序是在playbook的正常任务全部执行结束后才会被执行
handler里面的任务只会执行依次,即使handler中的一个任务被通知了多次
Ansible处理失败任务
处理失败任务ignore_errors
当ansibke任务执行失败时,就会中止playbook的执行,并跳过所有后续任务
当有时希望即使在任务失败时,忽略此处的错误,继续执行后续任务,此时就需要配置ignore_error:yes来实现(ignore_error元素与模块并列)
注意事项
并不是所有的错误都可以忽略,只有当任务的执行成功或失败对后面的任务没有关联的时候才可以忽略
实例
当php安装失败后继续执行mariadb的安装 --- - name: install hosts: server tasks: - name: install php yum: name: php state: present ignore_errors: yes - name: isntall mariadb yum: name: mariadb tate: present ignore_errors: yes
强制执行失败的任务对应的处理程序force_handlers
如果在主机上的执行的任务失败时,则此任务对应的处理程序不再运行
此时可以通过force_handlers: yes实现,即使notify对应的响应任务执行失败,仍继续执行noftify对应的处理程序(即使任务失败了也要调用notify触发handlers)
force_handlers与tasks同层级
实例
--- - name: httpd hosts: web force_handlers: yes tasks: - name: install httpd yum: name: httpd state: present notify: - start httpd handlers: - name: start httpd service: name: httpd state: started
指定任务失败的条件failed_when
通过failed_when来指定任务失败的条件;即人为指定此任务失败的条件,将正常的任务转为失败的任务(如果满足failed_when定义的条件,则就判断此任务执行失败)
注意
任务执行失败不一定就是任务存在错误(也有可能是人为制造的)
实例
如果主机属于ftp组,则显示bug模块的内容,然后中止任务 --- - name: httpd hosts: all tasks: - name: deubg debug: msg: "hostname is not web" when: inventory_hostname in groups['ftp'] failed_when: inventory_hostname in groups['ftp'] - name: copy copy: content: "Welcome to {{ ansible_facts.hostname }}" dest: /var/www/index.html
通过Ansible块block处理错误任务
在playbook中,通过块block可以对任务进行逻辑分组,可以实现错误处理
通过块block可以结合rescue和always语句来实现错误处理
block与when、rescue、always是同一级别,位于tasks之下
如果块block中的任何任务失败,则执行其rescue中的任务来进行
block、rescue、always概念
block:定义要运行的主要任务(block中的任何一个task出错,会顺序执行rescue中的task)
rescue:定义 当在block子句中定义的任务失败时 运行的任务
always:定义始终都独立运行的任务,不论block和rescue子句中定义的任务是成功还是失败
block任务执行成功 → 直接走always中的任务(不执行rescue对应的任务)
block任务执行失败 → 走rescue中的任务 → 走always中的任务
实例
对vdc磁盘分区,分为1500m(如果磁盘无法分为1500m则分为800m),最后将磁盘格式化为ext4格式 --- - name: create /dev/vdc hosts: web tasks: - name: block block: - name: create vdc1 1000MiB parted: device: /dev/vdc number: 1 state: present part_end: 1000MiB rescue: - name: create vdc 500MiB parted: device: /dev/vdc number: 1 state: present part_end: 500MiB always: - name: create ext4 filesystem: fstype: ext4 dev: /dev/vdc1