Ansible (playbook)

一、YAML

1.1 YAML介紹

YAML是一個可讀性高的用來表達資料序列的格式。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822等。Clark Evans在2001年在首次發表了這種語言,另外Ingy d?t Net與Oren Ben-Kiki也是這語言的共同設計者。

YAML Ain't Markup Language,即YAML不是XML。不過,在開發的這種語言時,YAML的意思其實是:"Yet Another Markup Language"(仍是一種標記語言)。其特性:

???????? YAML的可讀性好

???????? YAML和腳本語言的交互性好

???????? YAML使用實現語言的數據類型

???????? YAML有一個一致的信息模型

???????? YAML易于實現

???????? YAML可以基于流來處理

???????? YAML表達能力強,擴展性好

更多的內容及規范可參見http://www.yaml.org。

1.2 YAML語法

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

YAML文件擴展名通常為.yaml,如example.yaml。

1.2.1 list

列表的所有元素均使用“-”打頭,例如:

# A list of tasty fruits

- Apple

- Orange

- Strawberry

- Mango

1.2.2 dictionary

字典通過key與value進行標識,例如:

# An employee record

name: Example Developer

job: Developer

skill: Elite

也可以將key:value放置于{}中進行表示,例如:

# An employee record

{name: Example Developer, job: Developer, skill: Elite}

二、Ansible基礎元素

2.1 變量

2.1.1 變量命名

變量名僅能由字母、數字和下劃線組成,且只能以字母開頭。

2.1.2 facts

facts是由正在通信的遠程目標主機發回的信息,這些信息被保存在ansible變量中。要獲取指定的遠程主機所支持的所有facts,可使用如下命令進行:

# ansible hostname -m setup

2.1.3 register

把任務的輸出定義為變量,然后用于其他任務,示例如下:

? tasks:

???? - shell: /usr/bin/foo

?????? register: foo_result

?????? ignore_errors: True

2.1.4 通過命令行傳遞變量

在運行playbook的時候也可以傳遞一些變量供playbook使用,示例如下:

???????? ansible-playbook test.yml --extra-vars "hosts=www user=mageedu"

2.1.5 通過roles傳遞變量

當給一個主機應用角色的時候可以傳遞變量,然后在角色內使用這些變量,示例如下:

???????? - hosts: webservers

???????? ? roles:

???????? ??? - common

???????? ??? - { role: foo_app_instance, dir: '/web/htdocs/a.com',? port: 8080 }

2.2 Inventory

ansible的主要功用在于批量主機操作,為了便捷地使用其中的部分主機,可以在inventory file中將其分組命名。默認的inventory file為/etc/ansible/hosts。

inventory file可以有多個,且也可以通過Dynamic Inventory來動態生成。

2.2.1 inventory文件格式

inventory文件遵循INI文件風格,中括號中的字符為組名??梢詫⑼粋€主機同時歸并到多個不同的組中;此外,當如若目標主機使用了非默認的SSH端口,還可以在主機名稱之后使用冒號加端口號來標明。

???????? ntp.neinei.com

???????? [webservers]

???????? www1.neinei.com:2222

???????? www2.neinei.com

???????? [dbservers]

???????? db1.neinei.com

???????? db2.neinei.com

???????? db3.neinei.com

如果主機名稱遵循相似的命名模式,還可以使用列表的方式標識各主機,例如:

[webservers]

www[01:50].example.com

[databases]

db-[a:f].example.com

2.2.2 主機變量

可以在inventory中定義主機時為其添加主機變量以便于在playbook中使用。例如:

[webservers]

www1.neinei.com http_port=80 maxRequestsPerChild=808

www2.neinei.com http_port=8080 maxRequestsPerChild=909

2.2.3 組變量

組變量是指賦予給指定組內所有主機上的在playboo中可用的變量。例如:

[webservers]

www1.neinei.com

www2.neinei.com

[webservers:vars]

ntp_server=ntp.neinei.com

nfs_server=nfs.neinei.com

2.2.4 組嵌套

inventory中,組還可以包含其它的組,并且也可以向組中的主機指定變量。不過,這些變量只能在ansible-playbook中使用,而ansible不支持。例如:

[apache]

httpd1.neinei.com

httpd2.neinei.com

[nginx]

ngx1.neinei.com

ngx2.neinei.com

[webservers:children]

apache

nginx

[webservers:vars]

ntp_server=ntp.neinei.com

2.2.5 inventory參數

ansible基于ssh連接inventory中指定的遠程主機時,還可以通過參數指定其交互方式;這些參數如下所示:

ansible_ssh_host

? The name of the host to connect to, if different from the alias you wish to give to it.

ansible_ssh_port

? The ssh port number, if not 22

ansible_ssh_user

? The default ssh user name to use.

ansible_ssh_pass

? The ssh password to use (this is insecure, we strongly recommend using --ask-pass or SSH keys)

ansible_sudo_pass

? The sudo password to use (this is insecure, we strongly recommend using --ask-sudo-pass)

ansible_connection

? Connection type of the host. Candidates are local, ssh or paramiko.? The default is paramiko before Ansible 1.2, and 'smart' afterwards which detects whether usage of 'ssh' would be feasible based on whether ControlPersist is supported.

ansible_ssh_private_key_file

? Private key file used by ssh.? Useful if using multiple keys and you don't want to use SSH agent.

ansible_shell_type

? The shell type of the target system. By default commands are formatted using 'sh'-style syntax by default. Setting this to 'csh' or 'fish' will cause commands executed on target systems to follow those shell's syntax instead.

ansible_python_interpreter

? The target host python path. This is useful for systems with more

? than one Python or not located at "/usr/bin/python" such as \*BSD, or where /usr/bin/python

? is not a 2.X series Python.? We do not use the "/usr/bin/env" mechanism as that requires the remote user's

? path to be set right and also assumes the "python" executable is named python, where the executable might

? be named something like "python26".

ansible\_\*\_interpreter

? Works for anything such as ruby or perl and works just like ansible_python_interpreter.

? This replaces shebang of modules which will run on that host.

2.3 條件測試

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

2.3.1 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中定義的變量。

2.4 迭代

當有需要重復性執行的任務時,可以使用迭代機制。其使用格式為將需要迭代的內容定義為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)。

三、ansible playbooks

playbook是由一個或多個“play”組成的列表。play的主要功能在于將事先歸并為一組的主機裝扮成事先通過ansible中的task定義好的角色。從根本上來講,所謂task無非是調用ansible的一個module。將多個play組織在一個playbook中,即可以讓它們聯同起來按事先編排的機制同唱一臺大戲。下面是一個簡單示例。

??????? - hosts: webnodes

???????? ? vars:

???????? ??? http_port: 80

???????? ??? max_clients: 256

???????? ? remote_user: root

???????? ? tasks:

???????? ? - name: ensure apache is at the latest version

???????? ??? yum: name=httpd state=latest

???????? ? - name: ensure apache is running

???????? ??? service: name=httpd state=started

???????? ? handlers:

???????? ??? - name: restart apache

???????? ? ????service: name=httpd state=restarted

3.1 playbook基礎組件

3.1.1 Hosts和Users
????????
???????? playbook中的每一個play的目的都是為了讓某個或某些主機以某個指定的用戶身份執行任務。hosts用于指定要執行指定任務的主機,其可以是一個或多個由冒號分隔主機組;remote_user則用于指定遠程主機上的執行任務的用戶。如上面示例中的

?????????????????? -hosts: webnodes

?????????????????? ?remote_user: root

???????? 不過,remote_user也可用于各task中。也可以通過指定其通過sudo的方式在遠程主機上執行任務,其可用于play全局或某任務;此外,甚至可以在sudo時使用sudo_user指定sudo時切換的用戶。

?????????????????? - hosts: webnodes

?????????????????? ? remote_user: mageedu

?????????????????? ? tasks:

?????????????????? ??? - name: test connection

?????????????????? ????? ping:

?????????????????? ????? remote_user: mageedu

?????????????????? ????? sudo: yes

3.1.2 任務列表和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?????????

示例:- hosts: websrvs

?      remote_user: root

?      tasks:

