how to get metadata of aws instance created in ansible? - amazon-ec2

I'm creating an AWS instance and need to get the hostname, ip address in the same play. How to get the metadata. I tried 'ec2_instance_facts', 'ec2_metadata_facts', these are giving the host ansible playbook is running not the one just created.
I have tried using different modules '
- name: Debug
ec2_metadata_facts:
- debug: var=ansible_ec2_hostname
- debug: var=ansible_ec2_public_ipv4
- debug: var=ansible_ec2_public_hostname
- ec2_instance_facts:
region: "ap-southeast-2"
filters:
"tag:Name": A01NANISIM20
register: ec2_metadata
These snippets are not giving the details of the insatnce created, instead they give the details of the instance where playbook is run.

- ec2_instance_facts:
region: "ap-southeast-2"
filters:
"tag:Name": A01NANISIM04
register: ec2_metadata
- debug: msg="{{ ec2_metadata.instances }}"
- debug: msg="{{ ec2_metadata.instances[0].public_ip_address }}"
Finally I figured out myself. I didn't realize that ansible is an amalgamation of technologies. Just understood that the output is JSON data and all I need to form is the appropriate tags.

I've been using the ohai_ec2 fact run task based on the region or availability zone as ec2_instance_facts fails for me with a boto3 bug
using https://stackoverflow.com/a/51308298/4389552 let me see which facts I can use
e.g.
{{ ohai_ec2.region }}
# find the region
- name: get the region and availability zone
debug:
msg: "Region is {{ ohai_ec2.region }} and zone is {{ ohai_ec2.availability_zone }}"

Related

Ansible ec2_instance_facts

I have a basic Ansible playbook creating an ec2 instance in aws, its working fine, i want to pick the public ip from the created instance to do furthers task on it, i am using the following section:
- name: get-facts
ec2_instance_facts:
region: eu-west-1
aws_access_key: xxxxxxxxx
aws_secret_key: xxxxxxx
filters:
"tag:Name": docker-server
register: ec2
- debug: var=ec2.instances
But i want to get just the ip address, according to the documentation public_ip
is a string, but i cannot call it when i use ec2.instances.public_ip i get error:
"VARIABLE IS NOT DEFINED!"
what can i do to get the public ip for my created ec2 instance ? thanks.
It is ec2.instances.public_ip_address and public_ip
See: https://docs.ansible.com/ansible/2.9/modules/ec2_instance_info_module.html#return-instances/public_ip_address
ec2_instance_facts deprecated, ansible offer to use ec2_instance_info
See: https://docs.ansible.com/ansible/2.9/modules/ec2_instance_facts_module.html
UPDATE:
- name: Print info
debug: var="ec2.instances[0].public_ip_address"
- name: Loop instances
debug:
var: item.public_ip_address
with_items: "{{ ec2.instances }}"
Thank you for your support and clarification, its finally worked like this:
- name: get-facts
ec2_instance_info:
region: xxxxx
aws_access_key: xxxxxxxxxxx
aws_secret_key: xxxxxxxxxxx
filters:
"tag:Name": docker-server
register: ec2
- debug: var="ec2.instances[0].public_ip_address"

Access hosts in play filtered by task

I have a task that checks the redis service status on the host list below
- hosts: 192.168.0.1, 192.168.0.2, 192.168.0.3
tasks:
- command:
cmd: service redis-server status
register: result
- debug:
var: result
After checking I need to access hosts where service does not exist.
And they should be accessible as variable to proceed with them in the next tasks.
Can someone please help?
Similar to Ansible facts it is also possible to gather service_facts. In example
- name: Set facts SERVICE
set_fact:
SERVICE: "redis-server.service"
- name: Gathering Service Facts
service_facts:
- name: Show ansible_facts.services
debug:
msg:
- "{{ ansible_facts.services[SERVICE].status }}"
If you like to perform tasks after on a service of which you don't the status, with Conditionals you can check the state.
If the service is not installed at that time, the specific variable (key) would not be defined. You would perform Conditionals based on variables then
when: ansible_facts.services[SERVICE] is defined
when: ansible_facts.services['redis-server.service'] is defined
Also it is recommend to use the Ansible service module to perform tasks on the service
- name: Start redis-server, if not started
service:
name: redis-server
state: started
instead of using the command module.
Further services related Q&A
How to check service exists and is not installed in the server using service_facts module in an Ansible playbook?
Ansible: How to start stopped services?
Ansible: How to get disabled but running services?
How to list only the running services with ansible_facts?
Finally found the solution that perfectly matches.
- name: Check that redis service exists
systemd:
name: "redis"
register: redis_status
changed_when: redis_status.status.ActiveState == "inactive"
- set_fact:
_dict: "{{ dict(ansible_play_hosts|zip(
ansible_play_hosts|map('extract', hostvars, 'redis_status'))) }}"
run_once: true
- set_fact:
_changed: "{{ (_dict|dict2items|json_query('[?value.changed].key'))| join(',') }}"
run_once: true

How can I disable Cross region replication in oracle cloud using ansible playbook?

