Ansible regex replace String - regex

I am trying to replace the unnecessary words from the below string using regex_replace but unable to do to so for the last part of it.
String: Test_[u'Net::Route Domain: RD2001']
Regex being used: regex_replace('.*: (.*)$', '\\1')
Output printing: Test_RD2001']
Expected Output: Test_RD2001
Could someone suggest how can I get rid of the last characters after RDXXXX.
Also this RDXXXX number is dynamic.

As dicussed in comments, you should try to fix the data source. However, here is the regex to print the expected result:
---
- name: Sample playbook
connection: local
#gather_facts: false
hosts: localhost
vars:
String: "Test_[u'Net::Route Domain: RD2001']"
tasks:
- debug:
msg: "{{ String| regex_replace('^(\\w+)\\[.*:\\s+([\\w]+).*', '\\1\\2') }}"
Results:
PLAY [Sample playbook] ***************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************
ok: [localhost]
TASK [debug] *************************************************************************************************************************
ok: [localhost] => {
"msg": "Test_RD2001"
}
PLAY RECAP ***************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Related

Unable to create instance on gcp using ansible

Trying to create a gcp instance with ansible following the steps from this github link.
playbook:
---
- hosts: localhost
connection: local
tasks:
- name: creating instance
gcp_compute_instance:
name: ansible instance
machine_type: e2-micro
disks:
- auto_delete: true
boot: true
initialize_params:
source_image: projects/debian-cloud/global/images/family/debian-11
network_interfaces:
- access_configs:
- name: External NAT
type: ONE_TO_ONE_NAT
metadata:
startup-script: |
#!/bin/bash
sudo yum install httpd -y
sudo echo "HELLO WORLD !!" > /var/www/html/index.html
sudo systemctl restart httpd
zone: us-central1-a
project: capstone-project-347806
auth_kind: serviceaccount
service_account_file: service.json
state: present
output:
PLAY [localhost] ****************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [localhost]
TASK [creating instance] ********************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "GCP returned error: {u'error': {u'message': u"Invalid value for field 'instance': 'ansible instance'. Must be a match of regex 'a-z?|[1-9][0-9]{0,19}'", u'code': 400, u'errors': [{u'reason': u'invalid', u'message': u"Invalid value for field 'instance': 'ansible instance'. Must be a match of regex 'a-z?|[1-9][0-9]{0,19}'", u'domain': u'global'}]}}"}
PLAY RECAP **********************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
following the documentation for attribut name:
the name must be 1-63 characters long and match the regular expression
[a-z]([-a-z0-9]*[a-z0-9])? which means the first character must be a
lowercase letter, and all following characters must be a dash,
lowercase letter, or digit, except the last character, which cannot be
a dash.
so you cant have a space in the name, so the error says the same thing...

Match a key to value from a dict and replace a value matching another dictionary using ansible

