Ansible任务控制

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 ~]#
相关推荐
格林威2 分钟前
C# 相机图像配合频闪光源:实现高速稳定拍摄的几个方法
开发语言·网络·人工智能·数码相机·计算机视觉·c#·视觉检测
烂蜻蜓16 分钟前
Flask入门教程(七):请求与响应——Web应用的核心数据流
前端·python·flask
Elastic 中国社区官方博客22 分钟前
从告警到根因仅需 3 分钟:使用 Elastic Agent Builder 实现自动化根因分析
运维·数据库·人工智能·elasticsearch·自动化·可用性测试
web行路人29 分钟前
AI 全栈学习之旅 - Week4:容器化部署与生产环境实战
python·学习
月落汀兰35 分钟前
运维实战:LVS-NAT/DR 双模式完整落地,含一键启停脚本,线上直接复用
linux·运维·lvs
春涧草茶36 分钟前
慢就是快 - 10-2函数 特殊字面量 返回值
python
爱研究的小梁42 分钟前
公网地基与卫星天基如何平衡成本与可靠性
网络·信息与通信
慢云智慧空间43 分钟前
空间智能与计算机视觉的本质差异:不止于识别,更是空间决策能力
人工智能·python·计算机视觉
feng_you_ying_li1 小时前
linux之Udpsocket实践
linux·运维·c#
SatanII1 小时前
从零认识云计算|走进云时代,看懂服务器底层基石
运维·服务器·云计算