Webserver configuration on AWS EC2 Instance using Ansible

Nischal Vooda
6 min readSep 13, 2020

Problem Statement

1.Provision EC2 instance through ansible.

2. Retrieve the IP Address of instance using a dynamic inventory concept.

3. Configure the webserver through ansible!

4. Create a role for the webserver to customize the Instance and deploy the webpage to the root directory.

In this task we will learn how to deploy a webserver on the top AWS EC2 instance using Ansible roles.

We will be using RHEL8 as Controller Node and AWS Ec2 instance as Managed Node.

Overview

Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code. It runs on many Unix-like systems, and can configure both Unix-like systems as well as Microsoft Windows.

The Ansible inventory file contains the details of the hosts that will be configured. A static inventory file is a plain text file that contains a list of managed hosts declared under a host group using either hostnames or IP addresses. So we have to manually add managed host information if any new host come. So to overcome this issue Ansible also has concept of Dynamic inventory file which can pull inventory information from dynamic sources, like cloud sources, container services, etc.

Ansible supports two ways to connect with external inventory: Inventory Plugins and inventory scripts.

We are going to use inventory scripts

Prerequisites:

  1. Basic knowledge of AWS.
  2. Basic knowledge of Ansible like roles, playbook, vault, etc.
  3. Ansible configured on the Manager Node.
  4. Preinstalled boto python library on the Manager Node.

First of all, we have to set up an Ansible environment in our system. For doing anything on the AWS using the local system with the help of ansible then you have to install boto library of python.

# pip3 install boto
# pip3 install boto3

Now, Let’s started

Step 1: Create a key pair named MyKey using EC2 and download the nischal.pem file to the Manager Node’s /root directory. Remember to change the permissions of the host key file to 400.

Step 2: Then create a separate folder for this task named task2 then edit the ansible configuration file as:

[defaults]
inventory = /root/task2/inventory
host_key_checking = False
roles_path = /root/task2/roles
private_key_file = /root/nischal.pem
remote_user = ec2-user


[privilege_escalation]
become = yes
become_user = root
become_method = sudo
ask_pass = no

Step 3: Create the following directories as well:

mkdir -p /root/task2/inventory

mkdir -p /root/task2/roles

mkdir -p /root/task2/playbook

Inventory in ansible

ansible inventory is a collection of IP addresses and groups upon which all the commands and module run. We can say its something like an IP database.

We can’t go manually and fetch the IP Address we use automation to save our time and to develop quickly. Here we have to use a dynamic Inventory Concept to fetch the IP Address.

Step 4: Download the ansible dynamic inventory script for EC2 in your inventory directory and make it executable. You can fetch it from here using wget command.

Now we will download this file and make this executable and set the environmental variable as mentioned above then if we will run this file so we can see that we can Dynamically get the IP address of the Ec2 instance we also need one more file that is ec2.ini file

Now to make this files executable run following commands:

# chmod +x ec2.py# chmod +x ec2.ini

Provide your AWS IAM credentials as environment variable where you want to launch and manage EC2 services

export AWS_ACCESS_KEY_ID="KeyID"export AWS_SECRET_ACCESS_KEY="YourKey"export AWS_DEFAULT_REGION="ap-south-1"

You can check the file by running this command. It will show all information in your AWS profile

./ec2.py --list

Create 2 roles one for launching instance and one for configuring web server where you have specified roles path in ansible configuration file

ansible-galaxy init ec2_instanceansible-galaxy init web_server

You can verify the roles created by using the command:

ansible-galaxy list

Now Configure the Role 1: For launching EC2 instance.

Now edit tasks/main.yml file of ec2_instance and write below module to launch ec2 instance (Replace the fields with your EC2 profile):

---
# tasks file for ec2_instance
- name: Launch ec2 instance
ec2:
aws_access_key: "{{ access_key }}"
aws_secret_key: "{{ secret_key }}"
key_name: nischal
instance_type: t2.micro
image: ami-0ebc1ac48dfd14136
wait: yes
instance_tags:
name: myins
group: all
count: 1
vpc_subnet_id: subnet-92704ffa
assign_public_ip: yes
region: ap-south-1

Now the Role 2: For configuring the webserver.

Edit tasks/main.yml file of web_server role as:

---
# tasks file for web_server
- name: install package for httpd
package:
name: "httpd"
state: "present"
register: httpd_package_status
- name: Create Document Root Directory
file:
state: directory
dest: "{{ dr_dir }}"
register: root_dir_name
- name: Configuration file for apache web server
template:
dest: "/etc/httpd/conf.d/tavi.conf"
src: "templates/tavi.conf.j2"
when: httpd_package_status.rc == 0
notify: httpd service
- name: Copy web page from url
copy:
dest: "{{ dr_dir }}/index.html"
content: "This is a sample Page"
when: root_dir_name.failed == false
- name: Start httpd service
service:
name: httpd
state: started

Then, create a template file tavi.conf.j2 in the templates directory in web_server role and you can write your configuration in this

Listen {{ newPort }}
<Virtualhost {{ ansible_default_ipv4.address }}:{{ newPort }}>
DocumentRoot {{ dr_dir }}
</Virtualhost>

Also edit the handlers/main.yml file and provide service module here so if any change made in the configuration file and the playbook is run again then it will restart the service

---
# handlers file for web_server
- name: httpd service
service:
name: httpd
state: restarted

Also edit the vars/main.yml file and provide the variables here

---
# vars file for web_server
dr_dir: /var/www/tavi
newPort: 8080

Create two playbook in the files in the /root/task2/playbook directory one for ec2_instance role and one for web_server role

play1.yml

- hosts: localhost
roles:

- ec2_instance

play2.yml

- hosts: all
roles:
- web_server

Its time to run the playbooks:

To Running the playbook:

ansible-playbook play1.yml

Now Running the web_server playbook:

ansible-playbook play2.yml

Finally webpage is deployed on the webserver

Connect me on my LinkedIn as well.

--

--