Question: with_sequence and registered variables not having anticipated outcome

I have a playbook that creates an ec2 instance and from that creation I want to register the output as a var. From there I would use the registered var to create and attach an ebs volume. However I’m running into the following error.

 - name: Create EC2 instance for zone A
   ec2:
    key_name: "{{ keypair }}"
    group: "{{ security_groups }}"
    image: "{{ ami }}"
    instance_type: "{{ instance_type }}"
    wait: true
    region: "{{ ec2_region }}"
    vpc_subnet_id: "{{ subneta }}"
    assign_public_ip: "{{ public_choice }}"
    zone: "{{ zonea }}"
    count: 1
    instance_tags:
      Name: "db{{ item }}a.{{ env }}"
      envtype: "{{ envtype }}"
   register: ec2
   with_sequence: "start=1 end={{ num }}"

 - debug:
    msg: "{{ ec2 }}"
 - debug:
    msg: "{{ ec2.instance_ids }}"

With this I get the following output

dumbledore@ansible1a:/etc/ansible/roles/db_ec2/tasks > ansible-playbook db_ec2.yml -e 'env=qa num=1 ebs=true'
 ______
< PLAY >
 ------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                >>----w |
                >>     >>

 ______________________
< TASK [db_ec2 : fail] >
 ----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                >>----w |
                >>     >>

 _______________________
< TASK [db_ec2 : debug] >
 -----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                >>----w |
                >>     >>

ok: [localhost] => {
    "msg": "If you need to change any default variables for this playbook edit vars/qa.yml and vars/ebs.yml for ebs configs"
}
 _________________________
< TASK [db_ec2 : include] >
 -------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                >>----w |
                >>     >>

included: /etc/ansible/roles/db_ec2/tasks/./db_create.yml for localhost
 ________________________________________________
< TASK [db_ec2 : Create EC2 instance for zone A] >
 ------------------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                >>----w |
                >>     >>

changed: [localhost] => (item=1)
 _______________________
< TASK [db_ec2 : debug] >
 -----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                >>----w |
                >>     >>

ok: [localhost] => {
    "msg": {
        "changed": true,
        "msg": "All items completed",
        "results": [
            {
                "_ansible_no_log": false,
                "changed": true,
                "instance_ids": [
                    "i-1046c108"
                ],
                "instances": [
                    {
                        "ami_launch_index": "0",
                        "architecture": "x86_64",
                        "block_device_mapping": {
                            "/dev/sda1": {
                                "delete_on_termination": true,
                                "status": "attached",
                                "volume_id": "vol-55812edd"
                            }
                        },
                        "dns_name": "",
                        "ebs_optimized": false,
                        "groups": {
                            "sg-749f3c0d": "qa-ssh",
                            "sg-8f983bf6": "qa-db"
                        },
                        "hypervisor": "xen",
                        "id": "i-1046c108",
                        "image_id": "ami-55e31a35",
                        "instance_type": "m4.xlarge",
                        "kernel": null,
                        "key_name": "ccpkey",
                        "launch_time": "2016-09-28T00:28:00.000Z",
                        "placement": "us-west-2a",
                        "private_dns_name": "ip-10-50-36-201.us-west-2.compute.internal",
                        "private_ip": "10.50.36.201",
                        "public_dns_name": "",
                        "public_ip": null,
                        "ramdisk": null,
                        "region": "us-west-2",
                        "root_device_name": "/dev/sda1",
                        "root_device_type": "ebs",
                        "state": "running",
                        "state_code": 16,
                        "tags": {
                            "Name": "db1a.qa",
                            "envtype": "qa-db"
                        },
                        "tenancy": "default",
                        "virtualization_type": "hvm"
                    }
                ],
                "invocation": {
                    "module_args": {
                        "assign_public_ip": false,
                        "aws_access_key": null,
                        "aws_secret_key": null,
                        "count": 1,
                        "count_tag": null,
                        "ebs_optimized": false,
                        "ec2_url": null,
                        "exact_count": null,
                        "group": [
                            "qa-db",
                            "qa-ssh"
                        ],
                        "group_id": null,
                        "id": null,
                        "image": "ami-55e31a35",
                        "instance_ids": null,
                        "instance_profile_name": null,
                        "instance_tags": {
                            "Name": "db1a.qa",
                            "envtype": "qa-db"
                        },
                        "instance_type": "m4.xlarge",
                        "kernel": null,
                        "key_name": "ccpkey",
                        "monitoring": false,
                        "network_interfaces": null,
                        "placement_group": null,
                        "private_ip": null,
                        "profile": null,
                        "ramdisk": null,
                        "region": "us-west-2",
                        "security_token": null,
                        "source_dest_check": true,
                        "spot_price": null,
                        "spot_type": "one-time",
                        "spot_wait_timeout": 600,
                        "state": "present",
                        "tenancy": "default",
                        "termination_protection": false,
                        "user_data": null,
                        "validate_certs": true,
                        "volumes": null,
                        "vpc_subnet_id": "subnet-5d625c39",
                        "wait": true,
                        "wait_timeout": 300,
                        "zone": "us-west-2a"
                    },
                    "module_name": "ec2"
                },
                "item": "1",
                "tagged_instances": []
            }
        ]
    }
}
 _______________________
