第十二章 Ansible-playbook流程控制
阿新 • • 發佈:2021-12-23
一、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