Ansible - - playbook 使用

,1,playbook 簡介

  • playbook 是由一個或多個「play」 組成的列表
  • play 的主要功能在於將事先歸併爲一組的主機裝扮成事先經過 ansible 中的 task 定義好的角色。從根本上來說,全部的 task 無非是調用 ansible 的一個 module。將多個 play 組織在一個 playbook 中,便可以讓它們聯同起來按事先編排的機制同時進行。
  • playbook 採用 YAML 語法編寫

2,playbook 工做流程

圖片名稱

3,YAML 介紹

  • YAML 是一個可讀性高的用來表達資料序列的格式。YAML 參考了其它多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式 RFC2822 等。Clark Evans在2001年5月在首次發表了這種語言,另外Ingy döt Net與Oren Ben-Kiki也是這語言的共同設計者。
  • YAML是"YAML Ain't a Markup Language"(YAML不是一種置標語言)的遞歸縮寫。在開發的這種語言時,YAML 的意思實際上是:"Yet Another Markup Language"(還是一種置標語言),
  • 特性
    • YAML 的可讀性好
    • YAML 和腳本語言的交互性好
    • YAML 使用實現語言的數據類型
    • YAML 有一個一致的信息模型
    • YAML 易於實現
    • YAML 能夠基於流來處理
    • YAML 表達能力強,擴展性好
  • 更多內容及規範參見:www.yaml.org

3.1 YAML 語法簡介

  • 在單一配置文件中,可用連續三個連字號 --- 區分多個配置信息。另外選擇性的連續三個點號 ... 用來表示配置文件的結尾
  • 次行開始正常寫 playbook 的內容,通常建議寫明 playbook 的功能
  • 使用 # 號註釋代碼
  • 縮進必須是統一的,不能空格和tab 混用
  • 縮進的級別也是必須是一致的,一樣的縮進表明一樣的級別,程序判別配置的級別是經過縮進結合換行來實現的
  • YAML 文件的內容和 Linux 系統大小寫判斷方式保持一致,是區別大小寫的,key/value 的值均須要大小寫敏感
  • key/value 的值可同行寫也可換行寫。同行使用 : 分隔
  • value 但是個字符串,也但是另外一個列表
  • 一個完整的代碼塊功能須要最少元素需包括 name: task
  • 一個 name 只能包括一個 task
  • YAML 文件的擴展名一般爲 ymlyaml
  • List:列表,其全部元素均使用 - 大頭
  • 示例
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
  • Dictionary:字典,一般由多個 keyvalue 構成
  • 示例:
---
# An employee record
name: Example Developer
job: Developer
skill; Elite
  • 也能夠將 key:value 放置於 {} 中進行表示,用 , 分隔多個 key:value
  • 示例
---
# An employee record
{name: Example Developer, job: Developer, skill: Elite}
  • YAML的語法和其它高階語言相似,而且能夠簡單表達清單、散列表、標量等數據結構。其結構(Structure)經過空格來展現,序列(Sequence)裏的項用 - 來表明,Map 裏的鍵值對用 : 分隔
  • 示例
name: John Smith
age: 41
gender: Male
spouse:
  name: Jane Smith
  age: 37
  gender: Female
children:
  - name: Jimmy Smith
    age: 17
    gender: Male
  - name: Jenny Smith
    age: 13
    gender: Female

4,Playbook VS ShellScripts

  • Shell 腳本
#!/bin/bash
# 安裝 Apache
yum install --quiet -y httpd
# 複製配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp /tmp/vhosts.conf /etc/httpd/conf.d/vhosts.conf
# 啓動 Apache,並設置開機自啓
service httpd start
chkconfig httpd on
  • Playbook 定義
---
- hosts: all
  tasks:
    - name: "安裝Apache"
      yum: name=httpd
    - name: "複製配置文件 httpd.conf"
      copy: scr=/tmp/httpd.conf dest=/etc/httpd/conf/
    - name: "複製配置文件 vhosts.conf"
      copy: scr=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
    - name: "啓動Apache,並設置開機啓動"
      service: name=httpd state=started enabled=true

5,playbook 核心元素

  • Hosts 執行的遠程主機列表
  • Tasks 任務集
  • Varniables 內置變量或自定義變量在 playbook 中調用
  • Templates 模板,可替換模板文件中的變量並實現一些簡單邏輯的文件
  • Handlers 和 notify 結合使用,由特定條件觸發的操做,滿座條件方纔執行,不然不執行
  • tags 標籤,指定某條件任務執行,用於選擇運行 playbook 中的部分代碼。ansible 具備冪等性,所以會自動跳過沒有變化的部分,即使如此,有些代碼爲測試其確實沒有發生變化的時間依然會很是地長。此時,若是確信其沒有變化,就能夠經過 tags 跳過此代碼片斷
    • ansible-playbook -t tagsname useradd.yaml

5.1 Hosts:

  • playbook 中的每個 play 的目的都是爲了讓某個或某些主機以某個指定的用戶身份執行任務。hosts 用於指定要執行指定任務的主機,須事先定義在主機清單中
  • 能夠是以下形式:
one.example.com
one.example.com:two.example.com
192.168.1.120
192.168.1.*
  • Websrvs:dbsrvs 兩個組的並集
  • Websrvs:&dbsrvs 兩個組的交集
  • webservers:!phoenix 在 websrvs 組,但不在 dbsrvs 組
  • 示例
- hosts: websrvs:dbsrvs

5.2 remote_user

  • 可用於 Host 和 task 中。也能夠經過指定其經過 sudo 的方式在遠程主機上執行任務,其可用於 play 全局或某任務;此外,甚至能夠在 sudo 時使用 sudo_user 指定 sudo 時切換的用戶
- hosts: websrvs
  remote_user: root
  tasks:
    - name: tast connection
      ping:
      remote_user: test
      sudo: yes                    # 默認sudo 爲 root
      sudo_suer: wang        # sudo 爲 wang

5.3 task 列表和 action

  • play 的主體部分是 task list、task list 中 的各任務按次序逐個在hosts中指定的全部主機上執行,即在全部主機上完成第一個任務後再開始第二個。在運行自下而上某 playbook 時,若是中途發生錯誤,全部已執行任務都將回滾,所以,在更正 playbook 後從新執行一次便可
  • task 的目的是使用指定的參數指定模塊,而在模塊參數中可使用變量。模塊執行時冪等的,這意味着屢次執行時安全的,由於其結果均一致
  • 每一個task都應該有其 nam,用於 playbook 的執行結果輸出,建議其內容儘量清晰地描述任務執行步驟。若是未提供 name,則 action 的結果將用於輸出
  • task:任務列表
    • 格式:
      • 1,action: module arguments
      • 2,module: arguments 建議使用
      • 注意:shell 和 command 模塊後面跟命令,而非 key=value
  • 某任務的狀態在運行後爲 changed 時,可經過 notify 通知給相應的 handlers
  • 任務能夠經過 tags 打標籤,然後可在 ansible-playbook 命令上使用 -t 指定進行調用
  • 示例
tasks:
  - name: disable selinux
    command: /sbin/setenforce 0
  • 若是命令或腳本的退出碼不爲零,可使用以下方式替代
tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand || /bin/true
  • 或者使用 ignore_errors 來忽略錯誤信息
tasks:
  - name: run this command and ignore the result
    shell: /usr/bin/somecommand
    ignore_errors: True
  • 運行 playbook 的方式
    • ansible-playbook <filename.yml> ... [options]
  • 常見選項
    • --check 只檢測可能會發生的改變,但不真正執行操做
    • --list-hosts 列出運行任務的主機
    • --limit 主機列表 只針對主機列表中的主機執行
    • -v 顯示過程 -vv -vvvv 更詳細
  • 示例
ansible-playbook file.yml
ansible-playbook file.yml --check    # 只檢測
ansible-playbook file.yml --limit websrvs

5.3.1 playbook 示例

  • sysuser.yml
---
- hosts:all
  remote_user: root

  tasks:
  - name: create mysql user
    user: name=mysql system=yes uid=36

  - name: create a group
    group: name=httpd system=yes
  • httpd.yml
---
-hosts: websrvs
  remote_user: root

  tasks:
  - name: Install httpd
    yum: name=httpd state=present

  - name: copy configure file
    copy: src=files/httpd.conf dest=/etc/httpd/conf/

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

5.4 handlers 和 notify 結合使用觸發條件

  • Handlers 是task列表,這些 task 與前述的 task 並無本質上的不一樣,用於當關注的資源發生變化時,纔會採起必定的操做
  • Notify 此 action 可用於在每一個 play 的最後被觸發,這樣可避免屢次有改變發生時每次都執行指定的操做,僅在全部的變化發生完成後一次性地執行指定操做。在notify 中列出的操做稱爲 handler,也即 notify 中調用 handler 中定義的操做
  • 示例
---
-hosts: websrvs
  remote_user: root

  tasks:
  - name: Install httpd
    yum: name=httpd state=present

  - name: copy configure file
    copy: src=files/httpd.conf dest=/etc/httpd/conf/
    notify: restart httpd

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

  handlers:
    - name: restart httpd
      service: name=httpd status=restarted
