Long story short -
Task 1:
Through URI module I am querying Website to obtain json data. Output is saved to variable.
Task 2:
Json_search is used to filter data.
But result value comes with square brackets which I need to get rid off as it needs to be inserted into url address.
I am using not elegant replace module twice to solve this problem. This works but I more than sure you can engage regex_replace (or json_query in more intelligent way) to achieve same result.
Expected output: https://site1/api/host/1
Received output before using replace 2x:
https://site1/api/host/[1]
Snippet from playbook:
…
- name: display url
debug:
msg: {{ json_output_var.json|json_search('result[].id')|replace('[','')|replace(']','')
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 need to collect some information during run of ansible and print this information in the end.
I've tried to define empty list variable in role. I added in playbook handler which add new value to list ant print value of this variable in the end of playbook.
set_fact:
manual_tasks: "{{ manual_tasks + ['restart apache'] }}"
I miss that set_fact host related. So this solution stop working as soon as I start using different hosts. Delegate_to is not solve problem as well. Is there way to make this list global? Or any other solution exist?
Q: Add new value to list and print it at the end of the playbook. Is there way to make this list global?
A: No. It is not. "Global scope is set by config, environment variables and the command line." A host can't set_fact in the play or global scope.
You might want to take a look at ansible-runner. See Sending Runner Status and Events to External Systems.
I'm looking for a non-ugly way to extract a list of particular values from a list of maps in Ansible. I can find some ways to do it, for example here: here, but everything I have seen is very ugly, and it feels like there should be a way where it is clearer what is being done to someone reading it in future. I could write a filter, but it feels like this should be unnecessary since this must come up relatively regularly.
I have a data structure like so in Ansible:
interfaces:
- name: eth0
subnet: 192.168.2
netmask: 255.255.255.0
static_dhcp_hosts:
- {name: "hosta", mac: "00:01:02:03:04:05", ip: "192.168.2.20"}
- name: eth1
subnet: 192.168.5
netmask: 255.255.255.0
static_dhcp_hosts:
- {name: "hostb", mac: "00:02:03:04:05:06", ip: "192.168.5.20"}
- {name: "hostc", mac: "00:03:04:05:06:07", ip: "192.168.5.21"}
I'd like to get a space separated list of the interface names, so
eth0 eth1
Obviously this is just example data, the actual top level list has 10 elements for one host. I know that I can use the join filter to get from a list of interfaces to the string I want and how to do that.
Can anyone suggest a nice way to make the list, that is readable to future maintainers (code/configuration should be self-documenting as far as possible (and no further))?
I am looking to do something like
{% for interface in interfaces %}{{ interface.name }} {% endfor %}
or
" ".join([ interface['name'] for interface in interfaces ])
in Python.
but, AFAIK, you can't, or it is considered bad practice to, use jinja2 loops like this in a role's task/main.yml, and, as I said, it feels like it shouldn't be necessary to use a custom filter for this.
(This role isn't just configuring a DHCP server, so please don't just suggest a pre-existing role that does that, that wouldn't solve my issue).
Any non-ugly way to do this would be much appreciated, as would confirmation from people that there is no non-ugly way.
I am using Ansible 2.3, but I'm interested in answers still even if they only work in later versions.
Edit:
The following:
"{{ internal_interfaces | items2dict(key_name='name',value_name='name') | list | join(\" \") }}"
works, and is the least ugly I can think of. It makes a dictionary from the list, with both the key and values being from the name attribute of the dictionaries in the list, and then casts this dictionary to a list, which just gives a list of keys. I'd still like something less obtuse and ugly if anyione can think of anything, or for any Ansible gurus to reply if they think there is nothing nicer.
Map and join is what you require:
- set_fact:
interface_names: "{{ interfaces | map(attribute='name') | join(' ') }}"
OK. I am being stupid. There is a nice way to do this:
"{{ interfaces | map(attribute='name') | join(\" \") }}"
The output from map is a generator which generates a list of the interface names, and join turns this into the string I want. Perfect.
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