Is there a way to get the OS from AWS?

Hi all -

I’m trying to gather facts from an ec2 instance. Specially, the operating system release (i.e. /etc/redhat-release). I can gather the info from local VMs, but Ansible doesn’t seem to return the OS when I gather facts from an EC2 instance. I tried the ec2_instance_facts module (https://docs.ansible.com/ansible/latest/modules/ec2_instance_facts_module.html#ec2-instance-facts-module), but that doesn’t seem to return it (at least, it doesn’t return it for the Amazon Linux distro).

Does anyone have any idea how to gather this info from ec2 instances? Is it just a limitation with Amazon Linux? If so, then I can hardcode values if I have a way of knowing it’s Amazon Linux, but I can’t seem to figure out a way to find that out either.

Here’s a sample of when I pulled the facts from the instance:

“item”: {
“ami_launch_index”: 0,
“architecture”: “x86_64”,
“block_device_mappings”: [
{
“device_name”: “/dev/xvda”,
“ebs”: {
“attach_time”: “2019-05-21T17:34:55+00:00”,
“delete_on_termination”: true,
“status”: “attached”,
“volume_id”: “xxx”
}
}
],
“client_token”: “”,
“ebs_optimized”: false,
“ena_support”: true,
“hypervisor”: “xen”,
“image_id”: “ami-02c6024b3d5467e4a”,
“instance_id”: “xxx”,
“instance_type”: “r5d.2xlarge”,
“key_name”: “xxx”,
“launch_time”: “2019-05-21T17:34:55+00:00”,
“monitoring”: {
“state”: “disabled”
},
“network_interfaces”: [
{
“attachment”: {
“attach_time”: “2019-05-21T17:34:55+00:00”,
“attachment_id”: “xxx”,
“delete_on_termination”: true,
“device_index”: 0,
“status”: “attached”
},
“description”: “”,
“groups”: [
{
“group_id”: “xxx”,
“group_name”: “xxx”
}
],
“ipv6_addresses”: ,
“mac_address”: “xxx”,
“network_interface_id”: “xxx”,
“owner_id”: “xxx”,
“private_dns_name”: “xxx”,
“private_ip_address”: “xxx”,
“private_ip_addresses”: [
{
“primary”: true,
“private_dns_name”: “xxx”,
“private_ip_address”: “xxx”
}
],
“source_dest_check”: true,
“status”: “in-use”,
“subnet_id”: “xxx”,
“vpc_id”: “xxx”
}
],
“placement”: {
“availability_zone”: “us-east-1a”,
“group_name”: “”,
“tenancy”: “default”
},
“private_dns_name”: “xxx”,
“private_ip_address”: “xxx”,
“product_codes”: ,
“public_dns_name”: “”,
“root_device_name”: “/dev/xvda”,
“root_device_type”: “ebs”,
“security_groups”: [
{
“group_id”: “xxx”,
“group_name”: “xxx”
}
],
“source_dest_check”: true,
“state”: {
“code”: 16,
“name”: “running”
},
“state_transition_reason”: “”,
“subnet_id”: “xxx”,
“tags”: {
“Name”: “xxx”,
“class”: “xxx”
},
“virtualization_type”: “hvm”,
“vpc_id”: “xxx”
}

I don't think it's possible to reliably get that information if you
don't access the VM itself.
The closest thing is the AMI id, from which you can peel some more
information using ec2_ami_facts.
But it's all guestimation.
However, if you use a limited set of (possibly self generated) AMIs,
then you can declare which is which.

If you are able to access the hosts, and need reliable info, then go
that route I'd say.
Also, *IF* you go this route, I'd suggest to not manually parse
/etc/redhat-release to determine release/distros/versions, but use the
existing ansible logic from the setup module.

Dick

Thanks, Dick.

You’re right. You definitely need to access the system. I created a way to print the info from the system using the setup module. It seems to work well:

- name: Collect setup facts
  setup:
    gather_subset:
      - all
  with_items:
    - "{{ec2.results[0].instances}}"
  delegate_to: '{{ item.private_ip_address }}'
  register: ansible_setupfacts

what is trying to achive ? only one ec2 instance detail or multiple?

Hi Kashish -

I’m trying to iterate over multiple systems & then use when conditions to decide which tasks to use. See my reply to Dick above for a solution I found.