DEV Community

Cover image for Ansible AWS EC2 Dynamic Inventory Plugin
πŸš€ Vu Dao πŸš€
πŸš€ Vu Dao πŸš€

Posted on β€’ Edited 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

Top comments (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 πŸš€ β€’

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 πŸš€ β€’

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 πŸš€ β€’

Great!