Provision AWS EC2 virtual machine with Ansible

- By Manisha Sahasrabudhe on April 20, 2018

This tutorial explains how to manually provision an AWS EC2 virtual machine using Ansible. Before you start, you should be familiar with the following concepts:

 The best way to get started is to install ansible and run playbooks manually on your local machine to provision a VM. The first section of this tutorial explains how to do that. However, manual execution isn't the best and most efficient way to run ansible playbooks, so we will take a look at the challenges and learn how to automate this workflow.


Step-by-step instructions

Follow the steps below in order to provision your EC2 machine.


Step 1: Prep your machine

  • Have your security credentials handy to authenticate to your AWS Account. Refer to the AWS Credentials documentation.

  • Execute the following commands to set up your AWS credentials as environment variables. The playbook will need these at runtime.

    export AWS_ACCESS_KEY_ID=<enter your access key>
    export AWS_SECRET_ACCESS_KEY=<enter your secret key>
  • Install Ansible based on the OS of the machine from which you plan to execute the script. Refer to the Ansible Installation guide.


Step 2: Prepare Ansible playbook

  • Ansible uses a folder structure that looks like this:

    • ansible.cfg holds configuration info
    • inventory has the inventory of artifacts
    • variables.yml has the variables that are used to replace wildcards in your playbooks to make them more reusable
    • ec2_prov_playbook.yml is the playbook which has a list of tasks to provision an EC2 instance
    • ec2_term_playbook.yml is the playbook which has a list of tasks to terminate an EC2 instance
├── ansible.cfg
├── inventory
│   ├── base
│   ├── ec2.ini
│   ├──
│   ├── static_hosts
├── variables.yml
├── ec2_prov_playbook.yml
├── ec2_term_playbook.yml
  • It is important to note the following:
    • ec2_prov_playbook.yml and ec2_term_playbook.yml scripts have some wildcards, which ansible replaces with values from variables.yml.
    • Since we want to create a reusable playbook, we have not hardcoded values in variables.ymlbut left it up to the user to replace these when needed. This will be done in a later step, just before running the playbook.
  • In ansible.cfg, replace ${AWS_EC2_PEM_KEYPATH} with the path to the PEM key that should be used to provision the machine.

  • In variables.yml, replace these wildcards with your desired values: ${ec2_region} ${ec2_tag_Type} ${ec2_image} ${ec2_keypair} ${ec2_volume_size} ${ec2_count} ${security_group_id} ${public_subnet_id} ${ec2_tag_Type} ${ec2_tag_Role}.


Step 3: Run your playbook!

  • Execute the following command to run the ansible playbook from the directory that contains the playbook.

ansible-playbook -v ec2_prov_playbook.yml
  • Verify on AWS if the EC2 machine was provisioned.

  • You can terminate the instance by running the command below:

ansible-playbook -v ec2_term_playbook.yml

 Challenges with manual execution of Ansible playbooks

There are a few challenges with manual execution of Ansible playbooks:

  • Ansible playbook templates can be reused since they have wildcards. However, you need a programmatic way to replace wildcards at runtime. Creating static variables files is an option, but reduces reusability.
  • Automating provisioning for different environments and creating a dependency tree of all applications that are deployed into that environment is tedious to achieve with manual steps. You need an automated workflow to effectively transfer information like subnet_id, security_group_id to downstream activities. for e.g. EC2 provisioners.
  • Security with RBAC is a problem. The machine used to provision is authenticated to an AWS account (even in the case of service accounts). This means that the only way you can implement RBAC across multiple projects/teams is to use multiple accounts on the machine. This is messy and painful to maintain at scale.
  • The machine has to be prepped with the right version of the CLI. If multiple teams are deploying and they have a need to use different versions of the CLI, you will need different deployment machines for each team.

In a nutshell, if you want to achieve frictionless execution of Ansible playbooks with modular, reusable playbooks, you need to templatize your playbooks and automate the workflow used to execute them.


Automated provisioning of AWS EC2 VMs using Ansible 

To show you how to automate the provisioning of your AWS infrastructure, we have designed a step by step tutorial in our documentation:

Automate provisioning of AWS EC2 using Ansible

If you want a live demo of the Shippable platform and watch this scenario in action, schedule a demo with us:

Schedule a demo 

Topics: devops, AWS, infrastructure, Automation, ansible