在ansible中playbook是由多個play組成的列表
paly的主要功能在於將事先歸併爲一組的主機裝扮成事先經過ansible中的task定義好的角色,從根本上講,所謂的task無非是調用ansible的module講多個play組織在一個playbook中,便可以讓它們連同起來按事先編排好的機制運行
palybook採用的是YAML語言編寫的
palybook核心元素
hosts # 執行的遠程主機列表
tasks # 任務集
varniables # 內置變量或者自定義變量在playbook中調用
templates # 模板,可替換模板文件中的變量並實現一些簡單的邏輯文件
handlers和notify # 兩個集合使用,由特色條件觸發的操做,知足條件方纔執行,不然不執行
tags # 標籤,指定某條件任務執行,用於選擇運行playbook中的部分代碼
# ansible具備冪等性,所以會自動跳過沒有變化的代碼,即使如此,有些代碼爲測試其確實沒有發生變化的時間依然會很是的長,此時,若是確信其沒有變化,就能夠經過tags跳過這些代碼php
hosts元素 指定被控端的遠程主機列表 [root@ansible ~]# vim /root/ansible/hosts.yml --- - hosts: web remote_user: root 在hosts後面的主機列表形式能夠是單個主機的主機名、IP地址、組名,或者兩個組的並集、交集、差集,好比: brian.com # 單個主機名 192.168.192.129 # 單個IP web # 一個組名 web:db # 兩個組的並集 web:!db # 兩個組的差集 web:&db # 兩個組的交集 remote_user表示的是執行遠程的用戶,通常爲root
tasks元素 指定要執行的任務集 [root@ansible ~]# vim /root/ansible/tasks.yml --- - hosts: web remote_user: root tasks: - name: create new file file: name=/root/ansible/newfile state=touch - name: create new user user: name=zhujingzhi state=present system=yes shell=/sbin/onlogin 這裏tasks元素裏面寫的就是要執行的任務 name 表示一個描述信息 file和user表示使用的模塊名,後面跟着的就是使用模塊操做的具體的使用方法(這裏使用file模塊在/root/ansible/建立了一個新的文件,使用user模塊建立了一個zhujingzhi的用戶)
handlers和notify元素 notify元素,在tasks中的某段代碼中定義,做爲handlers的觸發器(當tasks中的代碼中觸發到notify的元素,則會執行notify指定的handlers中的代碼) handlers元素屬於和tasks同級的列表,其主要做用是定義一個任務(和tasks中的任務是同樣的)等待tasks中任務觸發notify後執行 [root@ansible ~]# vim /root/ansible/nginx.yml --- - hosts: web remote_user: root tasks: - name: install nginx yum: name=nginx - name: copy nginx config file copy: src="/etc/nginx/nginx.conf" dest="/etc/nginx/" backup=yes notify: - restart nginx - check service - name: start nginx service: name=nginx state=started enabled=yes handlers: - name: restart nginx service: name=nginx state=restarted - name: check service shell: killall -0 nginx > /tmp/nginx.log 這裏在運行的時候出現了在被管理機器上沒有killall的命令的錯誤,解決方法(yum -y install psmisc) killall -0 nginx 的意思就是檢查nginx的進程有沒有啓動返回0啓動,返回非0服務有問題
tags元素 tags元素爲tasks裏面的任務打上一個標籤,方便在執行的時候單獨執行tasks裏面的單獨的任務和被其餘調用 [root@ansible ~]# vim /root/ansible/nginx.yml --- - hosts: web remote_user: root tasks: - name: install nginx yum: name=nginx tags: installnginx - name: copy nginx config file copy: src="/etc/nginx/nginx.conf" dest="/etc/nginx/" backup=yes notify: - restart nginx - check service - name: start nginx service: name=nginx state=started enabled=yes tags: startnginx handlers: - name: restart nginx service: name=nginx state=restarted - name: check service shell: killall -0 nginx > /tmp/nginx.log 可單獨執行tasks裏面的startnginx任務 [root@ansible ~]# ansible-playbook -t startnginx /root/ansible/nginx.yml 也能夠指定兩個標籤執行 [root@ansible ~]# ansible-playbook -t installnginx,startnginx /root/ansible/nginx.yml 舒適提示: 這裏多個任務也是可使用一個標籤的名字的 好比: [root@ansible ~]# vim /root/ansible/nginx.yml --- - hosts: web remote_user: root tasks: - name: install nginx yum: name=nginx tags: nginx - name: copy nginx config file copy: src="/etc/nginx/nginx.conf" dest="/etc/nginx/" backup=yes notify: - restart nginx - check service - name: start nginx service: name=nginx state=started enabled=yes tags: nginx handlers: - name: restart nginx service: name=nginx state=restarted - name: check service shell: killall -0 nginx > /tmp/nginx.log 使用ansible執行(加-t參數) [root@ansible ~]# ansible-playbook -t nginx /root/ansible/nginx.yml
vars元素 vars元素指的是定義變量 變量名:僅能由字母、數字和下劃線組成,且只能以字母開頭 能夠在什麼地方定義變量呢?以下: 1.ansible setup facts 遠程主機的全部變量都是能夠被直接調用的 2.在/etc/ansible/hosts中定義 普通變量:主機組中主機單獨定義,優先級高於公共變量 公共(組)變量:針對主機組中全部主機定義統一的變量 3.經過命令行指定變量,優先級最高 ansible-playbook -e varname=value 4.在playbook中定義 vars: - var1: value1 - var2: value2 5.在role中定義(role是模塊化的設置模式,在role中var能夠定義在一個單獨的文件中) 示例: 1.ansible setup查看變量 # 查看全部的遠程主機上的可用變量 [root@ansible ~]# ansible all -m setup # grep過濾查看主機名的變量 [root@ansible ~]# ansible all -m setup | grep ansible_fqdn # setup模塊的filter方法過濾查看主機名 [root@ansible ~]# ansible all -m setup -a "filter=ansible_hostname" 2.在/etc/ansible/hosts中定義 [root@ansible ~]# vim /etc/ansible/hosts [testserver] 192.168.192.129 http_port=8080 在playbook中使用 --- - hosts: web remote_user: root tasks: - name: set hostname hostname: name=brian{{ http_port }}.python.com 詳細的設置請查看:https://www.cnblogs.com/brianzhu/p/10188676.html 3.經過命令行指定變量,優先級最高 playbook的定義以下(使用{{}}雙大括號定義中間是變量名): --- - hosts: web remote_user: root tasks: - name: install nginx yum: name={{ pkname1 }} - name: install nginx yum: name={{ pkname1 }} - name: copy nginx config file copy: src="/etc/nginx/nginx.conf" dest="/etc/nginx/" backup=yes - name: start nginx service: name={{ pkname }} state=started enabled=yes 在命令行執行指定(使用 -e 參數指定變量變量賦值的定義格式是k=v格式) [root@ansible ~]# ansible-playbook -e 'pkname1=nginx pkname2=vsftpd' /root/ansible/nginx.yml 4.在playbook中定義 直接是用vars元素定義變量列表 --- - hosts: web remote_user: root vars: - pkname1: nginx - pkname2: vsftpd tasks: - name: install nginx yum: name=nginx - name: copy nginx config file copy: src="/etc/nginx/nginx.conf" dest="/etc/nginx/" backup=yes - name: start nginx service: name=nginx state=started enabled=yes 5.將使用的變量存放到一個文件中,在playbook裏面調用 編輯變量文件 [root@ansible ~]# cat /root/ansible/vars.yml var1: nginx var2: nsftpd 在playbook中調用 --- - hosts: web remote_user: root vars_files: - vars.yml tasks: - name: install nginx yum: name={{ var1 }} - name: install vsftpd yum: name={{ var2 }}
templates元素 主要是對配置文件進行遠程主機的copy(可以實現根據不一樣的主機的配置修改不一樣的配置文件) templates 文件也是一個文本文件,嵌套有腳本(使用模板編程語言編寫) 模板文件的編程語言使用的是jinja2語言,支持下面的類型: 字符串: 使用單引號或者雙引號 數字: 整數,浮點數 列表: [item1,item2,..] 元組: (item1,item2,..) 字典: {key1:value1,key2:value2,..} 布爾值: true/false 算數運算符: +,-,*,/,//,%,** 比較運算符: ==,!=,>,>=,<,<= 邏輯運算符: and,or,not 流表達式: for if when 示例: 使用nginx的打開的進程數爲示例 建立模板目錄 [root@ansible ~]# mkdir -p /root/ansible/templates 編輯模板文件 在ansible管理機上安裝nginx,並copy nginx.conf到/root/ansible/templates中並更名爲nginx.conf.j2(更名是必須的這個是模塊的規定) [root@ansible ~]# cp /etc/nginx/nginx.conf /root/ansible/templates/nginx.conf.j2 這裏編輯nginx的模板文件將進程數**2 修改/root/ansible/templates/nginx.conf.j2 [root@ansible ~]# vim /root/ansible/templates/nginx.conf.j2 將 worker_processes auto;改爲 worker_processes {{ ansible_processor_vcpus**2 }}; 這裏ansible_processor_vcpus是使用ansible setup獲得的遠程主機的cpu的個數 編寫playbook [root@ansible ~]# vim /root/ansible/nginxtemp.yml --- - hosts: web remote_user: root tasks: - name: install nginx yum: name=nginx - name: copy templates file template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf notify: restart nginx - name: start nginx service: name=nginx state=started enabled=yes handlers: - name: restart nginx service: name=nginx state=restarted 執行playbook [root@ansible ~]# ansible-playbook /root/ansible/nginxtemp.yml 查看結果 這裏個人機器是2個CPU的,剛剛在nginx模板文件中設置了worker_processes {{ ansible_processor_vcpus**2 }};全部最後開啓的進程是4個 [root@ansible ~]# ansible all -m shell -a "ps aux |grep nginx" 192.168.192.129 | CHANGED | rc=0 >> root 6127 0.0 0.1 125092 2256 ? Ss 17:09 0:00 nginx: master process /usr/sbin/nginx nginx 6128 0.0 0.3 129348 7080 ? S 17:09 0:00 nginx: worker process nginx 6129 0.0 0.3 129348 7080 ? S 17:09 0:00 nginx: worker process nginx 6130 0.0 0.3 129348 7080 ? S 17:09 0:00 nginx: worker process nginx 6131 0.0 0.3 129348 7080 ? S 17:09 0:00 nginx: worker process 模板文件使用變量(改變nginx端口) 這裏把變量定義在了/etc/ansible/hosts中爲每臺主機定義的(也可使用上面提到的其餘方式定義變量) 設置變量 [root@ansible ~]# vim /etc/ansible/hosts [web] 192.168.192.129 http_port=8080 設置模板文件 [root@ansible ~]# vim /root/ansible/templates/nginx.conf.j2 修改: listen {{ http_port }} default_server; listen [::]:{{ http_port }} default_server; 執行playbook [root@ansible ~]# ansible-playbook /root/ansible/nginxtemp.yml 查看結果 [root@ansible ~]# ansible all -m shell -a "ss -ntl | grep 8080" 192.168.192.129 | CHANGED | rc=0 >> LISTEN 0 128 *:8080 *:* LISTEN 0 128 :::8080 :::*
做用主要是爲了解決在playbook中的tasks元素中某段代碼執行出現問題是否繼續往下執行的一個解決的方法(其默認是出錯及中止的) playbook文件 --- - hosts: web remote_user: root tasks: run this command and ignore the resullt - name: shell start nginx shell: /usr/bin/somecommand || /bin/true 或者 --- - hosts: web remote_user: root tasks: - name: run this command and ignore the resullt shell: /usr/bin/somecommand ignore_errors: True
when語句 when語句表示條件的測試,若是須要根據變量、facts或者此前任務的執行結果來作爲某task執行與否的前提時要用到條件測試,經過when語句就能夠實現 示例: 在生產環境中系統有6的和7的共存的狀況,那麼配置有些配置文件在不一樣的操做系統上是不同的,這時候咱們就要建立兩個模板文件根據不一樣的操做系統執行不一樣的配置文件copy # 定義兩個配置文件 [root@ansible ~]# cp /etc/nginx/nginx.conf /root/ansible/templates/nginx6.conf.j2 [root@ansible ~]# cp /etc/nginx/nginx.conf /root/ansible/templates/nginx7.conf.j2 編寫playbook [root@ansible ~]# vim /root/ansible/nginxtemp.yml --- - hosts: web remote_user: root tasks: - name: install nginx yum: name=nginx - name: copy templates file for centos7 template: src=nginx7.conf.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version == '7' notify: restart nginx - name: copy templates file for centos6 template: src=nginx6.conf.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version == '6' notify: restart nginx - name: start nginx service: name=nginx state=started enabled=yes handlers: - name: restart nginx service: name=nginx state=restarted
with_items語法 with_items表示迭代,當須要執行重複性的任務的時候,就可使用迭代機制來實現 對於迭代的引用,固定的變量名爲"item" 要在tasks中使用with_items給定要迭代的元素列表 支持的列表格式:字符串、字典 示例: 同時執行建立多個文件的任務 編寫playbook [root@ansible ~]# vim /root/ansible/items.yml --- - hosts: web remote_user: root tasks: - name: create file file: name=/root/ansible/{{ item }} state=touch with_items: - file1 - file2 - file3 - name: install packages yum: name={{ item }} with_items: - htop - sl - hping3
迭代嵌套子變量 建立多個組和用戶將多個用戶加入到不一樣的組中 編寫playbook [root@ansible ~]# vim /root/ansible/guser.yml --- - hosts: web remote_user: root tasks: - name: add groups group: name={{ item }} state=present with_items: - g1 - g2 - g3 - name: add user for goups user: name={{ item.name }} group={{ item.group }} state=present with_items: - { name: 'user1', group: 'g1'} - { name: 'user2', group: 'g2'} - { name: 'user3', group: 'g3'}
for語句 最後須要使用for語句生成的例子 server { listen: 81 } server { listen: 82 } server { listen: 83 } 這裏須要使用模板文件和變量來配合使用生成 palybook編寫 [root@ansible ~]# vim /root/ansible/testfor.yml --- - hosts: web remote_user: root vars: ports: - 81 - 82 - 83 tasks: - name: create for config template: src=/root/ansible/testfor.conf.j2 dest=/root/ansible/testfor.conf 模板文件編寫 [root@ansible ~]# vim /root/ansible/testfor.conf.j2 {% for p in ports %} server { listen {{ p }} } {% enfor %} 執行playbook [root@ansible ~]# ansible-playbook /root/ansible/testfor.yml 查看結果 [root@ansible ~]# ansible all -m shell -a "cat /root/ansible/testfor.conf" 192.168.171.129 | CHANGED | rc=0 >> server { listen: 81 } server { listen: 82 } server { listen: 83 } 經過模板文件來獲取playbook文件中的設置好的變量並經過for語句進行屢次循環(playbook中使用的變量是列表的形式),這樣的方式使用起來實際上是很靈活的,也能夠是上面的列表的形式,也能夠是使用字典的形式或者列表嵌套字典的形式 好比: playbook文件 --- - hosts: web remote_user: root vars: weblist: - web: port: 81 name: python.brian.com rootdir: /nginx/python - web2: port: 82 name: php.brian.com rootdir: /nginx/php tasks: - name: create for config template: src=/root/ansible/testfor.conf.j2 dest=/root/ansible/testfor.conf 模板文件 {% for w in weblist %} server { listen {{ w.port }} servername {{ w.name }} documentroot {{ w.rootdir }} } {% endfor %}
if語句 在for語句中使用,判斷playbook中有沒有設置變量,設置了生成,沒有則不生成,這裏只是舉例子,還有其餘使用的方式,好比一個變量等於大於小於多少執行什麼任務等等 [root@ansible ~]# vim /root/ansible/testfor.yml playbook文件 --- - hosts: web remote_user: root vars: weblist: - web: port: 81 rootdir: /nginx/python - web2: port: 82 name: php.brian.com rootdir: /nginx/php tasks: - name: create for config template: src=/root/ansible/testfor.conf.j2 dest=/root/ansible/testfor.conf 模板文件 [root@ansible ~]# vim /root/ansible/testfor.conf.j2 {% for w in weblist %} server { listen {{ w.port }} {% if w.name is defined %} servername {{ w.name }} {% endif %} documentroot {{ w.rootdir }} } {% endfor %} 執行playbook [root@ansible ~]# ansible-playbook /root/ansible/testfor.yml 查看結果 [root@ansible ~]# ansible all -m shell -a "cat /root/ansible/testfor.conf" 192.168.171.129 | CHANGED | rc=0 >> server { listen 81 documentroot /nginx/python } server { listen 82 servername php.brian.com documentroot /nginx/php }
上面的示例只是少部分的流程控制語句html
舒適提示:python
上面是我在生產中經常使用的元素,語句,這裏主要是把每一個元素分開來寫的,其實真正的playbook是要把上面的元素語句等結合一塊兒使用的nginx