四:Ansible流程控制

一:playbook条件语句---when判断

1. 根据不同的操作系统安装nginx

#官方示例:
tasks:
  - name: "shut down Debian flavored systems"
    command: /sbin/shutdown -t now
    when: ansible_facts['os_family'] == "Debian"
    # note that all variables can be used directly in conditionals without double curly braces
- hosts: web_group
  tasks:
    - name: Install CentOS nginx
      yum:
        name: nginx
        state: present
    #官方
      when: ansible_facts['os_family'] == "CentOS"
    #非官方
      when: ansible_distribution == "CentOS"

    - name: Install Ubuntu nginx
      yum:
        name: apache2
        state: present
      when: ansible_facts['os_family'] == "Ubuntu"

2. 使用括号对条件分组

tasks:
  - name: "shut down CentOS 6 and Debian 7 systems"
    command: /sbin/shutdown -t now
    when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or
          (ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7")

3. 指定多条件为列表

tasks:
  - name: "shut down CentOS 6 systems"
    command: /sbin/shutdown -t now
    when:
      - ansible_facts['distribution'] == "CentOS"
      - ansible_facts['distribution_major_version'] == "6"

案例:rsync推送配置文件(前期学习)

#服务端:
[root@m01 ~]# cat rsyncd/rsyncd.yml
- hosts: rsync_server
  tasks:
    - name: Install Rsyncd Server
      yum:
        name: rsync
        state: present

    - name: Create www Group
      group:
        name: www
        gid: 666
        
    - name: Create www User
      user:
        name: www
        group: www
        uid: 666
        create_home: false
        shell: /sbin/nologin

    - name: Scp Rsync Config
      copy:
        src: ./rsyncd.j2
        dest: /etc/rsyncd.conf
        owner: root
        group: root
        mode: 0644
      when: ansible_hostname == "backup"
           #ansible_fqdn == "backup"

    - name: Create Passwd File
      copy:
        content: 'rsync_backup:123'
        dest: /etc/rsync.passwd
        owner: root
        group: root
        mode: 0600
      when: ansible_hostname == "backup"

    - name: Create backup Directory
      file:
        path: /backup
        state: directory
        mode: 0755
        owner: www
        group: www
        recurse: yes
      when: ansible_hostname == "backup"

    - name: Start Rsyncd Server
      systemd:
        name: rsyncd
        state: started
      when: ansible_hostname == "backup"
      
#客户端
[root@m01 ~]# vim rsync.yml
- hosts: rsync_server
  tasks:
    - name: SCP Backup Shell
      copy:
        src: ./backup.sh
        dest: /root/backup.sh
      when: ansible_hostname is match "web*"

注意点:1.when需要和模块对齐

2.如果用正则需要用“is match”来匹配

3.正常情况下判断是“==” 如果不等于“!=”

4. 通过register将命令执行结果保存至变量,然后通过when语句进行判断

- hosts: web_group
  tasks:
    - name: Check Httpd Server
      command: systemctl is-active httpd
      ignore_errors: yes     #忽略错误,方便下一步继续执行
      register: check_httpd

    - name: Httpd Restart
      service:
        name: httpd
        state: started
      when: check_httpd.rc != 0
      
说明:
1.systemctl is-active httpd 查看httpd是否启动,没有启动会报错rc=3(0为正常)
2.register设置变量check_httpd
3.when判断check_httpd.rc是否等于0
4.如果不等于0,将开启nginx服务
      

二:playbook循环语句

如:同时启动多个服务或同时创建多个mysql用户

1. 定义变量循环

EX1:启动多个服务
- hosts: web_group
  tasks:
    - name: start service
      systemd:
        name: "{{ item }}"
        state: started
      with_items:
        - httpd
        - php-fpm
        - mariadb
        
EX2:安装多个服务
- hosts: web_group
  tasks:
    - name: ensure a list of packages installed
      yum: name= "{{ item }}" state=present
      with_items:
        - httpd
        - httpd-tools

2. 字典循环

EX1:创建多个用户
[root@m01 ~]# cat loop.yml
- hosts: web_group
  tasks:
    - name: Add Users
      user:
        name: "{{ item.name }}"
        groups: "{{ item.groups }}"
        state: present
      with_items:
        - { name: 'zls', groups: 'linux' }
        - { name: 'egon', groups: 'python' }
        
EX2:拷贝多个文件
- hosts: web_group
  tasks:
    - name: Configure Nginx Websit PHP Conf
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        mode: "{{ item.mode }}"
      with_items:
        - {src: './nginx.j2',dest: '/etc/nginx/nginx.conf',mode: '0644'}
        - {src: './php.drz.com.j2',dest: '/etc/nginx/conf.d/php.drz.com.conf',mode: '0755'}
        - {src: './php.j2',dest: '/etc/php-fpm.d/www.conf',mode: '0000'}

三:playbook handlers

handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。

在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可。

案例

[root@m01 ~]# cat handler.yml 
- hosts: web_group
  vars:
    - http_port: 8080
  tasks:
    - name: Install Http Server
      yum:
        name: httpd
        state: present

    - name: config httpd server
      template:
        src: ./httpd.j2
        dest: /etc/httpd/conf
      notify: 
        - Restart Httpd Server
        - Restart PHP Server

    - name: start httpd server
      service:
        name:httpd
        state: started
        enabled: yes

  handlers:
    - name: Restart Httpd Server
      systemd:
        name: httpd
        state: restarted 

    - name: Restart PHP Server
      systemd:
        name: php-fpm
        state: restarted

注意:
1.无论多少个task通知了相同的handlers,handlers仅会在所有tasks结束后运行一次。

2.Handlers只有在其所在的任务被执行时,才会被运行;如果一个任务中定义了notify调用Handlers,但是由于条件判断等原因,该任务未被执行,那么Handlers同样不会被执行。

3.Handlers只会在每一个play的末尾运行一次;如果想在一个playbook中间运行Handlers,则需要使用meta模块来实现。例如: -meta: flush_handlers。

4.如果一个play在运行到调用Handlers的语句之前失败了,那么这个Handlers将不会被执行。我们可以使用meta模块的--force-handlers选项来强制执行Handlers,即使Handlers所在的play中途运行失败也能执行。

5.不能使用handlers替代tasks

猜你喜欢

转载自www.cnblogs.com/captain-jiang/p/12078564.html