天天看點

自動化運維工具AnsibleAnsible

Ansible

  • Ansible
    • Ansible簡介
      • Ansible是什麼
      • Ansible的優勢及特性
      • Ansible的基本結構
    • 安裝 Ansible
    • 配置Ansible
      • ssh的基本配置
    • 常用Ansible子產品
      • setup子產品
      • ping子產品
      • file子產品
      • command子產品
      • copy子產品
      • 更多子產品
    • Ansible playbooks
      • playbook的組成部分
      • yaml的文法格式
    • Ansible變量
      • 定義playbook中的變量
      • 擷取facts變量

Ansible簡介

Ansible是什麼

Ansible是新出現的自動化運維工具,基于Python開發,集合了衆多運維工具(puppet、cfengine、chef、func、fabric)的優點,實作了批量系統配置、批量程式部署、批量運作指令等功能。ansible是基于子產品工作的,本身沒有批量部署的能力。真正具有批量部署的是ansible所運作的子產品,ansible隻是提供一種架構。

2015年RedHat收購了Ansible,并且将其多個平台自動化部署方案切換到Ansible。

Ansible官網 https://www.ansible.com/

Ansible幫助文檔:http://docs.ansible.com/

RedHat 中國的Ansible支援頁面:https://www.redhat.com/zh/technologies/management/ansible

Ansible的優勢及特性

Ansible作為一個自動化運維工具,優勢總共有一下幾點:

  • 輕量級:無需在用戶端安裝 agent ,并且也不需要啟動服務。
  • 配置靈活:Ansible基于SSH工作,可使用系統或自定義子產品滿足更為靈活的需求。
  • 文法簡潔:配置語言采用 yaml ,用來定義多條任務,文法更為簡潔,Ansible簡單易懂的自動化語言允許使用人員在很短的時間内完成自動化項目的部署。

Ansible的基本結構

  • Ansible的核心管理主機:亦可以稱為 管理節點 ,用來管理其他的受控節點。
  • 系統子產品:Ansible本身自帶一些子產品,提供一些常用的功能。
  • 擴充子產品:若Ansible的系統子產品無法滿足批量化管理的特定需求,則可以添加一些擴充子產品。
  • 插件:完成子產品功能的補充。
  • 主機組:用來定義實際管理維護的主機伺服器。
  • 劇本(playbooks):用來定義多條任務,由Ansible統一去執行。

安裝 Ansible

對于Ansible來說,實際批量化管理的操作都是基于 ssh 完成的。并且作為一個輕量級的自動化運維工具,它并不需要走一個C/S的模型,也不需要啟動服務,僅需要在一台管理節點上面安裝對應的軟體即可直接使用。由于這個特性,Ansible就避免了像其他自動化運維工具那樣(如Puppet),考慮更新版本造成的影響。目前隻要機器上安裝了 Python 2.6 以上版本,都可以運作Ansible。主機可以是 Red Hat, Debian, CentOS, OS X, BSD等系統,遺憾的是目前不支援Windows系統做控制主機。

下載下傳位址:http://releases.ansible.com/ 或 https://github.com/ansible/

在我們實驗環境中采用的是1.9.2的版本,以servera作為ansible的管理節點。

