ansible-playbook的YAML語法學習


YAML:可以將你打算對多機器的批量操作放到一個文件中,順序執行,可以根據機器做到根據機器信息判斷執行,其他命令執行結果判斷執行。

YAML有着嚴格的層級要求,稍微有個縮進問題就會無法運行,所以學習過程中,需要細心觀察。

 

 

命令      指定hosts文件位置     劇本文件     參數

-C 調試模式,調試劇本是否可以正常運行(這個模式中,任何更改的操作都不會執行)

ansible-playbook     -i hosts    yaml.file  
ansible-playbook     -i hosts    yaml.file   -C

  

劇本開始語法

---                                     #一個標識符,類似#!/bin/bash
- hosts: all                            #此劇本作用域
  remote_user: root                     #使用什么用戶運行此劇本
  gather_facts: True                    #在遠程主機運行setup模塊,並將收集的信息記錄起來(等於命令ansible  all -m setup#查看系統信息),可以通過系統信息來判斷是否執行
  vars:                                 #定義變量          
    variable: values
  tasks:                                #任務開始標簽
   - name: task_name
     model_name: values

  

  

每一個任務,可以指定一定的操作,定義一個任務基礎參數如下

#一個用name模塊被'命名'任務下只允許有一個同級的模塊存在(不包括輔助功能,后面會講)

- name: task_name
model_name: values

yaml語法中結構:

[
{
'name': 'task_name', 
'model_name': 'values'
}
]

  

  

以下這種情況,命名任務與模塊是同級的情況下,可以正常執行,只是不在命名任務模塊下的模塊執行起來顯示的是是模塊名稱,而不是任務名稱(例子1-1),任務多了無法判斷

- model_name: values
- name: task_name
model_name: values
- model_name: values

yaml語法中結構:

[
{'model_name': 'values'},
{
'name': 'task_name',
 'model_name': 'values'
}, 
{'model_name': 'values'}
]

  

 

 例子1-1

[root@host1 [10:02:30]/yaml/test]#cat test.yaml 
---
- hosts: all
  remote_user: root
  gather_facts: True
  tasks:
    - name: "ping test"
      ping:
    - ping:

[root@host1 [10:02:32]/yaml/test]#ansible-playbook -i hosts test.yaml  

PLAY [all] ***********************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************
ok: [192.168.100.3]

TASK [ping test] *****************************************************************************************************************************************************
ok: [192.168.100.3]

TASK [ping] **********************************************************************************************************************************************************
ok: [192.168.100.3]

PLAY RECAP ***********************************************************************************************************************************************************
192.168.100.3              : ok=3    changed=0    unreachable=0    failed=0   

[root@host1 [10:02:41]/yaml/test]#

 

 

 

  

 

 

實際情況演練

新建下方文件:

[root@host1 [18:32:56]/yaml/test]#cat test.yaml 
---
- hosts: all
  remote_user: root
  gather_facts: True
  tasks:
    - name: "ping test"
      ping:

 

上方意思是新建ping test的任務,並執行ping模塊,測試連通性,看下方結果,可以看到任務標簽,並且狀態也是成功的。(Gathering Facts 代表或許系統信息,也是成功的)

 

 #以下以"情況"的形式,向大家講解如何使用常用方法

 

情況1:你的環境中有多台機器,分別有CentOS6系統和CentOS7系列系統,兩類系統在某些方面可能是不一樣的,你現在兩台機器上執行不同的操作,讓我們來看看怎么實現。

 

hosts文件內容

100.3為centos6 秘鑰對認證,可以免密連接

100.7為centos7 沒做過密鑰對認證,通過密碼認證

192.168.100.3                          
192.168.100.7 ansible_user=root ansible_password=nihao123!     

 

  

 

執行下方命令

ansible  all -m setup

返回的是主機的信息,如系統類型,ip地址等,ansible可以根據這些做過濾

在此情況下,我們可以通過 ansible_distribution和ansible_distribution_major_version進行匹配(以下是兩台主機的信息組合,因為我使用的grep過濾的我需要的字段)

[root@host1 [14:30:55]/yaml/test]#ansible -i hosts all  -m setup |grep "ansible_distribution" 
        "ansible_distribution": "CentOS", 
        "ansible_distribution_file_parsed": true, 
        "ansible_distribution_file_path": "/etc/redhat-release", 
        "ansible_distribution_file_variety": "RedHat", 
        "ansible_distribution_major_version": "7", 
        "ansible_distribution_release": "Core", 
        "ansible_distribution_version": "7.2.1511", 
        "ansible_distribution": "CentOS", 
        "ansible_distribution_file_parsed": true, 
        "ansible_distribution_file_path": "/etc/redhat-release", 
        "ansible_distribution_file_variety": "RedHat", 
        "ansible_distribution_major_version": "6", 
        "ansible_distribution_release": "Final", 
        "ansible_distribution_version": "6.5", 

 

編寫下方劇本。

根據when執行判斷條件,當系統版本為6時執行對應的任務,為7時執行對應的任務。

[root@host1 [15:37:42]/yaml/test]#cat test2.yaml 
---
- hosts: all
  remote_user: root
  gather_facts: True
  tasks:
    - name: "ping test"
      ping:
    - name: "only on Centos6"
      shell: "echo 'ON THE Centos6'"
      when: ansible_distribution == 'CentOS' and  ansible_distribution_major_version == '6'
    - name: "only on Centos7"
      shell: "echo 'ON THE Centos7'"
      when: ansible_distribution == 'CentOS' and  ansible_distribution_major_version == '7'

 

執行測試,可以看到,任務執行時,都執行了對應的匹配條件,只有條件通過才執行對應的shell模塊指定的命令,不通過時跳過執行。

