1. 程式人生 > >Ansible變數詳解

Ansible變數詳解

一、在Inventory中定義變數

詳見《Ansible2:主機清單》

二、在Playbook中定義變數

1、通過vars關鍵字定義:

vars: 

  http_port: 80

  server_name: localhost

  cert_file: /etc/nginx/ssl/nginx.crt

  key_file: /etc/nginx/ssh/nginx.key

  conf_file: /etc/nginx/conf/default.conf

 

2、通過vars_files關鍵字引入變數檔案:

- hosts: all

  remote_user: root

  vars:

    favcolor: blue

  vars_files:

    - /vars/external_vars.yml

    - /vars/nginx_vars.yml

 

/vars/nginx_vars.yml示例:

 

http_port: 80

server_name: localhost

cert_file: /etc/nginx/ssl/nginx.crt

key_file: /etc/nginx/ssh/nginx.key

conf_file: /etc/nginx/conf/default.conf

 

 

 

3、通過vars_prompt來實現人機互動:

hosts: all

remote_user: root

vars_prompt:

  - name: 'https_passphrase'          #儲存資料的變數名

    prompt: 'Key Passphrase'          #手工輸入資料

    private: yes                      #當該值為yes,則使用者的輸入不會被列印


4、通過playbook的roles定義變數

詳見《ansible10:Playbook的角色與包含》

 

三、註冊變數

在有些時候,我們希望把某一條任務執行的結果儲存下來,可以在接下的任務中呼叫或者做些判斷,可以通過register關鍵字來實現:下面是個簡單的例子,如果/etc/motd檔案中包含有'hi'字串時,則輸出"mothd contains ther word hi":- name: test play
  hosts: all
  tasks:
      - shell: cat /etc/motd
        register: motd_contents
      - shell: echo "motd contains the word hi"
        when: motd_contents.stdout.find('hi') != -1下面是一個register的變數在迴圈中使用的例子:- name: registered variable usage as a with_items list
  hosts: all
  tasks:
      - name: retrieve the list of home directories
        command: ls /home
        register: home_dirs
      - name: add home dirs to the backup spooler
        file: path=/mnt/bkspool/{{ item }} src=/home/{{ item }} state=link
        with_items: home_dirs.stdout_lines
        # same as with_items: home_dirs.stdout.split()

四、通過fact獲取遠端主機變數

    我們在之前講ad-hoc常用模組的時候提到setup模組,用於獲取遠端主機的相關資訊,並可以將這些資訊作為變數在playbook裡進行呼叫。而setup模組獲取這些資訊的方法就是依賴於fact。在這裡,我們不再詳細說明獲取到的預設fact的內容。ansible除了能獲取到預定義的fact的內容,還支援手動為某個主機定製fact。稱之為本地fact。本地fact預設存放於目標主機的/etc/ansible/facts.d目錄下,如果檔案為.ini格式或者json格式,ansible會自動識別。以這種形式載入的fact是key為ansible_local的特殊變數。

下面是一個簡單的示例,一個.ini格式的example.fact檔案內容如下:

[book]

title=Ansible Book

author=Breeze Yan

將其複製到目標主機的/etc/ansible/facts.d/目錄,通過debug模組列印輸出:

- name: print ansible_local

  debug: var=ansibl_local

會打印出如下內容:

ok: [localhost] => {

    "var": {

        "ansible_local": {

            "example": {

                "book": {

                    "author": "Breeze Yan", 

                    "title": "Ansible Book"

                }

            }

        }

    }

}

如果不想從fact中獲取變數,可以通過如下方法關閉fact:

- hosts: whatever

  gather_facts: no

五、使用set_fact模組定義新的變數

在《ansible7:Playbook常用模組》中有對set_fact模組用法的詳細說明

 

六、內建變數

1、hostvars

    獲取某臺指定的主機的相關變數。如果有一臺web伺服器的配置檔案中需要指定db伺服器的ip地址,我們假定這臺db伺服器的hostname為db.exmaple.com,ip地址繫結在eth0網絡卡上,我們可以通過如下方法在web伺服器上呼叫db伺服器的ip地址:

