DEV Community

Cover image for Ansible AWS EC2 Dynamic Inventory Plugin
🚀  Vu Dao 🚀
🚀 Vu Dao 🚀

Posted on • Updated on

Ansible AWS EC2 Dynamic Inventory Plugin

  • Ansible can pull inventory information from dynamic sources by various dynamic inventory plugins.
  • One of them is the aws_ec2 plugin, a great way to manage AWS EC2 Linux instances without having to maintain a standard local inventory.

Here is just a quick example of how to use it.

1. Install aws_ec2 ansible plugin
amazon.aws.aws_ec2 – EC2 inventory source
Note: Uses a YAML configuration file that ends with aws_ec2.(yml|yaml)

2. Setup ansible.cfg

[defaults]
enable_plugins = aws_ec2
host_key_checking = False
pipelining = True
remote_user = ec2-user
private_key_file=/pem/key-pem
Enter fullscreen mode Exit fullscreen mode

3. Create inventory my_aws_ec2.yml file to group target
Filter here is tag:name and state of the instance (running)

---
plugin: aws_ec2
aws_profile: default
regions:
  - us-east-1
filters:
  tag:Name:
    - dev-*
    - share-resource
    - hotfix
  instance-state-name : running
keyed_groups:
  - prefix: env
    key: tags['env']
  - prefix: dev
    key: tags['ssm']
Enter fullscreen mode Exit fullscreen mode

4. Check the list and the host group

$ ansible-inventory -i my_aws_ec2.yml --list
    "all": {
        "children": [
            "aws_ec2",
            "env_dev",
            "dev_ssm",
            "ungrouped"
        ]
    },
    "aws_ec2": {
        "hosts": [
            "ec2-111-111-111-111.us-east-1.compute.amazonaws.com",
            "ec2-11-111-111-112.us-east-1.compute.amazonaws.com",
            "ec2-11-111-111-113.us-east-1.compute.amazonaws.com",
            "ec2-11-111-111-114.us-east-1.compute.amazonaws.com",
            "ec2-11-111-111-115.us-east-1.compute.amazonaws.com",
        ]
    },
    "env_dev": {
        "hosts": [
            "ec2-111-111-111-111.us-east-1.compute.amazonaws.com",
            "ec2-11-111-111-112.us-east-1.compute.amazonaws.com",
            "ec2-11-111-111-113.us-east-1.compute.amazonaws.com",
            "ec2-11-111-111-114.us-east-1.compute.amazonaws.com",
            "ec2-11-111-111-115.us-east-1.compute.amazonaws.com",
        ]
    },
    "dev_ssm": {
        "hosts": [
            "ec2-111-111-111-111.us-east-1.compute.amazonaws.com"
        ]
    }
Enter fullscreen mode Exit fullscreen mode

5. Now send the task to the expected group
The task here is to update the env files to to env_dev group. File name and value are parsed from ansible host and item list (Ansible echo into file)

update_env.yaml

---
- hosts: all
  become: yes
  tasks:
    - name: Get hostname
      command: echo {{ ansible_hostname.split('-')[1] }}
      register: hostname

    - name: Update env files
      become: yes
      become_user: root
      shell: |
        echo "AGENT_ID={{ hostname.stdout }}-{{ item }}::" >> "/opt/workdir/{{ item }}.env"
      with_items:
        - app
        - pet
        - gate
        - api
      tags: runcmd
      register: result

    - name: Print output
      debug:
        var: result
Enter fullscreen mode Exit fullscreen mode

Run

$ ansible-playbook update_env.yaml -i my_aws_ec2.yml --limit env_dev -vv
Enter fullscreen mode Exit fullscreen mode

Discussion (6)

Collapse
dishantpandya profile image
Dishant Pandya
[WARNING]: Unable to parse /home/dishant/Projects/nodejs-ansible/ec2-hosts.yaml as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
Enter fullscreen mode Exit fullscreen mode

This is the error I am getting while fetching the inventory

Collapse
vumdao profile image
🚀 Vu Dao 🚀 Author

Please check one of the following

  1. Your aws_profile as you set in ~/.aws/config
  2. Tags of the resources
Collapse
dishantpandya profile image
Dishant Pandya

Still, I am not able to get it working.

#aws_ec2.yaml
---
plugin: aws_ec2
aws_profile: default
regions:
  - eu-west-1
filters:
  instance-state-name : running
Enter fullscreen mode Exit fullscreen mode
# ansible.cfg

[default]
enable_plugins = aws_ec2
inventory       = hosts
host_key_checking = False
stdout_callback = debug
Enter fullscreen mode Exit fullscreen mode
# ~/.aws/config

[default]
region = eu-west-1
output = json
Enter fullscreen mode Exit fullscreen mode

Output of Describe Instances:

$ aws ec2 describe-instances

{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-0aef57767f5404a3c",
                    "InstanceId": "i-03da2458c13c728e3",
                    "InstanceType": "t2.micro",
                    "KeyName": "astroamoreapp",
                    "LaunchTime": "2020-12-08T12:27:17+00:00",
                    "Monitoring": {
                        "State": "disabled"
                    }
                 .....
                 .....
                }
            ],
            "OwnerId": "493670244487",
            "ReservationId": "r-033c3a14ba52afbf7"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Output of ansible-inventory -i aws_ec2.yml --list

[WARNING]: Unable to parse /home/dishant/nodejs-ansible/aws_ec2.yml as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
{
    "_meta": {
        "hostvars": {}
    },
    "all": {
        "children": [
            "ungrouped"
        ]
    }
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
vumdao profile image
🚀 Vu Dao 🚀 Author

Did you install aws_ec2 plugin? Read more here: docs.ansible.com/ansible/latest/co...

Plus, it requires boto3 and botocore python modules.

Thread Thread
dishantpandya profile image
Dishant Pandya

Thanks! its working, actually the issue was with the file name, as mentioned in the given documentation its should end end with aws_ec2.(yml/yaml)

Thread Thread
vumdao profile image
🚀 Vu Dao 🚀 Author

Great!