Ansible's gay doll equivalent

hiera.yaml

--- :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 

We currently have this hiera config. Thus, the config is combined in the following sequence common.yaml> users.yaml> sites.yaml> hosts.yaml> types / xxx_vxxx.yaml> etc. For a top-level hierarchy of a variable, it is overwritten only if this file exists.

for example: common.yaml

 server: instance_type: m3.medium 

site_config / mysite.yaml

 server: instance_type: m4.large 

So, for all other sites, the instance type will be m3.medium, but only for mysite it will be m4.large.

How can I achieve the same in Ansible?

+6
source share
3 answers

I think @Xiong is right that you should switch to variables in Ansible.
You can set up a flexible inventory with vars priority from general to specific.

But you can try this snippet if it helps:

 --- - 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 

This will try to load variables from files with a structure similar to your question.
Unused files are ignored (due to failed_when: false ).
Files are downloaded in the order of this list (from top to bottom), overwriting previous values.

Gotchas:

  • all the variables that you use in the list must be defined (for example, host_type in this example cannot be defined in common.yml ), because the list of elements for iteration is templated before the whole loop is executed (see update for workaround ways).

  • It is not necessary to overwrite (replace) dicts by default, I assume that your use case involves merging. This can be achieved with hash_behavior , but this is unusual for Ansible downloadable players.

PS . You can change the merge behavior from top to bottom by changing with_items to with_first_found and canceling the list (from specific to general). In this case, Ansible will load the variables from the first file found.

Update: the use of variables from the previous includes in the file path.

You can break the cycle into several tasks, so Ansible will evaluate each result of the task before the path is added to the next file.
Do 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 

And in your main play:

 - include: hiera_inc.yml 

This looks a little awkward, but in this way you can define host_type in common.yaml and it will execute in the path template for the following tasks.

With Ansible 2.2, you will be able to include_vars in a named variable (not the global host space), so you can hiera_facts in hiera_facts and use the combine filter to combine them without changing the behavior of the global hash.

+3
source

I am not familiar with Puppet, so this may not be a direct comparison. But I understand that your question is: "How to use values ​​in one common location, but redefine their definitions for different servers?". In Ansible, you do this with variables .

You can define variables directly in your inventory . You can define variables in files associated with the host and groups . You can define variables at the player level . You can define variables at the role level . Heck, you can even define variables using the command line .

Between all of these places, you should be able to define overrides according to your situation. You will probably want to take a look at the documentation section on how to determine where to define a variable for more information.

0
source

It seems like it's a little more thorough than Hiera, but someone has created a basic indispensable lookup plugin with similar syntax

https://github.com/sailthru/ansible-oss/tree/master/tools/echelon

0
source

All Articles