[[email protected] ansible]# ls
ansible--el7.noarch.rpm
ansible-inventory-grapher--el7.noarch.rpm
ansible-lint--el7.noarch.rpm
python-crypto--el7.x86_64.rpm
python-ecdsa--el7.noarch.rpm
python-httplib2--el7.noarch.rpm
python-jinja2--el7.noarch.rpm
python-keyczar-c-el7.noarch.rpm
python-paramiko--el7.noarch.rpm
[[email protected] ansible]# yum -y localinstall *.rpm
Loaded plugins: langpacks
Examining ansible--el7.noarch.rpm: ansible--el7.noarch
Marking ansible--el7.noarch.rpm to be installed
Examining ansible-inventory-grapher--el7.noarch.rpm: ansible-inventory-grapher--el7.noarch
Marking ansible-inventory-grapher--el7.noarch.rpm to be installed
Examining ansible-lint--el7.noarch.rpm: ansible-lint--el7.noarch
Marking ansible-lint--el7.noarch.rpm to be installed
Examining python-crypto--el7.x86_64.rpm: python-crypto--el7.x86_64
Marking python-crypto--el7.x86_64.rpm to be installed
Examining python-ecdsa--el7.noarch.rpm: python-ecdsa--el7.noarch
Marking python-ecdsa--el7.noarch.rpm to be installed
Examining python-httplib2--el7.noarch.rpm: python-httplib2--el7.noarch
Marking python-httplib2--el7.noarch.rpm to be installed
Examining python-jinja2--el7.noarch.rpm: python-jinja2--el7.noarch
Marking python-jinja2--el7.noarch.rpm to be installed
Examining python-keyczar-c-el7.noarch.rpm: python-keyczar-c-el7.noarch
Marking python-keyczar-c-el7.noarch.rpm to be installed
Examining python-paramiko--el7.noarch.rpm: python-paramiko--el7.noarch
Marking python-paramiko--el7.noarch.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package ansible.noarch :-el7 will be installed
---> Package ansible-inventory-grapher.noarch :-el7 will be installed
---> Package ansible-lint.noarch :-el7 will be installed
---> Package python-crypto.x86_64 :-el7 will be installed
---> Package python-ecdsa.noarch :-el7 will be installed
---> Package python-httplib2.noarch :-el7 will be installed
---> Package python-jinja2.noarch :-el7 will be installed
--> Processing Dependency: python-babel >=  for package: python-jinja2--el7.noarch
rhel_dvd                                                 |  kB     :     
(/): rhel_dvd/group_gz                                   |  kB   :     
(/): rhel_dvd/primary_db                                 |  MB   :     
--> Processing Dependency: python-markupsafe for package: python-jinja2--el7.noarch
---> Package python-keyczar.noarch :c-el7 will be installed
--> Processing Dependency: python-pyasn1 for package: python-keyczar-c-el7.noarch
---> Package python-paramiko.noarch :-el7 will be installed
--> Running transaction check
---> Package python-babel.noarch :-el7 will be installed
---> Package python-markupsafe.x86_64 :-el7 will be installed
---> Package python-pyasn1.noarch :-el7 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package         Arch   Version      Repository                            Size
================================================================================
Installing:
 ansible         noarch -el7  /ansible--el7.noarch           M
 ansible-inventory-grapher
                 noarch -el7  /ansible-inventory-grapher--el7.noarch
                                                                            k
 ansible-lint    noarch -el7  /ansible-lint--el7.noarch       k
 python-crypto   x86_64 -el7  /python-crypto--el7.x86_64     M
 python-ecdsa    noarch -el7   /python-ecdsa--el7.noarch       k
 python-httplib2 noarch -el7  /python-httplib2--el7.noarch   k
 python-jinja2   noarch -el7  /python-jinja2--el7.noarch     M
 python-keyczar  noarch c-el7  /python-keyczar-c-el7.noarch    k
 python-paramiko noarch -el7 /python-paramiko--el7.noarch  M
Installing for dependencies:
 python-babel    noarch -el7  rhel_dvd                              M
 python-markupsafe
                 x86_64 -el7  rhel_dvd                               k
 python-pyasn1   noarch -el7  rhel_dvd                               k

Transaction Summary
================================================================================
Install   Packages (+ Dependent packages)

Total size:  M
Total download size:  M
Installed size:  M
Downloading packages:
(/): python-markupsafe--el7.x86_64.rpm            |   kB   :     
(/): python-pyasn1--el7.noarch.rpm                |   kB   :     
(/): python-babel--el7.noarch.rpm                 |  MB   :     
--------------------------------------------------------------------------------
Total                                               MB/s |  MB  :     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : python-crypto--el7.x86_64                            / 
  Installing : python-babel--el7.noarch                             / 
  Installing : python-pyasn1--el7.noarch                            / 
  Installing : python-keyczar-c-el7.noarch                           / 
  Installing : python-ecdsa--el7.noarch                              / 
  Installing : python-paramiko--el7.noarch                         / 
  Installing : python-httplib2--el7.noarch                          / 
  Installing : python-markupsafe--el7.x86_64                        / 
  Installing : python-jinja2--el7.noarch                            / 
  Installing : ansible--el7.noarch                                 / 
  Installing : ansible-lint--el7.noarch                            / 
  Installing : ansible-inventory-grapher--el7.noarch               / 
  Verifying  : python-keyczar-c-el7.noarch                           / 
  Verifying  : python-markupsafe--el7.x86_64                        / 
  Verifying  : python-jinja2--el7.noarch                            / 
  Verifying  : python-crypto--el7.x86_64                            / 
  Verifying  : python-httplib2--el7.noarch                          / 
  Verifying  : ansible-lint--el7.noarch                             / 
  Verifying  : python-ecdsa--el7.noarch                              / 
  Verifying  : ansible-inventory-grapher--el7.noarch                / 
  Verifying  : python-pyasn1--el7.noarch                            / 
  Verifying  : python-babel--el7.noarch                            / 
  Verifying  : python-paramiko--el7.noarch                        / 
  Verifying  : ansible--el7.noarch                                 / 