{{ hostvars['db.example.com'].ansible_eth0.ipv4.address }}

需要注意的是db.example.com不能使用ip地址來取代,只能使用主機名或別名。

2、inventory_hostname與inventory_hostname_short

    inventory_hostname是Ansible所識別的當前正在執行task的主機的主機名。如果在inventory裡定義過別名,那麼這裡就是那個別名,如果inentory包含如下一行:

server1 ansible_ssh_host=192.168.1.1

則inventory_hostname即為server1

利用hostvars和inventory_hostname變數,可以輸出與當前主機相關聯的所有變數:

- debug: var=hostvars[inventory_hostname]

    與inventory_hostname相近的還有一個inventory_hostname_short,如果一臺主機的inventory_hostname為server1.exmaple.com,則inventory_hostname_short的值為server1

 

3、group_names

用於標識當前正在執行task的目標主機位於的主機組。假如我們有三臺主機,用來配置成一主二從的mysql伺服器。inventory配置如下:

[mdb]

db1

[sdb]

db2

db3

mysql配置檔案my.conf.j2示例如下:

 

{% if 'db1' in group_names %}

[mysqld]

server-id=1

log-bin=mysql-bin

log-bin-index=mysql-bin.index

sync-binlog=1

innodb_flush_log_at_trx_commit=1    #我們知道db1在mdb組,當db1與當前執行c一組時,我們認為當前主機即在mdb組,所以對當前主機應用mysql master的配置

{% else %}

[mysqld]

server-id=2

relay-log=relay-log

relay-log-index=relay-log.index

read-only = yes

sync_master_info = 1

sync_relay_log = 1

sync_relay_log_info = 1

relay_log_recovery = 1

skip_slave_start    #當db1與當前主機不在同一組時,則認為當前主機不在mdb組,即應用my slave的配置

{% endif %}

 

我們執行如下task:

- name: copy config file to mysql master

  template: src=my.conf.j2 dest=/etc/my.cnf

4、groups

當你想要訪問一組主機的變數時,groups變數會很有用。假如我們有一個inventory檔案定義如下:

[web]

server1

server2

在配置一臺HAproxy的負載均衡器時,我們的配置檔案肯定需要web群組的所有伺服器的IP,配置檔案包含如下片段:

backend web-backend

{% for host in groups.web%}

    server {{host.inventory_hostname}} {{ host.ansible_default_ipv4.address }}:80

{% endfor %}

最終生成的檔案如下:

backend web-backend

    server server1 192.168.1.1

    server server2 192.168.1.2

 

再給一個例子,在所有的dbservers組的伺服器上建立一個數據庫使用者kate:

- name: Create a user for all db servers

  mysql_user: name=kate password=test host={{ hostvars.[item].ansible_eth0.ipv4.address }} state=present

  with_items: groups['dbservers'] 

 

5、play_hosts    #當前playbook會在哪些hosts上執行

6、ansible_version    #當前ansible的版本

7、inventory_dir    #主機清單所在目錄

8、inventory_file    #主機清單檔案

 

七、通過命令列設定變數

示例如下:

---

- hosts: '{{ hosts }}'

  remote_user: '{{ user }}'

  tasks:

     - ...

ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"

也可以寫成類似如下方式:

--extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'

為了方便除錯,ansible提供了debug模組來很方便的檢視模組。用法可以參考通過fact獲取主機變數中的列印本地fact的示例九、變數優先順序
1、extra vars(命令中-e)最優先
2、inventory 主機清單中連線變數(ansible_ssh_user 等)
3、play 中 vars、vars_files 等
4、剩餘的在 inventory 中定義的變數
5、系統的 facts 變數
6、角色定義的預設變數(roles/rolesname/defaults/main.yml)
注:子組會覆蓋父組,主機總是覆蓋組定義的變數