How to Setup Ansible on Windows & Deploy Web Server on AWS

Sameed Uddin Mohammed
7 min readApr 19, 2021

Ansible is an simple agentless + configuration management + automation that automates deployment, + orchestration. Ansible is popularity due to it’s simplicity for being opensource, agentless, efficient, requires no additional software installed on target machine, It use the simple YAML .(which stands for “YAML Ain’t Markup Language”)

Ansible architecture is very simple. It requires Ansible Controller basically a node either a laptop, PC or server where Ansible is installed with the module of configuration files called playbook (like a recipe book) and inventory of target servers called hosts. Playbook consists of Roles, and Roles consists of Tasks. Task is an individual command in Ansible. By using inventory we group the nodes by using labels.

Ansible Server and the node talks by using SSH.

Steps to work with Ansible:

  1. If you are using Linux skip this step if not use this link to install Ubuntu VM on your Windows 10 & also install Visual Studio Code.
  2. Create playbook and inventory in local machine
  3. Create SSH to the target nodes
  4. Ansible Server gathers the facts of the target nodes to get the indication of the target nodes
  5. Playbook are sent to nodes
  6. Playbook are executed in the nodes

What is-

Ansible Server or Controller: The machine where Ansible is installed and from which all tasks and playbooks will be ran.
Module: Basically, a module is a command or set of similar commands meant to be executed on the client-side.
Task: A task is a section that consists of a single procedure to be completed.
Role: A way of organizing tasks and related files to be later called in a playbook
Fact: Information fetched from the client system from the global variables with the gather-facts operation.
Inventory: File containing data about the ansible client servers which can be defined in later examples as hosts file.
Play: Execution of a playbook.
Handler: Task which is called only if a notifier is present.
Notifier: Section attributed to a task which calls a handler if the output is changed.
Tag: Name set to a task which can be used later on to issue just that specific task or group of tasks.

Prerequisites for Installing Ansible:

  1. The control machine that we will run Ansible commands from.
  2. Preferably Linux/Unix based.
  3. You can also setup using Vagrant box or Docker .
  4. You will need Python 2.x or 3.x installed.
  5. Documentation for Installing Control Machine here.

Resources you will need to follow along this basic Ansible Lab:

  • Windows or Linux Setup
  • AWS (create if you dont have one , the wont charge as its comes under Free-Tier)or any of your favourite vendor specific Cloud Account.
  • For this lab you need 3 EC2 instances to create
  • To connect your ec2 instances, you need key-pair from AWS Account link.

STEP 1: Setup Windows Subsystem for Linux

(if you are using Linux :
$ sudo easy_install pip <---
you need to install pip first.
$ sudo pip install ansible <--- install ansible next.
$ ansible --version <---
finally make sure its installed.)
  • After installing Ubuntu WSL & Visual Studio Code , Login to Ubuntu,& create a user called ansible-user
  • Then login to AWS Console and go to CloudFormation > Create stack > Select Upload a Template file then use this code from Github repository.
  • Click Next & Set a Stack name & select a key-pair you have created from here (name it Ansible-keypair.pem), then click next > set a tag > next review and create stack.

STEP 2 : Install Ansible on WSL

$ sudo apt-get update  <--- update the OS packages.
$ sudo apt-get install ansible -y <-- install the ansible.
$ ansible -- version <--
make sure its installed correctly.

STEP 3: Setup SSH Connection to Target Server

  • Then log back in to your local host — open the Visual Studio Code(from Desktop) then press Ctrl + ~ which will open terminal then select default Shell as WSL Bash & then use the following commands:

(Make sure you can ssh to server with certificate and can ssh successfully)

  • Create a Directory for Ansible & also for ssh key-pairs.
  • Then change permissions on key-pair to read.

$ mkdir /home/ansible-user/ansible/
<--to keep all ansible files.
$ cd ~ <-- got go back to home directory
$ explorer.exe . <- will open the folder, then drag it in VS Code.
$ ansible --version <--
to check where default ansible.cfg stored, but we will create another location for easy access.
$ mkdir .ssh/ <---to store the key-pairs in hidden folder.
$ explorer.exe .ssh
<--- open the window, then drag key-pair from Downloads folder in Windows-10 which you got from AWS to .ssh
$ chmod 400 .ssh/ansible-keypair.pem
<-- to give ansible read permission.
$ ssh -i ~/.ssh/ansible-keypair.pem ec2-user@<ip address of any ec2 instance>
<-- Test check connectivity & permissions working.

Tip: Check the IP Addresses in Ouputs tab in AWS CloudFormation Stack

STEP 3: Setup Custom Inventory File (reference link)

  • We need to give Ansible a reference to over inventory servers we want to execute commands on.
  • There are two types of inventory files- Dynamic & we are using Static one.
  • You can use either YAML or INI format.
  • Create a host called hosts-dev .
#(refer AWS CloudFormation Stack Outputs tab,we have ec2 instances created earlier with same names & past accordingly with their names like below)# hosts-dev              <alias> <hostname> = ip address[webservers]  <--- group
app1 ansible_host=54.211.227.5 <--- hostname with ip address
app2 ansible_host=3.211.163.3
[loadbalancers]
lb1 ansible_host=52.3.9.173 <--- hostname with ip address
[local]
control ansible_connection=local

Then use the following command to use this file to list all hosts

sameed@local:~/ansible$ ansible -i hosts-dev — list-hosts all

Step 4: Setup Configuration File (reference link)

  • Creating a configuration file to control local Ansible Environment settings.
  • Use the following snippet to setup ansible.cfg & key-pair path to access your ec2 instances from your AWS account which we have created earlier.
# ansible.cfg
[defaults]
inventory = ./hosts-dev
remote_user = ec2-user
private_key_file = ~/.ssh/ansible-course-keypair.pem
host_key_checking = False
#Windows only users
[ssh_connection]
ssh_args = -o ControlMaster=no

Step 5: Creating & Working with Playbooks (reference link)

  • Playbooks use YAML syntax which allows you to model a configuration or a process.
  • Playbooks are composed of one or more plays in a list.
  • The goal of a play is to map a group of host (defined in inventory file) to a tasks that are used to call Ansible modules.
  • By composing a playbook of multiple plays, it makes it possible to orchestrate multi-machine deployments and allows us to run certain steps on all machines in a group.
  • to start with three dashes (---) & proper indentation using spaces and not tabs!

Download the playbooks via github here to follow along with me(also you can download other playbooks and use for other tasks)

In this example we are going to automate the simple task in Ubuntu by Updating the OS, installing different services for a Web-Server, :

Create playbooks folder in ansible folder,then copy & paste the following files individually.# yum-update.yml

---
- hosts: webservers:loadbalancers
become: true
tasks:
- name: Updating yum packages
yum: name=* state=latest
# install-services.yml

---
- hosts: loadbalancers
become: true
tasks:
- name: Installing apache
yum: name=httpd state=present
- name: Ensure apache starts
service: name=httpd state=started enabled=yes

- hosts: webservers
become: true
tasks:
- name: Installing services
yum:
name:
- httpd
- php
state: present
- name: Ensure apache starts
service: name=httpd state=started enabled=yes

Also create a index.php file in ansible folder:

<?php
echo "<h1>Hello, World! This is my Ansible page.</h1>";
?>

then create this one for webserver to access html file :

# setup-app.yml

---
- hosts: webservers
become: true
tasks:
- name: Upload application file
copy:
src: ../index.php
dest: /var/www/html
mode: 0755

- name: Configure php.ini file
lineinfile:
path: /etc/php.ini
regexp: ^short_open_tag
line: 'short_open_tag=On'
notify: restart apache

handlers:
- name: restart apache
service: name=httpd state=restarted

lastly you will need a setup-lb.yml for loadbalancer setup:

first create a config folder:$ mkdir ansible/config
and use the following to setup loadbalancer
create a file called lb-config.j2 & copy
ProxyRequests off
<Proxy balancer://webcluster >
{% for hosts in groups['webservers'] %}
BalancerMember http://{{hostvars[hosts]['ansible_host']}}
{% endfor %}
ProxySet lbmethod=byrequests
</Proxy>

# Optional
<Location /balancer-manager>
SetHandler balancer-manager
</Location>

ProxyPass /balancer-manager !
ProxyPass / balancer://webcluster/
Finally we are going to create last playbook for uploading template file # setup-lb.yml

---
- hosts: loadbalancers
become: true
tasks:
- name: Creating template
template:
src: ../config/lb-config.j2
dest: /etc/httpd/conf.d/lb.conf
owner: bin
group: wheel
mode: 064
notify: restart apache

handlers:
- name: restart apache
service: name=httpd state=restarted

Testing and Running Playbook

lets congregate all the playbooks we have created in all-playbooks.yml file in playbooks folder so we can run all at once.

# all-playbooks.yml
---
- import_playbook: yum-update.yml
- import_playbook: install-services.yml
- import_playbook: setup-app.yml
- import_playbook: setup-lb.yml
sameed@local:~/ansible$ ansible-playbooks/all-playbooks.yml

Once this is done run the following command to orchestrate the playbooks at once & see the magic!

Now open the ip address of one of EC2 Instances or LoadBalancer to check the webpage is working or not.

Summary:

  • Playbooks are an ordered lists of plays that can run tasks for configuration and orchestration.
  • These plays allows us to run commands on a group or subset of servers within our inventory.
  • Create infrastructure as a code that can be managed in a source control.
  • Playbooks can be run multiple times without affecting previous runs.

Reference links:

https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

https://docs.ansible.com/ansible/latest/user_guide/playbooks_conditionals.html

https://docs.ansible.com/ansible/latest/modules/import_playbook_module.html

Thank you for reading!

Please Do give a Clap, Share your thoughts and suggestions…

--

--

Sameed Uddin Mohammed

Terraform|3x-AWS|2x-Azure|2x-GCP|CertifiedCloud/DevOpsEngineerLooking for better opportunities- Remote| Join me https://chat.whatsapp.com/EiCi7XYnCSD7BQnPz2mJIa