You are on page 1of 27

Middleware Inventory ABOUT US MIDDLEWARE  DEVOPS  NEWSLETTER

BOOK A CONSULTATION

Ansible EC2 Example – Create EC2 instance with



Ansible
0

0UPDATED ON: JUNE 19, 2022  SARAV AK



0
     

Search … 

CATEGORIES

ActiveMQ (4)
Ansible (65)
Apache (8)
AWS (28)
Azure (1)
Best Practice (5)
BitBucket (1)
Boto (1)
Cloud (1)
Database (1)
Development (3)
Docker (11)
EFK (1)
Elastic Search (1)
Infrastructure as Code is getting all attention it deserves and everyone is trying to find their way to F5-Big-IP (6)
the `Completely automated Infrastructure Provisioning & Management` FluentD (2)
GCP – GoogleCloud (1)
While there are a lot of tools available now in the market starting from Terraform, AWS
Github Actions (1)
CloudFormation, Chef, Puppet, Salt Stack
Grafana (1)
There are some differences between each tool. Some of them are configuration management tools Graphite (1)
(Ansible, Chef, Saltstack) and Some of them are purely provisioning tools (terraform, cloud IBM Cloud (1)
formation). You have to choose your judgement based on various factors like Easy to learn, easy to IBM Websphere (2)
adopt. IHS and Apache (10)
Though Terraform is a wonderful cross-platform provisioning tool I feel it has a steep learning IIS (4)
curve. while Ansible is not that complex to start with an easy to learn and adopt. JavaScript (3)
Jenkins (4)
So this post is for those ( including me ) who love ansibleʼs simplicity and structure and want to see
Joomla (1)
how it works with AWS.
Kubernetes (16)

This is going to be a quick introduction to Ansible AWS Ec2 module. Middleware (3)
Network
Troubleshooting (1)
Networking (1)
Table of Contents  NodeJS (2)
1. How Ansible works with AWS EC2 – Setup Boto for Ansible Office365 (1)
2. Environment Setup for Ansible to work with AWS EC2 module OpenSource (2)
3. Ansible Playbook to create a new EC2 instance Oracle DB (3)
3.1. Setup AWS Authentication Before Running the Playbook with Ansible EC2
Oracle Weblogic (2)
3.2. Getting ready to execute the playbook – Ansible AWS EC2
Packer (2)
3.3. Execution Part – Run the playbook with Ansible EC2
Perl (1)
4. A Playbook with Ansible EC2 & Ansible Vault – Secure Approach
PHP (1)
4.1. Saving the AWS Secrets
5. Execution of Ansible AWS Playbook example PostgreSQL (1)
PowerShell (1)
problem/solution (8)
Prometheus (1)
Pulumi (1)
How Ansible works with AWS EC2 – Setup Boto for Ansible Python Flask (1)
python_scripts (7)
Ansible AWS combo is more like Hobbs and Shah ( Sorry! I am Fast & Furious Fan) while both of em
Redis (1)
have their own individual stardom they join together to create magic.
Serverless (1)

Stupid analogy right.!!! Shell Scripting (6)


SOAP Web Services (1)
Jokes Apart, But Ansible is a leader in configuration management tools and AWS is a leader in Cloud Splunk (1)
solutions and no doubt that they give best results as combined for the Infrastructure automation
SRE (1)
and management.
StatsD (1)
Terraform (12)
In Ansible Parlance, Everything is a module and Yes ansible provides ample amount of modules to
work with AWS resource. As I am typing this post, Ansible has 194 officially listed modules for aws. tomcat (7)

here is a list tools (5)


Traefik (1)
All these modules are helping us to accomplish a various level of tasks in AWS cloud resources Troubleshooting (3)
creation, deletion, management, assessment etc
Uncategorized (5)
Unix (5)
Our objective is precise, we want to create an EC2 Instance using Ansible and Ansible has a module
Vagrant (4)
for that named ec2
VueJS (2)
Before we jump right into the playbooks and stuff. we need to do some environment setup. Vulnerabilities & Fixes
(21)
weblogic (51)
Webserver (1)
Websphere (8)
Windows Server (5)
wlst (7)
wordpress (2)
wsadmin scripts (1)

Environment Setup for Ansible to work with AWS EC2 module

As we all know Ansible is pythonic and their modules are written in python as well. So for AWS
modules to work you need to have Certain prerequisite elements installed on your Ansible Control
machine ( where you have installed ansible )

boto
boto3
botocore
python version >= 2.6

You can install python easily but what is this boto. boto is one of the Amazon supported SDK. Boto3
is the latest version of boto.

to make sure you have boto installed in your python. Just Launch your Python interactive terminal
and type import boto and import boto3 if it works fine ( shows no error) you are good.
to install boto and boto3 you must have pip3 as well. If you are having python 2.7 there are
chances you might have this bundled in.

Some times when you have two versions of python installed in your system you have to try them out
both and make sure which one has the boto installed. by performing the `import boto` command
so that you can avoid some exceptions like this
If you take my MAC, for example, I have two python version installed, One is at
/usr/local/bin/python another one is at /usr/bin/python One comes as built-in with OS
another one is installed by `homebrew` , I had to lauch them both and check the if the boto
package is present in there like shown below.
You could see that my /usr/local/bin/python3 all necessary modules installed,

Note:

It is known that Python3 may not work properly with Ansible old versions. In that case, you can
choose to install your boto libraries in python 2.7.* version and it use it as your primary
version in ansible_python_interpreter

This is just a method to find the right python package to use it with ansible
The path and everything could be different for you. Before executing these commands, update the
paths based on your local installation.

Now I presume that you have a python with these necessary modules installed.

Ansible Playbook to create a new EC2 instance

Here is the playbook to create EC2 instances and also to get the list of in your AWS Cloud account.

We have used two blocks here (a block is just a group of tasks )

The first block is to just get the instances information


The second block is to create the instance

For security reasons, we made the Second block to run only when it is being explicitly called with --
tags
this has been done by using the tag never in the block

---
- name: Create Ec2 instances
hosts: localhost
gather_facts: false
tasks:

# Block is a Group of Tasks combined together


- name: Get Info Block
block:
- name: Get Running instance Info

ec2_instance_info:
register: ec2info

- name: Print info


debug: var="ec2info.instances"

# By specifying always on the tag,


# I let this block to run all the time by module_default
# this is for security to net create ec2 instances accidentally
tags: ['always', 'getinfoonly']

- name: Create EC2 Block


block:

- name: Launch ec2 instances


tags: create_ec2
ec2:
region: us-east-1
key_name: SaravAK-PrivateKey
group: app_sec_group
instance_type: t2.medium
image: ami-2051294a
wait: yes
wait_timeout: 500
count: 2
instance_tags:
name: appservers
os: ubuntu
monitoring: no
vpc_subnet_id: subnet-3d3ef270
assign_public_ip: yes
register: ec2
delegate_to: localhost

- name : Add instance to host group


add_host:
hostname: "{{ item.public_ip }}"
groupname: launched
loop: "{{ ec2.instances }}"

- name: Wait for SSH to come up


local_action:
module: wait_for
host: "{{ item.public_ip }}"
port: 22
delay: 10
timeout: 120
loop: "{{ ec2.instances }}"
# By specifying never on the tag of this block,
# I let this block to run only when explicitely being called
tags: ['never', 'ec2-create']

You might wonder where is my AWS Key and SECRET mentioned. How would I be able to login to my
AWS account? How the authentication will be done.

I hear ya.
Setup AWS Authentication Before Running the Playbook with Ansible EC2

To make this article precise, I just assume that you know how to create programmatic access for your
AWS account and get your AWS_ACCESS_KEY and AWS_SECRET

Once you have the keys, the easiest but an unsecured way is to save it as Environment Variables like
this and we are all set.

Getting ready to execute the playbook – Ansible AWS EC2

Before executing the playbook you must be sure which python interpreter you are going to use
which has `boto` libraries installed.
When it comes to using EC2 modules, It is always better to tell ansible explicitly which python
interpreter it has to use.

In my case, as I have said before my /usr/local/bin/python3 has the necessary boto libraries
and I have to tell ansible to use that python.

to do that, I can use ansible.cfg file or ansible inventory file but I prefer to do it in a
command line as a runtime variable

Here is the command I supposed to use

ansible-playbook ec2-creation.yml \
--connection=local \
-e "ansible_python_interpreter=/usr/local/bin/python3"

Here

–connection tells Ansible to run this task locally and not look for any remote server or hosts file

–e extra args or variables where we gave the python interpreter by setting the python full location
to ansible_python_interpreter variable

when I run this, I would get only the info of existing instances. it would not create the instances yet.
as we have the info as the default block
Now to create the ec2 instance or to run that block, I need to call the tag of that block using --
tags like shown below.

ansible-playbook ec2-creation.yml \
--connection=local \
--tags=ec2-create \
-e "ansible_python_interpreter=/usr/local/bin/python3"

Execution Part – Run the playbook with Ansible EC2

Here is the execution and the result of this playbook.


"state": {
"code": 16,
"name": "running"
},
"state_transition_reason": "",
"subnet_id": "subnet-3d3ef270",
"tags": {
"name": "appservers",
"os": "ubuntu"
},
"virtualization_type": "hvm",
"vpc_id": "vpc-4c357d36"
}
]
}

TASK [Launch ec2 instances] *************************************************************************************************


changed: [localhost -> localhost]

TASK [Add instance to host group] *******************************************************************************************


changed: [localhost] => (item={'id': 'i-05c8302b78135c198', 'ami_launch_index': '1', 'private_ip': '172.31.21.78', 'private_d
ns_name': 'ip-172-31-21-78.ec2.internal', 'public_ip': '3.89.103.61', 'dns_name': 'ec2-3-89-103-61.compute-1.amazonaws.com',
'public_dns_name': 'ec2-3-89-103-61.compute-1.amazonaws.com', 'state_code': 16, 'architecture': 'x86_64', 'image_id': 'ami-20
51294a', 'key_name': 'SaravAK-PrivateKey', 'placement': 'us-east-1c', 'region': 'us-east-1', 'kernel': None, 'ramdisk': None,
'launch_time': '2019-12-01T17:03:43.000Z', 'instance_type': 't2.medium', 'root_device_type': 'ebs', 'root_device_name': '/de
v/sda1', 'state': 'running', 'hypervisor': 'xen', 'tags': {'name': 'appservers', 'os': 'ubuntu'}, 'groups': {'sg-02325d3c4842
ab9d1': 'app_sec_group'}, 'virtualization_type': 'hvm', 'ebs_optimized': False, 'block_device_mapping': {'/dev/sda1': {'statu
s': 'attached', 'volume_id': 'vol-09e0417f7057b6b50', 'delete_on_termination': True}}, 'tenancy': 'default'})
changed: [localhost] => (item={'id': 'i-0b5152fc4afb31b9f', 'ami_launch_index': '0', 'private_ip': '172.31.24.198', 'private_
dns_name': 'ip-172-31-24-198.ec2.internal', 'public_ip': '184.72.209.46', 'dns_name': 'ec2-184-72-209-46.compute-1.amazonaws.
com', 'public_dns_name': 'ec2-184-72-209-46.compute-1.amazonaws.com', 'state_code': 16, 'architecture': 'x86_64', 'image_id':
'ami-2051294a', 'key_name': 'SaravAK-PrivateKey', 'placement': 'us-east-1c', 'region': 'us-east-1', 'kernel': None, 'ramdisk
': None, 'launch_time': '2019-12-01T17:03:43.000Z', 'instance_type': 't2.medium', 'root_device_type': 'ebs', 'root_device_nam
e': '/dev/sda1', 'state': 'running', 'hypervisor': 'xen', 'tags': {'name': 'appservers', 'os': 'ubuntu'}, 'groups': {'sg-0232
5d3c4842ab9d1': 'app_sec_group'}, 'virtualization_type': 'hvm', 'ebs_optimized': False, 'block_device_mapping': {'/dev/sda1':
{'status': 'attached', 'volume_id': 'vol-0522c075842388f43', 'delete_on_termination': True}}, 'tenancy': 'default'})

TASK [Wait for SSH to come up] **********************************************************************************************

Recorded with asciinema


A Playbook with Ansible EC2 & Ansible Vault – Secure Approach

to use the Ansible vault to securely store your AWS Keys, You might need one more file on the same
directory where you can save your credentials as variables and encrypt it with the vault.

The file can be imported later within the playbook.

Here is the modified playbook with a secure approach, Ansible Vault

---
- name: Create Ec2 instances
hosts: localhost
# import the secret file
vars_files:
- secrets.yml
gather_facts: false
tasks:

# Block is a Group of Tasks combined together


- name: Get Info Block
block:
- name: Get Running instance Info

ec2_instance_info:
register: ec2info

- name: Print info


debug: var="ec2info.instances"

# By specifying always on the tag,


# I let this block to run all the time by module_default
# this is for security to net create ec2 instances accidentally
tags: ['always', 'getinfoonly']
- name: Create EC2 Block
block:

- name: Launch ec2 instances


tags: create_ec2
ec2:
region: us-east-1
key_name: SaravAK-PrivateKey
group: app_sec_group
instance_type: t2.medium
image: ami-2051294a
wait: yes
wait_timeout: 500
count: 2
instance_tags:
name: appservers
os: ubuntu
monitoring: no
vpc_subnet_id: subnet-3d3ef270
assign_public_ip: yes
register: ec2
delegate_to: localhost

- name : Add instance to host group


add_host:
hostname: "{{ item.public_ip }}"
groupname: launched
loop: "{{ ec2.instances }}"

- name: Wait for SSH to come up


local_action:
module: wait_for
host: "{{ item.public_ip }}"
port: 22
delay: 10
timeout: 120
loop: "{{ ec2.instances }}"
# By specifying never on the tag of this block,
# I let this block to run only when explicitely being called
tags: ['never', 'ec2-create']
Saving the AWS Secrets

As we have included the secrets.yml file inside our playbook, Now we need to save our AWS KEY
and SECRET

This is the content of the secret.yml file

➜ cat secrets.yml
AWS_ACCESS_KEY_ID: AKIATQ7Q7SGKYB4TT3DX
AWS_SECRET_ACCESS_KEY: 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

It is saved as clear text info within the file so whoever opens it can see what is inside.

So Encrypt it

➜ ansible-vault encrypt secrets.yml


New Vault password:
Confirm New Vault password: Encryption successful
Now you have to remember this password and use it while you are starting the playbook.

For Ansible to ask you the password you should use a startup argument named --ask-vault-pass

ansible-playbook ec2-creation.yml \
--connection=local \
--tags=ec2-create \
-e "ansible_python_interpreter=/usr/local/bin/python3" \
--ask-vault-pass

It would prompt you for the password as it runs.

See the following Screen record if you want to see how it works in realtime.

Execution of Ansible AWS Playbook example


||----w |
|| ||
➜ ec2create git:(master) ✗ e "to see what is inside, you can do this"
________________________________________
< to see what is inside, you can do this >
----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
➜ ec2create git:(master) ✗ ansible-vault show secrets.yml
usage: ansible-vault [-h] [--version] [-v]
{create,decrypt,edit,view,encrypt,encrypt_string,rekey}
...
ansible-vault: error: argument action: invalid choice: 'show' (choose from 'create', 'decrypt', 'edit', 'view', 'encrypt', 'e
ncrypt_string', 'rekey')
➜ ec2create git:(master) ✗ ansible-vault view secrets.yml
Vault password:
➜ ec2create git:(master) ✗ e "you can view it with the password"
___________________________________
< you can view it with the password >
-----------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
➜ ec2create git:(master) ✗ e "To decrypt it use 'ansible-vault decrypt command'"
__________________________________
/ To decrypt it use 'ansible-vault \
\ decrypt command' /
----------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
➜ ec2create git:(master) ✗ e "

Recorded with asciinema

I know this is just a first step, Now you have got better things to do with that newly created server
and install and configure it. you might have further questions on how to use these servers and
configure them properly on the same playbook.

Please stay connected and Lookup for my next article. I am already drafting it.

hope this helps.

Rate this article [ratings] if you would like to

Cheers
Sarav AK

Follow us onFacebook orTwitter


For more practical videos and tutorials. Subscribe to our channel
Find me on Linkedin My Profile
For any Consultation or to hire us hello@gritfy.com
If you like this article. Show your Support! Buy me a Coffee.

Signup for Exclusive "Subscriber-only" Content


Name*

Email*

SUBSCRIBE

More from Middleware Inventory

Add SSH Key to EC2 instances with Ansible - Automated

Whether it is On-Prem (or) Cloud-hosted, A Typical Non-Containerized


Enterprise infrastructure would have ample of Virtual Machines aka Servers [
Linux ] Let us suppose that you work for the DevOps team of a Big Organization
where you manage 100+ ec2 instances. You have a new hire in your team…

Ansible sudo - ansible become example

Ansible Sudo or Ansible become Introduction Ansible Sudo or become is a


method to run a particular task in a playbook with Special Privileges like root
user or some other user. In the earlier versions of ansible there is an option
named as sudo which is deprecated now, Since ansible…

Ansible Playbook Examples - Sample Ansible Playbooks | Devops Junction


In this post, we are going to see examples of Ansible playbook and various
different modules and playbook examples with various modules and multiple
hosts. We will start with a basic Ansible playbook and learn what is task and
play and what is playbook etc. What is Ansible Playbook It…

Ansible Dry Run - How to Run Playbook in Ansible Check mode

Introduction Ansible Dry Run or Ansible Check mode feature is to check your
playbook before execution like Ansible's --syntax-check feature. With Ansible
Dry Run feature you can execute the playbook without having to actually make
changes on the server. With Ansible Dry Run you can see if the host is getting
changed…

How to Run Ansible Playbook Locally

In this post, we are going to see how to run the playbook locally on our
Localhost on the control machine. How to run Ansible Playbook locally is one
of the questions I used to have before I learnt it. Let me tell you how to Run
Ansible Playbook Locally…

Ansible and AWS Ansible AWS Boto Ansible AWS Example Ansible EC2 Ansible EC2 Creation Ansible EC2 example

« Ansible Async Poll Examples – Ansible nohup, task in background Ansible Unarchive Module Examples »
What do you think about this article ?
4 Responses

Upvote Funny Love Surprised Angry Sad

8 Comments 
1 Login

Join the discussion…

LOG IN WITH
OR SIGN UP WITH DISQUS ?

Name

Sort by Best  ⥅

Marco Reale • 10 months ago


Hi Sarav, very nice post because it is exactly what I need
Anyway I'm not able to make your playbook working.

I setup a clean environment (ubuntu wsl), created a venv with python3 and boto3.
This is the playbook in which I changed just security group, key name, region, instance type, ami name:

---
- name: Create Ec2 instances
hosts: localhost
# import the secret file
vars_files:
- secrets.yml
gather_facts: false
tasks:

# Block is a Group of Tasks combined together


- name: Get Info Block
block:
- name: Get Running instance Info
see more

△ ▽ • Reply • Share ›

Sarav AK Mod > Marco Reale • 10 months ago

If you do not want the `ec2_instance_info` to come into picture. you can just execute only the right tag

ansible-playbook ec2-creation.yml --tags=ec2-create

△ ▽ • Reply • Share ›

Sarav AK Mod > Marco Reale • 10 months ago • edited

Hi Marco.

The issue is that your default profile on the local system is being chosen with the first `ec2_instance_info`
block

Please add `regional` and `profile` blocks like this into the `ec2_instance_info` task and retry.

I just tried and it works fine.

Hope this helps.

- name: Get Running instance Info


ec2_instance_info:
region: us-east-1
profile: personal
register: ec2info

△ ▽ • Reply • Share ›

Sarav AK Mod > Sarav AK • 10 months ago

Hi Marco.

I have updated the solution Above. Please check


△ ▽ • Reply • Share ›

Marco Reale > Sarav AK • 10 months ago


Sorry Sarav please be patience with me but I'm an ansible beginner (as you probably already
understood...).
I just changed my playbook in this way but still doesn't work also because, to be honest, it isn't
clear to me what does mean profile: personal (I read the documentation but still not clear)
---
- name: Create Ec2 instances
hosts: localhost
# import the secret file
vars_files:
- secrets.yml
gather_facts: false
tasks:

# Block is a Group of Tasks combined together


- name: Get Info Block
block:
- name: Get Running instance Info

see more

△ ▽ • Reply • Share ›

Sarav AK Mod > Marco Reale • 10 months ago


Hi Marco.

No problem at all. I should have not presumed things.

In this case, personal means a profile name of AWS CLI. it also called as Boto profile.

https://docs.aws.amazon.com... Read about it here.

When you manage multiple AWS accounts from you AWS CLI. you would have multiple profiles
configured.

by default, it would be `default` thats your profile name.

Only if you have multiple profile, use the profile option otherwise remove it and just use the
region.

Next time when you want to post the code to me. please use a code block or use
https://gist.github.com/ so that I can check your Yaml file Indentation. as well.

If you would still need some help. Please let me know we can connect for a 30 minute zoom
call.

Happy to help
△ ▽ • Reply • Share ›
Marco Reale > Sarav AK • 10 months ago
Hi Sarav

before all I really thank you for your help :)Anyway after some more tests I finally have been
able to make it working. Actually it was just my stupid mistake and your playbook worked
perfectly since the beginning without any change. Sorry for wasting your time.
I have just a last question:

