【Ansible 文檔】【譯文】Playbooks 變量


Variables 變量

 自動化的存在使得重復的做事情變得很容易,但是我們的系統不可能完全一樣。

在某些系統中,你可能想要設置一些與其他系統不一樣的行為和配置。

同樣地,遠程系統的行為和狀態也可以影響到我們如何配置該系統。(例如,你可能需要找到一個系統的IP地址,並且用它來作為另一個系統的配置值)

你也可能有一些配置文件的模版,其大部分是一樣的,但是基於某些值有些許不同。

Ansible 中的變量幫助我們如何處理系統間的不同。

為了理解variables,你會需要深入理解 Conditionals 和Loop  。像 group_by 和 when 條件這樣有用的東西,可以和variables一起使用,來幫助管理系統間的不同。

強烈建議你學習 ansible-examples github代碼庫,里面有大量使用變量的例子。

對於最好的實踐建議,參考最佳實踐章節: Variables and Vaults

What Makes A Valid Variable Name 一個合法的變量名是什么樣的

在我們開始使用variables時,知道什么組成一個合法的變量名是重要的。

變量名應該是字母、數字和下划線。變量始終以字母開頭。

“foo_port”是個合法的變量名。”foo5”也是。 “foo-port”, “foo port”, “foo.port” 和 “12”則不是合法的變量名。

YAML 也支持字典,映射key到value。例如:

foo:
  field1: one
  field2: two

如此,你可以通過括號或者點引用字典中一個特定的字段。

foo['field1']
foo.field1

上面倆種方式都引用到了一個值("one")。然而,如果你使用點符號,需要意識到有些key可能會有問題,因為他們與python的方法或者屬性沖突。你應該使用括號而不是點符號如果你使用以倆個下划線開始和結尾(這些在python中有特殊含義而保留)的keys或者任何其他已知的公共屬性。

dd, append, as_integer_ratio, bit_length, capitalize, center, clear, conjugate, copy, count, decode, denominator, 
difference, difference_update, discard, encode, endswith, expandtabs, extend, find, format, fromhex, fromkeys, get,
has_key, hex, imag, index, insert, intersection, intersection_update, isalnum, isalpha, isdecimal, isdigit, isdisjoint,
is_integer, islower, isnumeric, isspace, issubset, issuperset, istitle, isupper, items, iteritems, iterkeys, itervalues,
join, keys, ljust, lower, lstrip, numerator, partition, pop, popitem, real, remove, replace, reverse, rfind, rindex, rjust,
rpartition, rsplit, rstrip, setdefault, sort, split, splitlines, startswith, strip, swapcase, symmetric_difference,
symmetric_difference_update, title, translate, union, update, upper, values, viewitems, viewkeys, viewvalues, zfill.

Variables Defined in Inventory 清單文件中定義的變量

在其他章節,我們實際上已經知道了需要 variables 的知識,到目前為止還沒有全新的知識,知識加深以下印象。

我們經常想要根據一台機器在哪個組里而設置變量。例如,在波士頓的機器可能需要使用 ‘boston.ntp.example.com’  作為NTP服務器

查看 Inventory 文檔學習在inventory文件中定義變量。

Variables Defined in a Playbook 在playbook中定義變量

在一個Playbook中,可以像下面這樣在內部直接定義變量:

- hosts: webservers
  vars:
    http_port: 80

當你正在閱讀playbook時,你可以直接看到變量,這是很好的。

Variables defined from included files and roles 在included files和roles中定義變量

這是我們已經在其他地方談論過的variables。

正如  Roles 描述的那樣,變量可以被包含在playbook中,通過included files,其可能是也可能不是Ansible Roles中的一部分。roles是更好的方式,因為它提供了一個很好的組織結構體系。

Using Variables: About Jinja2 使用變量:Jinja2

我們已經知道足夠多的關於定義變量,那么如何使用它們呢?

Ansible 允許你 在你的playbook中使用Jinja2來使用變量。而且,在Jinja中,你可以做許多復雜的事情,首先你需要學好基礎。

