Replacement with regex - ansible

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.

Related

Ansible filter dict based on key presence and list values

I have this variable :
components:
comp_one:
name: first_component
remote_server_path: "/tmp/path/one"
binaries:
- test
- test_two
comp_two:
name: second_component
remote_server_path: "/tmp/path/two"
binaries:
- ed_test
- ed_test_2
comp_three:
name: third_component
remote_server_path: "/tmp/path/three"
What I'm trying to achieve, is to only keep sub-dictionaries of components that has key binaries, and the filter those binaries using my group_names. Also, D'd like to only keep dict keys binaries and remote_server_path.
For example, if i have this hosts.yaml :
---
all:
children:
kubernetes_dev:
children:
ed_test:
hosts:
host_one:
ansible_host: XXX.XXX.XXX.XXX
ansible_ssh_user: ansible
test_two:
hosts:
host_one:
ansible_host: XXX.XXX.XXX.XXX
ansible_ssh_user: ansible
test:
hosts:
host_one:
ansible_host: XXX.XXX.XXX.XXX
ansible_ssh_user: ansible
The expected output would be :
comp_one:
remote_server_path: "/tmp/path/one"
binaries:
- test
- test_two
comp_two:
remote_server_path: "/tmp/path/two"
binaries:
- ed_test
I've successfully filtered the comp_three dict using this :
- name: Debug
ansible.builtin.debug:
msg: "{{ item }}"
with_items: "{{ components | dict2items | selectattr('value.binaries', 'defined') }}"
But, I can't figure out a way to only select binaries and remote_server_path keys while filtering with my `group_names.
Does anyone can't help me find a clean way to do this ?
Regards,
Use group_names. This is: "List of groups the current host is part of.". For the host host_one in the inventory hosts.yaml this is
group_names: [ed_test, test, test_two]
Convert the dictionary components to list and test intersect of binaries and group_names. Default to empty list if the attribute binaries is missing
- set_fact:
selected_list: "{{ selected_list|d([]) + [_item] }}"
loop: "{{ components|dict2items }}"
when: my_groups|length > 0
vars:
_item: "{{ item|combine(my_value) }}"
my_value: "{{ {'value': {'binaries': my_groups,
'remote_server_path': item.value.remote_server_path}} }}"
my_groups: "{{ item.value.binaries|d([])|intersect(group_names) }}"
gives
selected_list:
- key: comp_one
value:
binaries:
- test
- test_two
remote_server_path: /tmp/path/one
- key: comp_two
value:
binaries:
- ed_test
remote_server_path: /tmp/path/two
Conver the list into a dictionary
- set_fact:
selected_dict: "{{ selected_list|items2dict }}"
gives the expected result
selected_dict:
comp_one:
binaries:
- test
- test_two
remote_server_path: /tmp/path/one
comp_two:
binaries:
- ed_test
remote_server_path: /tmp/path/two
Example of a complete playbook
- hosts: all
vars:
components:
comp_one:
name: first_component
remote_server_path: /tmp/path/one
binaries:
- test
- test_two
comp_two:
name: second_component
remote_server_path: /tmp/path/two
binaries:
- ed_test
- ed_test_2
comp_three:
name: third_component
remote_server_path: /tmp/path/three
tasks:
- set_fact:
selected_list: "{{ selected_list|d([]) + [_item] }}"
loop: "{{ components|dict2items }}"
when: my_groups|length > 0
vars:
_item: "{{ item|combine(my_value) }}"
my_value: "{{ {'value': {'binaries': my_groups,
'remote_server_path': item.value.remote_server_path}} }}"
my_groups: "{{ item.value.binaries|d([])|intersect(group_names) }}"
- set_fact:
selected_dict: "{{ selected_list|items2dict }}"
- debug:
var: selected_dict

Ansible - tower_host bulk delete host from inventories

I would like to remove a host from all the inventories it is part of.
I tried something like this, but that does not work:
---
- hosts: [MYHOST]
tasks:
- name: "Test deletion"
tower_host:
name: "{{ vm_hostname }}"
inventory:
- "RedHat"
- "RedHat-Hors-Prod"
- "RedHat-Prod"
state: absent
...
Is this possible without create 3 differents tasks?
Thanks
The way to do this is by using a loop:
---
- hosts: pransibleapp
tasks:
- name: "Test deletion"
tower_host:
name: "{{ vm_hostname }}"
inventory: "{{ item }}"
state: absent
.
.
loop:
- "RedHat"
- "RedHat-Hors-Prod"
- "RedHat-Prod"
Doc : https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#iterating-over-a-simple-list

Ansible vars_prompt for host list into Import_playbook

