2016-09-13 29 views
6

hiera.yaml木偶hiera相當於Ansible

--- 
:hierarchy: 
- node/%{host_fqdn} 
    - site_config/%{host_site_name} 
    - site_config/perf_%{host_performance_class} 
    - site_config/%{host_type}_v%{host_type_version} 
    - site/%{host_site_name} 
    - environments/%{site_environment} 
    - types/%{host_type}_v%{host_type_version} 
    - hosts 
    - sites 
    - users 
    - common 
# options are native, deep, deeper 
:merge_behavior: deeper 

目前,我們有這個hiera配置。因此,配置會按照以下順序合併:common.yaml> users.yaml> sites.yaml> hosts.yaml> types/xxx_vxxx.yaml>等。對於變量最高的層次結構,只有在該文件存在時纔會被覆蓋。

如: common.yaml

server: 
    instance_type: m3.medium 

site_config/mysite.yaml

server: 
    instance_type: m4.large 

因此,對於所有其他網站,實例類型將是m3.medium,但僅限於mysite的它會be m4.large。

我如何在Ansible中實現相同?

+0

好了哇:這是一個超現實的問題。我想說這在內在的Ansible中是不可能的。按照Puppet的方式進行優先級動態數據查找的整個概念與Puppet作爲軟件運行的方式緊密相關,以至於我認爲它不適合Ansible試圖實現的目標。這聽起來像是一個非常酷的新FOSS想法。 –

回答

3

我認爲@Xiong是對的,你應該在Ansible中使用變量方法。
您可以設置靈活的庫存,從通用到特定的變量優先級。

不過你可以試試這個片斷是否有幫助:

--- 
- hosts: loc-test 
    tasks: 
    - include_vars: hiera/{{ item }} 
     with_items: 
     - common.yml 
     - "node/{{ ansible_fqdn }}/users.yml" 
     - "node/{{ ansible_fqdn }}/sites.yml" 
     - "node/{{ ansible_fqdn }}/types/{{ host_type }}_v{{ host_type_version }}.yml" 
     failed_when: false 

    - debug: var=server 

這將嘗試從文件加載變量類似於你的問題的結構。
不存在的文件被忽略(因爲failed_when: false)。
按照此列表的順序(從上到下)加載文件,覆蓋以前的值。

陷阱:

  • 您在使用列表中所有變量都必須定義(例如,在這個例子中host_type不能在common.yml定義),因爲項目迭代的名單之前模板整個循環都會執行(請參閱更新以獲得解決方法)。

  • Ansible默認覆蓋(替換)字典,我想你的用例期望合併行爲。這可以通過hash_behavior設置來實現 - 但這對於Ansible劇本來說並不常見。

P.S.您可以通過將with_items更改爲with_first_found並反轉列表(從特定到一般)來改變從頂端到底端的合併行爲。在這種情況下,Ansible將從第一個找到的文件中加載變量。

更新:使用先前包含在文件路徑中的變量。

您可以將循環分成多個任務,因此Ansible會在模板化下一個文件的包含路徑之前評估每個任務的結果。
製作hiera_inc.yml

- include_vars: hiera/common.yml 
    failed_when: false 
- include_vars: hiera/node/{{ ansible_fqdn }}/users.yml 
    failed_when: false 
- include_vars: hiera/node/{{ ansible_fqdn }}/sites.yml 
    failed_when: false 
- include_vars: hiera/node/{{ ansible_fqdn }}/types/{{ host_type | default('none') }}_v{{ host_type_version | default('none') }}.yml 
    failed_when: false 

而在你的主要劇本:

- include: hiera_inc.yml 

這看起來有點笨拙,但這樣一來,你可以定義common.yamlhost_type,它會在路徑模板進行表彰下一個任務。

隨着Ansible 2.2將有可能以include_vars到命名變量(不是全球性的主機空間),這樣你就可以include_vars到hiera_facts和使用combine過濾器,而不會改變全球的散列的行爲合併。

+0

謝謝康斯坦丁。序列表表示並不重要。但是預先定義變量將是一個問題。例如。 host_type在hosts.yaml中定義 – MavWolverine

+0

我仍然在學習理智。會有這樣的工作嗎? http://stackoverflow.com/questions/35489380/using-a-variable-from-one-ansible-var-file-in-a-second-var-file?rq=1 – MavWolverine

+0

這是非常接近,可能可能是調整爲一個真正的類似功能。 –

0

我對Puppet並不熟悉,所以這可能不是直接映射。但是我理解你的問題是:「我如何在一個共享位置使用值,但是覆蓋不同服務器的定義?」。在Ansible中,你可以用variables來做到這一點。

您可以define variables directly in your inventory。您可以define variables in host- and group-specific files。你可以define variables at a playbook level。你可以define variables at a role level。哎呀,你甚至可以define variables with command-line switches

在所有這些地方之間,您應該能夠定義覆蓋以適應您的情況。你可能想看看the documentation section on how to decide where to define a variable瞭解更多信息。

+0

不,他要問的是如何在Ansible中進行優先級動態數據查找。 –