# Iterating through a list of names to create EC2 instances

**URL:** <https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959>\
**Category:** Ansible Project\
**Created:** [November 21, 2013, 5:42pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959 "2013-11-21T17:42:31Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Renaud\_Guerin](https://avatars.discourse-cdn.com/v4/letter/r/e9bcb4/32.png) [@Renaud\_Guerin](https://forum.ansible.com/u/Renaud_Guerin)\
**Post date:** [November 21, 2013, 5:42pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/1 "2013-11-21T17:42:31Z")

</div>

Hello,

The EC2 module’s docs show how to create several instances at once using the “count” variable, and register the results into another variable (“ec2”).

You can then iterate on the created instances and do stuff (like add them to an inventory group) using “with\_items: ec2.instances”

However, I can’t figure out how to do the following :

1. Have the user provide a “names” list ( { “web1”, “web2”, “web3” } ). Or better yet, a naming prefix (“web”), a count (3) and a start index (1).
2. Create them using the ec2 module, register results into “ec2” to keep precious info like ec2.instances.public\_dns\_name.
3. Here’s the tricky bit : add a route53 DNS entry that CNAMEs together each entry in the “names” list with the public\_dns\_name values in “ec2.instances”.

I don’t believe with\_nested will help with 3) and you can’t walk through the 2 lists together side by side either by having several with\_items: statements, correct ?

Short of adding the feature to the ec2 module, how would you do that ?

Can you do something like :

- include add\_instance.yml  
with\_items: names

and then inside add\_instance.yml use the ec2 module with count=1 and create the DNS entries from there ?

Thanks !

---

<div class="post-metadata">

**Author:** ![tannerjc](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/tannerjc/32/985_2.png) [@tannerjc](https://forum.ansible.com/u/tannerjc)\
**Post date:** [November 21, 2013, 6:47pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/2 "2013-11-21T18:47:40Z")

</div>

> Hello,
> 
> The EC2 module's docs show how to create several instances at once using the "count" variable, and register the results into another variable ("ec2").
> 
> You can then iterate on the created instances and do stuff (like add them to an inventory group) using "with\_items: ec2.instances"
> 
> However, I can't figure out how to do the following :
> 
> 1) Have the user provide a "names" list ( { "web1", "web2", "web3" } ). Or better yet, a naming prefix ("web"), a count (3) and a start index (1).  
> 2) Create them using the ec2 module, register results into "ec2" to keep precious info like ec2.instances.public\_dns\_name.  
> 3) Here's the tricky bit : add a route53 DNS entry that CNAMEs together each entry in the "names" list with the public\_dns\_name values in "ec2.instances".

Can you give an example for what you are trying to convey here? I'm a bit confused.

---

<div class="post-metadata">

**Author:** ![Renaud\_Guerin](https://avatars.discourse-cdn.com/v4/letter/r/e9bcb4/32.png) [@Renaud\_Guerin](https://forum.ansible.com/u/Renaud_Guerin)\
**Post date:** [November 21, 2013, 7:14pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/3 "2013-11-21T19:14:49Z")

</div>

Thanks for replying James,

I’m trying to create a fleet of (for instance) web servers on EC2, and would like to give them meaningful ansible hostnames (web1, web2, etc) instead of the AWS generated public DNS names ([ec2-xxxxx.compute-1.amazonaws.com](http://ec2-xxxxx.compute-1.amazonaws.com))

I’d also like to create a CNAME DNS record (using the route53 module) pointing their chosen name (web1, web2, etc) to the EC2 DNS record ([ec2-xxxxx.compute-1.amazonaws.com](http://ec2-xxxxx.compute-1.amazonaws.com)). The latter is accessible in the « instances.public\_dns\_name »

Ideally, I would just need to provide the ec2 module with a list of hostnames for the instances it’s going to create (internally it just needs to set the « Name » EC2 tag), and I’d get back the « item.hostname » (web1,web2) alongside each « item.public\_dns\_name » ([ec2-xxxxx.compute-1.amazonaws.com](http://ec2-xxxxx.compute-1.amazonaws.com)) when using “with\_items: ec2”

The more I think of it, the more it sounds like just a few changes are needed in the ec2 module. I can try and have a go at it, but I’d like to know if there’s something similar already.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [November 23, 2013, 4:38pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/4 "2013-11-23T16:38:22Z")

</div>

[http://ansibleworks.com/docs/modules.html#route53](http://ansibleworks.com/docs/modules.html#route53)

---

<div class="post-metadata">

**Author:** ![Renaud\_Guerin](https://avatars.discourse-cdn.com/v4/letter/r/e9bcb4/32.png) [@Renaud\_Guerin](https://forum.ansible.com/u/Renaud_Guerin)\
**Post date:** [November 23, 2013, 4:55pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/5 "2013-11-23T16:55:34Z")

</div>

Thanks Michael,

I know (and mentioned) I’ll need to use the route53 module, that’s not the difficulty here.  
I did some more research and it looks like ‘with\_together’ is what I was looking for.

If anyone is looking to do the same (it’s a quite common provisioning pattern) :

- provide an « instances\_names » list
- create the required number of instances using the ec2 module, register the result.
- Use ec2\_tag, add\_host and route53 for, respectively: setting the AWS Name tag, adding the host to the inventory with its desired hostname (not the default EC2 name), adding a CNAME DNS entry for hostname → EC2 public\_dns\_name  
-For each of the modules above, use « with\_together » to iterate through both the created instances list (returned by the EC2 module), and the hostnames list you provided.

This would be slightly easier if the ec2 module would take an optional « instances\_names » list as a parameter; and used it to set different EC2 Name tags for each of the created instances.  
I can look at adding this functionality if it’s likely to be accepted and merged in. What do you think ?

---

<div class="post-metadata">

**Author:** ![Peter\_Sankauskas](https://avatars.discourse-cdn.com/v4/letter/p/ea666f/32.png) [@Peter\_Sankauskas](https://forum.ansible.com/u/Peter_Sankauskas)\
**Post date:** [November 24, 2013, 6:34pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/6 "2013-11-24T18:34:39Z")

</div>

Hi Renaud,

People that have been using AWS for a while don’t really use it this way, or at least, they shouldn’t. Treat servers like cattle, not pets.

If you haven’t yet, take a look at AutoScaling Groups:

> [http://aws.amazon.com/autoscaling/](http://aws.amazon.com/autoscaling/)

… and think about how to architect your application to run on dynamic infrastructure.

---

<div class="post-metadata">

**Author:** ![Peter\_Sankauskas](https://avatars.discourse-cdn.com/v4/letter/p/ea666f/32.png) [@Peter\_Sankauskas](https://forum.ansible.com/u/Peter_Sankauskas)\
**Post date:** [November 25, 2013, 9:24pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/7 "2013-11-25T21:24:51Z")

</div>

Just to belabor the point:

[https://www.youtube.com/watch?v=lQUdjPBJX5c](https://www.youtube.com/watch?v=lQUdjPBJX5c)

---

<div class="post-metadata">

**Author:** ![Renaud\_Guerin](https://avatars.discourse-cdn.com/v4/letter/r/e9bcb4/32.png) [@Renaud\_Guerin](https://forum.ansible.com/u/Renaud_Guerin)\
**Post date:** [November 27, 2013, 2:48pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/8 "2013-11-27T14:48:35Z")

</div>

Hi Peter,

Very interesting talk and this is probably the better approach, thanks.

You do need to address individual servers from time to time though : ssh’ing into them to debug something, for instance.

In this case, finding and copying the public\_dns\_name for a box sounds like a pain, and a big usability regression from a human-readable naming convention and DNS CNAMEs.

Am I missing a clever way to use ansible to provide « vagrant ssh » functionality basically ?  
Or do you know of any wrapper tools to do something similar ?

---

<div class="post-metadata">

**Author:** ![Peter\_Sankauskas](https://avatars.discourse-cdn.com/v4/letter/p/ea666f/32.png) [@Peter\_Sankauskas](https://forum.ansible.com/u/Peter_Sankauskas)\
**Post date:** [November 27, 2013, 4:38pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/9 "2013-11-27T16:38:21Z")

</div>

Actually yes. You can tag AWS resources and find them using tags. For example, an Amazon Linux instance with tag Name=foo could be SSHed into using

> ansible-ec2 ssh --name foo -u ec2-user

You can find the code here:

> [https://github.com/pas256/ansible-ec2](https://github.com/pas256/ansible-ec2)

It uses Ansible’s EC2 inventory plugin to do the lookup of public DNS name (or whatever you configure it to).

One further tip. In a distributed environment, debugging can be tough because you don’t know which server is causing issues. Get all of the logging out of the instances and into some central and searchable location. There are plenty of SaaS providers (Loggly, Splunk, Sumologic, Papertrail) and open source (logstash, etc) options available.

---

<div class="post-metadata">

**Author:** ![Renaud\_Guerin](https://avatars.discourse-cdn.com/v4/letter/r/e9bcb4/32.png) [@Renaud\_Guerin](https://forum.ansible.com/u/Renaud_Guerin)\
**Post date:** [November 27, 2013, 5:36pm UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/10 "2013-11-27T17:36:12Z")

</div>

Nice tool !

But your ssh example shows how a unique name is still unavoidable sometimes, be it Tags or DNS based.

If I left instances with their EC2 birth names, I couldn’t just make up « ansible-ec2 ssh --name web1 » when I need to log into a web server, I’d have to « ansible-ec2 list » first with a raw group name to find web servers, then pick one and ssh into it.

Also, some tools just rely on a nice hostname being set (the New Relic server dashboard would be unreadable with ec2-xxxx host names all mixed up)  
RabbitMQ for instance, names its task queues after the current hostname and warns against changing it. I know it’s bad practice and not autoscaling friendly, but it’s just how it is in some occasions.

So, I’ll forget about CNAMEs in Route53 but I think my original feature request is still relevant : being able to pass a list of names to the EC2 module to be added to the Name tag of each created instance.  
If I submitted such a patch, would you guys merge it ?

---

<div class="post-metadata">

**Author:** ![Peter\_Sankauskas](https://avatars.discourse-cdn.com/v4/letter/p/ea666f/32.png) [@Peter\_Sankauskas](https://forum.ansible.com/u/Peter_Sankauskas)\
**Post date:** [November 29, 2013, 12:08am UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/11 "2013-11-29T00:08:52Z")

</div>

One more example to clear up uniqueness:

3 instances tagged Name=foo, SSH into 2nd instance:

> ansible-ec2 ssh --name foo -u ec2-user -n 2

(sorted by public DNS name, I think)

---

<div class="post-metadata">

**Author:** ![vaida.dan](https://avatars.discourse-cdn.com/v4/letter/v/5daacb/32.png) [@vaida.dan](https://forum.ansible.com/u/vaida.dan)\
**Post date:** [June 23, 2014, 11:05am UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/12 "2014-06-23T11:05:21Z")

</div>

Hello,

What about adding an EIP to the instance(s)?

Because that changes the game completely making the registered ec2 instances info outdated (at least the IP-related one).

How about cycling through Route53 with those EIPs? Has anyone done that successfully? Don’t want to hijack this thread, but I find this rather relevant.

I know some would indicate the ec2\_facts module, registering the output from ec2\_eip or using the add\_host module but I couldn’t do it in any way so even a pseudo-code would be appreciated.

Thanks !

---

<div class="post-metadata">

**Author:** ![Sankalp\_Khare](https://avatars.discourse-cdn.com/v4/letter/s/f1d935/32.png) [@Sankalp\_Khare](https://forum.ansible.com/u/Sankalp_Khare)\
**Post date:** [October 29, 2014, 9:02am UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/13 "2014-10-29T09:02:19Z")

</div>

Hi Renaud,

I totally get what you are looking to achieve. Perhaps you’ve achieved it already in the past year. Assuming that you are happy with specifying a start index = x and a count = N to produce machines with names containing x, x+1, x+2, … x+N, I think the following playbook example will be instructive. I had the same requirement and this is what I was able to produce:

`

# ansible-playbook create-web.yml --extra-vars “count=n startindex=x env=production”

# provisions n web servers in prod env with indices x, x+1, x+2, … x+n

---

<div class="post-metadata">

**Author:** ![Sankalp\_Khare](https://avatars.discourse-cdn.com/v4/letter/s/f1d935/32.png) [@Sankalp\_Khare](https://forum.ansible.com/u/Sankalp_Khare)\
**Post date:** [October 29, 2014, 9:06am UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/14 "2014-10-29T09:06:11Z")

</div>

I must also add that I’ve got a central group\_vars/all file from which I pull all the variables like region, instance types, environment specific load balancer names, etc.

---

<div class="post-metadata">

**Author:** ![gabriel.laden](https://avatars.discourse-cdn.com/v4/letter/g/e47774/32.png) [@gabriel.laden](https://forum.ansible.com/u/gabriel.laden)\
**Post date:** [September 1, 2016, 12:03am UTC](https://forum.ansible.com/t/iterating-through-a-list-of-names-to-create-ec2-instances/13959/15 "2016-09-01T00:03:32Z")

</div>

Thank you very much for answering the question.

Gabriel
