在我之前的文章中, ansible劇本 描述如何使用劇本來創建和運行任務。在本文中,我們更進一步,學習如何在 Ansible 劇本中使用變量。

內容

  1. 什麼是 Ansible 變量
  2. 變量 – 鍵,值映射
  3. 變量——元素列表
  4. 變量——字典
  5. 回放和任務級優先級
  6. 劇本和命令行參數的優先級
  7. 變量文件
  8. 宿主變量和組變量
  9. 魔術變量
  10. 可變事實
  11. 結論是

什麼是 Ansible 變量

多變的 存儲數據並在代碼中使用它是所有編程語言的基本概念。 Ansible 也有存儲值的變量,這些值稍後會在 playbook 中用於各種處理。

Ansible 支持在多個地方聲明變量,包括劇本、host_vars 和 group_vars 文件以及命令行參數。

在下一節中,我們將解釋變量在各個地方是如何定義的,並了解變量的優先順序。

變量 – 鍵,值映射

變量可以在遊戲級別和任務級別使用”vars” 關鍵字。關鍵字 vars 後面是帶有鍵和值的變量。這些變量可以被遊戲中的所有任務訪問。

我使用調試模塊創建了一個打印帶有變量值的消息的任務。變量必須用雙花括號括起來 {{現在改變}}.

如何在 Ansible 劇本中使用調試模塊

- name: Print vars
  hosts: m1
  gather_facts: false

  vars:
    os_name: "PoP!_OS Desktop"
    version: "21.10"

  tasks:
    - name: Task1 - Substitute variables
      debug:
        msg: "My current desktop OS is {{ os_name }} - {{ version }}"
Key-value variable Mapping

要運行劇本,請在終端中運行以下命令:

$ ansible-playbook playbook_name.yml

從下圖中您可以看到兩個變量都已替換為它們的值 味精 打印到標準輸出。

任務輸出

變量——元素列表

您可以在變量中創建元素列表。查看下面的定義,我們以兩種方式創建列表變量。

  • 定義項目/元素列表的標準 YAML 方式。這裡我們將變量名指定為 “top_linux_desktops”.
  • 用於創建項目/元素列表的 Python 語法。這裡我們將變量名指定為 “top_desktops”.
  vars:
    
    top_linux_desktops:
      - MXlinux
      - pop-os
      - Linux Mint
      - Manjaro
      - Fedora

    top_desktops: [MXLinux, pop-os, Linux Mint, Manjaro, Fedora]

您可以使用變量名打印列表中的所有元素。 我創建了兩個任務。第一個任務打印自 top_linux_desktops 變量,第二個任務打印元素 頂級桌面 改變。

  tasks:
    - name: Task1 - List of elements
      debug:
        msg: "My fav linux desktops are {{ top_linux_desktops }}"

    - name: Task2 - List of elements using Python syntax
      debug:
        msg: "My fav linux desktops are {{ top_desktops }}"    
元素列表

列表還允許您通過索引位置訪問單個元素,類似於從 Python 列表訪問元素的方式。有兩種方法可以做到這一點。

  • 使用點符號(variable.index)
  • Python 符號(變量[index])

我創建了兩個任務。第一個任務使用點符號,第二個任務使用 Python 符號打印第一和第二位置的元素。

  tasks:    

    - name: Task3 - Accessing List element using dot notation
      debug:
        msg: "My fav linux desktops are {{ top_linux_desktops.1 }} and {{ top_desktops[2] }}"

    - name: Task4 - Accessing List element using python notation(list[i])
      debug:
        msg: "My fav linux desktops are {{ top_linux_desktops[1] }} and {{ top_desktops[2] }}"
使用其索引位置打印元素使用其索引位置打印元素

變量——字典

您可以創建一個字典對象並將其分配給一個變量。這類似於 Python 字典。可以通過兩種方式創建字典。

  • 用於定義字典的標準 YAML 語法
  • Python字典符號

