回顧
劇本中可以使用判斷的方式,減少hosts(play)的個數
template jinjia2
劇本中不能使用if判斷,使用when判斷
shutdown -a 取消關機
shutdown -s 關機
shutdown -f 強行關閉應用程序
shutdown -m \\計算機名 控制遠程計算機
shutdown -i 顯示“遠程關機”圖形用戶界面,但必須是Shutdown的第一個參數
shutdown -l 注銷當前用戶
shutdown -r 關機並重啟
shutdown -s -t 時間 設置關機倒計時
shutdown -h 休眠
centos6啟動httpd /etc/init.d/httpd start
變量的使用並不能減少代碼量,使用循環就可以減少代碼量了
還原快照要重新推送m01上的公鑰,才能使用ansible
bool值純數字要加引號,字符串不用加
yum localinstall 在劇本中不會報錯
文件類型:str
int 字符串類型
python中文件類型的區分是很嚴格的,
劇本中變量加雙引號
循環一般在啟動服務或者copy的時候使用
yum支持列表,一般不用循環
命令行不支持字典的形式調用變量,playbook支持
根據不同的操作系統安裝apache
官方示例:
- hosts: all
tasks:
- name: "shut down Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_facts['os_family'] == "Debian" #不等於表示:!= 0
# 注意,'所有變量'都可以直接在條件語句中使用,而無需使用雙大括號
- hosts: web_group
tasks:
- name: Install CentOS Httpd
yum:
name: httpd
state: present
#官方
when: ansible_['os_family'] == "CentOS" #判斷系統
when: ansible.os_family == "CentOS"
#非官方()
when: ansible_distribution == "CentOS"
- name: Install Ubuntu Httpd
yum:
name: apache2
state: present
when: ansible_facts['os_family'] == "Ubuntu"
when后面既可以是變量,又可以是指定值,一般后面跟變量,與hosts一起使用
[root@www ~]# ansible web01 -m setup |grep os_family
"ansible_os_family": "RedHat",
when的縮進和name注釋一樣
#facts 指的是 ansible_facts 變量,ansible 中使用 setup 模塊來獲取,包含系統的大部分基礎硬件信息
還可以使用括號,and , or對條件進行分組
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")
#使用ansible_facts['distribution'] 判斷系統 注意大小寫
也可以指定多條件為列表(and 並且)
tasks:
- name: "shut down CentOS 6 systems"
command: /sbin/shutdown -t now
when:
- ansible_facts['distribution'] == "CentOS"
- ansible_facts['distribution_major_version'] == "6"
#列表形式等效於and
條件運算
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 #
rsync服務端推送配置文件
[root@m01 ~]# cat rsyncd/rsyncd.yml
- hosts: all ######
tasks:
- name: Install Rsyncd Server
yum:
name: rsync
state: present #可在這里使用ls -l 判斷rsync是否安裝
- 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" #判斷主機名
- 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"
rsync客戶端推送腳本
[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*" #when支持通配符
when: ansible_hostname ~= "web*"
#when: ansible_hostname == "backup" or ansible_hostname == "nfs"
#這三種方式類似模糊匹配,都可以匹配多台web
#模糊匹配和and or不能一起使用
通過register將命令執行結果保存至變量,然后通過when語句進行判斷
- hosts: web_group
tasks:
- name: Check Httpd Server
command: systemctl is-active httpd #查看服務狀態
ignore_errors: yes #忽略報錯,繼續執行
register: check_httpd #將命令的執行結果注冊變量
- name: debug outprint
debug: var=check_httpd #偶爾調試
- name: Httpd Restart
service:
name: httpd
state: restarted
when: check_httpd.rc == 0
#通過變量注冊的方式可以進行非系統變量的調用,與'register: check_httpd'對應
#htpd
[root@lb01 ~]# systemctl is-active httpd
active
[root@lb01 ~]# systemctl stop httpd
[root@lb01 ~]# systemctl is-active httpd
unknown
#nginx
[root@lb01 ~]# systemctl is-active nginx
active
[root@lb01 ~]# systemctl stop nginx
[root@lb01 ~]# systemctl is-active nginx
failed
playbook循環語句
在之前的學習過程中,我們經常會有傳送文件,創建目錄之類的操作,創建2個目錄就要寫兩個file模塊來創建,如果要創建100個目錄,我們需要寫100個file模塊???媽耶~~~~ 當然不是,只要有循環即可,減少重復性代碼。
啟動多個服務
- hosts: web_group
tasks:
- name: start service
systemd:
name: "{{ item }}"
state: started
with_items:
- httpd
- php-fpm
- mariadb
定義變量循環
- name: ensure a list of packages installed
yum:
name: "{{ packages }}"
vars: #模塊內定義變量
packages:
- httpd
- httpd-tools
- hosts: web_group
tasks:
- name: ensure a list of packages installed
yum: name= "{{ item }}" state=present #可以使用多個'='
with_items:
- httpd
- httpd-tools
#with_items一般放到模塊的末尾,與模塊同一縮進級別
字典循環
1.創建用戶
[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' }
2.拷貝文件
- hosts: web_group
tasks:
- name: copy conf and code
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{ item.mode }}"
with_items:
- { src: "./httpd.conf", dest: "/etc/httpd/conf/", mode: "0644" }
- { src: "./upload_file.php", dest: "/var/www/html/", mode: "0600" }
#同一模塊在一個劇本中多次出現,即可考慮使用循環
#同一模塊在一個劇本中多次出現,對同一主機多次操作,即可考慮字典循環
playbook handler
handler
用來執行某些條件下的任務,比如當配置文件發生變化的時候,通過notify觸發handler去重啟服務。
實踐案例
[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
練習:多個nginx配置文件的推送及觸發器
注意:
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
playbook任務標簽
默認情況下,Ansible在執行一個playbook時,會執行playbook中定義的所有任務,Ansible的標簽(tag)功能可以給單獨任務甚至整個playbook打上標簽,然后利用這些標簽來指定要運行playbook中的個別任務,或不執行指定的任務。
打標簽的方式
1.對一個task打一個標簽
2.對一個task打多個標簽
3.對多個task打一個標簽
打完標簽如何使用
-t:執行指定的tag標簽任務
--skip-tags:執行--skip-tags之外的標簽任務
使用-t指定tag
[root@m01 m01]# cat tag.yml
- hosts: web_group
vars:
- http_port: 8080
tasks:
- name: Install Http Server
yum:
name: httpd
state: present
tags:
- install_httpd
- httpd_server
- name: configure httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify: Restart Httpd Server
tags:
- config_httpd
- httpd_server
- name: start httpd server
service:
name: httpd
state: started
enabled: yes
tags: service_httpd
handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted
[root@m01 m01]# ansible-playbook tag.yml --list-tags
[root@m01 m01]# ansible-playbook tag.yml -t httpd_server
[root@m01 m01]# ansible-playbook tag.yml -t install_httpd,confiure_httpd
[root@m01 m01]# ansible-playbook tag.yml --skip-tags httpd_server
playbook文件復用
在之前寫playbook的過程中,我們發現,寫多個playbook沒有辦法,一鍵執行,這樣我們還要單個playbook挨個去執行,很雞肋。所以在playbook中有一個功能,叫做include
用來動態調用task任務列表。

只調用task:include_tasks
調用整個task文件:include
(新版本:import_playbook)
在saltstack中,叫做top file
入口文件。
示例一:
[root@m01 m01]# cat task.yml
- hosts: web_group
vars:
- http_port: 8080
tasks:
- include_tasks: task_install.yml
- include_tasks: task_configure.yml
- include_tasks: task_start.yml
handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted
[root@m01 m01]# cat task_install.yml
- name: Install Http Server
yum:
name: httpd
state: present
[root@m01 m01]# cat task_configure.yml
- name: configure httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify: Restart Httpd Server
[root@m01 m01]# cat task_start.yml
- name: start httpd server
service:
name: httpd
state: started
enabled: yes
示例二
- include: httpd.yml
- include: nfs.yml
- include: rsync.yml
示例三
- import_playbook: httpd.yml
- import_playbook: nfs.yml
- import_playbook: rsync.yml
playbook忽略錯誤
默認playbook會檢測task執行的返回狀態,如果遇到錯誤則會立即終止playbook的后續task執行,然鵝有些時候playbook即使執行錯誤了也要讓其繼續執行。
加入參數:ignore_errors:yes 忽略錯誤
[root@m01 ~]# cat ignore.yml
---
- hosts: web_group
tasks:
- name: Ignore False
command: /bin/false
ignore_errors: yes
- name: touch new file
file:
path: /tmp/zls.txt
state: touch
playbook錯誤處理
如上所述,當task執行失敗時,playbook將不再繼續執行,包括如果在task中設置了handler也不會被執行。
但是我們可以采取強制措施...
強制調用handler
[root@m01 ~]# cat handler.yml
- hosts: web_group
vars:
- http_port: 8080
force_handlers: yes
tasks:
- name: config httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf
notify:
- Restart Httpd Server
- Restart PHP Server
- name: Install Http Server
yum:
name: htttpd
state: present
- 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
抑制changed
被管理主機沒有發生變化,可以使用參數將change狀態改為ok
[root@m01 ~]# cat handler.yml
- hosts: web_group
vars:
- http_port: 8080
force_handlers: yes
tasks:
- name: shell
shell: netstat -lntup|grep httpd
register: check_httpd
changed_when: false
- name: debug
debug: msg={{ check_httpd.stdout.lines }}
[root@m01 project2]# cat changed_when.yml
- hosts: webservers
vars:
- http_port: 8080
tasks:
- name: configure httpd server
template:
src: ./httpd.j2
dest: /etc/httpd/conf/httpd.conf
notify: Restart Httpd Server
- name: Check HTTPD
shell: /usr/sbin/httpd -t
register: httpd_check
changed_when:
- httpd_check.stdout.find('OK')
- false
- name: start httpd server
service:
name: httpd
state: started
enabled: yes
handlers:
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted