# Ansible EC2 dynamic inventory

One of the steps of creating and testing Ansible roles is verifying that the role does what it was intended to do in real EC2 instances. 

To automate this workflow I usually launch 5 instances (`centOS 7`, `centOS 8`, `Ubuntu 18`, and `Ubuntu 20`) using python and boto3. 


### LAUNCH EC2

Here is a snippet of my script, you can find the complete script [here](https://gist.github.com/libert-xyz/e7e60c04f695ad9ca77de5ff61359bc2)

The script adds the tags `env: ansible` and `distro: AMI['distro']` to the instances. This comes handy for grouping the Ansible dynamic inventories

```
    instances = ec2.create_instances(
        ImageId = AMIS[i]["ami"],
        MinCount = 1,
        MaxCount = 1,
        InstanceType = 't3.micro',
        KeyName = KEY,
        SecurityGroupIds=[SG],
        SubnetId=SUBNET,
        TagSpecifications=[
            {
                'ResourceType': 'instance',
                'Tags': [
                    {
                        'Key': 'Name',
                        'Value': AMIS[i]["os"]
                    },
                    {
                        'Key' : 'env',
                        'Value': 'ansible'
                    },
                                        {
                        'Key' : 'distro',
                        'Value': AMIS[i]["distro"]
                    }
                ]
            }
        ]
    )
```


### DYNAMIC INVENTORY

Once the instances are running, instead of updating the `inventory` file manually, we can use the Ansible `plugin: aws_ec2` to make our inventory dynamic.

Here you can see the inventory file that groups our EC2 instances by their tags, in this case, `distro`.

The name of the file is important and needs to be `inventory_aws_ec2.yml`

```
plugin: aws_ec2
boto_profile: default
regions:
  - us-east-1
filters:
  tag:env:
    - ansible
keyed_groups:
  - key: tags.distro
    separator: ''

hostnames:
  - network-interface.association.public-ip

```
### OUTPUT

Notice that the output groups the distribution name with the public IP address assigned to the EC2 instance.

You can use this command to list the dynamic inventory:

`ansible-inventory -i inventory_aws_ec2.yml --list`

The output is going to look something like this:

```
{
    "aws_ec2": {
        "hosts": [
            "18.232.x.x",
            "34.228.x.x",
            "34.230.x.x",
            "54.226.x.x",
        ]
    },
    "centos": {
        "hosts": [
            "18.232.x.x",
            "34.228.x.x"
        ]
    },
    "ubuntu": {
        "hosts": [
            "54.226.x.x",
            "54.234.x.x"
        ]
    }
}

```


### RUN THE PLAYBOOK

And finally, you can run your playbook using the dynamic inventory:

`ansible-playbook -u ubuntu play.yml`


```
---
- hosts: ubuntu
  become: true
  roles:
    - ansible-role-update

```

Don't forget to terminate your instances after testing.




 
