Ansible基礎使用規則

條件測試

如果需要根據變量、facts或此前任務的執行結果來做爲某task執行與否的前提時要用到條件
測試。

when語句

在task後添加when子句即可使用條件測試;when語句支持Jinja2表達式語法。例如:

tasks:
  - name: "shutdown Debian flavored systems"
    command: /sbin/shutdown -h now
    when: ansible_os_family == "Debian"

when語句中還可以使用Jinja2的大多“filter”,例如要忽略此前某語句的錯誤並基於
其結果(failed或者sucess)運行後面指定的語句,可使用類似如下形式:

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

此外,when語句中還可以使用facts或playbook中定義的變量。

迭代

當有需要重複性執行的任務時,可以使用迭代機制。其使用格式爲將需要迭代的內
容定義爲item變量引用,並通過with_items語句來指明迭代的元素列表即可。例如:

- name: add several users
  user: name={{ item }} state=present groups=wheel
  with_items:
     - testuser1
     - testuser2

上面語句的功能等同於下面的語句:

- name: add user testuser1
  user: name=testuser1 state=present groups=wheel
- name: add user testuser2
  user: name=testuser2 state=present groups=wheel

事實上,with_items中可以使用元素還可爲hashes,例如:

- name: add several users
  user: name={{ item.name }} state=present groups={{ item.groups }}
  with_items:
    - { name: 'testuser1', groups: 'wheel' }
    - { name: 'testuser2', groups: 'root' }

