I am trying to make sense of a variable reference I found in an incomplete Ansible role. The role references a value using
dest: “{{params['box'].t1}}”
In a separate yaml file I have
box:
t1: "Albany"
t2: "Albuquerque"
params isn't defined, so obviously this isn't going to work, but I can't figure out the correct way to define it. Can someone tell me where (or how) params must be defined for this variable reference to work in Ansible?
Related questions. Does the use of square brackets in dest: “{{params['box'].t1}}” indicate that it is a dictionary? If yes, could I also write this as dest: “{{params['box']['t1']}” or dest: “{{params.box.t1}”?
params['box'].t1 refers to Albany in:
params:
box:
t1: "Albany"
t2: "Albuquerque"
It is the same as params.box.t1 and params['box']['t1'].
Brackets refer to a key name, so they imply it is a dictionary.
You typically use square bracket-notation when you want to refer to a key via a variable:
vars:
wanted_key: box
params:
box:
t1: Albany
other:
t1: Albuquerque
Then params[wanted_key].t1 refers to Albany.
In your example the value inside square brackets is a string (quoted), so all above examples are equivalent.
Related
I have a YAML file like below.
Details:
Name: Jack
Location: USA
ABC: TestValue
Refer:
Test1: %Details.Name%
Test2: %Details.Location%
Wanted to check if the value given in Test1 works? As I know if %Details.Name% is present under parameters. But above keys are not parameters. So, is there any way to refer the values from another key?
There are anchors and aliases, which you can use like this:
Details:
Name: &name Jack
Location: &location USA
ABC: TestValue
Refer:
Test1: *name
Test2: *location
However, there is no way to refer to other values via their „paths“. Applications using YAML may support pre- or postprocessing to do this (often via templating engines like Jinja), but plain YAML doesn't implement this feature.
If you are under the impression that %Details.Name% would work in some context, you are already using a pre- or postprocessing feature that is not plain YAML.
I have to validate a pipeline before triggering it. One criterion of the validation is if a CI/CD variable has one of the accepted values. Is there a way to find if it is matching the correct values?
I tried to create an array of values then to check it in the workflow rules but it is not clear from the other questions how to do that.
So it should be looking like this:
#WARNING: invalid yml!
variables:
ValidValues: ["Value1", "Value2", "SomeOtherValue"]
workflow:
rules:
- if: ValidValues contains $GivenValue
when: always
Searching on this issue, I found that I can add the allowed values to a regex on which I can check at the workflow rules. In the end it looks like this:
workflow:
rules:
- if: $GivenValue =~ /\b(Value1|Value2|SomeOtherValue)\b/
when: always
- when: never
Unfortunately I did not found a solution on my initial approach (adding the allowed values to an array, then looking for them) but this works as well.
I have inventory with a very complicated structure. For my specific installation I want to override only some values. For example, I have structure:
---
System:
atr1: 47
config:
- nodes:
- logger:
id: 'all'
svr: 'IEW'
- Database:
constr: 'login/pass#db'
atr2: 'some value'
I want to override severity of the logger, i.e. add statistic information
svr: 'IEWS'. I want to provide an override within --extra-vars parameter.
In ansible.cfg -> hash_behaviour = merge
I don't want to use something like - svr: "{{ svr_custom | default('IEW') }}", because there are too many parameters, and thus it will be difficult to write the entire inventory in such way.
I read about combine filter, but I can't use it, when I had to override only one item in hash.
How can I achieve my goal?
The way you found is the simplest one. It's verbose to write but very easy to debug and to fix.
If you REALLY want to shrink this job, you can write your own lookup plugin. (https://docs.ansible.com/ansible/2.5/plugins/lookup.html).
From my experience, I really want to say that direct and dumb approach (write verbose) is much better for overall maintainability. A next person will see a dumb dump (pun intended) which is easy to fix, not a some obscure python snippet.
To make life easier you may want to store this configuration as a separate file (with all jinja pieces) and use lookup (st right from docs):
# Since 2.4, you can pass in variables during evaluation
- debug: msg="{{ lookup('template', './some_template.j2', template_vars=dict(x=42)) }} is evaluated with x=42"
Moreover, you can use Jinja's |from_yaml (or from_json) to convert loaded and processed template into data structure.
I read about combine filter, but I can't use it, when I had to override only one item in hash.
Why is that? Wouldn't new_svr defined in --extra-vars achieve what you want?
- set_fact:
System: "{{ System | combine({'config':[{'nodes':[{'logger':{'svr':new_svr }}]}]}, recursive=True) }}"
I am trying to make sense of a variable reference I found in an incomplete Ansible role. The role references a value using
dest: “{{params['box'].t1}}”
In a separate yaml file I have
box:
t1: "Albany"
t2: "Albuquerque"
params isn't defined, so obviously this isn't going to work, but I can't figure out the correct way to define it. Can someone tell me where (or how) params must be defined for this variable reference to work in Ansible?
Related questions. Does the use of square brackets in dest: “{{params['box'].t1}}” indicate that it is a dictionary? If yes, could I also write this as dest: “{{params['box']['t1']}” or dest: “{{params.box.t1}”?
params['box'].t1 refers to Albany in:
params:
box:
t1: "Albany"
t2: "Albuquerque"
It is the same as params.box.t1 and params['box']['t1'].
Brackets refer to a key name, so they imply it is a dictionary.
You typically use square bracket-notation when you want to refer to a key via a variable:
vars:
wanted_key: box
params:
box:
t1: Albany
other:
t1: Albuquerque
Then params[wanted_key].t1 refers to Albany.
In your example the value inside square brackets is a string (quoted), so all above examples are equivalent.
If I have the following YAML list item (I think that's what it's called) which is expressed as a key/value pair, how do I read the value? I've been looking through the YAML documentation and didn't see this situation discussed.
---
apache_vhosts:
- servername: localhost
documentroot: "/var/www/html"
I want to do something like this and set install_path to "/var/www/html":
...
# This doesn't work
install_path: "{{ apache_vhosts.servername[documentroot] }}"
apache_vhosts is a list of mappings. You are trying to access the key servername from this list, but lists don't have keys.
Also I don't know what you want to achieve with .servername[documentroot].
My guess is you need:
apache_vhosts[0].documentroot (the first element of apache_vhosts -> key documentroot)
Please have a look at the Jinja2 Template Docs.
Edit: Probably better for your case: Ansible Templating