when匹配方式有多種,除了我們使用的a=a and b=b之外,大致常用的如下

when: (ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6') or 
(ansible_distribution == 'CentOS' and  ansible_distribution_major_version == '5')

#等同於and,匹配多個條件
when:
      -ansible_distribution== "CentOS" 
      -ansible_distribution_major_version== "6"
#對數字做大於小於的判斷
when:ansible_distribution_major_version|int >= 6
#定義變量,並根據變量來判斷對應任務是否是否執行
vars:
  epic: true


when: epic
when not epic
#通過上個模塊執行結果來判斷此模塊是否執行(result|failed 可以替換為result is failed ),此方法使用方法詳見例子1-2
tasks:
  - command: /bin/false
    register: result
    ignore_errors: True              
  - command: /bin/something
    when: result|failed              
  - command: /bin/something_else
    when: result|success
  - command: /bin/still/something_else
    when: result|skipped

  

 

 

 

例子1-2

新建下方劇本,

劇本含義:當cat /etc/fapweifjapewijfapwejfpawjf成立時,判斷"when: result is success"才成立 

(需要配合

register: result #將執行結果記錄到result變量上,給when提供判斷條件

ignore_errors: True #跳過錯誤,錯誤時繼續執行,給when提供判斷機會

使用)

---
- hosts: all
  remote_user: root
  gather_facts: True
  tasks:
    - shell: "cat /etc/fapweifjapewijfapwejfpawjf"
      register: result
      ignore_errors: True

    - shell: "head -10 /etc/fapweifjapewijfapwejfpawjf"
      when: result is success

執行結果

 

 

情況2:需要給多台機器添加yum源配置

像這種問題,就是需要使用echo "" >> ..repo 到文件中去,但是,yum倉庫的配置可不是只是一項,有什么能寫的更簡潔的方法呢。

 

with_items  一個迭代器,你可以在里面定義很多的東西,然后在某處引用時,里面的東西會循環的輸出,直到定義的值輸出完。

 

類似下方例子

items=[1,2,3,4,5,6,7,8]

for i in items:
    print(i)

 

 

新建下方劇本

gather_facts: no  在不需要獲取機器信息時,根據信息做判斷時,將其關閉,避免影響執行速度。

定義名稱:with_items,調用名稱:item都是固定的,不能更改.

{{variable}} 調用變量的方法,也是調用迭代器的方法。

 

---
- hosts: all
  remote_user: root
  gather_facts: no
  tasks:
    - name: "setting yum"
      shell: "echo {{ item }} >> /etc/yum.repos.d/base.repo" with_items:
         - "[base]"
         - "name=base"
         - "baseurl=ftp://10.124.164.114/pub/Server"
         - "enabled=1"
         - "gpgcheck=0"

 

 

 

在客戶端上查看結果,已經正常寫入。

 

 

 

情況3:你需要一次操作多個服務,如啟動,重啟等。

你可以使用情況2中的,定義with_items方法,但是你需要去with_items字段中定義,代碼量多了難免有點麻煩,我們可以結合變量使用(在文首就直接定義了),定義一個列表,然后將列表傳給with_items,交由它來做一個迭代器,當引用item時引用多個值。

 

問:為什么不直接在{{}}中引用變量,而要引用迭代器

因為變量無法在引用時被循環,就算列表里面有多個值,它引用時也只會識別一個列表,就是[nginx,ntpd]。

---
- hosts: all
  remote_user: root
  gather_facts: no
  vars:
    service_list: [nginx,ntpd]
    service_state: restarted
  tasks:
    - service: name="{{item}}" state="{{service_state}}" with_items: '{{ service_list }}'

 

 

情況4:你的劇本文件中,定義了很多功能,但是這次,你只想運行某個功能,該如何實現呢。

debug模塊,只是一個功能,在此情況中,可以用任何模塊替換,此模塊是將msg定義的消息回顯到終端,供我們調試。

tags標簽,定義在模塊下,標簽名稱建議有意義,無難輸入的特殊字符,無空格

---
- hosts: all
  remote_user: root
  gather_facts: no
  tasks:
    - debug: msg="task 1"
      tags: task1
    - debug: msg="task two"
      tags: task2

 

執行測試

 

此情況重點來了,單獨運行某個標簽。使用如下命令

只運行task1標簽的任務

[root@host1 [18:17:53]/yaml/test]#ansible-playbook -i hosts  --tags=task1   test5.yaml  

 

 

 

 

學習了上面的使用情況,你已經可以寫一個屬於你的yaml劇本,使用什么模塊實現什么功能,這個你可以邊學邊用,你可以試着完成下方我根據我工作環境自制的精簡版ansible yaml劇本練習作業,鞏固你的學習。

 

以下要求需要在你寫時,寫在同一劇本中

 

1.新建用戶 admin,deployer,並定義密碼

2.設置用戶永不過期

3.備份/home/admin/   的所有文件(包括隱藏文件) ,(假設你有一個叫/dev/vdb的磁盤),判斷/dev/vdb是否掛載,如果掛載了,就不用管,如果沒有掛載,將其掛載到/home/admin/ ,恢復你備份的文件至/home/admin/

4.同步服務器的時間,將時間同步服務設置為自啟動

5.先零時,后永久的增加ulimit ("max user processes", "open files", "pending signals")這三個值的大小,具體大小自定義,達到更改效果即可。

6.先零時關閉防火牆,selinux,后設置永久關閉。

7.將hostname 和本機ip的對應關系增加至/etc/hosts文件中

8.設置yum倉庫,讓其能正常下載軟件,

9,支持運行此劇本時,指定值運行[同步時間]任務,而不設置時間同步服務自啟動


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM