Populate list from results (list)

I’m using the ec2_remote_facts module to get a list of instances based on filters.

I want to create another list that contains the ec2_facts.instances[0-n].private_ip

This is the logic I’m after

  • name: Set server names address for webapp proxy server
    set_fact:
    servers[item]: “{{ ec2_facts.instances[item].private_ip_address }}”
    with_sequence: “start=0 end={{ ec2_facts.instances|(length -1) }}”

but it doesn’t work

“msg”: “ERROR! ‘list object’ has no attribute u’0’”

I can manually set each fact

  • name: Set server names address for webapp proxy server
    set_fact:
    servers: [“{{ ec2_facts.instances[0].private_ip_address }}”, “{{ ec2_facts.instances[1].private_ip_address }}” ]

But this is not optimal as it doesn’t work for variable length lists.

I think you can do this using the map filter

something like (untested)

  • name: Set server names address for webapp proxy server
    set_fact:
    servers: “{{ ec2_facts.instances|map(‘private_ip_address’)|list }}”

Have a look at: http://jinja.pocoo.org/docs/dev/templates/#map

HTH

Jon

Hi Jon,

That helped, I needed to specific attribute=‘private_ip_address’ for a map() arguments and was able to find some more documentation here, http://docs.ansible.com/ansible/playbooks_filters.html#other-useful-filters

I’m now trying to break out subnet ids from subnet_facts

  • name: Get subnets
    ec2_vpc_subnet_facts:
    aws_access_key: “{{ aws_access_key }}”
    aws_secret_key: “{{ aws_secret_key }}”
    region: “{{ aws_region }}”
    security_token: “{{ security_token }}”
    filters:
    vpc-id: “{{ returned_vpc.vpcs[0].id }}”
    “tag:Name”: “{{ item }}”
    register: subnetDMZ_facts
    with_items:
  • “{{ DMZ_subnet1 }}”
  • “{{ DMZ_subnet2 }}”
  • “{{ DMZ_subnet3 }}”

I get a data structure like this

ok: [localhost] => {
“subnetDMZ_facts.results”: [
{
“_ansible_no_log”: false,
“changed”: false,
“invocation”: {
“module_args”: {
“aws_access_key”: “XXXXX”,
“aws_secret_key”: “VALUE_SPECIFIED_IN_NO_LOG_PARAMETER”,
“ec2_url”: null,
“filters”: {
“tag:Name”: “SubDMZ1”,
“vpc-id”: “vpc-XXXXXXXX”
},
“profile”: null,
“region”: “us-west-2”,
“security_token”: “VALUE_SPECIFIED_IN_NO_LOG_PARAMETER”,
“validate_certs”: true
},
“module_name”: “ec2_vpc_subnet_facts”
},
“item”: “SubDMZ1”,
“subnets”: [
{
“availability_zone”: “us-west-2a”,
“available_ip_address_count”: 57,
“cidr_block”: “10.201.0.0/26”,
“default_for_az”: “false”,
“id”: “subnet-XXXXXXX”,
“map_public_ip_on_launch”: “false”,
“state”: “available”,
“tags”: {
“Name”: “SubDMZ1”
},

“vpc_id”: “vpc-XXXXXXX”
}
]
},
{…

Subnets is a list. I was previously manually setting each subnet_id value manually via
subnet_ids: [‘{{ subnetDMZ_facts.results[0].subnets[0].id }}’, ‘{{ subnetDMZ_facts.results[1].subnets[0].id }}’, ‘{{ subnetDMZ_facts.results[1].subnets[0].id }}’ ]

I tried using the subnet[0].id as the attribute
subnets_map: “{{ subnetDMZ_facts.results|map(attribute=‘subnets[0].id’)|list }}”

fatal: [localhost]: FAILED! => {“failed”: true, “msg”: “ERROR! ‘dict object’ has no attribute ‘subnets[0]’”}

I can access other vales, just not list items, e.g.
subnets_map: “{{ subnetDMZ_facts.results|map(attribute=‘invocation.module_args.aws_access_key’)|list }}”

TIA

This works

subnets_map: “{{ subnetDMZ_facts.results|map(attribute=‘subnets.0.id’)|list }}”