---
- hosts: websrvs
  remote_user: root

  task:
    - name: add group nginx
      tags: user
      user: name=nginx state=present

    - name: add user nginx
      user: name=nginx statepresent group=nginx

    - name: Install Nginx
      yum: name=nginx state=present

    - name: config
      copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
      notify:
        - Restart Nginx
        - Check Nginx Process

  handlers:
    - name: Restart Nginx
      service: name=nginx state=restarted enabled=yes
    - name: Check Nginx Process
      shell: killall -0 nginx > /tmp/nginx.log

5.5 playbook 中 tags

  • tags 見名之意,tags 能夠幫助咱們對任務進行 「打標籤」 的操做,當任務存在標籤之後,能夠在執行 playbook 時,藉助標籤,指定執行哪些任務,或者指定不執行哪些任務
  • 示例
---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: Install httpd
      yum: name=httpd state=present
      tags: install,always

    - name: Install configure file
      copy: src=file/httpd.conf dest=/etc/httpd/conf/
      tags: conf,always

    - name: start httpd service
      tags: service
      service: name=httpd state=started enabled=yes
  • 在調用標籤時,也能夠一次性指定多個標籤,調用多個標籤須要用逗號隔開
ansible-playbook --tags install,service httpd.yml
  • 在調用標籤以前,預覽一下 playbook 中都有哪些標籤,使用 --list-tags
ansible-playbook --list-tags httpd.yml
  • 若是有不想執行的任務,可使用 --skip-tags 跳過指定的標籤
ansible-playbook --skip-tags always httpd.yml

6,Playbook 中變量使用

  • 變量名:僅能有字母、數字和下劃線組成,且只能以字母開頭
  • 變量來源:
    • 1 ansible setup facts 遠程主機的全部變量均可直接調用
    • 2 在 /etc/ansible/hosts 中定義
      • 普通變量:主機中主機單獨定義,優先級高於公共變量
      • 公共(組)變量:針對主機組中全部主機定義統一變量
    • 3 經過命令行指定變量,優先級最高
      • ansible-playbook -e varname=value file.yml
    • 4 在 playbook 中定義
    • 5 在獨立的變量YAML文件中定義
    • 6 在 role 中定義
  • 變量命名
    • 變量命名僅能由字母、數字和下劃線組成,且只能以字母開頭
  • 變量定義:key=value
    • 示例:http_port=80
  • 變量調用方式
    • 經過 {{ variable_name }} 調用變量,且變量名先後必須有空格,有時用 "{{ variable_name }}"才生效
    • ansible-playbook -e 選項指定
      • ansible-playbook test.yml -e "hosts=www user=test"

6.1 實例

  • 按照不一樣的方式優先級爲:命令行,playbook定義變量文件,playbook定義變量,hosts定義私有變量,hosts定義公共變量mysql

    6.1.1 命令行定義

  • testvars.ymllinux

---
- hosts: websrvs
  remote_user: root

  tasks:
    - name:  create file
      copy: content={{ var }} dest=/tmp/file.txt
  • 執行結果
# ansible-playbook -e "var=command" testvars.yml

# ansible websrvs -m shell -a 'cat /tmp/file.txt'
192.168.2.132 | CHANGED | rc=0 >>
command

192.168.2.131 | CHANGED | rc=0 >>
command

6.1.2 在 playbook 中定義

6.1.2.1 定義變量文件

  • testvars.yml
---
- hosts: websrvs
  remote_user: root
  vars_files:
    - vars.yml

  tasks:
    - name: create file
      copy: content={{ var.content }} dest=/tmp/file.txt
  • vars.yml
var:
  content: vars.yml
  • 執行結果
# ansible-playbook testvars.yml

# ansible websrvs -m shell -a 'cat /tmp/file.txt'192.168.2.131 | CHANGED | rc=0 >>
vars.yml


192.168.2.132 | CHANGED | rc=0 >>
vars.yml

6.1.2.2 playbook 中定義變量

  • testvars.yml
---
- hosts: websrvs
  remote_user: root
  vars:
    var: {content: playbook}

  tasks:
    - name: create file
      copy: content={{ var.content }} dest=/tmp/file.txt
  • 執行結果
# ansible-playbook testvars.yml

# ansible websrvs -m shell -a 'cat /tmp/file.txt'192.168.2.132 | CHANGED | rc=0 >>
playbook

192.168.2.131 | CHANGED | rc=0 >>
playbook

6.1.3 /etc/ansible/hosts 中定義

  • testvars.yml
---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: create file
      copy: content={{ var }} dest=/tmp/file.txt
6.1.3.1 定義私有變量
  • /etc/ansible/hosts
[websrvs]
192.168.2.131 var=hosts_websrvs1
192.168.2.132 var=hosts_websrvs2
  • 執行結果
# ansible-playbook testvars.yml