例如,在簡單的模版中,你可以如下使用:

My amp goes to {{ max_amp_value }}

這提供了變量替換最基礎的形式。在playbooks中,你可以在playbook中直接這樣用,並且你可能偶爾想這樣做:

template: src=foo.cfg.j2 dest={{ remote_install_path }}/foo.cfg

在上面的例子中,我們使用了一個變量來幫助決定文件的存放地址。

在一個模版中,你自動會獲取在主機范圍之內的所有變量的訪問權。事實上更多,你可以讀取其它主機的變量。我們將演示如何做。

注意:

Ansible允許在模版里面Jinja2循環和條件,但是在playbook中,我們不使用它們。Ansible Playbooks是純粹的機器解析的YAML。這是一個相當重要的功能,因為這意味着可以根據文件生成代碼,或者其它系統工具能夠讀取Ansible文件。

雖然並不是所有人都需要這個功能,但我們不能封鎖可能性。

查看 Templating (Jinja2) 獲取更多Jinja2 模版的信息。

Jinja2 Filters Jinja2 過濾器

這是一個不常用的工具包。只在合適的時候使用它們,這是一個附加知識點。

Jinja2中的Filters 是一種方式,轉換模版表達式從一種數據形式到另一種。Jinja2附帶了很多這樣的功能。請參見Jinja2官方模板文檔中的 builtin filters 。

另外,Ansible還支持更多的其它特性。請看  Filters  文檔中關於一系列可用的過濾器及示例。

Hey Wait, A YAML Gotcha 嘿,等等,有一個YAML的陷阱

YAML語法要求如果你以 {{ foo }} 開始一個值,你需要把行引號引起來,因為 YAML想要確定是你不是在開始聲明一個字典。在 YAML Syntax  中有所描述。

以下將不會工作:

- hosts: app_servers
  vars:
      app_path: {{ base_path }}/22

如下將會工作:

- hosts: app_servers
  vars:
       app_path: "{{ base_path }}/22"

Information discovered from systems: Facts 系統信息發現:Facts

還有其他地方可以獲取變量,但是這些變量是自動發現的,不是由用戶設置的。

Facts是通過與遠程主機通信獲取的的信息。

舉個例子,可以獲取主機的IP地址或者操作系統。

為了查看可以獲取到什么信息,使用如下命令來確定:

ansible hostname -m setup

這會返回大量的變量數據。

在template或者Playbooks中,可以通過如下的方式,獲取第一塊磁盤的Model:

{{ ansible_devices.sda.model }}

同樣地,hostname:

{{ ansible_nodename }}

hostname中第一個點之前的部分:

{{ ansible_hostname }}

Facts 在 conditionals中很常用,在templates中也是。

Facts 也可以用來創建動態主機組,匹配特定條件的。查看  About Modules 中 group_by 更多細節,以及在  Conditionals  章節中描述的條件聲明。

Turning Off Facts 關閉 Facts 收集

如果你知道你不需要主機上的任何facts數據,集中地知道主機的任何事情,你可以關閉facts收集。這對擴大Ansible推模式適用的主機規模有利,或者你正在實驗性的平台上使用Ansible。通過在任何Playbook中如下做即可:

- hosts: whatever
  gather_facts: no

Local Facts (Facts.d) 本地 Facts(Facts.d)

Ansible 1.3 新特性

如在Playbooks章節討論的那樣, Ansible facts 是一種獲取遠程主機數據的方式。

通常,由Ansible的setup模塊自動發現變量。用戶可以寫自定義的facts模塊,在API指導中描述的。然而,如果不借助於fact模塊,而是通過一個簡單的方式為Ansible變量提供系統或用戶數據呢?

比如,如果您希望用戶能夠控制他們的系統是如何管理的,那該怎么辦呢? “Facts.d”是這樣的一種機制。