I've a dictionary containing the below items.
PID:
Cisco:
- A9K-MOD80-TR
- A9K-RSP440-TR
- ASR9001-LC
- SFP-10G-SR
The above dictionary I want to match with the list below with the following logic, if "SFP-10G-SR" (or any of the other values exist) exist in any of the part_id below, then replace 'Manufacturer' with Cisco (Cisco in this case is the key in the dict PID).
ok: [localhost] => (item={'hostname': '-', 'device_id': 287, 'serial': '-', 'Name': '-', 'Manufacturer': '', 'part_id': 'ASR9001-LC'})
ok: [localhost] => (item={'hostname': '-', 'device_id': 287, 'serial': '-', 'Name': '-', 'Manufacturer': '', 'part_id': 'SFP-10G-SR'})
I've somehow managed to get it to work but it's ugly and it's in a weird format with the below code.
- name: test
set_fact:
new_merged_list: "{{new_merged_list}} {{ item|combine({'Manufacturer': PID|dict2items|json_query(query)}) }}"
loop: "{{ merged_list | flatten(levels=1) }}"
vars:
query: "[?contains(value, '{{item.part_id }}')].key"
- debug:
msg: "{{ new_merged_list }}"
It gives me the below output
{
"msg": "
{'hostname': '-', 'device_id': 287, 'serial': '-', 'Name': '-', 'Manufacturer': ['Cisco'], 'part_id': 'ASR9001-LC'}
{'hostname': '-', 'device_id': 287, 'serial': '-', 'Name': '-', 'Manufacturer': ['Cisco'], 'part_id': 'SFP-10G-SR'}
}
If I run a debug on the "new_merged_list" I'm getting the below message
"msg": "AnsibleUnsafeText"
What I want is to keep the above as a dictionary, could anyone assist with a better solution or maybe assist in converting this back to a dictionary? In it's current state I'm having issues working with the "new_merged_list".
Your approach is correct despite the fact that it might seem ugly and weird. Let's simplify the data, e.g.
PID:
Cisco: [A, B]
HP: [C, D]
merged_list:
- {Manufacturer: '', part_id: A}
- {Manufacturer: '', part_id: D}
Your code with only a few modifications
- set_fact:
new_merged_list: "{{ new_merged_list|default([]) +
[item|combine({'Manufacturer': manufacturer})] }}"
loop: "{{ merged_list }}"
vars:
_dict: "{{ PID|dict2items }}"
query: "[?contains(value, '{{ item.part_id }}')].key"
manufacturer: "{{ _dict|json_query(query)|first }}"
gives the new list
new_merged_list:
- Manufacturer: Cisco
part_id: A
- Manufacturer: HP
part_id: D
In a nutshell, the folowing playbook:
---
- hosts: localhost
gather_facts: false
vars:
PID:
Cisco:
- A9K-MOD80-TR
- A9K-RSP440-TR
- ASR9001-LC
- SFP-10G-SR
toto:
- bla
- ble
- bli
model_brand: >-
{{
PID
| dict2items(key_name='brand', value_name='model_list')
| selectattr('model_list', 'contains', model | default('none'))
| map(attribute='brand')
| default(['Unkown brand'], true)
| first
}}
tasks:
- name: Show brand for known models (pass as extra param -e model='test')
debug:
msg: "Model {{ model | default('none')}} is of brand {{ model_brand }}"
Gives
$ ansible-playbook playbook.yml
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Show brand for known models (pass as extra param -e model='test')] ***************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Model none is of brand Unkown brand"
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ansible-playbook playbook.yml -e brand='ASR9001-LC'
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Show brand for known models (pass as extra param -e model='test')] ***************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Model none is of brand Unkown brand"
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ansible-playbook playbook.yml -e model='ASR9001-LC'
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Show brand for known models (pass as extra param -e model='test')] ***************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Model ASR9001-LC is of brand Cisco"
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
$ ansible-playbook playbook.yml -e model='ble'
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Show brand for known models (pass as extra param -e model='test')] ***************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "Model ble is of brand toto"
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Get a value from a variable key in dictionary

I have a variable env: prod and I am trying to get the value from a prod list for a specific zone.
properties are like below
prod:
us-west-2a: xxxxxxxx
us-west-2b: xxxxxxxx
us-east-1a: xxxxxxxx
us-east-1b: xxxxxxxx
- set_fact:
reg: "{{ ansible_ec2_placement_availability_zone }}"
- set_fact:
detach_volumeid: '{{ vars[env].'reg' }}'
I am trying to get the value of prod region volume id where prod is a variable and reg is a variable.
A specific dictionary key can be addressed with the dot (.) notation but can also be addressed with the brackets notation [].
When you want to address a key as a variable, you will use the later form.
So given the playbook:
- hosts: all
gather_facts: no
tasks:
- debug:
msg: '{{ vars[env][reg] }}'
vars:
env: prod
reg: us-east-1a
prod:
us-west-2a: xxxxxxxx-w-2a
us-west-2b: xxxxxxxx-w-2b
us-east-1a: xxxxxxxx-e-1a
us-east-1b: xxxxxxxx-e-1b
This yields the recap:
PLAY [all] ********************************************************************************************************
TASK [debug] ******************************************************************************************************
ok: [localhost] => {
"msg": "xxxxxxxx-e-1a"
}
PLAY RECAP ********************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Extract substring from variable in Ansible