??      - name: creat nginx group

?     ??? group: name=nginx system=yes gid=208

?     ? - name: creat nginx user

?     ??? user: name=nginx uid=208 group=nginx system=yes

3.1.3 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

示例:- hosts: websrvs

     ? remote_user: root

     ? tasks:
 
     ?? - name: install httpd package

      ???? yum: name=httpd state=latest

?     ? - name: install configuration file for httpd

???     ? copy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf

?  ? - notify:
   
???? - restart httpd

?   ??? name: start httpd service

??   ?? service: enabled=true name=httpd state=started

?    handlers:

   ?? - name: restart httpd

?   ??? service: name=httpd 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傳遞參數,例如:

– 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'” }

 

4.1 創建role的步驟

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

4.2 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相關

6.1 字面量
 表達式最簡單的形式就是字面量。字面量表示諸如字符串和數值的 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 。

6.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 。

6.3 比較操作符

==
 比較兩個對象是否相等。
 !=
 比較兩個對象是否不等。
 >
 如果左邊大于右邊,返回 true 。
 >=
 如果左邊大于等于右邊,返回 true 。
 <
 如果左邊小于右邊,返回 true 。
 <=
 如果左邊小于等于右邊,返回 true 。
6.4 邏輯運算符

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

and
 如果左操作數和右操作數同為真,返回 true 。
 or
 如果左操作數和右操作數有一個為真,返回 true 。
 not
 對一個表達式取反(見下)。
 (expr)
 表達式組。

原創文章,作者:nene,如若轉載,請注明出處:http://www.www58058.com/88178

(1)
nenenene
上一篇 2017-10-31
下一篇 2017-11-01

相關推薦

  • Linux批量創建用戶、passwd、shadow、組管理、group、gshadow、默認配置文件login.defs、切換用戶su、提升權限(一)

    Linux批量創建用戶、passwd、shadow、組管理、group、gshadow、默認配置文件login.defs、切換用戶su、提升權限 在Linux中用戶運行某個程序時,該程序的權限屬于當前用戶,進程所能夠訪問資源的權限取決于進程的運行者的身份。如果用戶的id號為0,即使不叫root,他也是管理員;就算名字叫root它也可能是普通用戶。當有多個不同…

    Linux干貨 2016-08-03
  • 正則表達式—grep的用法詳解

    grep與sed、awk共稱為文字處理三劍客,支持正則表達式語句,具體用法如下: grep [options] PATTERN [file]     #常用選項:     –color=auto  #對匹配到的文本著色顯示 &n…

    Linux干貨 2016-07-04
  • LINUX課堂筆記(第二周)

    2018.03.12 rpm httpd*** service httpd start ab 模仿用戶訪問 cat /var/log/httpd/access_log curl 訪問web服務 rev 字符顛倒顯示 sort ? -r 執行反方向(由上至下)整理 ? -R 隨機排序 ? -n 執行按數字大小整理 ? -f 選項忽略(fold)字符串中的字符大…

    Linux干貨 2018-03-17
  • bash特性

    2018-03-11

    2018-03-11
  • find可以這么用

    在工作中不可或缺的工具find:查找系統中的各種文件,對查找的文件進行操作,這就是find的作用。進入正題: 1、查找下系統中有一下系統中有幾個文件叫issue的     [root@localhost private]#find / -name issue      …

    Linux干貨 2017-03-05
  • 磁盤管理及文件系統

    磁盤及文件系統管理初步與進階(重點內容) 磁盤分區及文件系統 linux系統管理 磁盤分區及文件系統管理:分區工具 linux磁盤及文件系統管理 整個操作系統的硬件組成部分,最底層是硬件設備,計算能力得以運行的最根本的基礎。 計算機的五大基本部件:cpu,運算器,控制器被整合到一起,由一個硬件部件來提供。 存儲器(主存rom可編址的存儲單元)。主板上有cpu…

    Linux干貨 2016-08-30

評論列表(1條)

  • aaaa
    aaaa 2017-11-16 12:29

    求md5破解:’aa208b5a53f3e7dd077d0ffe3328a8b1′

欧美性久久久久