Ansible with AWS EC2 and Apache web server

Launch a Apache Web Server on AWS EC2 using Ansible Roles

Shashi Kant

--

Task -

Deploy Web Server on AWS EC2 through ANSIBLE !!!

  1. Provision EC2 instance through ansible.
  2. Retrieve the IP Address of instance using dynamic inventory concept.
  3. Configure the web server through ansible!
  4. Create role for web server to customize the Instance and deploy the webpage to root directory.

prerequisites -

  1. Configure Ansible on controller node.
  2. AWS account with IAM role with its access key and secret key.
  3. Basic knowledge of Ansible.

So, lets get started

we’re going to run all the tasks on localhost (controller node), so there is no need to configure static inventory of controller node.

Configure ansible.cfg File

First we have to configure our ansible.cfg file in the “/etc/ansible/” directory.

[defaults]
inventory = /root/ansible/inventory/myhosts.txt
host_key_checking = False
remote_user = ec2-user
ask_pass = false
private_key_file = /root/mykey.pem
roles_path = /root/ansible/roles/

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ask_pass = false

In this file, Add your inventory location, host_key_checking, ask_pass

add remote_user - here, ec2-user because in AWS instances by default root login is not enabled.

To configure Instance ansible have to login into ec2-instance so it also need ssh key to login into it. that why in private_key_file pass your ssh key location (ssh key should be in .pem format).

and in roles_path - pass the location where your ansible roles are present.

Ansible need root power to configure ec2-instance (Installing the softwares, starting the services, etc.) so here we are using sudo method to give ansible power of root user.

Install boto python Library

To connect with AWS cloud Ansible need boto python library installed on Host (Here host is localhost) so, we need to install boto library on our controller node.

Here, I’m installing ‘boto3’ library of python.

pip3 install boto3
Installing boto3 library of python

Ansible Playbook

Now, its time to write Ansible playbook to create EC2 Instance for Launching Apache Web server

so, create a workspace in controller node and start writing playbook and extension should be “.yml or .yaml” of file, because we write playbook in yaml format.

but before writing playbook we have to create Ansible Vault, to store AWS IAM user credential.

Ansible Vault

In this vault we can write our ID and Password to hide them from world. and we lock this file with some password, so that our credentials will be secure.

To create Ansible vault run below command.

## ansible-vault create <name_of_vault.yml> ##ansible-vault create vault.yml

after running this command, give some password to lock your ansible vault file. and it will open VI editor for you. Inside this file write your access key and secret key of AWS user.

accesskey: <your aws access key>
secretkey: <your aws secret key>

save this file. your credential will be secure.

Now finally Start writing Ansible Playbook

- hosts: localhost
vars_files:
- vault.yml
tasks:
- name: "launching ec2 instance on AWS"
ec2:
key_name: "mykey"
instance_type: t2.micro
image: "ami-0a9d27a9f4f5c0efc"
wait: yes
count: 1
instance_tags:
Name: "myAnsibleOS"
state: present
region: "ap-south-1"
group_id: "sg-0115c41a0b3c39bda"
aws_access_key: "{{ accesskey }}"
aws_secret_key: "{{ secretkey }}"
register: ec2

we’re running this part of playbook on localhost, that’s why we write localhost in hosts keyword.

then we pass our vault file name in vars_files. so, when ansible go to AWS to launch EC2 instance then it need those credentials(access key and secret key)

In tasks I use ec2 module to launch ec2 instance, here we have to write.

key_name so that ansible can login into instance and configure it as Apache web server.

instance_type , image - here we have to pass our instance type whichever we want, and ‘image’(ami) here I’m using RedHat ami.

wait - It is very important keyword here, because I want when this playbook run, till the time my instance launched this play will wait then it will go to the next play. Because my other plays are dependent on this Instance launch.

count - give no. of instances you want to launch.

instance_tags - Give some tags to your Instance so that it will be easily recognizable.

state - Set instance state. here I put ‘present’ means I have to launch it.

region - Select your region where you want to launch your instance.

group_id - Give some security group-id here. and in security group inbound rule SSH(22) and HTTP(80) port should be allowed.

aws_access_key and aws_secret_key - Write the variable name which are created in vault file.

and all the details of Instance are stored in ec2 variable through register keyword.

   - name: "Add new Instance to Host group"
add_host:
hostname: "{{ item.public_ip }}"
groupname: webserver
loop: "{{ ec2.instances }}"

- name: "Wait for SSH in Instance"
wait_for:
host: "{{ item.public_dns_name }}"
port: 22
state: started
loop: "{{ ec2.instances }}"

Now after launching the instance we have to add the public IP of instance in the dynamic inventory of Ansible.

Through add_host module we can add new host in dynamic inventory.

Here groupname I’ve given webserver and hostname is public IP of instance. And I put a loop here so, that if we launch more than 1 instance then all the instance will be added in the webserver group.

After that my playbook is waiting for SSH enable in instance because Ansible need to login into instance to configure as web server. that is why we have to allow SSH port in the security group of instance. Once the Instance is ready to do SSH then it will go on next play.

- hosts: webserver
gather_facts: yes
tasks:
- name: running role
include_role:
name: httpdserver

Finally on our webserver host group which we just created above, we have to run our Ansible Role name as httpdserver. which I will tell below how to create this Ansible Role.

Ansible Role

Ansible roles are basically a collection of files, tasks, templates, variables, and modules. It is used for breaking a playbook into multiple files. This will helps you to write a complex playbook and make it easier to reuse.

Creating Role

we’ve seen in the last play that we are using one Ansible Role called ‘httpdserver’. But first we need to create it.

So, for creating Ansible Role we need to go to ‘roles’ directory that we’ve specified in the ansible.cfg file.

So, go into ‘roles’ directory in your workspace, where roles will be created and run this below mentioned command and role will be created.

ansible-galaxy init httpdserver

This command will be initialize the ‘httpdserver’ Ansible role in ‘roles’ directory.

Creating task inside role

Now, we need to write the tasks which will configure HTTPD server on our EC2 Instance.

For that go into the “httpdserver” role (or we can say directory) and then go inside the ‘tasks’ folder. There we’ve one file called “main.yml”. we have to edit this main.yml file. and write some plays to configure instance as a httpd web server.

Create httpdserver role
 - name: "Install httpd and php packages"
package:
name:
- "httpd"
- "php"
state: present

- name: "copy code from GitHub"
get_url:
url: https://raw.githubusercontent.com/Shashikant17/ansible_task_for_httpdserver/main/index.php
dest: "/var/www/html/index.php"

- name: "Start httpd services"
service:
name: httpd
state: started

Here I used the ‘package’ module to install ‘httpd’ and ‘php’ packages. Next using “get_url” module we fetch code from GitHub and save it in web server default document root path i.e. ‘/var/www/html/’ with our code file name, here it is ‘index.php’. Finally I’m using ‘service’ module to start the service of httpd server.

Edit main.yml file in tasks folder.

Now let’s deploy our Ansible Playbook

Go to workspace where is our Playbook and Run it.

## ansible-playbook <playbook_name.yml> --ask-vault-passansible-playbook ansibleTask2.yml --ask-vault-pass

It will run your playbook but just before running playbook this command will ask vault password, give that password and you will see your deployment started perfectly fine.

Run ansible playbook
Playbook run successfully…Now check your EC2 instance on AWS and put its public IP in browser

Finally if you go to the browser and type the public IP of the instance you will see that your web page is working completely fine.

Apache Web server is configured successfully by Ansible.

--

--