Ansible: looping over with multiple {{ items }} - ansible

I have an inventory file with the following variables:
vpc_public_net1=["10.30.0.0/24","AZ=a"]
vpc_public_net2=["10.30.1.0/24","AZ=b"]
I can extract AZ value with "{{ item[1].split('=')[1] }}"
I'm having difficulties extracting both subnet and AZ using the same
ansible task
my Ansible code:
- name: Create Public Subnets
ec2_vpc_subnet: state="present"
vpc_id="{{ vpc_id }}"
cidr="{{ item.subnet }}"
az="{{ item.az }}"
region="{{ aws_region }}"
aws_access_key="{{ aws_access_key }}"
aws_secret_key="{{ aws_secret_key }}

Redefine as a dictionary:
vpc_public_net1='{"subnet": "10.30.0.0/24", "az": "a"}'
vpc_public_net2='{"subnet": "10.30.1.0/24", "az": "b"}'
and:
- name: Create Public Subnets
ec2_vpc_subnet:
state: present
vpc_id: "{{ vpc_id }}"
cidr: "{{ item.subnet }}"
az: "{{ item.az }}"
region: "{{ aws_region }}"
aws_access_key: "{{ aws_access_key }}"
aws_secret_key: "{{ aws_secret_key }}"
with_items:
- "{{ vpc_public_net1 }}"
- "{{ vpc_public_net2 }}"

Related

how to generate list arguments of ansible task with Jinja2 template?

ansible theforeman.foreman.content_view module has repositories arguments need to be used like this:
- name: "Create or update Fedora content view"
theforeman.foreman.content_view:
username: "admin"
password: "changeme"
server_url: "https://foreman.example.com"
name: "Fedora CV"
organization: "My Cool new Organization"
repositories:
- name: 'Fedora 26'
product: 'Fedora'
I need to generate it dynamically. tried to do like following:
- name: "Create or update content views"
theforeman.foreman.content_view:
username: "{{ foreman.user }}"
password: "{{ foreman.password }}"
server_url: "{{ foreman.url }}"
organization: "{{ org.name }}"
name: "{{ item.0.name }}_content"
repositories: |
- name: '{{ item.1.name }}'
product: "{{ item.0.name }}_repos"
loop: "{{ os|subelements('repos') }}"
loop_control:
label: "{{ item.0.name }}"
this also not worked
- name: "Create or update content views"
theforeman.foreman.content_view:
username: "{{ foreman.user }}"
password: "{{ foreman.password }}"
server_url: "{{ foreman.url }}"
organization: "{{ org.name }}"
name: "{{ item.0.name }}_content"
repositories: |
{% for n in item.0.name %}
- name: '{{ item.1.name }}'
product: "{{ item.0.name }}_repos"
{% endfor %}
loop: "{{ os|subelements('repos') }}"
loop_control:
label: "{{ item.0.name }}"
but it always overwrites previous one and last executed remains. Howcould we achive to generate repositories with loop?
example vars:
os:
- name: alma9
repos:
- name: "almalinux9_base_x86_64"
url: "https://repo.almalinux.org/almalinux/9/BaseOS/x86_64/os/"
gpg_key: "RPM-GPG-KEY-AlmaLinux9"
- name: "almalinux9_appstream_x86_64"
url: "https://repo.almalinux.org/almalinux/9/AppStream/x86_64/os/"
gpg_key: "RPM-GPG-KEY-AlmaLinux9"

Ansible: playbook to deploy VM (Linux and Windows)

I created this playbook to deploy new VM from template.
Now if I try to deploy a new Linux VM it works correctly, if I try to deploy a Windows WM I received this error:
TASK [Clone the template]
************************************************************************************************************************************* fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed to
create a virtual machine : A specified parameter was not correct:
spec.identity"}
This is my playbook:
...
- name: Clone the template
vmware_guest:
hostname: "{{ vcenter_server }}"
username: "{{ vcenter_user }}"
password: "{{ vsphere_pass_result.user_input }}"
validate_certs: False
name: "{{ vm_name }}"
template: "{{ template_name_sel[tmpl] }}"
datacenter: "{{ datacenter_name }}"
cluster: "{{ cluster_name }}"
folder: "/{{ host_location_sel[loc] }}/{{ vm_env_sel[env] }}"
datastore: "{{ vm_datastore_sel[dstg] }}"
guest_id: "{{ vm_name }}"
networks:
- name: "{{ vm_network_sel[vlan] }}"
ip: "{{ vm_ip_result.user_input }}"
netmask: "{{ vm_mask_result.user_input }}"
gateway: "{{ vm_gw_result.user_input }}"
type: static
dns_servers: "8.8.8.8"
customization:
autologon: yes
dns_servers:
- "{{ vm_dns1_result.user_input }}"
- "{{ vm_dns2_result.user_input }}"
hardware:
memory_mb: "{{ vm_ram_sel[ram] }}"
num_cpus: "{{ vm_cpu_result.user_input }}"
num_cpu_cores_per_socket: "{{ vm_core_result.user_input }}"
state: poweredon
wait_for_ip_address: yes
delegate_to: localhost
register: vm_info
- debug:
var: vm_info
Thanks for the support.

