1
votes

I am using Ansible to deploy to Amazon EC2, and I have ec2.py and ec2.ini set up such that I can retrieve a list of servers from Amazon. I have my server at AWS tagged rvmdocker:production, and ansible all --list returns my tag as ec2_tag_rvmdocker_production. I can also run:

ansible -m ping tag_rvmdocker_production`

and it works. But if I have that tag in a static inventory file, and run:

ansible all -m ping -i production

it returns:

tag_rvmdocker_production | UNREACHABLE! => {
    "changed": false, 
    "msg": "ERROR! SSH encountered an unknown error during the connection. Werecommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue", 
    "unreachable": true
}

Here is my production inventory file:

[dockerservers]
tag_rvmdocker_production

It looks like Ansible can't resolve tag_rvmdocker_production when it's in the static inventory file.

UPDATE

I followed ydaetskcoR's advice and am now getting a new error message:

$ ansible-playbook -i production app.yml 
ERROR! ERROR! production:2: Section [dockerservers:children] includes undefined group: tag_rvmdocker_production

But I know the tag exists, and it seems like Ansible and ec2.py know it:

$ ansible tag_rvmdocker_production --list
  hosts (1):
    12.34.56.78

Here is my production inventory:

[dockerservers:children]
tag_rvmdocker_production

And my app.yml playbook file:

---
- name: Deploy RVM app to production
  hosts: dockerservers
  remote_user: ec2-user
  become: true
  roles:
    - ec2
    - myapp

In the end, I'd love to be able to run the same playbook against development (a VM on my Mac), staging, or production, to start an environment. My thought was to have static inventory files that pointed to tags or groups on EC2. Am I even approaching this the right way?

2
What makes you think you can target instances by tag names in a static inventory file?ydaetskcoR
It looked in the docs like I could have a static inventory file with dynamic groups in it. I'm brand new to Ansible and EC2 though and have probably misunderstood it.David Ham
You've misunderstood. That example is showing 2 dynamic groups called tag_Name_staging_foo and tag_Name_staging_bar and then a static group called staging which contains both of the dynamic groups as children of the staging group. See here for an example of groups of groups outside of dynamic inventories.ydaetskcoR

2 Answers

2
votes

I had a similar issue to this, and resolved it as follows.

First, I created a folder to contain my inventory files, and put in there a symlink to my /etc/ec2.ini, a copy (or symlink) to the ec2.py script (with executable status), and a hosts file as follows.

$ ls amg-dev/*
amg-dev/ec2.ini -> /etc/ec2.ini
amg-dev/ec2.py
amg-dev/hosts

My EC2 instances are tagged with a Type = amg_dev_web

The hosts file contains the following information - the blank first entry is important here.

[tag_Type_amg_dev_web]

[webservers:children]
tag_Type_amg_dev_web

[all:children]
webservers

Then when I run ansible-playbook I specify the name of the folder only as the inventory which makes Ansible read the hosts file, and execute the ec2.py script to interrogate AWS.

ansible-playbook -i amg-dev/ playbook.yml

Inside my playbook, I refer to these as webservers as follows

- name: WEB | Install and configure relevant packages
  hosts: webservers
  roles:
    - common
    - web

Which seems to work as expected.

1
votes

As discussed in the comments, it looks like you've misunderstood the use of tags in a dynamic inventory.

The AWS EC2 dynamic inventory script allows you to target groups of servers by a tag key/value combination. So to target your web servers you may have a tag called Role that in this case is set to web which you would then target as a dynamic group with tag_Role_web.

You can also have static groups that contain children dynamic groups. This is much the same as how you use groups of groups normally in an inventory file that might be used like this:

[web-servers:children]
front-end-web-servers
php-web-servers

[front-end-web-servers]
www-web-1
www-web-2

[php-web-servers]
php-web-1
php-web-2

Which would allow you to generically target or set group variables for all of the web servers above simply by using the more generic web-servers group and then specifically configure the types of web servers using the more specific groups of either front-end-web-servers or php-web-servers.

However, if you put an entry under a group where it isn't defined as a child group then Ansible will assume that this is a host and will then attempt to connect to that host directly.

If you have a uniquely tagged instance that you are trying to reach via dynamic inventory then you simply use it as if it was a group (it just happens to currently only have one instance in it).

So if you want to target or set variables for the dockerservers group which then includes an instance that is tagged with the key-pair combination of rvmdocker: production then you would just do this:

[dockerservers:children]
tag_rvmdocker_production

[tag_rvmdocker_production]