Merv
Merv

Reputation: 81

Using ec2.py for dynamic inventory

I've managed to create a ec2 instance on the fly using ansible -

tasks:

- name: Launch Instance
  ec2:
    group_id: "{{ item.group_id }}"
    count: 1
    instance_type: 't2.micro'
    image: '{{ item.image }}'
    wait: true
    region: 'us-east-1'
    aws_access_key: ''
    aws_secret_key: ''
    key_name: "{{ pem }}"
    instance_profile: "{{ profile }}"
  register: ec2
  with_items: ec2_instances

And when i run ec2.py --list i can see the json response. How do i use this in any ansible playbook. I want to add these dynamically create hosts to a file how can I do this?

Upvotes: 0

Views: 714

Answers (1)

Arbab Nazar
Arbab Nazar

Reputation: 23811

You can tag your instance(s) and then call your instance with tag using ansible.

First create a directory filter_plugins where your playbook exist and then copy this code inside the file with the name get_ec2_info.py:

from jinja2.utils import soft_unicode

'''
USAGE:
 - debug:
     msg: "{{ ec2.results | get_ec2_info('id') }}"
Some useful ec2 keys:
id
dns_name
public_ip
private_ip
'''

class FilterModule(object):
    def filters(self):
        return {
            'get_ec2_info': get_ec2_info,
        }

def get_ec2_info(list, ec2_key):
    ec2_info = []
    for item in list:
        for ec2 in item['instances']:
            ec2_info.append(ec2[ec2_key])
    return ec2_info

here is the modified code of your example:

- name: Launch Instance
  ec2:
    group_id: "{{ item.group_id }}"
    count: 1
    instance_type: 't2.micro'
    image: '{{ item.image }}'
    wait: true
    region: 'us-east-1'
    aws_access_key: ''
    aws_secret_key: ''
    key_name: "{{ pem }}"
    instance_profile: "{{ profile }}"
    instance_tags:
      Name: "myserver"
      Environment: "staging"
      Server_Role: "webserver"
  register: ec2
  with_items: ec2_instances

- name: Create SSH Group to login dynamically to EC2 Instance(s)
  add_host: 
    hostname: "{{ item }}"
    groupname: webserver
  with_items: "{{ ec2.results | get_ec2_info('public_ip') }}"

- name: Add the newly created EC2 instance(s) to the local host group (located at ./inventory/hosts)
  lineinfile:
    dest: "./inventory/hosts" 
    regexp: "{{ item }}" 
    insertafter: "[webserver]" 
    line: "{{ item }}"
  with_items: "{{ ec2.results | get_ec2_info('public_ip') }}"

- name: Wait for SSH to come up on EC2 Instance(s)
  wait_for:
    host: "{{ item }}" 
    port: 22 
    state: started
  with_items: "{{ ec2.results | get_ec2_info('public_ip') }}" 

Set the ec2.py inventory as environment variables on the system(or you can call the inventory by -i parameter):

export ANSIBLE_HOSTS=/your-inventory-path/ec2.py
export EC2_INI_PATH=/your-inventory-path/ec2.ini

After that setup your SSH Key:

cp /tmp/mykey.pem ~/.ssh/
chmod 600 ~/.ssh/mykey.pem
ssh-agent bash
ssh-add ~/.ssh/mykey.pem

Now you can also use tags to call your instance (I am supposing that you are using Ubuntu instance please change the user accordingly):

ansible -m ping tag_Name_myserver -u ubuntu

or

ansible -m ping tag_Environment_staging -u ubuntu

or

ansible -m ping tag_Server_Role_webserver -u ubuntu

OR you can use this in your playbook like this:

- hosts: tag_Name_myserver
  become: yes
  remote_user: ubuntu
  roles:
    - your-role-here

Hope this will help you. For complete reference, please check these locations:

Upvotes: 1

Related Questions