I came across a situation where when deleting an image with CRR enabled, you must first disable CRR before you can successfully delete the image. I cannot come with an ansible role or task to do the same.
So far I've come up with this:
- name: Get information of all boot volume attachments in a compartment and availability domain
oci_boot_volume_attachment_facts:
compartment_id: "{{ COMPARTMENT_ID }}"
availability_domain: "{{ Availability_Domain}}"
instance_id: "{{ matching_id_instance }}"
register: boot_volume_data
- name: Update boot_volume
oci_blockstorage_boot_volume:
# required
boot_volume_id: "{{ item.boot_volume_id }}"
boot_volume_replicas: []
- # required
availability_domain: "{{ Availability_Domain}}"
with_items: "{{ boot_volume_data.boot_volume_attachments }}"
when:
- item.instance_id == "{{ matching_id_instance }}"
'm unable to test it because there is difficulty in setting up connectivity from my ubuntu machine to oracle cloud as I don't have required permission to add public key in the oracle cloud for my user. For connectivity I followed this: https://docs.oracle.com/en-us/iaas/Content/API/Concepts/sdkconfig.htm
I also came across a cli command to do so in oracle: https://docs.oracle.com/en-us/iaas/Content/Block/Concepts/volumereplication.htm#To_disable_boot_replication
So I actually want this ansible tasks to be verified and rectify for errors if any? Or a particular way in ansible to disable CRR in oracle cloud
Error message I'm getting at "Update boot_volume" task:
"msg": "Updating resource failed with exception: Parameters are invalid or incorrectly formatted. Update volume requires at least one parameter to update."}
No need to paas the availability_domain for disabling CRR. You can refer below ansible task for your reference.
- name: Disable CRR for boot_volume
oci_blockstorage_boot_volume:
boot_volume_id: "{{ boot_volume_id }}"
boot_volume_replicas: []
register: result

Setting Ansible vars with set_fact results

Im running ansible 2.9.18 on RHEL7.
I am using hvac to retrieve usernames and passwords from a Hashicorp vault.
vars:
- creds: "{{ lookup('hashi_vault', 'secret=tst2/data/cisco token= url=http://10.80.23.81:8200') }}"
tasks:
- name: set Cisco creds
set_fact:
cisco: "{{ creds['data'] }}"
- name: Get nxos facts
nxos_command:
username: "{{ cisco['username'] }}"
password: "{{ cisco['password'] }}"
commands: show ver
timeout: 30
register: ver_out
- debug: msg="{{ ver_out.stdout }}"
But username and password are deprecated and I am trying to figure out how to pass the username, password as a "provider" variable. And this code doesn't work:
vars:
asa_api:
- creds: "{{ lookup('hashi_vault', 'secret=tst2/data/cisco token= url=http://10.80.23.81:8200') }}"
set_fact:
cisco: "{{ creds['data'] }}"
username: "{{ cisco['username'] }}"
password: "{{ cisco['password'] }}"
tasks:
- name: show run
asa_command:
commands: show run
provider: "{{ asa_api }}"
register: run
become: yes
tags:
- show_run
I cannot figure how syntax for making this work. I would greatly appreciate any help.
Thanks,
Steve
Disclaimer: This is a generic answer. I do not have any network device to test this fully so you might have to adapt a bit after reading the documentation
Your are taking this the wrong way. You don't need set_fact at all and both method you are trying to use (user/pass or provider dict) are actually deprecated. Ansible treats you network device as any host and will use the available user and password you have configured if they exist.
In the following example, I'm assuming your playbook only targets network devices and that the login/pass stored in your vault is the same on all devices.
- name: Untested network device connection configuration demo
hosts: my_network_device_group
vars:
# This indicates which connection plugin to use. Default is ssh
# An other possible value is httpapi. See above documentation link
ansible_connection: network_cli
vault_secret: tst2/data/cisco
vault_token: verysecret
vault_url: http://10.80.23.81:8200
vault_options: "secret={{ vault_secret }} token={{ vault_token }} url={{ vault_url }}"
creds: "{{ lookup('hashi_vault', vault_options).data }}"
# These are the user and pass used for connection.
ansible_user: "{{ creds.username }}"
ansible_password: "{{ creds.password }}"
tasks:
- name: Get nxos version
nxos_command:
commands: show ver
timeout: 30
register: ver_cmd
- name: show version
debug:
msg: "NXOS version on {{ inventory_hostname }} is {{ ver_cmd.stdout }}"
- name: An other task to play on targets
debug:
msg: "Task played on {{ inventory_hostname }}"
Rather than vars at play level, you can store this information in your inventory for all hosts or for a specific group, even for each host. See how to organise your group and host variables if you want to use that feature.

Import ansible facts into servicenow cmdb

I'm trying to determine if it's possible to populate our servicenow CMDB with Ansible facts gathered from our Ansible Tower instance. I can find a lot of documentation on pulling inventory FROM CMDB, or for using Ansible to create incidents, but nothing on updating CI objects based on gathered facts. Is this possible?
check out this repo, https://github.com/michaelford85/ansible-servicenow-exercises
especially the Ansible Playbook-> snow-table-fields.yml
- name: Retrieve fields for a table {{ snow_table }}
snow_record:
state: present
table: "{{ snow_table }}"
data:
name: delete_this_record
username: "{{ SN_USERNAME }}"
password: "{{ SN_PASSWORD }}"
instance: "{{ SN_INSTANCE }}"
register: table_output
where {{snow_table}} can be something like cmdb_ci_linux_server

Resources