I want to use a specific host / host list for an imported playbook which I get from a vars_prompt input. How can I do this? So far I wasn´t able to get this running.
I have two playbooks which I need to run separately and ios_check_routerports.yaml is the parent playbook:
ios_check_routerports.yaml
---
- hosts: '{{ branch_number }}'
connection: network_cli
gather_facts: False
any_errors_fatal: no
throttle: 75
vars_prompt:
- name: "branch_number"
prompt: "Which branch do you want to check?"
default: all
private: no
tasks:
- name: Check facts
ios_facts:
gather_subset: hardware
- name: Create directory
file:
path: /root/ansible/pb-outputs/ios_check_routerports/
state: directory
delegate_to: 127.0.0.1
- name: Run playbook
import_playbook: ios_check_routerports_main.yaml
ios_check_routerports_main.yaml
---
- hosts: '{{ branch_number }}'
connection: network_cli
gather_facts: False
any_errors_fatal: no
throttle: 75
tasks:
- name: Check default-gateway
ios_command:
commands: sh run | i default-gateway
register: default_gateway
I tried to set a fact for the var {{ branch_number }} like this:
ios_check_routerports.yaml
- set_fact:
devices: "{{ branch_number }}"
ios_check_routerports_main.yaml
---
- hosts: '{{ devices }}'
connection: network_cli
The playbook always runs into an error because the hosts var is not defined. What am I doing wrong here?
try this: no need to create a new variable devices but a dummy host
in ios_check_routerports.yaml add a task:
- name: Register dummy host with variable
add_host:
name: "DUMMY_HOST"
DEVICES: "{{ branch_number }}"
then :
- hosts: "{{ hostvars['DUMMY_HOST']['DEVICES'] }}"
connection: network_cli
as you create a new host, i suggest you to delete it if you havent need the variable branch_number so remove_host doesnt exit:
either you do a first task - meta: refresh_inventory
or you modify your host like this:
- hosts: "{{ hostvars['DUMMY_HOST']['DEVICES'] }},!DUMMY_HOST"

"search" a string in "when:" conditional statement?

In the following playbook, I have to use search in a when: statement. Can you please tell me what is wrong with the statement when: item.name is search (domain_list)? domain_list is an array variable defined in files.yml as shown below.
---
- hosts: localhost
gather_facts: False
connection: local
vars_files:
- files.yml
vars:
infra:
- name: ironman.vcloud-lab.com
connection_state: CONNECTED
- name: hulk.vcloud-lab.com
connection_state: CONNECTED
- name: captain.vcloud-lab.com
connection_state: DISCONNECTED
- name: hawkeye.vcloud-lab.com
connection_state: DISCONNECTED
tasks:
- name: Filter list of only connected esxi
set_fact:
esxilist: "{{esxilist | default([]) + [item]}}"
with_items: "{{infra}}"
when: item.name is search (domain_list) ## <= please correct me here, it doesn't work
- name: Show connected esxi list information
debug:
var: esxilist
files.yml
---
domain_list:
- ironman
- captain
Select the short name and test the presence in the list. For example, use regex_replace
- name: Filter list of only connected esxi
set_fact:
esxilist: "{{ esxilist|default([]) + [item] }}"
loop: "{{ infra }}"
when: _short in domain_list
vars:
_short: "{{ item.name|regex_replace('^(.*?)\\.(.*)$', '\\1') }}"
gives
esxilist:
- connection_state: CONNECTED
name: ironman.vcloud-lab.com
- connection_state: DISCONNECTED
name: captain.vcloud-lab.com
The next option is to split the string and select the first item. For example
vars:
_short: "{{ item.name.split('.')|first }}"
gives the same result.
See How to create a Minimal, Reproducible Example. For example
- hosts: localhost
vars:
domain_list: [a, b]
infra:
- {name: a.vcloud-lab.com, state: CONNECTED}
- {name: b.vcloud-lab.com, state: DISCONNECTED}
- {name: c.vcloud-lab.com, state: CONNECTED}
tasks:
- set_fact:
l1: "{{ l1|default([]) + [item] }}"
with_items: "{{ infra }}"
when: _short in domain_list
vars:
_short: "{{ item.name.split('.')|first }}"
- debug:
var: l1

VARIABLE IS NOT DEFINED when trying to register output in playbook

I'm trying to register a variable with the output to a query of a F5 pool and I'm getting this error:
"<type 'list'>": "VARIABLE IS NOT DEFINED!",
What is that I'm doing wrong?
Any help appreciated.
Thanks!
---
- name: GRAB F5 FACTS
hosts: f5
connection: local
gather_facts: no
tasks:
- name: Collect BIG-IP facts
bigip_device_facts:
gather_subset: ltm-pools
provider: "{{ prov }}"
register: bigip_device_facts
- name: FACTS OUTPUT
debug:
var: "{{ item.members | rejectattr('state', 'match', '^present$') | map(attribute='name') | list }}"
register: jkout
with_items: "{{ bigip_device_facts.ltm_pools }}"
when: item.full_path == "/Common/mypool"
- name: Set a variable
debug:
msg: "jkvar={{ jkout }}"
You are using the debug: module with the option var: and this expects a variable, not a jinja2 template.
So either change it to:
debug:
var: item.members
or
debug:
msg: "{{ item.members }}"
Like said by #dgw, the problem is with the var option of debug module.
https://docs.ansible.com/ansible/latest/modules/debug_module.html#parameters
This playbooks works:
- name: test rejectattr
hosts: localhost
gather_facts: no
vars:
members:
- { name: "one", state: "present" }
- { name: "two", state: "absent" }
- { name: "three", state: "present" }
tasks:
- name: FACTS OUTPUT
debug:
msg: "{{ members | rejectattr('state', 'match', '^present$') | map(attribute='name') | list }}"
Thanks for your responses. I'll investigate it further.
Apart from that, I think I've been able to solve it another way.
- name: FACTS OUTPUT
set_fact:
listado: "{{ item.members | rejectattr('state', 'match', '^present$') | map(attribute='name') | list }}"
with_items: "{{ bigip_device_facts.ltm_pools }}"
when: item.full_path == "/Common/mypool"
- debug: msg={{ listado }}
register: jkout
- name: Set a variable
debug:
msg: "jkvar={{ jkout }}"
Is that a right way to do it?
Thanks!!

Resources