in my test environment I created a venv environment that works perfectly (source aws-
venv/bin/activate)
and now I have the following folder structure with your playbook:

(aws-venv) marcoreale@REALE-NB:~/aws-venv/ec2-create$ pwd


/home/marcoreale/aws-venv/ec2-create
(aws-venv) marcoreale@REALE-NB:~/aws-venv/ec2-create$ ls -liah
total 8.0K
7318349394583567 drwxr-xr-x 1 marcoreale marcoreale 4.0K Dec 23 12:41 .
17169973579460982 drwxr-xr-x 1 marcoreale marcoreale 4.0K Dec 23 12:41 ..
14918173765774685 -rw-r--r-- 1 marcoreale marcoreale 1.7K Dec 23 12:39 ec2-creation.yml
844424930723364 -rw-r--r-- 1 marcoreale marcoreale 31 Dec 21 16:23 hosts
see more

△ ▽ • Reply • Share ›

Marco Reale > Marco Reale • 10 months ago


Ok, never mind, I fixed by myselft; actually the venv enviroment wasn't configured properly. Now
everything worked perfectly.
Thanks again Sarav!!!
△ ▽ • Reply • Share ›

Powered by MiddlewareInventory and gritfy

PDFmyURL.com - convert URLs, web pages or even full websites to PDF online. Easy API for developers!

You might also like