
Setting up Ansible on AWS EC2 Instance
By Thomas Suebwicha
Written June 17, 2020
Last Edited October 23, 2020
Requirements
2 free tier AWS EC2 Instances running
- A — Free Tier Amazon Linux (This will act as the master)
- B — Free Tier Ubuntu 18.04 (Server that we will do stuff to)
- C — Free Tier Ubuntu 18.04 (Server that we will do stuff to)
NOTE: The execution commands can vary depending on your machine type
Outline
- Setting up AWS EC2 Instances
- Setting up Ansible
- Setting up Ansible Project
- Execution
1. Setting up AWS EC2 Instances
Create the following instances in your AWS Instances list:
NOTE: There are no configuration changes when making them and so can click on the “Review and Launch Button”.
- A — Free Tier Amazon Linux (This will act as the master)

- B — Free Tier Ubuntu 18.04 (Server that we will do stuff to)

- C — Free Tier Ubuntu 18.04 (Server that we will do stuff to)

To make this process easier, Create a PEM key that is the same for each of the three. I.E. One pem key can be used to access all three for this demonstration.
Example

As you can see awssydneya is private key that will be used for all three instances.
You may access each instance by your ssh agent in command line or shell. Here is the following structure.
$ ssh -i <path to pem>/awssydneya.pem user@<public DNS address>
For me it was as follows
- Amazon Linux (Current directory contains pem key & user is ec2-user)
- Ubuntu (Current directory contains pem key & user is ubuntu)
NOTE: Every time you start and stop your instance, the public DNS address changes!
On all instances please update and install accordingly such that it is up to date.
- Amazon Linux
- Ubuntu
2. Setting up Ansible
On Instance A we will install ansible
#Perform a quick update on your instance
$ sudo yum update -y
#Install ansible in your EC2 instance
$ sudo pip install ansible
Verify that ansible is install correctly
$ ansible --version
(Optional) Setting up Git
We could use Git as version control for this ansible project.
- Amazon Linux
- Ubuntu
Verify it is installed correctly with a response of specific version.
$ git --version
3. Setting up Ansible Project
Please find a copy of the project files here on github.
Make a new directory in the home & direct current directory into there
mkdir playbook
cd ./playbook
Required file structure for this project below
playbooks
ansible.cfg
hosts
keypair.pem
web-notls.yml
files
nginx.conf
templates
index.html.j2
We will go through each file and what they consist of.
ansible.cfg File
This is the configuration file. Instead of housing this information for each individual host, we are able to abstract it in here.
[defaults]
inventory = hosts
remote_user = ubuntu
private_key_file = /home/ec2-user/playbooks/keyfile.pem
[defaults] is given to the last resort if no special configuration is labelled.
inventory specifies the hosts we intend to make the changes to.
remote_user is the username to access that instance/server.
private_key_file is path directory to the private key.
hosts File
This file will consist of the hosts we want to act upon. This will be Instance B & C. To inform ansible which servers to act upon we will do the following.
$ vim hosts
Displays
[webservers]
testserver ansible_host=ec2-3-25-79-101.ap-southeast-2.compute.amazonaws.com
testserverB ansible_host=ec2-13-210-104-229.ap-southeast-2.compute.amazonaws.com
[webservers] is the group label below.
“testserver” is the name of instance B with its domain name server given to ansible_host.
To Test connection with all the hosts, we are able to ping them all by selecting their group label.
ansible webservers -m ping
You should see green writing with “SUCCESS” otherwise red writing with an error.

The ECDSA key fingerprint is just confirming you want to connect with a new server.
Web-notls.yml File
This is what our web-notls.yml will look like.
---
- name: Configure webserver with nginx
hosts: webservers
become: True
tasks:
- name: install nginx
apt: name=nginx update_cache=yes- name: copy nginx config file
copy: src=files/nginx.conf dest=/etc/nginx/sites-available/default- name: enable configuration
file: >
dest=/etc/nginx/sites-enabled/default
src=/etc/nginx/sites-available/default
state=link- name: copy index.html
template: src=templates/index.html.j2 dest=/usr/share/nginx/html/index.html
mode=0644- name: restart nginx
service: name=nginx state=restarted
Keypair.pem File
Create a pem key named “keypair” that will have the same content as our awssydneya.pem on the host computer.
vim keypair.pem
Inside, make sure you are in “INSERT” mode. Go to “awssydneya.pem” and open in text editor then copy and paste the content into vim with a right click. You should see it auto typing.
chmod 700 keypair.pem
Since this we will be deploying nginx basic server page we will want to expose ports 8080(through the inbound rules of AWS).
Click on security group

Edit Inbound rules as follows

NOTE: Won’t be setting up TLS encryption since this would make it more complex
nginx.conf File
We need to create a directory called “files”. This follows the ansible folder layout.
In there we will put the following information.
server {
listen 8080 default_server;
listen [::]:8080 default_server ipv6only=on;root /usr/share/nginx/html;
index index.html index.htm;server_name server_name ec2-3-25-79-101.ap-southeast-2.compute.amazonaws.com ec2-13-210-104-229.ap-southeast-2.compute.amazonaws.com;location / {
try_files $uri $uri/ =404;
}
}
Change the server_name to be public DNS of Instance B & C.
index.html.j2 File
Create a directory called templates. In there a file called index.html.j2.
Copy this default template.
<html>
<head>
<title>Welcome to ansible</title>
</head>
<body>
<h1>nginx, configured by Ansible</h1>
<p>If you can see this, Ansible successfully installed nginx.</p><p>Running on {{ inventory_hostname }}</p>
</body>
</html>
Inventory_hostname specifies the name given to that host.
4. Execution
We can now execute the ansible playbook!
Current directory is in playbooks.
$ ansible-playbook web-notls.yml
If successful, you should see something similar to the following.

Second execution.

Verification
To verify it works, let’s check out the servers listed in host on port 8080!
You should see something like this.
Instance B

Instance C

We notice that the html page references back to the name we called each host in [webservers].