Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having trouble provisioning EC2 instances using Ansible

I'm very confused on how you are supposed to launch EC2 instances using Ansible.

I'm trying to use the ec2.py inventory scripts. I'm not sure which one is supposed to be used, because there is three installed with Ansible:

  • ansible/lib/ansible/module_utils/ec2.py
  • ansible/lib/ansible/modules/core/cloud/amazon/ec2.py
  • ansible/plugins/inventory/ec2.py

I thought running the one in inventory/ would make most sense, so I run it using:

ansible-playbook launch-ec2.yaml -i ec2.py

which gives me:

msg: Either region or ec2_url must be specified

So I add a region (even though I have a vpc_subnet_id specified) and I get:

msg: Region us-east-1e does not seem to be available for aws module boto.ec2. If the region definitely exists, you may need to upgrade boto or extend with endpoints_path

I'm thinking Amazon must have recently changed ec2 so you need to use a VPC? Even when I try and launch an instance from Amazon's console, the option for "EC2 Classic" is disabled.

When I try and use the ec2.py script in cloud/amazon/ I get:

ERROR: Inventory script (/software/ansible/lib/ansible/modules/core/cloud/amazon/ec2.py) had an execution error:

There are no more details than this.

After some searching, I see that ec2.py module in /module_utils has been changed so a region doesn't need to be specified. I try to run this file but get:

ERROR: The file /software/ansible/lib/ansible/module_utils/ec2.py is marked as executable, but failed to execute correctly. If this is not supposed to be an executable script, correct this with chmod -x /software/ansible/lib/ansible/module_utils/ec2.py.

So as the error suggests, I remove the executable permissions for the ec2.py file, but then get the following error:

ERROR: /software/ansible/lib/ansible/module_utils/ec2.py:30: Invalid ini entry: distutils.version - need more than 1 value to unpack

Does anyone have any ideas on how to get this working? What is the correct file to be using? I'm completely lost at this point on how to get this working.

like image 380
Brian DiCasa Avatar asked Apr 24 '15 21:04

Brian DiCasa


People also ask

Can we create EC2 instance with Ansible?

So if you are using Ansible to launch an EC2 instance you can set this up with CI/CD, dynamic creation on the instance. There are many use cases you can implement using Ansible. So let's get started.

How long does it take to provision an EC2 instance?

You do not need to wait for the Instance Status Check to complete before using an Amazon EC2 instance. Linux instances are frequently ready 60-90 seconds after launch. Windows instances take considerably longer because the AMI has been configured for sysprep , which involves a reboot.

Can we provision infrastructure using Ansible?

Ansible can be used to provision the underlying infrastructure, install OpenStack services, add a compute host, and more. Once the underlying OpenStack environment is provisioned, Ansible can also be used provision resources, services, and applications inside of your OpenStack cloud.


1 Answers

There are several questions in your post. I'll try to summarise them in three items:

  1. Is it still possible to launch instances in EC2 Classic (no VPC)?
  2. How do I create a new EC2 instance using Ansible?
  3. How to launch the dynamic inventory file ec2.py?

1. EC2 Classic

Your options will differ depending on when did you create your AWS account, the type of instance and the AMI virtualisation type used. Refs: aws account,instance type.

If none of the above parameters restricts the usage of EC2 classic you should be able to create a new instance without defining any VPC.

2. Create a new EC2 instance with Ansible

Since your instance doesn't exist yet a dynamic inventory file (ec2.py) is useless. Try to instruct ansible to run on your local machine instead.

Create a new inventory file, e.g. new_hosts with the following contents:

[localhost]
127.0.0.1

Then your playbook, e.g. create_instance.yml should use a local connection and hosts: localhost. See an example below:

--- # Create ec2 instance playbook

- hosts: localhost
  connection: local
  gather_facts: false
  vars_prompt:
    inst_name: "What's the name of the instance?"
  vars:
      keypair: "your_keypair"
      instance_type: "m1.small"
      image: "ami-xxxyyyy"
      group: "your_group"
      region: "us-west-2"
  tasks:
    - name: make one instance
      ec2: image={{ image }}
           instance_type={{ instance_type }}
           keypair={{ keypair }}
           instance_tags='{"Name":"{{ inst_name }}"}'
           region={{ region }}
           group={{ group }}
           wait=true
      register: ec2_info

    - name: Add instances to host group
      add_host: hostname={{ item.public_ip }} groupname=ec2hosts
      with_items: ec2_info.instances

    - name: Wait for SSH to come up
      wait_for: host={{ item.public_dns_name }} port=22 delay=60 timeout=320 state=started
      with_items: ec2_info.instances

This play will create an EC2 instance and it will register its public IP as an ansible host variable ec2hosts ie. as if you had defined it in the inventory file. This is useful if you want to provision the instance just created, just add a new play with hosts: ec2hosts.

Ultimately, launch ansible as follows:

export ANSIBLE_HOST_KEY_CHECKING=false
export AWS_ACCESS_KEY=<your aws access key here>
export AWS_SECRET_KEY=<your aws secret key here>

ansible-playbook -i new_hosts create_instance.yml

The purpose of the environment variable ANSIBLE_HOST_KEY_CHECKING=false is to avoid being prompted to add the ssh host key when connecting to the instance.

Note: boto needs to be installed on the machine that runs the above ansible command.

3. Use ansible's ec2 dynamic inventory

EC2 dynamic inventory is comprised of 2 files, ec2.py and ec2.ini. In your particular case, I believe that your issue is due to the fact that ec2.py is unable to locate ec2.ini file.

To solve your issue, copy ec2.py and ec2.ini to the same folder in the machine where you intend to run ansible, e.g. to /etc/ansible/.

Pre Ansible 2.0 release (change the branch accordingly).

cd /etc/ansible
wget https://raw.githubusercontent.com/ansible/ansible/stable-1.9/plugins/inventory/ec2.py
wget https://raw.githubusercontent.com/ansible/ansible/stabe-1.9/plugins/inventory/ec2.ini
chmod u+x ec2.py

For Ansible 2:

cd /etc/ansible
wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.py
wget https://raw.githubusercontent.com/ansible/ansible/devel/contrib/inventory/ec2.ini
chmod u+x ec2.py

Configure ec2.ini and run ec2.py, which should print an ini formatted list of hosts to stdout.

like image 61
olluch Avatar answered Sep 29 '22 23:09

olluch