< TASK [db_ec2 : debug] >
 -----------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                >>----w |
                >>     >>

fatal: [localhost]: FAILED! => {"failed": true, "msg": "'dict object' has no attribute 'instance_ids'"}
 ____________
< PLAY RECAP >
 ------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                >>----w |
                >>     >>

localhost                  : ok=4    changed=1    unreachable=0    failed=1

So I can see that the variable that should exist does in the output of the full ec2 variable. But when trying to use the key specific variable of ec2.instance_ids it fails…

<snip>

- name: Create EC2 instance for zone A
   ec2:
    key_name: "{{ keypair }}"
    group: "{{ security_groups }}"
    image: "{{ ami }}"
    instance_type: "{{ instance_type }}"
    wait: true
    region: "{{ ec2_region }}"
    vpc_subnet_id: "{{ subneta }}"
    assign_public_ip: "{{ public_choice }}"
    zone: "{{ zonea }}"
    count: 1
    instance_tags:
      Name: "db{{ item }}a.{{ env }}"
      envtype: "{{ envtype }}"
   register: ec2
   with_sequence: "start=1 end={{ num }}"

Remember that all the with_ is a loop, and the register is a little different as described here
https://docs.ansible.com/ansible/playbooks_loops.html#using-register-with-a-loop

The result is stored in a list ec2.results

<snip>

ok: [localhost] => {
    "msg": {
        "changed": true,
        "msg": "All items completed",
        "results": [

Here you can see the results list.

<snip>

So I can see that the variable that should exist does in the output of the
full ec2 variable. But when trying to use the key specific variable of
ec2.instance_ids it fails...

The correct entry would be ec2.results[0].instance_ids for the first iteration of the loop and for the second iteration ec2.results[1].instance_ids and so on.

OK that makes total sense.

Follow up question, what is the syntax in ansible to iterate over every entry in the array.

So for individual results you do ec2.results[0].instance_ids.

What do you do for all results or to loop over this to get every instance id from multiple entries.

like ec2.results[i].instance_ids or something?

- debug: var=item.instance_ids
   with_items: "{{ ec2.results }}"

That’s what I thought but I get an error when trying to pass it to an ebs volume attachment.

  • name: Create and attach ec2 volume
    ec2_vol:
    instance: “{{ item.instance_ids }}”
    volume_size: “{{ volume_size }}”
    volume_type: “{{ volume_type }}”
    device_name: “/dev/xvd{{ drive }}”
    region: us-west-2
    with_items: “{{ ec2a.results }}”
    when: ebs is defined

dumbledore@ansible1a:/etc/ansible > ansible-playbook /etc/ansible/playbooks/db_ec2.yml -e ‘env=qa num=1 ebs=true’

That's what I thought but I get an error when trying to pass it to an ebs
volume attachment.
- name: Create and attach ec2 volume
   ec2_vol:
    instance: "{{ item.instance_ids }}"

I have no knowledge about ec2_vol but can instance: be a list?

    volume_size: "{{ volume_size }}"
    volume_type: "{{ volume_type }}"
    device_name: "/dev/xvd{{ drive }}"
    region: us-west-2
   with_items: "{{ ec2a.results }}"
   when: ebs is defined

<snip>

u'group_id': None, u'validate_certs': True}}}) => {
    "item": {
        "changed": true,
        "instance_ids": [
            "i-3a0e8822"
        ],

Here you see that item.instance_ids is a list.

<snip>

"tagged_instances": }, "msg": "Invalid id: \"['i-3a0e8822']\""}

Tells me invalid ID. I have wait set to wait for the instance to be
running.

I guess instance: can't be a list, if so you can get the first item in the list by using item.instance[0].