1.任务控制类型
有些任务并不总是行云流水向下执行的,例如nginx配置文件的复制和服务的启动要在nginx安装成功后才能执行。有些任务的重复内容很多,例如批量创建用户,只是用户名不一样,其他语句没有区别。针对以上情况,可以使用Ansible中的if判断和for循环。
cpp
---
- name: task control playbook example
hosts: webservers
tasks:
- name: create tomcat user
user: name=tomcat state=present
- name: create www user
user: name=www state=present
- name: create mysql user
user: name=mysql state=present
- name: yum nginx webserver
yum: name=nginx state=present
- name: update nginx main config
copy: src=nginx.conf dest=/etc/nginx/
- name: add virtualhost config
copy: src=www.qfedu.com.conf dest=/etc/nginx/conf.d/
- name: start nginx server
service: name=nginx state=started
2.条件判断when
cpp
[root@localhost ~]# ansible-playbook -i hosts my_if.yml
PLAY [task control playbook example] ************************************************************************************
TASK [Gathering Facts] **************************************************************************************************
ok: [192.168.95.132]
TASK [yum nginx webserver] **********************************************************************************************
ok: [192.168.95.132]
TASK [update nginx main config] *****************************************************************************************
changed: [192.168.95.132]
TASK [add virtualhost config] *******************************************************************************************
ok: [192.168.95.132]
TASK [check nginx syntax] ***********************************************************************************************
changed: [192.168.95.132]
TASK [print nginx syntax] ***********************************************************************************************
ok: [192.168.95.132] => {
"nginxsyntax": {
"changed": true,
"cmd": "/usr/sbin/nginx -t",
"delta": "0:00:00.016340",
"end": "2026-04-19 19:17:54.668256",
"failed": false,
"rc": 0,
"start": "2026-04-19 19:17:54.651916",
"stderr": "nginx: the configuration file /etc/nginx/nginx.conf syntax is ok\nnginx: configuration file /etc/nginx/nginx.conf test is successful",
"stderr_lines": [
"nginx: the configuration file /etc/nginx/nginx.conf syntax is ok",
"nginx: configuration file /etc/nginx/nginx.conf test is successful"
],
"stdout": "",
"stdout_lines": []
}
}
TASK [start nginx server] ***********************************************************************************************
ok: [192.168.95.132]
PLAY RECAP **************************************************************************************************************
192.168.95.132 : ok=7 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@localhost ~]# cat my_if.yml
---
- name: task control playbook example
hosts: webservers
tasks:
- name: yum nginx webserver
yum: name=nginx state=present
- name: update nginx main config
copy: src=nginx.conf dest=/etc/nginx/
- name: add virtualhost config
copy: src=www.qfedu.com.conf dest=/etc/nginx/conf.d/
- name: check nginx syntax
shell: /usr/sbin/nginx -t
register: nginxsyntax
- name: print nginx syntax
debug: var=nginxsyntax
- name: start nginx server
service: name=nginx state=started
when: nginxsyntax.rc == 0
[root@localhost ~]# cat www.qfedu.com.conf
server {
listen 80;
server_name www.qfedu.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/www.qfedu.com-access_log main;
error_log /var/log/nginx/www.qfedu.com-error_log;
add_header Access-Control-Allow-Origin *;
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 1d;
}
location ~ .*\.(js|css)?$ {
expires 1d;
}
}
[root@localhost ~]# cat nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
listen [::]:80;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
error_page 404 /404.html;
location = /404.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
when支持的运算符
cpp
==
!=
> >=
< <=
is defined
is not defined
true
false
支持逻辑运算符:and or
3.循环控制with_items
item关键字是固定写法
cpp
[root@localhost ~]# ansible-playbook -i hosts my_with_items.yml
PLAY [variable playbook example] ****************************************************************************************
TASK [Gathering Facts] **************************************************************************************************
ok: [192.168.95.132]
TASK [create user] ******************************************************************************************************
changed: [192.168.95.132] => (item=tomcat)
changed: [192.168.95.132] => (item=www)
changed: [192.168.95.132] => (item=mysql)
PLAY RECAP **************************************************************************************************************
192.168.95.132 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@localhost ~]# cat my_with_items.yml
---
- name: variable playbook example
hosts: webservers
vars:
createuser:
- tomcat
- www
- mysql
tasks:
- name: create user
user: name={{ item }} state=present
with_items: "{{ createuser }}"
[root@localhost ~]#
4.循环控制loop
只是替换了with_items而已
cpp
[root@localhost ~]# ansible-playbook -i hosts my_loop.yml
PLAY [loop and when] ****************************************************************************************************
TASK [show words] *******************************************************************************************************
ok: [192.168.95.131] => (item=a) => {
"ansible_loop_var": "item",
"item": "a"
}
ok: [192.168.95.131] => (item=b) => {
"ansible_loop_var": "item",
"item": "b"
}
ok: [192.168.95.131] => (item=c) => {
"ansible_loop_var": "item",
"item": "c"
}
ok: [192.168.95.132] => (item=a) => {
"ansible_loop_var": "item",
"item": "a"
}
ok: [192.168.95.132] => (item=b) => {
"ansible_loop_var": "item",
"item": "b"
}
ok: [192.168.95.132] => (item=c) => {
"ansible_loop_var": "item",
"item": "c"
}
TASK [show nums when num > 3] *******************************************************************************************
skipping: [192.168.95.131] => (item=1)
skipping: [192.168.95.131] => (item=2)
skipping: [192.168.95.131] => (item=3)
ok: [192.168.95.131] => (item=5) => {
"ansible_loop_var": "item",
"item": 5
}
skipping: [192.168.95.132] => (item=1)
skipping: [192.168.95.132] => (item=2)
skipping: [192.168.95.132] => (item=3)
ok: [192.168.95.132] => (item=5) => {
"ansible_loop_var": "item",
"item": 5
}
PLAY RECAP **************************************************************************************************************
192.168.95.131 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
192.168.95.132 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@localhost ~]# cat my_loop.yml
---
- name: loop and when
gather_facts: no
hosts: all
vars:
word_list:
- "a"
- "b"
- "c"
num_list:
- 1
- 2
- 3
- 5
tasks:
- name: show words
debug:
var: item
loop: "{{ word_list }}"
- name: show nums when num > 3
debug:
var: item
loop: "{{ num_list }}"
when: item > 3
[root@localhost ~]#
5.tags属性
当nginx.conf文件或网站配置文件发生变动时,不是所有的任务都要重新执行一次,只有更新配置文件和重启nginx服务的任务才需要执行,不用安装nginx。
加上了tags属性的任务会执行,其他的任务跳过。
cpp
[root@localhost ~]# ansible-playbook -i hosts my_tags.yml -t updateconfig
PLAY [tags playbook example] ************************************************************
TASK [update nginx main config] *********************************************************
ok: [192.168.95.132]
TASK [add virtualhost config] ***********************************************************
ok: [192.168.95.132]
TASK [check nginx syntax] ***************************************************************
changed: [192.168.95.132]
TASK [check nginx running] **************************************************************
ok: [192.168.95.132]
TASK [reload nginx server] **************************************************************
changed: [192.168.95.132]
TASK [start nginx server] ***************************************************************
skipping: [192.168.95.132]
PLAY RECAP ******************************************************************************
192.168.95.132 : ok=5 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
[root@localhost ~]# cat my_tags.yml
---
- name: tags playbook example
hosts: webservers
gather_facts: no
vars:
createuser:
- tomcat
- www
- mysql
tasks:
- name: create user
user:
name: "{{ item }}"
state: present
with_items: "{{ createuser }}"
- name: yum nginx webserver
yum:
name: nginx
state: present
- name: update nginx main config
copy:
src: nginx.conf
dest: /etc/nginx/
tags: updateconfig
- name: add virtualhost config
copy:
src: www.qfedu.com.conf
dest: /etc/nginx/conf.d/
tags: updateconfig
- name: check nginx syntax
shell: /usr/sbin/nginx -t
register: nginxsyntax
tags: updateconfig
- name: check nginx running
stat:
path: /var/run/nginx.pid
register: nginxrunning
tags: updateconfig
- name: print nginx syntax
debug:
var: nginxsyntax
- name: print nginx running status
debug:
var: nginxrunning
- name: reload nginx server
service:
name: nginx
state: reloaded
when:
- nginxsyntax.rc == 0
- nginxrunning.stat.exists == true
tags: updateconfig
- name: start nginx server
service:
name: nginx
state: started
when:
- nginxsyntax.rc == 0
- nginxrunning.stat.exists == false
tags: updateconfig
[root@localhost ~]#
6.handlers属性
按照上一个playbook的逻辑,即便配置文件没有变化,每次更新配置文件都会重启nginx服务。
当Ansible 认为⽂件的内容发⽣了变化(⽂件MD5发⽣变化了),它就会发送⼀个notify通知信号,通知 handlers 中的对应名称的任务。
cpp
[root@localhost ~]# ansible-playbook -i hosts my_handlers.yml -t updateconfig
PLAY [handlers playbook example] ********************************************************
TASK [update nginx main config] *********************************************************
ok: [192.168.95.132]
TASK [add virtualhost config] ***********************************************************
changed: [192.168.95.132]
TASK [check nginx syntax] ***************************************************************
changed: [192.168.95.132]
TASK [check nginx running] **************************************************************
ok: [192.168.95.132]
RUNNING HANDLER [reload nginx server] ***************************************************
changed: [192.168.95.132]
PLAY RECAP ******************************************************************************
192.168.95.132 : ok=5 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@localhost ~]# cat my_handlers.yml
---
- name: handlers playbook example
hosts: webservers
gather_facts: no
vars:
createuser:
- tomcat
- www
- mysql
tasks:
- name: create user
user:
name: "{{ item }}"
state: present
with_items: "{{ createuser }}"
- name: yum nginx webserver
yum:
name: nginx
state: present
- name: update nginx main config
copy:
src: nginx.conf
dest: /etc/nginx/
tags: updateconfig
notify: reload nginx server
- name: add virtualhost config
copy:
src: www.qfedu.com.conf
dest: /etc/nginx/conf.d/
tags: updateconfig
notify: reload nginx server
- name: check nginx syntax
shell: /usr/sbin/nginx -t
register: nginxsyntax
tags: updateconfig
- name: check nginx running
stat:
path: /var/run/nginx.pid
register: nginxrunning
tags: updateconfig
- name: start nginx server
service:
name: nginx
state: started
when:
- nginxsyntax.rc == 0
- nginxrunning.stat.exists == false
handlers:
- name: reload nginx server
service:
name: nginx
state: reloaded
when:
- nginxsyntax.rc == 0
- nginxrunning.stat.exists == true
[root@localhost ~]#