也許 “local facts” 這個詞不太恰當,它意思是 “locally supplied user values” ,與  “centrally supplied user values” 相反,或者是  “locally dynamically determined values”.

如果遠程主機管理系統有 /etc/ansible/facts.d 目錄,任何在該目錄中的以 .fact 結尾的文件,可能是json/ini或者可執行的返回json的文件,這些提供了 local facts。可以使用fact_path來指定替代目錄。

例如,假設有一個 /etc/ansible/facts.d/perferences.fact 文件:

[general]
asdf=1
bar=2

這將會產生一個hash變量fact,名為general,包含 asdf and bar 的成員。為了驗證是這樣的情況,運行如下指令:

ansible <hostname> -m setup -a "filter=ansible_local"

你會看見如下facts添加:

"ansible_local": {
        "preferences": {
            "general": {
                "asdf" : "1",
                "bar"  : "2"
            }
        }
 }

這樣該數據可以在template/Playbooks中訪問:

{{ ansible_local.preferences.general.asdf }}

local 命名空間防止其他用戶提供的fact覆蓋系統facts或者在Playbooks中定義的變量。

 在 ansible_local variable 中, key 會被轉成小寫的,如果你是大寫的話。所以,如果你在ini文件中寫的是XYZ=123,你應該只能通過 {{ ansible_local.preferences.general.xyz }} 來訪問,並且不是 {{ ansible_local.preferences.general.XYZ }} 

這是因為Ansible使用了Python的ConfigParser,其會把所有的選項名轉成小寫格式

如果你有一個Playbook:拷貝自定義的fact並運行,使用一個顯示setup調用來允許那樣的fact在這個Playbook運行的時候可用。否則,你會在下一次play中被收集fact信息。下面是這樣的一個例子:

- hosts: webservers
  tasks:
    - name: create directory for ansible custom facts
      file: state=directory recurse=yes path=/etc/ansible/facts.d
    - name: install custom impi fact
      copy: src=ipmi.fact dest=/etc/ansible/facts.d
    - name: re-read facts after adding custom fact
      setup: filter=ansible_local

Ansible version Ansible 版本變量

Ansible 1.8 新特性

 為了適應特定版本Ansible,一個 ansible_version 變量是可用的,結構如下:

"ansible_version": {
    "full": "2.0.0.2",
    "major": 2,
    "minor": 0,
    "revision": 0,
    "string": "2.0.0.2"
}

Fact Caching Fact 緩存

Ansible 1.8 新特性

正如文檔中的某處展示的,一台服務器可以引用另一台的相關變量,像這樣:

{{ hostvars['asdf.example.com']['ansible_os_family'] }}

當 “Fact Caching” 被禁用時,為了這樣做,Ansible 必須已經和 ‘asdf.example.com’ 在當前的play,或者另外一個play優先級更高的play中 通信過。這是Ansible的默認配置。

為了避免這種情況,Ansible 1.8 允許在playbook運行之間保存facts的能力,但是,這個特性必須手動啟用。這個特性會有什么用呢?

想一下,例如,一個非常大的基礎設施,有幾千hosts。Fact 緩存可能在晚上配置運行,而一個小的服務器集合的配置可以運行ad-hoc或每天定時執行。當fact-caching啟用時,沒有必要去訪問所有的服務器來引用他們的變量。

fact caching 啟用時,一個組中的一台機器引用其他組中機器的變量是可能的。盡管他們還沒有在當前的 /usr/bin/ansible-playbook 執行過程中通信過。

為了從緩存中的facts中受益,你會想要改變gathering設置為smart或者explicit或者設置gather_facts為False。

當前來說,Ansible封裝了倆個持久化緩存插件:redis和jsonfile。

為了配置 fact caching 使用redis:在ansible.cfg中如下來啟用:

[defaults]
gathering = smart
fact_caching = redis
fact_caching_timeout = 86400
# seconds

為了使 redis 啟用並運行,執行等價的 OS 命令:

yum install redis
service redis start
pip install redis