Ansible: How to create nested dictionary using Jinja2

Here is the output.
"result.containers":[
{
"Image":"ca.docker/webproxy:1.0.0",
"Names":[
"/customer1"
]
},
{
"Image":"docker.local/egacustomer:1.0.1",
"Names":[
"/registrator"
]
}
]
I'm trying to get the following output using jinja2
"containerlist"=>{
"webproxy": {
"name": "customer1"
},
"egacustomer": {
"name": "registrator"
}
}
Here is my jinja2 code.
- set_fact:
containerlist: |
{
{% for item in result.containers %}
{{ item.Image.split('/')[-1].split(':')[0] | replace('\n', '') }}
name : {{ item.Names[0][1:] | replace('\n', '') }}
{% endfor %}
}
I get the below output.
"containerlist": "{\nwebproxy\n name : customer1\negacustome\n name : registrator\n}"
Could someone please help me get the desired output. Any help would be greatly appreciated
The data in YAML
result:
containers:
- Image: ca.docker/webproxy:1.0.0
Names:
- /customer1
- Image: docker.local/egacustomer:1.0.1
Names:
- /registrator
The tasks below
- set_fact:
containerlist: "{{ containerlist|default({})|
combine({key: {'name': name}}) }}"
loop: "{{ result.containers }}"
vars:
key: "{{ (item.Image.split(':')|first).split('/')|last }}"
name: "{{ item.Names[0][1:] }}"
- debug:
var: containerlist
give
containerlist:
egacustomer:
name: registrator
webproxy:
name: customer1
But, the result is not a list. It's a dictionary. If you want a list use this
- set_fact:
containerlist: "{{ containerlist|default([]) +
[{key: {'name': name}}] }}"
loop: "{{ result.containers }}"
vars:
key: "{{ (item.Image.split(':')|first).split('/')|last }}"
name: "{{ item.Names[0][1:] }}"
- debug:
var: containerlist
give
containerlist:
- webproxy:
name: customer1
- egacustomer:
name: registrator

Creating dictionary with same values in all elements

I have dictionary like this:
abc:
xyz1:
url: "{{ url }}"
api_key: "{{ key }}"
xyz2:
url: "{{ url }}"
api_key: "{{ key }}"
xyz3:
url: "{{ url }}"
api_key: "{{ key }}"
I know that all xyz{number} have the same values in url and api_key and will have same values in the future.
I need this nested format, but what will be more elegant way to write this instead the way I did it (which will be quite long with few more elements)?
Create template
shell> cat myvars.yml.j2
abc:
{% for index in range(1, size+1) %}
xyz{{ index }}:
url: "{{ '{{' }} url {{ '}}' }}"
api_key: "{{ '{{' }} key {{ '}}' }}"
{% endfor %}
The playbook
- hosts: localhost
vars:
size: 3
key: mykey
url: myurl
tasks:
- template:
src: myvars.yml.j2
dest: myvars.yml
- include_vars: myvars.yml
- debug:
var: abc
will create file myvars.yml
shel> cat myvars.yml
abc:
xyz1:
url: "{{ url }}"
api_key: "{{ key }}"
xyz2:
url: "{{ url }}"
api_key: "{{ key }}"
xyz3:
url: "{{ url }}"
api_key: "{{ key }}"
and debug will display the included variable
"abc": {
"xyz1": {
"api_key": "mykey",
"url": "myurl"
},
"xyz2": {
"api_key": "mykey",
"url": "myurl"
},
"xyz3": {
"api_key": "mykey",
"url": "myurl"
}
}

ansible-playbook when conditions on uri module

I have ansbile playbook code :
- name: Send file to server
uri:
url: "{{ url }}:{{ port }}/application/{{ item | basename }}"
method: POST
body: "{{ lookup('file','{{ item }}') }}"
force_basic_auth: yes
status_code: 201
body_format: json
with_fileglob: "{{ tmp_dir)_for_files }}/configs/*"
register: code_result
until: code_result.status == 201
retries: "{{ uri_retries }}"
delay: "{{ uri_delays }}"
What I need to achieve is that file will be uploaded to the sever only if the is not already there.
Here is my approach to this problem
- name: Get file from server
uri:
url: "{{ url }}:{{ port }}/application/{{ item | basename }}"
method: GET
body: "{{ lookup('file','{{ item }}') }}"
force_basic_auth: yes
status_code: 404
body_format: json
with_fileglob: "{{ tmp_dir }}/configs/*"
register: get_code_result
ignore_errors: true
- name: Send file to server
uri:
url: "{{ url }}:{{ port }}/application/{{ item.item | basename }}"
method: POST
body: "{{ lookup('file','{{ item.item }}') }}"
force_basic_auth: yes
status_code: 201
body_format: json
with_items:
- "{{ get_code_result.results }}"
when: item.status == 404
register: code_result
until: code_result.status == 201
retries: "{{ uri_retries }}"
delay: "{{ uri_delays }}"
It appears to be working

Resources