内容大纲
1 条件判断
1.1 when
- 只有当条件符合时才执行对应任务
- 如下例 , 只有当cpu 大于等于3个, 且内存大于等于400时, 才会执行同等级的debug,输出信息
- 注意: when 中用于判断的变量无需使用双花括号来引用 (因为when语句默认包含一层双花括号)
---
- hosts: group_a
remote_user: root
tasks:
- name: a
debug:
msg: "{{ ansible_processor_vcpus }} , {{ ansible_memtotal_mb }}"
when:
- ansible_processor_vcpus >= 3
- ansible_memtotal_mb >= 400
1.2 changed_when
- 当条件满足时,会将本任务的执行状态设置为 changed
- 可以用来触发 handlers
---
- name: test
hosts: group_a
gather_facts: false
vars:
flag: 1
tasks:
- name: aaa
debug:
msg: "aaaaaaaaaaaaaa"
changed_when: flag==1 # 当flag值为1的时候,本任务的状态将变为changed,从而触发handlers,重启nginx
notify: restart_nginx
handlers:
- name: restart_nginx
service:
name: nginx
state: restarted
可以看到, 默认是ok状态的debug输出信息变成了changed状态信息, nginx也因为handlers重启了
1.3 failed_when
- 当条件满足时,会将本任务的执行状态设置为 failed
- 可以用来触发 handlers
---
- name: test
hosts: group_a
tasks:
- name: echo error
shell: "echo 'start error aaaaaaaaaa'"
register: status
failed_when: " 'error' in status.stdout" # echo输出的内容中有error,所以触发失败
- name: debug
debug:
msg: "{{ status.stdout }}"
去除 failed_when 后,顺利执行
2 循环语句
2.1 with_items
2.1.1 循环数组
若有多个数组,会将各数组展开, 然后逐个循环其中元素
---
- hosts: host_1
remote_user: root
gather_facts: no # 不获取facts,加快执行速度
tasks:
- name: a
debug:
msg: "{{ item }}"
when:
- item | int >= 2 # 先通过管道符,尝试转化为整型,再参与判断
- item | int <= 3
with_items: # with_items 中若有多个数组,会将各数组展开,逐个循环其中元素
- [1,2,3,4]
- [aaa,bbb]
- "2"
2.1.2 循环字典
例; 使用循环创建用户和组
---
- hosts: group_a
remote_user: root
gather_facts: no
tasks:
- name: add group
group:
name: "{{ item.groups }}"
state: present
with_items:
- { name: 'testuser1',groups: 'testgroup1'}
- { name: 'testuser2',groups: 'testgroup2'}
- name: add users
user:
name: "{{ item.name }}"
group: "{{ item.groups }}"
state: present
with_items:
- { name: 'testuser1',groups: 'testgroup1'}
- { name: 'testuser2',groups: 'testgroup2'}
- name: check user
shell: "id testuser1;id testuser2"
register: "user_status"
- name: debug user
debug:
msg: "{{ user_status.stdout_lines }}"
2.2 with_list
不会将数组展开, 而是作为一个整体参与循环
---
- hosts: host_1
remote_user: root
gather_facts: no # 不获取facts,加快执行速度
tasks:
- name: a
debug:
msg: "{{ item }}"
when:
- item | int >= 2 # 先通过管道符,尝试转化为整型,再参与判断
- item | int <= 3
with_list: # with_items 中若有多个数组,会将各数组展开,逐个循环其中元素
- [1,2,3,4]
- [aaa,bbb]
- "2"
2.3 with_together
数组会对位重组
---
- hosts: host_1
remote_user: root
gather_facts: no
tasks:
- name: a
debug:
msg: "{{ item }}"
with_together:
- [1,2,3,4]
- [a,b,c,d]
- ['1','2','3','4']
3 触发器 handlers
在task 任务之后再加一个同级的 handlers ,其中定义要执行的任务
随后在需要监听的地方通过 notify 调用 handlers下具体任务
---
- hosts: group_a
remote_user: root
tasks:
- name: add group
group:
name: nginx
state: present
- name: add user
user:
name: nginx
group: nginx
- name: install nginx
yum:
name: nginx
state: latest
- name: config
template:
src: ./template/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: nginx
group: nginx
mode: '0644'
notify: nginx restart
- name: start nginx
service:
name: nginx
state: started
handlers:
- name : nginx restart
service:
name: nginx
state: restarted
--tags=
---
- hosts: group_a
remote_user: root
tasks:
- name: echo aaaa
debug:
msg: "aaaa"
- name: check worker_processes
shell: "ps -ef |grep nginx"
register: "wk_pcs"
tag: c_w_p
- name: debug worker_processes
debug:
msg: "{{ wk_pcs.stdout_lines }}"
tag: c_w_p
可以看到,仅仅执行了指定标签的任务
--skip-tags
tags:
- aaaa
- bbbb
tags: ['aaaa','bbbb']
tags: aaaaa,bbbb
4.4 为一个play指定一组标签
添加之后,此play下的所有tasks都将继承这些tags
- name: nginx_web_install_config
hosts: group_a
remote_user: root
tags:
- web
tasks:
...
...
4.5 ansible内置的标签
除了用户自定义tag,ansible也内置了几个tag,这些tag都包含特殊含义:
-
always:一旦某个task被打上了always的tag,则无论是playbook的完整执行,还是指定tag执行,不管你指定的tag是啥,该任务总是会被执行。除非明确指定"--skip-tags=always"选项,才不会执行该task。
-
never:该标签与always正好相反,总是不会执行,除非明确指定"--tags=never"选项。
-
tagged:在调用时使用
# 所有打了tag的任务都会被执行,包含never tag的除外,没有标签的不会被执行 ansible-playbook --tags tagged install_web.yaml # 所有打了tag的任务都不会被执行,包括always tag也不会被执行 ansible-playbook --skip-tags tagged install_web.yaml
-
untagged:在调用时使用
# 所有未打tag的任务都会被执行,打了always tag的也会被执行 ansibl-playbook --tags untagged install_web.yaml # 所有未打tag的任务都不会被执行 ansibl-playbook --skip-tags untagged install_web.yaml
-
all:表示所有任务都会被执行,在默认情况下,不指定任何标签,则使用的就是该标签
5 include和import 导入
5.1 使用方法
共有2种常见的导入方法
include 和 import
2者使用方法都相似, 在tasks中直接导入即可
tasks:
- include_tasks: test1.yml
tasks:
- import_tasks: test1.yml
5.2 主要区别
include和import的主要区别有2点
- 导入时变量作用域不同
- 导入时的文件名称是否可以加变量
文件 test1.yml
---
- set_fact: aaaa=="bbbb"
- name: test1
debug:
msg: "{{ aaaa }}"
5.2.1 include_tasks
-
ansible会在完全执行完test.yml里的task后,再加载test1.yml里的变量,
即若本地变量和待导入的文件中有变量冲突时, 不会发生变量值的替换
- 举例:
test.yml中aaaa的值为"aaaa1234",test1.yml中aaaa的值为"bbbb",两者互不影响;
由于when判断通过,从而执行test1.yml中的task
---
- name: test
hosts: group_a
gather_facts: false
vars:
aaaa: "aaaa1234"
file_name: "test1"
tasks:
- include_tasks: "{{ file_name }}.yml"
# include 导入方法可以将文件名用变量表示, import会直接报错
when:
aaaa=="aaaa1234"
5.2.2 import_tasks
- ansible会在playbook解析阶段就将所有文件的变量都全部解析,此时可能会出现变量重新赋值等问题
举例:
test.yml中aaaa的值开始时定义为"aaaa1234",test1.yml中aaaa的值为"bbbb"
合并之后,后导入的test1中变量会替换test中变量,将test.yml中aaaa的值更新为"bbbb"
导致test.yml中when判断不符,从而跳过执行test1.yml中的task
---
- name: test
hosts: group_a
gather_facts: false
vars:
aaaa: "aaaa1234"
tasks:
- import_tasks: test1.yml # import方法此处只能指明文件名,用变量会报错
when:
aaaa=="aaaa1234"
6 错误忽略 ignore_errors
在playbook执行的过程中,难免会遇到一些错误,但是playbook遇到错误后,不会执行之后的任务,不便于调试。
所以此时可以使用ignore_errors来暂时忽略错误,使得playbook继续执行
---
- name: test
hosts: group_a
gather_facts: false
vars:
aaaa: "aaaa1234"
tasks:
- name: copy # 创建一个copy模块,并指定一个不存在的src源文件
copy:
src: ./aaaa/aaaa/aaa.sh
dest: /root/aaa.sh
ignore_errors: True # 配置此项后,会暂时跳过忽略错误
- name: echo
debug:
msg: "已经跳过上一步copy错误"