Reputation: 196
I'd like to define my hosts by their aws_instance_id only and pull data relative to the hosts (private/public IP, DNS hostname, instance type etc) from aws but store it in hostvars
as if I'd manually declared all that stuff in the hosts
file.
I've tried a number of ways:
hostname: "{{ ec2_info.results[0].instances[0].public_dns_name }}"
in each host's host_vars file (where ec2_info
is declared in a separate playbook which works and gets me the info I need)add_host
set_fact
none of these seem to work. Whenever I debug print hostvars
, I see: "hostname": "{{ ec2_info.results[0].instances[0].public_dns_name }}"
Is there a way to do this? Thanks,
Edit1
I should specify the reason behind trying to do this: I want to declare some hosts in the Ansible repo using their human readable names (eg: DEV-BATCH_1
). But tasks which need to remote onto the hosts fail because they try to SSH onto DEV-BATCH_1
instead of the IP or the DNS name. So, I want to dynamically pull the IP from EC2 and use that information to connect.
Example
hosts
file:
my_hosts:
hosts:
DEV-BATCH_1:
aws_instance_id: i-xyz
DEV-QA_1:
aws_instance_id: i-yzx
host_vars
file for each host:
hostname: ""
EC2 info gathering playbook:
ec2_info
ec2_info
and build ec2_host_data
with fields such as the private IP, instance type etc. This is what I was using so far, but I'd like to inject it back into hostvars
set_fact
to set the information into hostvars
hostvars
.- name: Gather EC2 information and set hostvars
hosts: localhost
gather_facts: false
vars:
ec2_host_data: {}
tasks:
- name: Get EC2 instance info for each host
amazon.aws.ec2_instance_info:
instance_ids: "{{ hostvars[item]['aws_instance_id'] }}"
region: us-east-1
loop: "{{ groups['all'] }}"
loop_control:
loop_var: item
register: ec2_info
no_log: false
- name: Build a dictionary of EC2 instance details
set_fact:
ec2_host_data: >-
{{
ec2_host_data | combine({
ec2_result.instances[0].instance_id: {
'private_ip': ec2_result.instances[0].private_ip_address,
'private_dns_name': ec2_result.instances[0].private_dns_name,
'instance_type': ec2_result.instances[0].instance_type,
'availability_zone': ec2_result.instances[0].placement.availability_zone
}
})
}}
loop: "{{ ec2_info.results }}"
loop_control:
loop_var: ec2_result
no_log: false
- name: Add EC2 instances as inventory hosts
add_host:
name: "{{ item }}"
groups: dynamic_ec2_hosts
ansible_host: "{{ ec2_host_data[item].private_ip }}"
hostname: "{{ ec2_host_data[item].private_dns_name }}"
instance_id: "{{ item }}"
instance_type: "{{ ec2_host_data[item].instance_type }}"
availability_zone: "{{ ec2_host_data[item].availability_zone }}"
loop: "{{ ec2_host_data.keys() }}"
loop_control:
loop_var: item
- name: Debug updated hostvars
debug:
var: hostvars
The final debug print shows that hostname
is still empty:
[...]
"hostname": "",
"iam_instance_profile": "SomeRole",
[...]
"inventory_hostname": "DEV-QA_2",
[...]
Note: I've also tried to add a debug print for ansible facts
:
- name: Print all available facts
ansible.builtin.debug:
var: ansible_facts
but it shows as empty:
TASK [Print all available facts] ***********************************************************************************************************************************************
ok: [localhost] => {
"ansible_facts": {}
}
Upvotes: 0
Views: 52