Insert a line on each findings from given file using ansible playbook - ansible

I want to add the line "*{My-Dept$2}" in file.yaml after *{My-Dept$1} this on every finding, I was able to find a line that starts with *{My-Dept$1} and inserted only one time, and ended with this trouble.
I have this in Multiple lines in the file and wanted to insert after "*{My-Dept$1}".
The reference are below:
Infrastructure:
- *{My-Dept$0}
- *{My-Dept$1}
Applications:
- *{My-Dept$1}
- *{My-Dept$3}
- *{My-Dept$4}
Database:
- *{My-Dept$0}
- *{My-Dept$1}
- *{My-Dept$3}
With the below code i was able to add the line "- *{My-Dept$2}" after only in the last "Database arry " entry.
- name: Add missing Dept
lineinfile:
dest: ./file.yaml
insertafter: '[*{]My-Dept[$]1[}]' #
line: ' - *{My-Dept$2}'
and the Output:
Infrastructure:
- *{My-Dept$0}
- *{My-Dept$1}
Applications:
- *{My-Dept$1}
- *{My-Dept$3}
- *{My-Dept$4}
Database:
- *{My-Dept$0}
- *{My-Dept$1}
- *{My-Dept$2}
- *{My-Dept$3}
I wish to get "*{My-Dept$2}" on every next line of each of the findings of *{My-Dept$1} entries. Most of the search find talks about replace, but my requirement is to insert multiple times on each finding.

Make the file.yaml valid YAML. For example
shell> cat file.yaml
---
Infrastructure:
- '*{My-Dept$0}'
- '*{My-Dept$1}'
Applications:
- '*{My-Dept$1}'
- '*{My-Dept$3}'
- '*{My-Dept$4}'
Database:
- '*{My-Dept$0}'
- '*{My-Dept$1}'
- '*{My-Dept$3}'
Q: "Put *{My-Dept$2} on every next line of each of the findings of *{My-Dept$1} entries."
A: It's possible to edit the file on your own.
Read the variables from the file into a dictionary. For examle
- include_vars:
file: file.yaml
name: my_dict
- debug:
var: my_dict
gives
my_dict:
Applications:
- '*{My-Dept$1}'
- '*{My-Dept$3}'
- '*{My-Dept$4}'
Database:
- '*{My-Dept$0}'
- '*{My-Dept$1}'
- '*{My-Dept$3}'
Infrastructure:
- '*{My-Dept$0}'
- '*{My-Dept$1}'
Modify the data. For example
- set_fact:
my_dict1: "{{ my_dict1|default({})|
combine({item: (my_dict[item] + add_items)|unique|sort}) }}"
loop: "{{ my_dict.keys()|list }}"
vars:
add_items:
- '*{My-Dept$2}'
- debug:
var: my_dict1
gives
my_dict1:
Applications:
- '*{My-Dept$1}'
- '*{My-Dept$2}'
- '*{My-Dept$3}'
- '*{My-Dept$4}'
Database:
- '*{My-Dept$0}'
- '*{My-Dept$1}'
- '*{My-Dept$2}'
- '*{My-Dept$3}'
Infrastructure:
- '*{My-Dept$0}'
- '*{My-Dept$1}'
- '*{My-Dept$2}'
Create template
shelll> cat file.yaml.j2
---
{% for k,v in my_dict1.items() %}
{{ k }}:
{% for item in v %}
- '{{ item }}'
{% endfor %}
{% endfor %}
Write the modified data into the file
- template:
src: file.yaml.j2
dest: file.yaml
gives
shell> cat file.yaml
---
Infrastructure:
- '*{My-Dept$0}'
- '*{My-Dept$1}'
- '*{My-Dept$2}'
Applications:
- '*{My-Dept$1}'
- '*{My-Dept$2}'
- '*{My-Dept$3}'
- '*{My-Dept$4}'
Database:
- '*{My-Dept$0}'
- '*{My-Dept$1}'
- '*{My-Dept$2}'
- '*{My-Dept$3}'

Related

Replacement with regex

I tried to trim the custom facts but it will not give me expected result. My entire code as below.
---
- name: Extarcting the Value
hosts: localhost
gather_facts: no
connection: local
vars:
app_brach: onkar-test
vars_files:
- common.yml
tasks:
- name: setting the facts
set_fact:
app_name_list: "{{ app_name_list|default([])) + [item.name] }}'
loop: "{{apps_to_deploy}}"
- name: display information
debug:
var: app_name_list
- name: resetting the fact
set_fact:
app_name_list: "{{ item | reject('search', '{{app_branch'}} | list }}"
loop: app_name_list
- name: display new list
debug:
var: app_name_list1
and my common.yml is as below.
---
apps_to_deploy:
- name: jaw-app-worker-{{app_branch}}
version: 1.0.0
- name: jaw-pat-valid-{{app_branch}}
version: 1.0.1
basically first I want to assign app_name_list with app_branch which is vriable and again need to reset app_name_list custome facts by removing app_branch variable.

Ansible how to split string in newline

