• 第二十八章 ansible流程控制


    一、playbook条件语句

    不管是shell还是各大编程语言中,流程控制,条件判断这些都是必不可少的,在我们使用Ansible的过程中,条件判断的使用频率极其高。
    例如:
    1.我们使用不同的系统的时候,可以通过判断系统来对软件包进行安装。
    2.在nfs和rsync安装过程中,客户端服务器不需要推送配置文件,之前我们都是写多个play,会影响效率。
    3.我们在源码安装nginx的时候,执行第二遍就无法执行了,此时我们就可以进行判断是否安装过。
    

    1.判断主机

    [root@m01 ~]# cat lnmp5.yml 
    - hosts: nfs_group
      tasks:
        - name: Install nfs Server
          yum:
            name: nfs-utils
            state: present
    
        - name: Install rpcbind Server
          yum:
            name: rpcbind
            state: present
    
        - name: Config nfs Server
          copy:
            content: /data/wp-content 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
            dest: /etc/exports      
          when: ansible_fqdn == "nfs"
    
        - name: Mkdir data
          file:
            path: /data
            state: directory
            owner: www
            group: www
          when: ansible_fqdn == "nfs"
    
        - name: Start nfs Server
          systemd:
            name: nfs
            state: started
          when: ansible_fqdn == "nfs"
    
        - name: Copy wp-content to NFS
          copy:
            src: /root/package/wp-content
            dest: /data
            owner: www
            group: www
          when: ansible_fqdn == "nfs"
        
        - name: Start rpcbind Server
          systemd:
            name: rpcbind
            state: started
          when: ansible_fqdn != "nfs"
    
        - name: Mount nfs
          mount:
            src: 172.16.1.31:/data/wp-content
            path: /code/wordpress/wp-content/
            fstype: nfs
            opts: defaults
            state: mounted
          when: ansible_fqdn != "nfs"
    

    2.多条件判断

    [root@m01 ~]# cat lnmp5.yml 
    - hosts: all
      tasks:
        - name: Install nfs Server
          yum:
            name: nfs-utils
            state: present
          when: (ansible_fqdn == "nfs") or (ansible_fqdn is match "web*")
    
        - name: Install rpcbind Server
          yum:
            name: rpcbind
            state: present
          when: (ansible_fqdn == "nfs") or (ansible_fqdn is match "web*")
    
        - name: Config nfs Server
          copy:
            content: /data/wp-content 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
            dest: /etc/exports      
          when: ansible_fqdn == "nfs"
    
        - name: Mkdir data
          file:
            path: /data
            state: directory
            owner: www
            group: www
          when: ansible_fqdn == "nfs"
    
        - name: Start nfs Server
          systemd:
            name: nfs
            state: started
          when: ansible_fqdn == "nfs"
    
        - name: Copy wp-content to NFS
          copy:
            src: /root/package/wp-content
            dest: /data
            owner: www
            group: www
          when: ansible_fqdn == "nfs"
        
        - name: Start rpcbind Server
          systemd:
            name: rpcbind
            state: started
          when: (ansible_fqdn == "nfs") or (ansible_fqdn is match "web*")
    
        - name: Mount nfs
          mount:
            src: 172.16.1.31:/data/wp-content
            path: /code/wordpress/wp-content/
            fstype: nfs
            opts: defaults
            state: mounted
          when: ansible_fqdn is match "web*"
    

    3.判断服务是否安装

    [root@m01 ~]# cat lnmp3.yml 
    - hosts: web_group
      tasks:
        - name: Tar php.tar.gz
          unarchive:
            src: /root/package/php.tar.gz
            dest: /tmp/
    
        - name: Get PHP Install status
          shell: "rpm -qa | grep php"
          ignore_errors: yes
          register: get_php_install_status
        
        #打印注册的变量信息,没有任何作用,只是为了获取安装状态判断参数 rc
        - name: print PHP Install status
          debug:
            msg: "{{ get_php_install_status }}"
    
        - name: Install PHP Server
          shell: yum localinstall -y /tmp/*.rpm
          when: get_php_install_status.rc != 0
    
        - name: Config php Server
          copy:
            src: /root/conf/php.ini
            dest: /etc/
    
        - name: Config php Server
          copy:
            src: /root/conf/www.conf
            dest: /etc/php-fpm.d/
    
        - name: Start php Server
          systemd:
            name: php-fpm
            state: started
            enabled: yes
    

    4.判断系统

    [root@m01 ~]# vim web.yml
    - hosts: nfs
      tasks:
        - name: Install httpd
          shell: "yum install -y httpd"
          when: ansible_distribution == "CentOS"
    
        - name: Install apache2
          shell: "apt-get apache2"
          when: ansible_distribution == "Ubuntu"
    

    5.判断系统版本

    1)方式一:
    [root@m01 ~]# cat version.yml 
    - hosts: nfs
      tasks:
        - name: CentOS6 Start httpd
          shell: "service httpd start"
          when: (ansible_distribution == "CentOS") and (ansible_distribution_major_version == "6")
    
        - name: CentOS7 Start httpd
          shell: "systemctl start httpd"
          when: (ansible_distribution == "CentOS") and (ansible_distribution_major_version == "7")
    
    2)方式二
    #多条件判断的第二种方式,列表的形式(只能表示并且and和)
    [root@m01 ~]# cat version.yml 
    - hosts: nfs
      tasks:
        - name: CentOS6 Start httpd
          shell: "service httpd start"
          when: 
            - ansible_distribution == "CentOS"
            - ansible_distribution_major_version == "6"
    
        - name: CentOS7 Start httpd
          shell: "systemctl start httpd"
          when: 
            - ansible_distribution == "CentOS"
            - ansible_distribution_major_version == "7"
    
    3)一般使用场景
    tasks:
      - shell: echo "only on Red Hat 6, derivatives, and later"
        when: ansible_facts['os_family'] == "RedHat" and ansible_facts['lsb']['major_release']|int >= 6
    

    二、playbook循环语句

    1.定义变量安装多服务

    [root@m01 ~]# vim install.yml 
    - hosts: nfs
      tasks:
        - name: Install Server
          yum: 
            name: "{{ package }}"
            state: present
          vars:
            package:
              - httpd
              - nfs-utils
              - mariadb-server
    

    2.定义变量启动多服务

    [root@m01 ~]# cat install.yml 
    - hosts: nfs
      vars:
        package:
          - httpd
          - nfs-utils
          - mariadb-server
      tasks:
        - name: Install Server
          yum: 
            name: "{{ package }}"
            state: present
      
        - name: Start Server
          systemd:
            name: "{{ item }}"
            state: started
            enabled: yes
          with_items:
            - httpd
            - nfs-utils
            - mariadb
    

    3.字典定义变量

    1)创建多个用户组
        - name: Create www Group
          group:
            name: "{{ item.name }}"
            gid: "{{ item.gid }}"
          with_items:
            - { name: www, gid: 666 }
            - { name: lhd, gid: 777 }
            - { name: dsb, gid: 888 }
    
    2)创建多个用户
        - name: Create www User
          user:
            name: "{{ item.name }}"
            uid: "{{ item.uid }}"
            group: "{{ item.name }}"
            shell: "{{ item.shell }}"
            create_home: "{{ item.create_home }}"
          with_items:
            - { name: www, uid: 666, shell: "/sbin/nologin", create_home: no }
            - { name: lhd, uid: 777, shell: "/bin/bash", create_home: no }
            - { name: dsb, uid: 888, shell: "/bin/bash", create_home: yes }
    
    4.使用字典定义变量的方式优化lnmp剧本
    [root@m01 ~]# cat lnmp.yml 
    - hosts: all
      tasks:
        - name: Stop selinux
          selinux:
            state: disabled
    
        - name: Stop Firewalld
          systemd:
            name: firewalld
            state: stopped
            enabled: no
    
        - name: Install unzip
          yum:
            name: unzip
            state: present
    
        - name: Create www Group
          group:
            name: www
            gid: 666
    
        - name: Create www User
          user:
            name: www
            uid: 666
            group: www
            shell: /sbin/nologin
            create_home: no
    
        - name: Copy nginx.repo
          copy:
            src: /root/conf/nginx.repo
            dest: /etc/yum.repos.d/
          when: (ansible_fqdn == "lb01") or (ansible_fqdn is match "web*")
    
        - name: Install Nginx Server
          yum:
            name: nginx
            state: present
          when: (ansible_fqdn == "lb01") or (ansible_fqdn is match "web*")
    
        - name: Config Nginx Server
          copy:
            src: /root/conf/nginx.conf
            dest: /etc/nginx/
          when: (ansible_fqdn == "lb01") or (ansible_fqdn is match "web*")
    
        - name: Config slb Server
          copy:
            src: /root/conf/proxy.conf
            dest: /etc/nginx/conf.d
          when: ansible_fqdn == "lb01"
    
        - name: Copy proxy_params
          copy:
            src: /root/conf/proxy_params
            dest: /etc/nginx/
          when: ansible_fqdn == "lb01"
        
        - name: Start slb Server
          systemd:
            name: nginx
            state: started
          when: ansible_fqdn == "lb01"
    
        - name: Config nginx Server
          copy:
            src: /root/conf/linux.wp.com.conf
            dest: /etc/nginx/conf.d/
          when: ansible_fqdn is match "web*"
          
        - name: Mkdir Code
          file:
            path: /code
            state: directory
          when: ansible_fqdn is match "web*"
    
        - name: Tar wordpress and php
          unarchive:
            src: "{{ item.src }}"
            dest: "{{ item.dest }}"
          with_items:
            - { src: /root/package/wordpress-5.0.3-zh_CN.tar.gz, dest: /code/ }
            - { src: /root/package/php.tar.gz, dest: /tmp/ }
          when: ansible_fqdn is match "web*"
    
        - name: Grant Code Dir
          file:
            path: /code
            owner: www
            group: www
            recurse: yes
          when: ansible_fqdn is match "web*"
    
        - name: Start Web Nginx Server
          systemd:
            name: nginx
            state: started
            enabled: yes
          when: (ansible_fqdn is match "web*") or (ansible_fqdn is match "lb01")
    
        - name: Get PHP Install status
          shell: "rpm -qa | grep php"
          ignore_errors: yes
          register: get_php_install_status
    
        - name: Install PHP Server
          shell: yum localinstall -y /tmp/*.rpm
          when: 
            - ansible_fqdn is match "web*"
            - get_php_install_status.rc != 0
    
        - name: Config php Server
          copy:
            src: "{{ item.src }}"
            dest: "{{ item.dest }}"
          with_items:
            - { src: /root/conf/php.ini, dest: /etc/ }
            - { src:/root/conf/www.conf, dest: /etc/php-fpm.d/ }
          when: ansible_fqdn is match "web*"
    
        - name: Start php and nginx Server
          systemd:
            name: "{{ item.name }}"
            state: started
            enabled: yes
          with_items:
            - { name: php-fpm }
            - { name: nginx }
          when: ansible_fqdn is match "web*"
    
        - name: Install Mariadb Server
          yum:
            name: "{{ db }}"
            state: present
          vars:
            db:
              - mariadb-server
              - MySQL-python
          when: ansible_fqdn == "db01"
        
        - name: Start Mariadb Server
          systemd:
            name: mariadb
            state: started
            enabled: yes
          when: ansible_fqdn == "db01"
    
        - name: Create wordpress Database
          mysql_db:
            name: wordpress
            state: present
          when: ansible_fqdn == "db01"
    
        - name: Create wordpress Database User
          mysql_user:
            name: "wp"
            host: "172.16.1.%"
            password: '123456'
            priv: "wordpress.*:ALL"
            state: present
          when: ansible_fqdn == "db01" 
            
        - name: Install nfs Server
          yum:
            name: "{{ nfs_server }}"
            state: present
          vars:
            nfs_server:
              - nfs-utils
              - rpcbind
          when: (ansible_fqdn == "nfs") or (ansible_fqdn is match "web*")
    
        - name: Config nfs Server
          copy:
            content: /data/wp-content 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)
            dest: /etc/exports      
          when: ansible_fqdn == "nfs"
    
        - name: Mkdir data
          file:
            path: /data
            state: directory
            owner: www
            group: www
          when: ansible_fqdn == "nfs"
    
        - name: Start nfs Server
          systemd:
            name: nfs
            state: started
          when: ansible_fqdn == "nfs" 
    
        - name: Copy wp-content to NFS
          copy:
            src: /root/package/wp-content
            dest: /data
            owner: www
            group: www
          when: ansible_fqdn == "nfs"
        
        - name: Start rpcbind Server
          systemd:
            name: rpcbind
            state: started
          when: (ansible_fqdn == "nfs") or (ansible_fqdn is match "web*")
    
        - name: Mount nfs
          mount:
            src: 172.16.1.31:/data/wp-content
            path: /code/wordpress/wp-content/
            fstype: nfs
            opts: defaults
            state: mounted
          when: ansible_fqdn is match "web*"
    
        - name: Install rsync Server
          yum:
            name: rsync
            state: present
          when: ansible_fqdn == "backup"
    
        - name: Config Rsync Server
          copy:
            src: /root/conf/rsyncd.conf
            dest: /etc/
          when: ansible_fqdn == "backup"
    
        - name: Config rsync.passwd
          copy:
            content: rsync_backup:123456
            dest: /etc/rsync.passwd
            mode: 0600
          when: ansible_fqdn == "backup"
    
        - name: Mkdir backup Dir
          file:
            path: /backup
            state: directory
            owner: www
            group: www
          when: ansible_fqdn == "backup"
    
        - name: Start rsync Server
          systemd:
            name: rsyncd
            state: started
          when: ansible_fqdn == "backup"
    
        - name: Install rsync and Inotify-tools Server
          yum:
            name: "{{ item }}"
            state: present
          with_items:
            - rsync
            - inotify-tools
          when: ansible_fqdn == "nfs"
    
        - name: Install sersync Server
          copy:
            src: /root/package/sersync
            dest: /usr/local/
            mode: 0755
          when: ansible_fqdn == "nfs"
    
        - name: Config rsync.pass
          copy:
            content: 123456
            dest: /etc/rsync.pass
            mode: 0600
          when: ansible_fqdn == "nfs"
    
        - name: Start sersync
          script: /root/start_rsync.sh
          when: ansible_fqdn == "nfs"
    

    三、playbook handlers 触发器

    1.什么是触发器

    handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。
    在saltstack中也有类似的触发器,写法相对Ansible简单,只需要watch,配置文件即可
    

    2.配置触发器

    [root@m01 ~]# cat handler.yml 
    - hosts: web_group
      tasks:
        - name: Install Http Server
          yum:
            name: httpd
            state: present
    
        - name: config httpd server
          copy:
            src: ./httpd.conf
            dest: /etc/httpd/conf
          notify: Restart Httpd Server
    
        - name: start httpd server
          service:
            name:httpd
            state: started
            enabled: yes
    
      handlers:
        - name: Restart Httpd Server
          systemd:
            name: httpd
            state: restarted
    

    3.注意事项

    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
    

  • 相关阅读:
    笔记
    Dwarf Tower
    第k小数
    np
    noi 抓住那头牛
    HDU 1575 Try A
    acm 易错警示
    E
    魔改森林 题解(dp+容斥+组合数学)
    F. Unusual Matrix 题解(思维)
  • 原文地址:https://www.cnblogs.com/jhno1/p/13879310.html
Copyright © 2020-2023  润新知