Edited:
I wrote this playbook but it does not show the extracted variable:
---
- hosts: fppc
gather_facts: false
remote_user: xyz
connection: local
tasks:
- name: N1
ios_command:
commands:
- sh run | i bann
register: sr
- debug: msg="{{ sr.stdout}}"
- set_fact:
rid: "{{ sr.stdout | regex_search('.*ID: (..)') }}"
- debug: msg="{{ rid }}"
Execution:
ansible#Ansible:~$ ansible-playbook pb1.yml
PLAY [fppc] *************************************************************************
TASK [N1] ***************************************************************************
ok: [192.168.250.161]
TASK [debug] ************************************************************************
ok: [192.168.250.161] => {
"msg": [
"banner login ^CID: A4"
]
}
TASK [set_fact] *********************************************************************
fatal: [192.168.250.161]: FAILED! => {"failed": true, "msg": "Unexpected templating type error occurred on ({{ sr.stdout | regex_search('.*ID: (..)') }}): expected string or buffer"}
to retry, use: --limit #/home/ansible/pb1.retry
PLAY RECAP **************************************************************************
192.168.250.161 : ok=2 changed=0 unreachable=0 failed=1
ansible#Ansible:~$
I found the solution:
---
- hosts: fppc
gather_facts: false
remote_user: xyz
connection: local
tasks:
- name: N1
ios_command:
commands:
- sh run
register: sr
- set_fact:
temp: "{{ sr.stdout_lines | join }}"
- set_fact:
rid: "{{ temp | regex_replace('.*ID: (..).*', '\\1') }}"
- debug: msg="{{ rid }}"
Execution:
ansible#Ansible:~$ ansible-playbook pb1.yml
PLAY [fppc] ********************************************************************
TASK [N1] **********************************************************************
ok: [192.168.250.161]
TASK [set_fact] ****************************************************************
ok: [192.168.250.161]
TASK [set_fact] ****************************************************************
ok: [192.168.250.161]
TASK [debug] *******************************************************************
ok: [192.168.250.161] => {
"msg": "A4"
}
PLAY RECAP *********************************************************************
192.168.250.161 : ok=4 changed=0 unreachable=0 failed=0
Other solution, more logical:
---
- hosts: fppc
gather_facts: false
remote_user: xyz
connection: local
tasks:
- name: N1
ios_command:
commands:
- sh run
register: sr
- set_fact:
rid: "{{ sr.stdout | regex_search('(?<=ID:)\\s+\\S+', multiline=True) | trim }}"
- debug: msg="{{ rid }}"
Execution:
ansible#Ansible:~$ ansible-playbook pb1.yml
PLAY [fppc] ********************************************************************
TASK [N1] **********************************************************************
ok: [192.168.250.161]
TASK [set_fact] ****************************************************************
ok: [192.168.250.161]
TASK [debug] *******************************************************************
ok: [192.168.250.161] => {
"msg": "A4"
}
PLAY RECAP *********************************************************************
192.168.250.161 : ok=3 changed=0 unreachable=0 failed=0

'ansible_date_time' is undefined

Trying to register an ec2 instance in AWS with Ansible's ec2_ami module, and using current date/time as version (we'll end up making a lot of AMIs in the future).
This is what I have:
- name: Create new AMI
hosts: localhost
connection: local
gather_facts: false
vars:
tasks:
- include_vars: ami_vars.yml
- debug: var=ansible_date_time
- name: Register ec2 instance as AMI
ec2_ami: aws_access_key={{ ec2_access_key }}
aws_secret_key={{ ec2_secret_key }}
instance_id={{ temp_instance.instance_ids[0] }}
region={{ region }}
wait=yes
name={{ ami_name }}
with_items: temp_instance
register: new_ami
From ami_vars.yml:
ami_version: "{{ ansible_date_time.iso8601 }}"
ami_name: ami_test_{{ ami_version }}
When I run the full playbook, I get this error message:
fatal: [localhost]: FAILED! => {"failed": true, "msg": "ERROR! ERROR! ERROR! 'ansible_date_time' is undefined"}
However, when run the debug command separately, from a separate playbook, it works fine:
- name: Test date-time lookup
hosts: localhost
connection: local
tasks:
- include_vars: ami_vars.yml
- debug: msg="ami version is {{ ami_version }}"
- debug: msg="ami name is {{ ami_name }}"
Result:
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "ami version is 2016-02-05T19:32:24Z"
}
TASK [debug] *******************************************************************
ok: [localhost] => {
"msg": "ami name is ami_test_2016-02-05T19:32:24Z"
}
Any idea what's going on?
Remove this:
gather_facts: false
ansible_date_time is part of the facts and you are not gathering it.
> cat tasks/test.yml
---
- hosts: node
gather_facts: no
tasks:
- setup:
gather_subset:
- min
- name: q
debug: var=ansible_date_time.epoch
and run
> ansible-playbook -i conf/share_var.conf tasks/test.yml --private-key=/root/.ssh/id_rsa -u ${USER} -b --become-method=sudo
PLAY [node] ********************************************************************************************************************************************************************************************************************************
TASK [setup] *******************************************************************************************************************************************************************************************************************************
ok: [xxxx.94.182]
ok: [xxxx.94.183]
ok: [xxxx.94.181]
TASK [q] ***********************************************************************************************************************************************************************************************************************************
ok: [xxxx.94.181] => {
"ansible_date_time.epoch": "1636712223"
}
ok: [xxxx.94.182] => {
"ansible_date_time.epoch": "1636712223"
}
ok: [xxxx.94.183] => {
"ansible_date_time.epoch": "1636712223"
}
PLAY RECAP *********************************************************************************************************************************************************************************************************************************
xxxx.94.181 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
xxxx.94.182 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
xxxx.94.183 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0