Installed:
  ansible.noarch :-el7                                                  
  ansible-inventory-grapher.noarch :-el7                                
  ansible-lint.noarch :-el7                                             
  python-crypto.x86_64 :-el7                                            
  python-ecdsa.noarch :-el7                                              
  python-httplib2.noarch :-el7                                          
  python-jinja2.noarch :-el7                                            
  python-keyczar.noarch :c-el7                                           
  python-paramiko.noarch :-el7                                         

Dependency Installed:
  python-babel.noarch :-el7    python-markupsafe.x86_64 :-el7  
  python-pyasn1.noarch :-el7  

Complete!
           

配置Ansible

ssh的基本配置

Ansible是基于ssh來實作批量化的配置,Ansible1.2.1及其之後的版本都會預設啟用公鑰認證。于是我們可以先來配置下ssh基于公鑰的認證。

servera依舊作為管理節點,serverb作為受控節點。在這裡我們使用密鑰方式來保證servera和serverb的連接配接。

[[email protected] ansible]# ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
d9:::::aa:d::b:e::d4:f::a:ae [email protected]
The key's randomart image is:
+--[ RSA ]----+
|     .o.+.       |
|  . .  +  o      |
| . o .  .+ .     |
|  = . ...+o      |
| B . o .So.      |
|o o +   E .      |
|   .     .       |
|                 |
|                 |
+-----------------+
           
[[email protected] ansible]# ssh-copy-id [email protected]
The authenticity of host '172.25.0.11 (172.25.0.11)' can't be established.
ECDSA key fingerprint is b:f:b::e:d2:::c:d:c8:f4:::d3:e.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO:  key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password: 

Number of key(s) added: 

Now try logging into the machine, with:   "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.

[[email protected] ansible]# ssh [email protected]
Last login: Thu Oct  ::  from 
[[email protected] ~]# exit
logout
Connection to  closed.
           
  • ansible的配置,配置主目錄/etc/ansible

ansible.cfg為主配置檔案。hosts定義了主機組相關的内容。

[root@servera ansible]# cd /etc/ansible/
[root@servera ansible]# ls
ansible.cfg  hosts  roles
           
  • 變更ansible.cfg
[root@servera ansible]# vim ansible.cfg
private_key_file=/root/.ssh/id_rsa   # 定義ssh信任檔案所在位置
           
  • 定義inventory檔案(定義主機組)
[[email protected] ansible]# vim /etc/ansible/hosts

# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups
[webserver]


           

測試(可以通過以下指令做簡單的測試,具體操作後續分析):

[root@servera .ssh]# ansible webserver -m command -a 'uptime'
.. | success | rc= >>
 :: up  min,   users,  load average: ., ., .

.. | success | rc= >>
 :: up  min,   users,  load average: .08, ., .
​````

有些時候我們可能會遇到一個問題,如果有個主機重新安裝并在“known_hosts”中有了不同的key值記錄,這會提示一個錯誤資訊直到被糾正為止。如果有個主機沒有在“known_hosts”中被初始化将會導緻在互動使用Ansible或定時執行Ansible時對key資訊的确認提示。如果你想禁用此項行為并明白其含義,你能夠通過編輯 /etc/ansible/ansible.cfg來實作。