查看下面的腳本片段,已經創建了兩個字典變量。第一個變量 《發布通知》 遵循 YAML 語法方法和第二個變量 “new_release_info” 遵循 Python 字典語法。

  vars:
    release_info:
      name: PoP!_OS Desktop
      version: 22.04
      release_month: April, 2022
    
    new_release_info: { name: PoP!_OS Desktop, version: 22.04, release_month: "April, 2022"}

您可以使用鍵從變量或特定字典元素中獲取所有值。與列表一樣,字典根據點和 Python 表示法打印鍵值。

我創建了兩個任務。第一個任務使用 點符號 要從字典中獲取元素,第二個任務使用: 蟒蛇符號 抓住元素。

  tasks:

    - name: Task1 - Accessing dictionary values using its key with dot notation(dict.key)
      debug:
        msg: "{{ release_info.name }} version {{ release_info.version }} is released on {{ release_info.release_month }}"

    - name: Task2 - Accessing dictionary values using its key with python notation(dict['key'])
      debug:
        msg: "{{ new_release_info['name'] }} version {{ new_release_info['version'] }} is released on {{ new_release_info['release_month'] }}"
字典變量 - 輸出字典變量 – 輸出

回放和任務級優先級

變量可以在任務級別或遊戲級別定義,但在任務級別定義的變量優先於在遊戲級別定義的變量。

下面的示例在播放級別和任務級別創建一個具有相同變量名稱的變量。 當您運行劇本時,它將使用任務變量名稱。

  vars:
    os_name: "PoP!_OS Desktop"
    version: "21.10"

  tasks:
    - name: Task1 - Substitute variables
      vars:
        os_name: "Linux Mint"
        version: "20.03"
      debug:
          msg: "My current desktop OS is {{ os_name }} - {{ version }}"
任務和遊戲 - 優先任務和遊戲 – 優先

劇本和命令行參數的優先級

可用於覆蓋劇本中傳遞的變量。 -e 橫幅。傳遞的變量具有更高的優先級 -e 橫幅。

我們正在運行與上一節相同的劇本。 -e 橫幅。

$ ansible-playbook 4_var_precedence.yml -e "os_name=fedora" -e "version=35"
使用命令行參數的變量使用命令行參數的變量

你可以傳遞變量 -e 登錄 Json, YAML 再次 ini 格式。

# INI FORMAT
$ ansible-playbook 4_var_precedence.yml -e "os_name=fedora" -e "version=35"

# JSON FORMAT
$ ansible-playbook 4_var_precedence.yml -e '{"os_name": "fedora"}' -e '{"version": 35}'

# YAML FORMAT
$ ansible-playbook 4_var_precedence.yml -e "{os_name: fedora}" -e "{version: 35}"

您還可以為變量創建一個單獨的文件並傳遞 -e 橫幅。語法是:我在這裡 vars.yml 對所有變量進行分組。現在,當文件通過時 -e 標記劇本中導入的所有變量。

$ ansible-playbook 4_var_precedence.yml -e @vars.yml

變量文件

您可以創建一個文件並在文件中聲明所有變量,而不是在您的劇本中定義變量。我創建了一個名為 vars.yml 並將上一節中提到的所有變量分組到這個文件中。

文件中聲明的變量文件中聲明的變量

而不是使用關鍵字 多變的,你應該使用 變量文件 在劇本中傳遞文件名。現在當你運行 playbook 時,ansible 將從文件中選擇變量。這個文件可以放在任何路徑。

劇本中的 Var_files 關鍵字劇本中的 Var_files 關鍵字
文件中定義的變量文件中定義的變量

宿主變量和組變量

您可以在清單文件中定義主機級別和組級別的變量。有關如何創建主機級別和組級別變量的快速說明,請參閱以下文章。

Ansible 清單和配置文件

作為最佳實踐,不要在清單文件中定義變量。反而, host_varsgroup_vars ansible 會自動選擇目錄中的文件。創建一個名為 . host_vars.

$ mkdir host_vars

host_vars 這意味著您可以創建 INI、YAML 或 JSON 格式的文件來存儲特定主機的變量。查看下面的清單文件,有兩個名為“ubuntu”和“rocky”的主機,每個主機都創建了一個變量文件。