ansible的循環機制還有更多的高級功能,具體請參見官方文檔(http://docs.ansible.com/playbooks_loops.html)。

playbook基礎組件

任務列表和action

play的主體部分是task list。task list中的各任務按次序逐個在hosts中指定的所有主機上執
行,即在所有主機上完成第一個任務後再開始第二個。在運行自下而下某playbook時,如
果中途發生錯誤,所有已執行任務都將回滾,因此,在更正playbook後重新執行一次即可。

task的目的是使用指定的參數執行模塊,而在模塊參數中可以使用變量。模塊執行是冪等的,
這意味着多次執行是安全的,因爲其結果均一致。

每個task都應該有其name,用於playbook的執行結果輸出,建議其內容儘可能清晰地描述
任務執行步驟。如果未提供name,則action的結果將用於輸出。

定義task的可以使用“action: module options”或“module: options”的格式,推薦使
用後者以實現向後兼容。如果action一行的內容過多,也中使用在行首使用幾個空白字符進
行換行。

        tasks:
          - name: make sure apache is running
            service: name=httpd state=running

在衆多模塊中,只有command和shell模塊僅需要給定一個列表而無需使用“
key=value”
格式,例如:

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 

handlers
用於當關注的資源發生變化時採取一定的操作。
“notify”這個action可用於在每個play的最後被觸發,這樣可以避免多次有改變發生時每
次都執行指定的操作,取而代之,僅在所有的變化發生完成後一次性地執行指定操作。
在notify中列出的操作稱爲handler,也即notify中調用handler中定義的操作。

- name: template configuration file
  template: src=template.j2 dest=/etc/foo.conf
  notify:
     - restart memcached
     - restart apache   

handler是task列表,這些task與前述的task並沒有本質上的不同。

handlers:
    - name: restart memcached
      service:  name=memcached state=restarted
    - name: restart apache
      service: name=apache state=restarted

案例:

heartbeat.yaml
- hosts: hbhosts
  remote_user: root
  tasks:
    - name: ensure heartbeat latest version
      yum: name=heartbeat state=present
    - name: authkeys configure file
      copy: src=/root/hb_conf/authkeys dest=/etc/ha.d/authkeys
    - name: authkeys mode 600
      file: path=/etc/ha.d/authkeys mode=600
      notify:
        - restart heartbeat
    - name: ha.cf configure file
      copy: src=/root/hb_conf/ha.cf dest=/etc/ha.d/ha.cf
      notify: 
        - restart heartbeat
  handlers:
    - name: restart heartbeat
      service: name=heartbeat state=restarted

roles

ansilbe自1.2版本引入的新特性,用於層次性、結構化地組織playbook。roles能夠根據層次型結構自動裝載變量文件、tasks以及handlers等。
要使用roles只需要在playbook中使用include指令即可。簡單來講,roles就是通過分別將變量、文件、任務、模板及處理器放置於單獨的目錄
中,並可以便捷地include它們的一種機制。角色一般用於基於主機構建服務的場景中,但也可以是用於構建守護進程等場景中。

一個roles的案例如下所示:
    site.yml
    webservers.yml
    dbservers.yml
    roles/
       common/
         files/
         templates/
         tasks/
         handlers/
         vars/
         meta/
       webservers/
         files/
         templates/
         tasks/
         handlers/
         vars/
         meta/

而在playbook中,可以這樣使用roles:

- hosts: webservers
  roles:
     - common
     - webservers

也可以向roles傳遞參數,例如:

113.209.20.234
    - hosts: webservers
      roles:
        - common
        - { role: foo_app_instance, dir: '/opt/a',  port: 5000 }
        - { role: foo_app_instance, dir: '/opt/b',  port: 5001 }

甚至也可以條件式地使用roles,例如:

- hosts: webservers
      roles:
        - { role: some_role, when: "ansible_os_family == 'RedHat'" }

創建role的步驟

(1) 創建以roles命名的目錄;
(2) 在roles目錄中分別創建以各角色名稱命名的目錄,如webservers等;
(3) 在每個角色命名的目錄中分別創建files、handlers、meta、tasks、templates
和vars目錄;用不到的目錄可以創建爲空目錄,也可以不創建;
(4) 在playbook文件中,調用各角色;

role內各目錄中可用的文件

tasks目錄:至少應該包含一個名爲main.yml的文件,其定義了此角色的任務列表;
此文件可以使用include包含其它的位於此目錄中的task文件;
files目錄:存放由copy或script等模塊調用的文件;
templates目錄:template模塊會自動在此目錄中尋找Jinja2模板文件;
handlers目錄:此目錄中應當包含一個main.yml文件,用於定義此角色用到的各handler;
在handler中使用include包含的其它的handler文件也應該位於此目錄中;
vars目錄:應當包含一個main.yml文件,用於定義此角色用到的變量;
meta目錄:應當包含一個main.yml文件,用於定義此角色的特殊設定及其依賴關係;
ansible 1.3及其以後的版本才支持;
default目錄:爲當前角色設定默認變量時使用此目錄;應當包含一個main.yml文件;

Tags

tags用於讓用戶選擇運行playbook中的部分代碼。ansible具有冪等性,因此會
自動跳過沒有變化的部分,即便如此,有些代碼爲測試其確實沒有發生變化的時間依然會
非常地長。此時,如果確信其沒有變化,就可以通過tags跳過此些代碼片斷。

Jinja2相關

字面量
表達式最簡單的形式就是字面量。字面量表示諸如字符串和數值的 Python 對象。下面
的字面量是可用的:

“Hello World”:
雙引號或單引號中間的一切都是字符串。無論何時你需要在模板中使用一個字 符串
(比如函數調用、過濾器或只是包含或繼承一個模板的參數),它們都是 有用的。

42 / 42.23:
直接寫下數值就可以創建整數和浮點數。如果有小數點,則爲浮點數,否則爲 整數。
記住在 Python 裏, 42 和 42.0 是不一樣的。

[‘list’, ‘of’, ‘objects’]:
一對中括號括起來的東西是一個列表。列表用於存儲和迭代序列化的數據。例如 你可以
容易地在 for 循環中用列表和元組創建一個鏈接的列表:

<ul>
{% for href, caption in [('index.html', 'Index'), ('about.html', 'About'),
                         ('downloads.html', 'Downloads')] %}
    <li><a href="{{ href }}">{{ caption }}</a></li>
{% endfor %}
</ul>

(‘tuple’, ‘of’, ‘values’):

元組與列表類似,只是你不能修改元組。如果元組中只有一個項,你需要以逗號 結尾它。
元組通常用於表示兩個或更多元素的項。更多細節見上面的例子。

{‘dict’: ‘of’, ‘key’: ‘and’, ‘value’: ‘pairs’}:
Python 中的字典是一種關聯鍵和值的結構。鍵必須是唯一的,並且鍵必須只有一個 值。
字典在模板中很少使用,罕用於諸如 xmlattr() 過濾器之類。
    true / false:
    true 永遠是 true ,而 false 始終是 false

10.2 算術運算

Jinja 允許你用計算值。這在模板中很少用到,但是爲了完整性允許其存在。支持下面的
運算符:

    +
        把兩個對象加到一起。通常對象是素質,但是如果兩者是字符串或列表,你可以用這 
        種方式來銜接它們。無論如何這不是首選的連接字符串的方式!連接字符
        串見 ~ 運算符。 {{ 1 + 1 }} 等於 2 。
    -
        用第一個數減去第二個數。 {{ 3 - 2 }} 等於 1 。
    /
        對兩個數做除法。返回值會是一個浮點數。 {{ 1 / 2 }} 等於 {{ 0.5 }} 。
    //
        對兩個數做除法,返回整數商。 {{ 20 // 7 }} 等於 2 。
    %
        計算整數除法的餘數。 {{ 11 % 7 }} 等於 4 。
    *
        用右邊的數乘左邊的操作數。 {{ 2 * 2 }} 會返回 4 。也可以用於重 復一個字符
        串多次。 {{ ‘=’ * 80 }} 會打印 80 個等號的橫條。
    **
        取左操作數的右操作數次冪。 {{ 2**3 }} 會返回 8 。

10.3 比較操作符

==
        比較兩個對象是否相等。
    !=
        比較兩個對象是否不等。
    >
        如果左邊大於右邊,返回 true 。
    >=
        如果左邊大於等於右邊,返回 true 。
    <
        如果左邊小於右邊,返回 true 。
    <=
        如果左邊小於等於右邊,返回 true

10.4 邏輯運算符

對於 if 語句,在 for 過濾或 if 表達式中,它可以用於聯合多個表達式:

    and
        如果左操作數和右操作數同爲真,返回 trueor
        如果左操作數和右操作數有一個爲真,返回 truenot
        對一個表達式取反(見下)。
    (expr)
        表達式組。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章