​```shell
[root@servera ansible]# ls
ansible.cfg  hosts  roles
[root@servera ansible]# vim ansible.cfg 
[defaults]
host_key_checking = False
[root@servera ansible]# pwd
/etc/ansible
           

常用Ansible子產品

Ansible可以通過子產品的方式來完成一些原理的管理工作,可以通過ansible-doc -l檢視到所有自帶的子產品。 ansible-doc -s 子產品名 可以用來檢視具體子產品對應的用法。

這裡主要講一些常用的子產品。

setup子產品

用來收集遠端主機的基本資訊

ansible webserver -m setup
. | success >> {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.0.12", 
            "172.25.0.12", 
            "192.168.1.12"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::5054:ff:fe01:c", 
            "fe80::5054:ff:fe00:c", 
            "fe80::5054:ff:fe02:c"
        ], 
        ...... # 以下内容省略
        ......
        ......
           

ping子產品

用來檢視遠端主機的運作狀态

““shell

[[email protected] ansible]# ansible webserver -m ping

172.25.0.12 | success >> {

“changed”: false,

“ping”: “pong”

}

172.25.0.11 | success >> {

“changed”: false,

“ping”: “pong”

}

““

file子產品

用來設定檔案的屬性,用-a指定選項。

file子產品相關選項如下:

參數
force 強制,有兩個選項:yes或no
group 定義檔案/目錄的所屬組
mode 定義檔案/目錄的權限
owner 定義檔案/目錄的屬主
path 必選項,定義檔案/目錄的路徑
src 被連結的源檔案路徑,隻應用于state=link的情況
dest 被連結到的路徑,隻應用于state=link的情況
recurse 遞歸設定檔案的屬性,隻對目錄有效
state 定義檔案/目錄的參數,常用參數如下:
directory:如果目錄不存在,就建立目錄
file:即使檔案不存在,也不會被建立
link:建立軟連結
hard:建立硬連結
touch:如果檔案不存在,則會建立一個新的檔案,如果檔案或目錄已存在,則更新其最後修改時間
absent:删除目錄、檔案或者取消連結檔案

以下例子展示了在多台受控主機上使用file子產品建立檔案的方式:

[root@servera ansible]# ansible server -m file -a 'state=touch owner=student group=student mode=444 path=/tmp/testfile'
.. | success >> {
    "changed": true, 
    "dest": "/tmp/testfile", 
    "gid": , 
    "group": "student", 
    "mode": "0444", 
    "owner": "student", 
    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 
    "size": , 
    "state": "file", 
    "uid": 
}

.. | success >> {
    "changed": true, 
    "dest": "/tmp/testfile", 
    "gid": , 
    "group": "student", 
    "mode": "0444", 
    "owner": "student", 
    "secontext": "unconfined_u:object_r:user_tmp_t:s0", 
    "size": , 
    "state": "file", 
    "uid": 
}

[root@serverb ~]# ll /tmp/testfile 
-r--r--r--.  student student  Oct  : /tmp/testfile
           

command子產品

用以ssh的方式,在遠端主機上執行指令

例子如下:

““shell

[[email protected] ansible]# ansible server -m command -a ‘ls -l /etc/hosts’

172.25.0.12 | success | rc=0 >>

-rw-r–r–. 1 root root 324 Oct 21 05:55 /etc/hosts

172.25.0.11 | success | rc=0 >>

-rw-r–r–. 1 root root 324 Oct 21 05:54 /etc/hosts

““

copy子產品

将對應的檔案複制至遠端主機

參數 說明
backup 将源檔案備份。
dest 必選項。要将源檔案複制到的遠端主機的絕對路徑,如果源檔案是一個目錄,那麼該路徑也必須是個目錄
directory_mode 遞歸設定目錄的權限,預設為系統預設權限
force 如果目标主機包含該檔案,但内容不同,如果設定為yes,則強制覆寫,如果為no,則隻有當目标主機的目标位置不存在該檔案時,才複制。預設為yes
src 被複制到遠端主機的本地檔案,可以是絕對路徑,也可以是相對路徑。如果路徑是一個目錄,它将遞歸複制。在這種情況下,如果路徑使用“/”來結尾,則隻複制目錄裡的内容,如果沒有使用“/”來結尾,則包含目錄在内的整個内容全部複制,類似于rsync。

示例:

[root@servera ansible]# ansible server -m copy -a 'src=/etc/hosts dest=/tmp/hosts mode=444'
.. | success >> {
    "changed": true, 
    "checksum": "69f4c26657963dc7d4fcf97c24f78e1f9e9e971f", 
    "dest": "/tmp/hosts", 
    "gid": , 
    "group": "root", 
    "md5sum": "1b2b40d5fb755dad0d1f8c5e7ab07ff4", 
    "mode": "0444", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": , 
    "src": "/root/.ansible/tmp/ansible-tmp-1477049366.36-247610647111921/source", 
    "state": "file", 
    "uid": 
}

.. | success >> {
    "changed": true, 
    "checksum": "69f4c26657963dc7d4fcf97c24f78e1f9e9e971f", 
    "dest": "/tmp/hosts", 
    "gid": , 
    "group": "root", 
    "md5sum": "1b2b40d5fb755dad0d1f8c5e7ab07ff4", 
    "mode": "0444", 
    "owner": "root", 
    "secontext": "unconfined_u:object_r:admin_home_t:s0", 
    "size": , 
    "src": "/root/.ansible/tmp/ansible-tmp-1477049366.35-135289460451279/source", 
    "state": "file", 
    "uid": 
}
           

更多子產品

ansible-doc -l可以羅列ansible所有子產品名稱

ansible-doc -s 子產品名,可以用來檢視對應子產品的實際用法。

舉例:

[[email protected] ansible]# ansible-doc -s at
less  (POSIX regular expressions)
Copyright (C) - Mark Nudelman

less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less
- name: S c h e d u l e   t h e   e x e c u t i o n   o f   a   c o m m a n d   o r   s c r i p t   f i l e   v i a   t h e   a t   c o m m 
  action: at
      command                # A command to be executed in the future.
      count=                 # The count of units in the future to execute the command or script file.
      script_file            # An existing script file to be executed in the future.
      state                  # The state dictates if the command or script file should be evaluated as present(added) or absent(deleted).
      unique                 # If a matching job is present a new job will not be added.
      units=                 # The type of units in the future to execute the command or script file.
(END)

           

以上方式可以稱為 adhoc的方式來運作ansible,适用于單行指令的場景。但如果涉及到多條任務同時執行,則請看下節内容。

Ansible playbooks

我們使用 adhoc 時,主要是使用 /usr/bin/ansible 程式執行任務,而使用 playbooks 時,更多是将之放入源碼控制之中,用之推送你的配置或是用于确認你的遠端系統的配置是否符合配置規範。playbooks也屬于ansible核心的一個部分,用來定義一系列ansible要去執行的任務。

play主要的功能就是将實作歸并為一組的主機裝扮成實作通過ansible的task定義好的角色,所謂task就是調用ansible的子產品。而所謂的playbooks就是将多個play統一去完成。簡單來說,playbooks 是一種簡單的配置管理系統與多機器部署系統的基礎,非常适合于複雜應用的部署。

playbook的組成部分

  • 受控節點hosts(主機組)
  • 運作使用者身份:remote_user
  • 變量部分vars,後續任務中可以采用一些變量
  • 任務部分tasks:具體執行什麼樣的任務
  • 後續任務部分handlers:定義task完成後需要調用的任務。

yaml的文法格式

對于 Ansible,,每一個 YAML 檔案都是從一個清單開始。清單中的每一項都是一個鍵值對, 通常它們被稱為一個 “哈希” 或 “字典”。是以, 我們需要知道如何在 YAML 中編寫清單和字典。YAML 還有一個小的怪癖,所有的 YAML 檔案(無論和 Ansible 有沒有關系)開始行都應該是 —。這是 YAML 格式的一部分, 表明一個檔案的開始。

清單中的所有成員都開始于相同的縮進級别,并且使用一個“- ”作為開頭(一個橫杠和一個空格):

下面是一種基本的 task 的定義,service moudle 使用 key=value 格式的參數,這也是大多數 module 使用的參數格式:

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

舉例1:安裝httpd并啟動服務

[[email protected] ansible]# vim test.yml 
- hosts: server # 定義主機組
  remote_user: root # 在 Ansible 1.4 以後才改為 remote_user,原先參>數為user
  tasks:  # 定義實際執行的任務
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: ensure apache is running
    service: name=httpd state=started
           

執行yml方法:

[[email protected] ansible]# ansible-playbook test.yml

PLAY [server] ***************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [ensure apache is at the latest version] ******************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [ensure apache is running] ********************************************** 
changed: [172.25.0.12]
changed: [172.25.0.11]

PLAY RECAP ******************************************************************** 
172.25.0.11                : ok=3    changed=1    unreachable=0    failed=0   
172.25.0.12                : ok=3    changed=1    unreachable=0    failed=0   
           

練習:使用ansible的playbook在受控節點上安裝mariadb-server,并啟動mariadb服務

答案:

- hosts : server
  remote_user: root
  tasks:
     - name: install mariadb-server
       yum: name=mariadb-server state=present
     - name: start service
       service: name=mariadb state=started enabled=yes
           

舉例2:變更httpd配置檔案

Handlers 也是一些 task 的清單,通過名字來引用,它們和一般的 task 并沒有什麼差別,Handlers 是由通知者進行 notify,,如果沒有被 notify,handlers 不會執行,不管有多少個通知者進行了 notify,等到 play 中的所有 task 執行完成之後,handlers 也隻會被執行一次.

- hosts: server # 定義主機組
  remote_user: root # 在 Ansible 1.4 以後才改為 remote_user,原先參數為user
  tasks:  # 定義實際執行的任務
  - name: ensure apache is at the latest version
    yum: name=httpd state=latest
  - name: ensure apache is running
    service: name=httpd state=started
  - name: change httpd config file
    copy: src=/tmp/www.abc.com.conf dest=/etc/httpd/conf.d/www.abc.com.conf
    notify:
          - restart apache
  handlers:
   - name: restart apache
     service:  name=httpd state=restarted
           

執行結果如下:

[[email protected] ansible]# ansible-playbook  test.yml 

PLAY [server] ********


********************************************************* 

GATHERING FACTS *************************************************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [ensure apache is at the latest version] ******************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [ensure apache is running] ********************************************** 
ok: [172.25.0.11]
ok: [172.25.0.12]

TASK: [change httpd config file] ********************************************** 
ok: [172.25.0.12]
changed: [172.25.0.11]

NOTIFIED: [restart apache] **************************************************** 
changed: [172.25.0.11]

PLAY RECAP ******************************************************************** 
172.25.0.11                : ok=5    changed=2    unreachable=0    failed=0   
172.25.0.12                : ok=4    changed=0    unreachable=0    failed=0  
           

Ansible變量

在Ansible裡面會有許多種設定變量的方式。

在使用變量之前最好先知道什麼是合法的變量名。變量名可以為字母,數字以及下劃線。變量始終應該以字母開頭, “foo_port”是個合法的變量名。”foo5”也是,“foo-port”,“foo port”,“foo.port” 和 “12”則不是合法的變量名。

定義playbook中的變量

定義的方式如下:

- hosts: server # 定義主機組
  vars:
        server_name: www.efg.com  # 定義變量
  remote_user: root # 在 Ansible 1.4 以後才改為 remote_user,原先參數為user
  tasks:  # 定義實際執行的任務
  - name: ensure apache is at the latest version
    yum: name=httpd state=latest
  - name: ensure apache is running
    service: name=httpd state=started
  - name: change abc config file
    copy: src=/tmp/www.abc.com.conf dest=/etc/httpd/conf.d/www.abc.com.conf
    notify:
          - restart apache
  - name: change efg config file
    copy: src=/tmp/{{server_name}}.conf dest=/etc/httpd/conf.d/{{server_name}}.conf # 通過{{變量名}}來引用變量
    notify:
          - restart apache
  handlers:
   - name: restart apache
     service:  name=httpd state=restarted
           

執行結果如下:

[[email protected] ansible]# ansible-playbook test.yml 

PLAY [server] ***************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [ensure apache is at the latest version] ******************************** 
ok: [172.25.0.11]
ok: [172.25.0.12]

TASK: [ensure apache is running] ********************************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [change abc config file] ************************************************ 
ok: [172.25.0.11]
ok: [172.25.0.12]

TASK: [change efg config file] ************************************************ 
changed: [172.25.0.12]
changed: [172.25.0.11]

NOTIFIED: [restart apache] **************************************************** 
changed: [172.25.0.11]
changed: [172.25.0.12]

PLAY RECAP ******************************************************************** 
172.25.0.11                : ok=6    changed=2    unreachable=0    failed=0   
172.25.0.12                : ok=6    changed=2    unreachable=0    failed=0  
           

使用copy子產品無法将變量傳遞到配置檔案裡,在這裡,我們可以使用到ansible裡面的模闆功能

- hosts: server # 定義主機組
  vars:
        server_name: www.efg.com
        nametem: www.lucky.com
  remote_user: root # 在 Ansible 1.4 以後才改為 remote_user,原先參數為user
  tasks:  # 定義實際執行的任務
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: ensure apache is running
    service: name=httpd state=started
  - name: change abc config file
    copy: src=/tmp/www.abc.com.conf dest=/etc/httpd/conf.d/www.abc.com.conf
    notify:
          - restart apache
  - name: change efg config file
    copy: src=/tmp/{{server_name}}.conf dest=/etc/httpd/conf.d/{{server_name}}.conf
    notify:
          - restart apache
  - name: test
    template: src=/tmp/lucky.conf dest=/etc/httpd/conf.d/lucky.conf
    notify:
          - restart apache
  handlers:
   - name: restart apache
     service:  name=httpd state=restarted

[[email protected] tmp]# cat lucky.conf 
<VirtualHost *:80>
    ServerName {{ nametem }}
    DocumentRoot /var/www/html/lucky.com
</VirtualHost>
[[email protected] tmp]# 
           

執行結果如下

[[email protected] ansible]# ansible-playbook test.yml 

PLAY [server] ***************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [ensure apache is at the latest version] ******************************** 
ok: [172.25.0.11]
ok: [172.25.0.12]

TASK: [ensure apache is running] ********************************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [change abc config file] ************************************************ 
ok: [172.25.0.11]
ok: [172.25.0.12]

TASK: [change efg config file] ************************************************ 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [test] ****************************************************************** 
changed: [172.25.0.11]
changed: [172.25.0.12]

PLAY RECAP ******************************************************************** 
172.25.0.11                : ok=6    changed=1    unreachable=0    failed=0   
172.25.0.12                : ok=6    changed=1    unreachable=0    failed=0   

[[email protected] conf.d]# cat lucky.conf 
<VirtualHost *:80>
    ServerName www.lucky.com
    DocumentRoot /var/www/html/lucky.com
</VirtualHost>
           

擷取facts變量

之前提到過一個子產品setup,能夠擷取到每台主機自己的參數

這些變量也是可以直接在模闆中拿來引用的。

- hosts: server # 定義主機組
  vars:
        server_name: www.efg.com
        nametem: www.lucky.com
  remote_user: root # 在 Ansible 1.4 以後才改為 remote_user,原先參數為user
  tasks:  # 定義實際執行的任務
  - name: ensure apache is at the latest version
    yum: pkg=httpd state=latest
  - name: ensure apache is running
    service: name=httpd state=started
  - name: change abc config file
    copy: src=/tmp/www.abc.com.conf dest=/etc/httpd/conf.d/www.abc.com.conf
    notify:
          - restart apache
  - name: change efg config file
    copy: src=/tmp/{{server_name}}.conf dest=/etc/httpd/conf.d/{{server_name}}.conf
    notify:
          - restart apache
  - name: lucky
    template: src=/tmp/lucky.conf dest=/etc/httpd/conf.d/lucky.conf
    notify:
          - restart apache
  - name: test
    template: src=/tmp/server.conf dest=/etc/httpd/conf.d/server.conf
    notify:
          - restart apache
  handlers:
   - name: restart apache
     service:  name=httpd state=restarted

[[email protected] tmp]# cat server.conf 
<VirtualHost *:80>
    ServerName {{ ansible_nodename }}
    DocumentRoot /var/www/html/{{ ansible_nodename }}
</VirtualHost>
           

執行結果如下

[[email protected] ansible]# ansible-playbook  test.yml 

PLAY [server] ***************************************************************** 

GATHERING FACTS *************************************************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [ensure apache is at the latest version] ******************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [ensure apache is running] ********************************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [change abc config file] ************************************************ 
ok: [172.25.0.11]
ok: [172.25.0.12]

TASK: [change efg config file] ************************************************ 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [lucky] ***************************************************************** 
ok: [172.25.0.12]
ok: [172.25.0.11]

TASK: [test] ****************************************************************** 
changed: [172.25.0.11]
changed: [172.25.0.12]

NOTIFIED: [restart apache] **************************************************** 
changed: [172.25.0.11]
changed: [172.25.0.12]

PLAY RECAP ******************************************************************** 
172.25.0.11                : ok=8    changed=2    unreachable=0    failed=0   
172.25.0.12                : ok=8    changed=2    unreachable=0    failed=0 
           

檢視配置結果

[[email protected] conf.d]# cat server.conf 
<VirtualHost *:>
    ServerName serverb.pod0.example.com
    DocumentRoot /var/www/html/serverb.pod0.example.com
</VirtualHost>