# ansible websrvs -m shell -a 'cat /tmp/file.txt'
192.168.2.131 | CHANGED | rc=0 >>
hosts_websrvs1

192.168.2.132 | CHANGED | rc=0 >>
hosts_websrvs2
6.1.3.2 定義公共變量
  • /etc/ansible/hosts
[websrvs]
192.168.2.131
192.168.2.132

[websrvs:vars]
var=hosts_websrvs_vars
  • 執行結果
# ansible-playbook testvars.yml

# ansible websrvs -m shell -a 'cat /tmp/file.txt'
192.168.2.131 | CHANGED | rc=0 >>
hosts_websrvs_vars

192.168.2.132 | CHANGED | rc=0 >>
hosts_websrvs_vars

7,批量部署 zabbix-agent

  • /etc/ansible/hosts
# children 底下爲父羣組 zabbix-agent 的子羣組
# vars底下爲羣組共同便變量,包括已定義變量和自定義變量

[zabbix-agent:children]    # 父羣組
test1    # 子羣組1
test2    # 子羣組2

[test1]    # 子羣組1
192.168.2.13[0:2]    # 遠端服務器 IP 列表

[test1:vars]    # 子羣組1 參數
ansible_ssh_user=root    # 遠端 ssh 服務器用戶
ansible_ssh_pass="test1123"    # 遠端 ssh 服務器密碼
ansible_ssh_port=22    # 遠端 ssh 服務器端口

[test2]    # 子羣組2
192.168.2.10[1:3]    # 遠端服務器 IP 列表
192.168.2.11{1:3]    # 遠端服務器 IP 列表

[test2:vars]    # 子羣組2 參數
ansible_ssh_user=root    # 遠端 ssh 服務器用戶
ansible_ssh_pass="test2123"    # 遠端 ssh 服務器密碼
ansible_ssh_port=22    # 遠端 ssh 服務器端口
  • zabbix-agent.yaml
---
- hosts: zabbix-agent    # /etc/ansible/hosts 羣組名
  gather_facts: no    # 跳過檢查
  remote_user: root    # 遠端服務器用戶

#  tasks:    # 任務
#    - name: judge a file or dir is exits    # 判斷該文件是否存在
#      shell: /etc/zabbix/zabbix_agentd.conf
#      ignore_errors: True    # 忽略報錯
#      register: result    # 定義變量

    - name: ssh-copy    # 複製 ssh 公鑰到遠端主機
      authorized_key: user=root key="{{ lookup('file', '/root/.ssh/id_rsa.pub')}}"
      tags:    # 標籤
        - sshkey

    - name: CentOS6 install zabbix-agent rpm    # 安裝 zabbix-agent 客戶端 rpm 包
      yum: name=http://repo.zabbix.com/zabbix/3.0/rhel/6/x86_64/zabbix-agent-3.0.0-2.el6.x86_64.rpm state=present
      when:    # 判斷系統及版本號
        - ansible_distribution == "CentOS"
        - ansible_distribution_major_version == "6"
#        - result|failed    # 判斷該文件不存在

    - name: CentOS7 install zabbix-agent rpm
      yum: name=http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-agent-3.0.0-1.el7.x86_64.rpm state=present
      when:
        - ansible_distribution == "CentOS"
        - ansible_distribution_major_version == "7"
#        - result|failed    # 判斷該文件不存在

    - name: configure Server IP    # 配置自動註冊  zabbix-server 端IP 
      shell: sed -i 's/Server=.*/Server=192.168.2.160/' /etc/zabbix/zabbix_agentd.conf

    - name: configure ServerActive IP    # 配置自動註冊  zabbix-server 端IP 
      shell: sed -i 's/ServerActive=.*/ServerActive=192.168.2.160/' /etc/zabbix/zabbix_agentd.conf

    - name: configure HostMetadata    # 配置自動註冊 key/value 值
      shell: sed -i 's/# HostMetadata=/HostMetadata=zabbixs/' /etc/zabbix/zabbix_agentd.conf

    - name: system configure Hostname    # 配置當前服務器的主機名
      shell: host=`hostname`;sed -i 's/Hostname=Zabbix server/Hostname='$host'/' /etc/zabbix/zabbix_agentd.conf

    - name: start service    # 啓動 zabbix-agent 服務
      service: name=zabbix-agent state=started enabled=true
  • 經過編輯 /etc/ansible/ansible.cfg 或者 ~/.ansible.cfg 來實現 跳過ssh首次鏈接時,提示 是否continue,須要輸入yes
[defaults]
host_key_checking = False
  • 設置環境變量方式以下
export ANSIBLE_HOST_KEY_CHECKING=False
相關文章
相關標籤/搜索