當心: 文件名應與清單文件中的主機/別名相同。

# Inventory file
[m1]
ubuntu ansible_host=ubuntu.anslab.com 

[m2]
rocky ansible_host=rocky.anslab.com
$ mkdir host_vars/ubuntu.yml
$ echo "message: This variable is read from host_vars/ubuntu.yml file" > host_vars/ubuntu.yml"

$ mkdir host_vars/rocky.yml
$ echo "message: This variable is read from host_vars/rocky.yml file" > host_vars/rocky.yml

添加了一個名為 message 包含在兩個變量文件中。現在,當我運行劇本時,我從這兩個文件中獲取了變量。

host_vars - 變量定義host_vars——變量定義

同樣,您可以為組創建變量文件。創建一個目錄 group_vars 然後根據清單文件創建一個組名文件。

[m1]
ubuntu ansible_host=ubuntu.anslab.com 

[m2]
rocky ansible_host=rocky.anslab.com

[servers:children]
m1
m2

我創建了一個名為 “服務器”,所以我將文件名創建為 servers.yml.

$ mkdir group_vars
$ mkdir group_vars/servers.yml
$ echo "message: This variable is read from group_vars/servers.yml file" > group_vars/servers.yml

當我運行劇本時,我得到 servers.yml組變量.

組變量組變量

當心: 如果你有兩個 host_varsgroup_varsansible首先搜索 host_vars 定義,如果沒有找到, group_vars.

魔術變量

Ansible 提供了一些內部變量,其狀態在您運行劇本時定義。這些變量可通過劇本獲得。有關可用特殊變量的列表,請參見下面的鏈接。

Ansible 特殊變量

例如,我有一個名為 inventory_dir 存儲劇本使用的清單文件的絕對路徑。

    - name: Magic Variables - Get inventory directory path
      debug:
        msg: "{{ inventory_dir }}"
魔術變量魔術變量

一個重要的魔法變量是 hostvars. 這個變量以json格式輸出一些魔法變量的集合。

      - name: Magic Variables - hostvars
        debug:
          msg: "{{ hostvars }}"
主機變量輸出主機變量輸出

輸出包含 str、列表和字典格式的信息。如果我想查看我的 ubuntu 主機屬於哪個組,我可以通過以下方式獲取:我們在這裡使用 Python 語法符號。

      - name: Magic Variables 
        debug:
          msg: "{{ hostvars['ubuntu']['group_names'] }}"
團隊名字團隊名字

並不是所有的魔法變量在日常工作中都有用。探索所有魔法變量,看看哪一個適合您的用例。

可變事實

當你運行你的劇本時,ansible 使用一個設置模塊從目標主機收集事實並將輸出存儲在內存中以供你的劇本使用。事實也稱為遊戲變量。

首先了解fact的輸出,得到具體的屬性。運行以下命令以收集事實輸出並將其保存到文件中。

$ ansible all -m setup --tree /tmp/facts_result

為每個主機創建一個單獨的輸出文件。查看輸出,它只是 JSON 格式。

事實輸出事實輸出

事實輸出屬性採用 List、Dictionary 和 AnsibleUnsafeText 格式。下面是一些不同類型的示例。

      - name: Facts output - AnsibleUnsafeText
        debug:
          msg: "{{ discovered_interpreter_python }}"

      - name: Facts output - List
        debug:
          msg: "{{ ansible_all_ipv4_addresses }}"

      - name: Facts output - Dictionary
        debug:
          msg: "{{ ansible_python }}"
事實輸出 1事實輸出

Facts 收集了大量信息,因此請查看輸出以了解哪些符合您的要求。

結論是

這篇文章解釋了什麼是 ansible 變量以及如何在不同的地方聲明它們。聲明變量時,變量優先級非常重要。這將在本文中解釋。我們還討論了魔術變量及其使用示例。最後,我們討論了什麼是事實以及如何使用事實輸出作為變量。

AnsibleAnsible 命令Ansible 劇本Ansible 系列Ansible 教程Ansible 變量DevOpsLinuxLinux 管理開源Sysadmin