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
Related
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
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
I have the following playbook which is essentially working -
vars:
ansible_network_os: ios
IOSserials: []
tasks:
- name: Get all facts from ios devices
register: all_facts
ios_facts:
gather_subset: hardware
- name: Create list Serials
set_fact:
IOSserials: "{{IOSserials|default([]) + [{ 'name': all_facts.ansible_facts.ansible_net_hostname, 'IOS_serial': all_facts.ansible_facts.ansible_net_serialnum }] }}"
when: hostvars[inventory_hostname].serial != all_facts.ansible_facts.ansible_net_serialnum
- name: Display list
debug:
msg: "These switches have a difference in serial number {{ ansible_play_hosts_all|map('extract', hostvars, 'IOSserials')|list }}"
run_once: true
With the following result (I have one 'not equal' scenario in the switches):
TASK [Create list Serials] *****************************************************
skipping: [lab3650s1] => {"changed": false, "skip_reason": "Conditional result was False"}
skipping: [lab4500s1] => {"changed": false, "skip_reason": "Conditional result was False"}
ok: [lab3650s2] =>
{"ansible_facts": {"IOSserials": [{"IOS_serial": "FDO201XXXXD", "name": "lab3650s2"}]}, "changed": false}
TASK [Display list] ************************************************************
ok: [lab3650s1] => {
"msg": "These switches have a difference in serial number [Undefined, [{'name': 'lab3650s2', 'IOS_serial': 'FDO201XXXXD'}], Undefined]"
}
PLAY RECAP *********************************************************************
lab3650s1 : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
lab3650s2 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
lab4500s1 : ok=1 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
I do not want the 'undefined' entries in the output list, I'd also like to understand why Ansible is inserting this in the list when its is skipping the set_fact for these entries.
That map pipeline is missing the select that would filter out the ones where extract did not produce a meaningful value; you can see it trivially reproducible:
- set_fact:
thingy:
one:
apple: is red
two:
banana: is yellow
three:
apple: is green
- debug:
msg: >
{{ ["one", "two", "three"] | map("extract", thingy, "banana") | list }}
- debug:
msg: >
{{ ["one", "two", "three"]
| map("extract", thingy, "banana")
| select
| list }}
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
I am getting and error when I want to provision an ec2. This is how i set up my environment.
I put my aws credentials in ~/.boto
cat /etc/ansible/hosts
[local]
localhost
cat /etc/ansible/ec2-vars/testserver.yml
ec2_keypair: "ansible"
ec2_security_group: "sg-*******"
ec2_instance_type: "t2.micro"
ec2_image: "ami-********"
ec2_subnet_ids: ['subnet-*******','subnet-REDACTED','subnet-REDACTED']
ec2_region: "us-east-1"
ec2_tag_Name: "testserver"
ec2_tag_Type: "testserver"
ec2_tag_Environment: "development"
ec2_volume_size: 8
cat /etc/ansible/provision-ec2.yml
---
- hosts: localhost
connection: local
gather_facts: false
user: root
pre_tasks:
- include_vars: ec2_vars/{{type}}.yml
roles:
- provision-ec2
cat /etc/ansible/roles/provision-ec2/tasks/main.yml
---
- name: Provision EC2 Box
local_action:
module: ec2
key_name: "{{ ec2_keypair }}"
group_id: "{{ ec2_security_group }}"
instance_type: "{{ ec2_instance_type }}"
image: "{{ ec2_image }}"
vpc_subnet_id: "{{ ec2_subnet_ids|random }}"
region: "{{ ec2_region }}"
instance_tags: '{"Name":"{{ec2_tag_Name}}","Type":" {{ec2_tag_Type}}","Environment":"{{ec2_tag_Environment}}"}'
assign_public_ip: yes
wait: true
count: 1
volumes:
- device_name: /dev/sda1
device_type: gp2
volume_size: "{{ ec2_volume_size }}"
delete_on_termination: true
register: ec2
- debug: var=item
with_items: ec2.instances
- add_host: name={{ item.public_ip }} >
groups=tag_Type_{{ec2_tag_Type}},tag_Environment_{{ec2_tag_Environment}}
ec2_region={{ec2_region}}
ec2_tag_Name={{ec2_tag_Name}}
ec2_tag_Type={{ec2_tag_Type}}
ec2_tag_Environment={{ec2_tag_Environment}}
ec2_ip_address={{item.public_ip}}
with_items: ec2.instances
- name: Wait for the instances to boot by checking the ssh port
wait_for: host={{item.public_ip}} port=22 delay=60 timeout=320 state=started
with_items: ec2.instances
Now I run the following command and this is what i get.
[root#ip-**-**-*** ansible]# ansible-playbook -vv -i localhost, -e "type=testservers" provision-ec2.yml
Using /etc/ansible/ansible.cfg as config file
PLAYBOOK: provision-ec2.yml ****************************************************
1 plays in provision-ec2.yml
PLAY [localhost] ***************************************************************
TASK [include_vars] ************************************************************
task path: /etc/ansible/provision-ec2.yml:7
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "file": "/etc/ansible/ec2_vars/testservers.yml", "msg": "Source file not found."}
NO MORE HOSTS LEFT *************************************************************
to retry, use: --limit #provision-ec2.retry
PLAY RECAP *********************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=1
please help.
New error:
TASK [provision-ec2 : Provision EC2 Box] ***************************************
task path: /etc/ansible/roles/provision-ec2/tasks/main.yml:2
fatal: [localhost -> localhost]: FAILED! => {"changed": false, "failed": true, "msg": "No handler was ready to authenticate. 1 handlers were checked. ['HmacAuthV4Handler'] Check your credentials"}
NO MORE HOSTS LEFT *************************************************************
to retry, use: --limit #provision-ec2.retry
PLAY RECAP *********************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=1
You are mixing underscore and hyphen.
cat /etc/ansible/ec2-vars/testserver.yml
include_vars: ec2_vars/{{type}}.yml