I am running in ansible playbook with:
--extra-vars "log_path=/var/logs/a*.log,/repo/log-events-a*.json,repo/user1/log-events-b*.json"
as comma separated lines, I want the output in filebeat.yml file as
paths:
- /var/logs/a*.log
- /repo/log-events-a*.json
- /repo/user1/log-events-b*.json
I am using jinja2 for filebeat.yml
paths:
- {{ log_path }}
And my ansible file testconfigure.yml is
- hosts: localhost
gather_facts: no
vars:
log_path: "{{ logpath.replace(',', '\n-')}}"
tasks:
- name: a jija test
template:
src: /repo/filebeat/filebeat.j2
dest : /repo/filebeat/filebeat.yml
I am getting the output in filebeat.yml file as:
paths:
- /var/logs/*.log,/repo/log-events-a*.json,/repo/user1/log-events-b*.json
I also tried logpath: "{{ logpath | regex_replace(',', '\n-') }" in my playbook, but still getting same output.
How should I try it?
create a j2 file :
paths:
{% for log in log_path %}
- {{ log }}
{% endfor %}
playbook:
- hosts: localhost
vars:
log_path: "{{ logpath.split(',') }}"
tasks:
- name: templating
template:
src: filebeat.j2
dest: filebeat.yml
and the command to call:
ansible-playbook yourplaybook.yml --extra-vars "logpath=/var/logs/a*.log,/repo/log-events-a*.json,repo/user1/log-events-b*.json
result:
paths:
- /var/logs/a*.log
- /repo/log-events-a*.json
- repo/user1/log-events-b*.json
if you just want to create a var file, no need to template:
- name: create var file
copy:
content: "{{ log_path | to_nice_yaml }}"
dest: filebeat.yml
result:
paths:
- /var/logs/a*.log
- /repo/log-events-a*.json
- repo/user1/log-events-b*.json

Can't extract a nested variable in ansible of a dict based on another variable

I have a variables file like so
apps:
appOne:
slug: none
ports:
- "8999:8999"
kong:
slug: somerepo/ansible.kong.git
ports:
- "8000:8000"
- "8001:8001"
- "8443:8443"
- "8445:8445"
in my vars/apps_config file
I'm trying to figure out the ports based on the {{ app_name }} but can't seem to find a way to drill into the apps object.
So in my yml file I'm executing I have
vars_files:
- "vars/app_config"
vars:
app_name: kong
container_ports: "{{ apps [{{ app_name }}]['ports'] }}"
but ansible doesn't like the nested variable {{ app_name }}. I saw someone mention using vars['somestring'] before but the following doesn't seem to work
vars['apps.{{ app_name }}']
any ideas?
the right syntax is:
container_ports: "{{ apps[app_name]['ports'] }}"
*inside {{}} app_name is seen like a variable
test:
- name: test
hosts: localhost
vars_files:
- "vars/app_config"
vars:
app_name: kong
container_ports: "{{ apps[app_name]['ports'] }}"
tasks:
- debug:
var: container_ports
result:
ok: [localhost] =>
container_ports:
- 8000:8000
- 8001:8001
- 8443:8443
- 8445:8445

Select and concatenate dict value lists

I've got a dict of lists like this:
packages:
server:
- foo
- bar
- baz
client:
- spam
- ham
- eggs
runtime:
- corge
- grault
- garply
and I want to generate a list by defining keys to select in another dict, so e.g.:
enable:
server: true
client: false
runtime: true
would result in:
output:
- foo
- bar
- baz
- corge
- grault
- garply
Any ideas how to do this in ansible/jinja?? Ideally without using the loop construct but I could live with that. I suspect it'll need an intermediate variable and so far all I've got is something to extract a list of the keys from enable which have a true value:
- set_fact:
enabled: "{{ (enable | dict2items | selectattr('value') | list | items2dict).keys() }}"
If this looks a bit convoluted its because both packages and enable are existing role variables which I'd prefer not to change. But open to suggestions (especially on packages) if reshaping them makes this much easier.
Let's create the list of enabled hosts first. For example
- set_fact:
my_hosts: "{{ enable|dict2items|
selectattr('value')|
map(attribute='key')|list }}"
- debug:
var: my_hosts
give
my_hosts:
- server
- runtime
Then use this list to extract the packages. For example
- set_fact:
my_list: "{{ my_hosts|map('extract', packages)|list|flatten }}"
- debug:
var: my_list
give
my_list:
- foo
- bar
- baz
- corge
- grault
- garply
The single task below comprises both steps
- set_fact:
my_list: "{{ my_hosts|map('extract', packages)|list|flatten }}"
vars:
my_hosts: "{{ enable|dict2items|
selectattr('value')|
map(attribute='key')|list }}"

loop using with_sequence over with_subelement in ansible

I am trying to loop over a subelement variables using the a loop like with_sequence,
For the moment I have :
---
- hosts: corosync
gather_facts: no
vars:
host_list:
- node_one
- node_two
list_services:
- group: ALPHA
services:
- name: DHCP
directory: /etc/dhcp
- name: DNS
directory : /etc/dns
- group: BETA
services:
- name: SSH
directory: /etc/ssh
- name: FTP
directory: /ztc/ftp
tasks:
- name: create group-services
debug:
msg: "the service name is {{ item.0.group}}-{{ item.1.name}} , directory is {{ item.1.directory }}"
with_subelements:
- "{{ list_services }}"
- services
Since I have 2 nodes in my cluster
node_one
node_two
I want to deplucate each service like below :
{{ item.0.group}}-{{host_id}}-{{ item.1.name}}
with {{ host_id }} a list that equal ['0','1'] since I have 2 nodes
and the with_subelement function loop over the {{ host_id }} twice since we have two nodes, what gives :
ALPHA-0-DHCP
ALPHA-0-DNS
ALPHA-1-DHCP
ALPHA-1-DNS
BETA-0-SSH
BETA-0-FTP
BETA-1-SSH
BETA-1-FTP
I want to use something like with_sequence function beside with_subelement like
with_sequence: start=0, end={{ groups['host_list']|length}}
Any suggestions please
The loop declaration introduced in Ansible 2.5 makes it pretty straightforward ー you just need to combine the two patterns replacing legacy with_sequence and legacy with_subelements:
- name: create group-services
debug:
msg: "{{item.1.0.group}}-{{item.0}}-{{item.1.1.name}}"
loop: "{{ range(0, host_list|length) | product(list_services|subelements('services')) | list }}"

Resources