Using registered variables and ec2 with_items

461 views
Skip to first unread message

Tim Van de Walle

unread,
Sep 5, 2014, 9:33:37 PM9/5/14
to ansible...@googlegroups.com
I have a role that launches ec2 instances, registers them in a group and waits for the ssh port to respond before continuing on in provisioning. The play works as expected, however for reliability reasons we have to launch instances in more than one availability zone. This requires executing the ec2 module multiple times with different definitions. We can't use count to launch multiple instances. The standard task for the role is listed below (this only launches one instance definition at a time):

- name: Launch image(s)
  local_action
:
   
module: ec2
    region
: "{{item.ec2_region}}"
    zone
: "{{item.ec2_zone}}"
    instance_type
: "{{item.ec2_instance_type}}"
    image
: "{{item.ec2_image}}"
    key_name
: "{{item.ec2_keypair}}"
    exact_count
: "{{item.ec2_exact_count}}"
   
group: "{{item.ec2_security_groups}}"
    instance_tags
: "{{item.ec2_tags}}"
    count_tag
: "{{item.ec2_tags}}"
    vpc_subnet_id
: "{{item.ec2_vpc_subnet_id}}"
    instance_profile_name
: "{{item.ec2_instance_profile_name}}"
    wait
: true
 
register: ec2

- name: Add new servers to group for configuration
  local_action
: add_host hostname={{item.public_dns_name}} groupname={{ec2_groupname}}
  with_items
: ec2.instances
 
when: ec2.changed


- name: Wait for the instances to boot by checking the ssh port
  local_action
: wait_for host={{item.public_dns_name}} port=22 delay=60 timeout=320 state=started
  with_items
: ec2.instances
 
when: ec2.changed


To simplify the calling playbook I decided to pass in a list of ec2 definitions and use with_items to launch them. The launching of the instances works fine, but I can't seem to find the right way to use the registered result. The playbook and a slightly edited version of the registered result is listed below. I need to be able to loop through the instances in the results list, but it doesn't seem like the looping constructs work in this situation. Anybody run into this kind of pattern and solve it in a different way? I feel like maybe I'm just coming at it from the wrong direction.

- name: Launch image(s)
  local_action
:
   
module: ec2
    region
: "{{item.ec2_region}}"
    zone
: "{{item.ec2_zone}}"
    instance_type
: "{{item.ec2_instance_type}}"
    image
: "{{item.ec2_image}}"
    key_name
: "{{item.ec2_keypair}}"
    exact_count
: "{{item.ec2_exact_count}}"
   
group: "{{item.ec2_security_groups}}"
    instance_tags
: "{{item.ec2_tags}}"
    count_tag
: "{{item.ec2_tags}}"
    vpc_subnet_id
: "{{item.ec2_vpc_subnet_id}}"
    instance_profile_name
: "{{item.ec2_instance_profile_name}}"
    wait
: true
 
register: ec2
  with_items
: ec2_defs

The registered result looks like this:

ok: [localhost] => {
   
"ec2": {
       
"changed": true,
       
"msg": "All items completed",
       
"results": [
           
{
               
"changed": true,
               
"instance_ids": [
                   
"i-85170f6a"
               
],
               
"instances": [
                   
{
                       
"ami_launch_index": "0",
                       
"architecture": "x86_64",
                       
"ebs_optimized": false,
                       
"hypervisor": "xen",
                   
}
               
],
               
]
           
},
           
{
               
"changed": true,
               
"instance_ids": [
                   
"i-9c18cf77"
               
],
               
"instances": [
                   
{
                       
"ami_launch_index": "0",
                       
"architecture": "x86_64",
                       
"ebs_optimized": false,
                       
"hypervisor": "xen",
                   
}
               
],
               
]
           
}
       
]
   
}

Thanks.

Tim


Michael DeHaan

unread,
Sep 6, 2014, 9:57:24 AM9/6/14
to ansible...@googlegroups.com
"The launching of the instances works fine, but I can't seem to find the right way to use the registered result. "

Looks like there are two arrays here:

 ec2.results[0].instances
 and
 ec2.results[1].instances

So, trivially, you could wait like this:

- name: Wait for the instances to boot by checking the ssh port
  local_action
: wait_for host={{item.public_dns_name}} port=22 delay=60 timeout=320 state=
started
  with_items
: ec2.results.0.instances

- name: Wait for the instances to boot by checking the ssh port
  local_action
: wait_for host={{item.public_dns_name}} port=22 delay=60 timeout=320 state=
started
  with_items
: ec2.results.1.instances

Which I realize isn't perfect, but it's ok-ish.

An alternative might be to write a role that launches instances into an AZ, and invoke that role twice.

 


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
To post to this group, send email to ansible...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ansible-project/e74d2d54-43c0-4c85-8d46-4dfe3d40ab66%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Weiyi Yang

unread,
Apr 10, 2015, 2:12:17 PM4/10/15
to ansible...@googlegroups.com
Use this if  you only spin up 1 instance in each step of your loop.


- local_action: wait_for port=22 host="{{ item.instances[0].private_ip }}" search_regex=OpenSSH delay=10
  with_items: "{{ ec2.results }}"

Weiyi Yang

unread,
Apr 10, 2015, 2:12:27 PM4/10/15
to ansible...@googlegroups.com
If you can limit your instance count to 1 at each of your loop step, you can use this one:

local_action: wait_for port=22 host="{{ item.instances[0].private_ip }}" search_regex=OpenSSH delay=10  with_items: "{{ ec2.results }}"
  with_items: "{{ ec2.results }}"


On Friday, September 5, 2014 at 6:33:37 PM UTC-7, Tim Van de Walle wrote:

Pavel Georgiev

unread,
Apr 23, 2015, 6:08:34 PM4/23/15
to ansible...@googlegroups.com
I have the same issue, need to instantiate multiple instances in different configuration, possibly more than one instance per configuration. Provisioning the instances works file but I don't know how to iterate over the result which is an array of hashes and I need to iterate over var[x].instances.

Is this possible with ansible?

On Friday, September 5, 2014 at 6:33:37 PM UTC-7, Tim Van de Walle wrote:
Reply all
Reply to author
Forward
0 new messages