注意,Python redis 庫應該通過pip安裝,EPEL中的包太老了。

在當前的情況下,這個特性還處於beta測試階段,並且Redis插件還不支持端口和密碼的配置,后續版本將會支持。

為了配置fact caching使用jsonfile,如下在ansible.cfg中啟用:

[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /path/to/cachedir
fact_caching_timeout = 86400
# seconds

fact_caching_connection is a local filesystem path to a writeable directory (ansible will attempt to create the directory if one does not exist).

fact_caching_timeout is the number of seconds to cache the recorded facts.

Registered Variables 注冊變量

變量的另一個主要用途是在運行命令時,把命令結果存儲到一個變量中。不同模塊的執行結果是不同的。運行playbook時使用-v選項可以看到可能的結果值。

在ansible中,任務執行的結果值可以保存在變量中,並且隨后可以使用。 See some examples of this in the Conditionals chapter。

在上面的例子中有所提及,這里是一個快速的語法例子:

- hosts: web_servers

  tasks:

     - shell: /usr/bin/foo
       register: foo_result
       ignore_errors: True

     - shell: /usr/bin/bar
       when: foo_result.rc == 5

注冊的變量在playbook運行的剩余部分是合法的,其和Ansible中的facts的生命周期是一樣的。實際上,注冊變量和facts是很類似的。

當在一個loop中使用 register時,這個數據結構再循環中設置變量,其會包含一個results屬性,這是一個列表,循環所有值的結果。查看  Loops  獲取更深入的細節。

如果一個任務失敗或者跳過,變量仍然被注冊為一個失敗或者跳過的值。避免注冊一個變量的唯一方式是使用tags。

Accessing Complex Variable Data 訪問復雜變量數據

我們已經在本章早先部分討論了facts。

一些提供的facts,像網絡信息,是一個嵌套的數據結構。為了訪問他們,簡單的{{ foo }}是不足夠的,但是他一直很容易做。以下是我們如何獲取IP地址:

{{ ansible_eth0["ipv4"]["address"] }}

或者用下面的方式:

{{ ansible_eth0.ipv4.address }}

類似的,我們可以訪問如下的方式訪問數組中的第一個元素:

{{ foo[0] }}

Magic Variables, and How To Access Information About Other Hosts 魔法變量,以及如何訪問其他主機的信息

Ansible會自動提供給你一些變量,即使你並沒有定義過它們。這些變量中重要的有 ‘hostvars’、’group_names’ 和 ‘groups’。由於這些變量名是預留的,所以用戶不應當覆蓋它們。

hostvars 讓你可以獲取其他主機的變量,包含已經從那台主機收集的facts。在這點上,如果你還沒有在playbook或者playbooks中的任何play中與那台主機通信,那么你可以獲取變量,但無法看到facts值。

如果你的數據庫服務器想要使用其他節點的一個fact的值,或者一個清單文件中賦值給另一個節點的變量,很容易在一個模版中甚至是在action中使用:

{{ hostvars['test.example.com']['ansible_distribution'] }}

此外,group_names 是一個列表(數組),包含了當前主機所在的所有組。這個可以在templates中使用Jinja2語法基於主機的組成員關系的不同而產生不同的template源文件

{% if 'webserver' in group_names %}
   # some part of a configuration file that only applies to webservers
{% endif %}

groups 是清單文件中所有組(和主機)的列表。這個可以用來迭代一個組內的所有主機。例如:

{% for host in groups['app_servers'] %}
   # something that applies to all app servers.
{% endfor %}

一個常用的使用方式是遍歷一個組找到那個組的所有IP地址

{% for host in groups['app_servers'] %}
   {{ hostvars[host]['ansible_eth0']['ipv4']['address'] }}
{% endfor %}

舉個例子:指向前端代理服務器到所有的app 服務器,在服務器之間設置正確的firewall rules等等。你需要確保那些主機的facts已經被填充了,例如通過對它們運行一個play。如果facts還沒有緩存到的話(fact caching已經在Ansible 1.8中添加)。

此外, inventory_hostname 是Ansible inventory主機文件中配置的主機名稱。由於其它一些神秘原因你不想使用自發現的主機名 ansible_hostname 時,你可以使用 inventory_hostname。如果主機的FQDN很長,那么*inventory_hostname_short*則會只包含域名第一個分號之前的部分,而舍棄其它部分。

在2.2版本中,play_hosts ,已經過時了。相同功能的變量是:ansible_play_batch 

New in version 2.2.

ansible_play_hosts 是指在當前的play中仍然活躍的完整列表。

New in version 2.2.

ansible_play_batch 是一個hostnames的列表,針對當前play中的一批主機。 The batch size 由 serial 定義,當沒有設置時,它等於整個play中的所有主機 (和  ansible_play_hosts 一樣)。

New in version 2.3.

ansible_playbook_python 是python 可執行文件的路徑,用來調用Ansible命令行工具。

這些 vars 對於填充 多個主機名到 templates 或者注入該列表到一個負載均衡器中是有用的。

不要擔心任何問題,除非你需要使用它。你會知道什么時候你會知道。

同樣地, inventory_dir 是存放Ansible inventory host 文件的目錄路徑名, inventory_file 是這個路徑名和文件名指向 the Ansible’s inventory host file.

playbook_dir 含有playbook基礎目錄。

我們然后有role_path會返回當前role的路徑名(1.8開始)這僅會在運行role時可用。

最后, ansible_check_mode (added in version 2.1), 一個boolean 魔法值,如果你使用 --check 模式運行 Ansible 時,其會被設置為 True 。

Variable File Separation 變量文件分離

保持你的playbook在源碼控制系統是一個好注意,但是你可能希望使得playbook源碼公開,同時保持某些重要變量私密性。類似地,有時你可能僅僅想要保持某些信息在不同的文件,與主要的playbook脫離

你也可以使用外部變量文件,或者文件集,如下所示:

---

- hosts: all
  remote_user: root
  vars:
    favcolor: blue
  vars_files:
    - /vars/external_vars.yml

  tasks:

  - name: this is just a placeholder
    command: /bin/echo foo

當你分享playbook源碼給別人是,就沒有暴露敏感數據的風險。

每個變量文件的格式是簡單的YAML字典,像這樣:

---
# in the above example, this would be vars/external_vars.yml
somevar: somevalue
password: magic

保持每個主機和每個組 的變量在非常相似的文件是可能的,這在Splitting Out Host and Group Specific Data 描述

Passing Variables On The Command Line 在命令行上傳遞變量

除了 vars_prompt and vars_files 之外,通過Ansible命令行發送變量是可以的。如果你想編寫一個通用的發布playbook時則特別有用,你可以傳遞應用的版本以便部署

ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"

這是有用的,例如,在其他的配置中,設置playbook的hosts組或者用戶:

---

- hosts: '{{ hosts }}'
  remote_user: '{{ user }}'

  tasks:
     - ...

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

Ansible 1.2 開始,你可以通過extra vars傳遞JSON,例如:

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

key=value形式非常簡單,但很實用!

使用 key=value 語法 傳遞的值被翻譯為字符串。如果你想要傳遞任何不是strings的值,使用JSON 格式, (Booleans, integers, floats, lists etc)。

Ansible 1.3 起,extra vars 可以從一個JSON文件中加載,使用@語法:

--extra-vars "@some_file.json"

同樣在Ansible 1.3中,我們可以為extra-vars傳遞YAML格式,無論直接通過命令行還是放置在文件中。

Variable Precedence: Where Should I Put A Variable? 變量順序

許多人可能會問variable2 如何覆蓋其他的。歸根結底,這是Ansible的哲學:你最好知道把一個變量放到哪里,然后你可以無需怎么考慮變量是如何互相覆蓋的了。

避免在47個地方定義變量 “x” ,然后問哪個 “x” 會被使用的問題。為什么?因為這不是Ansible 哲學解決的問題。

世界上只有一個帝國大廈。也只有一個蒙娜麗莎。請弄明白在那里定義變量,而不要把事情搞復雜。

然而,我們還是來討論一下優先權的問題。它存在。你有可能會用到它。

如果同樣名稱的變量在多個地方都有定義,他們會以某種順序覆蓋。

在1.x之前,優先順序是如下這樣(越在后面優先級越高):

  • “role 默認值”, 優先級最低,很容易被覆蓋。
  • variables inventory中定義的變量。
  • facts 系統自發現變量。
  • “most everything else”  大多數其他的變量: 命令行切換,play中的 vars,included vars,roles vars 等等。
  • connection variables 連接變量,ansible_user 等
  • extra vars (-e in the command line) always win

在1.5.4版本之后,系統自發現的變量也會在  “most everything else” 分類中。

在2.0之后,我們使得優先級的順序更加的具體,最后面的變量優先級最高,即從低到高的優先級順序如下:

  • role defaults [1]
  • inventory file or script group vars [2]
  • inventory group_vars/all
  • playbook group_vars/all
  • inventory group_vars/*
  • playbook group_vars/*
  • inventory file or script host vars [2]
  • inventory host_vars/*
  • playbook host_vars/*
  • host facts
  • play vars
  • play vars_prompt
  • play vars_files
  • role vars (defined in role/vars/main.yml)
  • block vars (only for tasks in block)
  • task vars (only for the task)
  • role (and include_role) params
  • include params
  • include_vars
  • set_facts / registered vars
  • extra vars (always win precedence)

基本上,任何在 “role defaults”(在特定角色的 defaults 文件夾) 中的東西是最具可塑性和很容易覆蓋的。任何在特定角色的vars 目錄的變量會覆蓋命名空間中之前版本的變量。理想的確認方法是:你在的范圍越具體,優先級越高,同時,命令行 -e 額外參數總是winning。 Host and/or inventory 變量可以贏role defaults,但是不顯示包含像vars目錄或者include_vars 任務。

1. 在每個role中的task會看見他們自己的role defaults,在role之外的任務會看見最后的role的默認值。

2. 在任何的部分,重復定義一個變量會覆蓋先前的定義。如果多個組有相同的變量,最后加載的贏。如果你在play的 vars: 部分定義一個變量倆次,第二次定義的贏

另一個重要的事情是(對於所有的版本):連接變量會覆蓋 config,命令行,以及play/role/task 特定的選項和指令。例如:

ansible -u lola myhost

這仍然會按照ramon連接,因為 ansible_ssh_user 在inventory中對 myhost主機 設置為 ramon 。對於plays/tasks 的 remote_user 也是這樣的。

- hosts: myhost
  tasks:
   - command: i'll connect as ramon still
     remote_user: lola

這樣做是因為特定主機的設置可以覆蓋一般設置。這些變量通常在inventory中的每個host或者組定義,但是他們的行為和其他變量一樣。如果你想要全局地覆蓋遠程用戶(甚至是inventory)你可以使用extra vars:

ansible... -e "ansible_user=<user>"

你也可以在play中定義一個普通變量來重寫:

- hosts: all
  vars:
    ansible_user: lola
  tasks:
    - command: i'll connect as lola!

Variable Scopes 變量范圍

Ansible 有 3 個主要范圍:

  • 全局的:這是由 config、環境變量和命令行設置的
  • Play范圍: 每一個play及其包含的結構、vars 條目(vars/vars_files/vars_prompt)、roles defaults和vars。
  • Host范圍:直接關聯到一個主機的變量,像 inventory、included_vars、facts、或者注冊任務輸出。

Variable Examples 變量例子

這樣看似乎有點理論化了。讓我們看看一些例子,同時你可以選擇在哪放置那些值,基於你想要的控制類型。

首先,組變量是強有力的一種。

站點范圍的默認值應該作為一個group_vars/all被定義。組變量一般和你的inventory文件放在一起。他們可由一個動態的inventory腳本返回。(查看  Dynamic Inventory) 或者定義在類似Ansible Tower中,通過UI或者API。

---
# file: /etc/ansible/group_vars/all
# this is the site wide default
ntp_server: default-time.example.com

區域信息可以被定義在一個group_vars/region變量。如果該組是all的子組,他會覆蓋上層的組並且更具一般性:

---
# file: /etc/ansible/group_vars/boston
ntp_server: boston-time.example.com

對於某些瘋狂的原因來說,如果我們想要告訴一個特定的主機使用一個特定的NTP 服務器,則其會覆蓋組變量:

---
# file: /etc/ansible/host_vars/xyz.boston.example.com
ntp_server: override.example.com

因此,那覆蓋了inventory和你通常的設置在那里。對於處理地理或者行為的事情來說,這是很好的地方。因為 groups 常常用作將roles映射到主機的實體,所以一個快捷路徑是在組中設置變量而不是在role中定義。你可以隨意選擇任意一種方式。

記住:子組覆寫父組,同時,hosts 總是覆寫 他們的組。

更進一步:了解role變量順序

我們更願意假設你正在使用roles,你應該要使用roles。roles是很好的。

OK,所以,如果你正在寫一個發布角色,其有一些合理的默認值,把他們放在roles/x/defaults/main.yml文件中。這意味着role會使用這個默認值,但是Ansible中任何的地方都可能會覆寫它。See Roles for more info about this:

---
# file: roles/x/defaults/main.yml
# if not overridden in inventory or as a parameter, this is the value that will be used
http_port: 80

因此,對於嵌入一個角色的常量,上面的方式總是極好。如果你不像分享你的role給其他人,應用特定的行為,例如端口放在這里是好的。但是如果想分享角色給其他人,在這里設置一個變量不是壞事。沒人能通過inventory覆寫他們,但是他們仍然可以傳遞一個參數值給這個role。

參數化roles是有用的。

如果你正在使用一個role並且想要覆寫一個默認值,傳遞它作為一個參數給該role,像這樣:

roles:
   - { role: apache, http_port: 8080 }

這樣的話,playbook的讀者就很清晰你有意識的覆寫了一些role中的默認值,或者傳遞一些role不能自己決定的配置。它允許你傳遞一些特定site的東西,這些東西其實不是真正屬於該角色的部分。

這經常被用來對那些可以在一些主機上應用多次的步驟(動作),像這樣:

roles:
   - { role: app_user, name: Ian    }
   - { role: app_user, name: Terry  }
   - { role: app_user, name: Graham }
   - { role: app_user, name: John   }

這有點武斷,但是您可以看到如何多次調用相同的角色。

在那個例子中,“name” 很有可能沒有提供默認值。Ansible 可以在變量沒有定義的時候告訴你 - 這是默認行為。

role還有一些額外的好處。

通常來說,在一個角色中設置的變量對於其他的角色是可用的。這意味着,如果你有 roles/common/vars/main.yml 你可以在這里設置變量,並且在其他角色或者playbook中的任意地方使用:

roles:
   - { role: common_settings }
   - { role: something, foo: 12 }
   - { role: something_else }

注意:

有一些保護措施避免命令空間變量的需要。在上面的例子中,在common_settings中定義的變量對於“something”和“something_else”任務來說是可用的,但是如果something確保foo設置為12,即使common settings 設置 foo 為20

所以,直接點說,這就是優先順序的問題。不要擔心這個順序,只要考慮如果你的role正在定義一個有默認值的變量,或者你想要使用的一個“live”變量。inventory files優先級位於倆者之間,如果你想要強制覆蓋某些配置,使用 -e 。

如果你發現有一點難以理解,看看  ansible-examples github repo 來查看更多的關於如何更好的一起使用。

Advanced Syntax 高級語法

For information about advanced YAML syntax used to declare variables and have more control over the data placed in YAML files used by Ansible, see Advanced Syntax.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM