Install Apache Web Server and Serve a Custom Webpage Using Ansible

Install Apache Web Server and Serve a Custom Webpage Using Ansible

As a cloud engineer, automation should be at the center of everything you do. Imagine you had to setup two servers, install some webservers and add some programs for a new staff, easy peasy to do on the two servers. Just log into them one at a time and install what needs to be installed and hand over to the new staff.

Now flip it and you have to setup 100 or 200 servers for 3 departments, it would take you weeks to do this manually and you are prone to making mistakes cos the repetition would become very tiring. However when you automate the process it will take you less than an hour to complete.

⚡ What is Ansible

Ansible is an open-source platform used for automation and for various operations such as configuration management, application deployment, task automation, and IT orchestration. Ansible is easy to set up, and it is efficient, reliable, and powerful.

⚡ Ansible Architecture

Ansible uses the concepts of control and managed nodes. It connects from the control node, any machine with Ansible installed, to the managed nodes sending commands and instructions to them.

⚡ Control node requirements

For your control node (the machine that runs Ansible), you can use nearly any UNIX-like machine with Python installed. This includes Red Hat, Debian, Ubuntu, macOS, BSDs, and Windows under a Windows Subsystem for Linux (WSL) distribution. Windows without WSL is not natively supported as a control node.

⚡ Managed node requirements

The managed node (the machine that Ansible is managing) does not require Ansible to be installed, but requires Python to run Ansible-generated Python code. The managed node also needs a user account that can connect through SSH to the node with an interactive POSIX shell.

⚡ Install Ansible on Ubuntu

To install Ansible on Ubuntu you need to add the PPA to you apt repository and also install the necessary dependencies. Use the below commands:

sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository –yes –update ppa:ansible/ansible
sudo apt install ansible

⚡ Create a Common User

Ansible requires a common user across all the nodes, if the user you are working with is called ansible ensure you have an ansible user on all your nodes.

The user on my control node is named vagrant and so I will create a vagrant user (or any other user you want) with sudo privilege on my other nodes and ensure that the user can run sudo commands without password.

(I already have a vagrant user on all my servers and so I will be using the vagrant user for this walkthrough).

This is useful and necessary so that when we run the commands and SSH into our nodes, we won’t be stuck because any of the nodes requires a password.

sudo adduser vagrant

To give this user sudo privilege and ensure that the user can run sudo commands without password, I will edit the /etc/sudoers file using the command below:

sudo visudo

Enter the below into the file

vagrant ALL=(ALL) NOPASSWD:ALL

Do this for all the servers.

⚡ Generate SSH Keys on the Control Node

Before you begin this step switch to the Vagrant user.

Generate an SSH key on the control node. The private key will be on the master and we will copy the public key to the managed nodes (hosts).

Use the command below:

sudo su vagrant
ssh-keygen

Now we will copy the public key to the managed nodes, retrieve the public key and then navigate to the .ssh/authorized_keys/ file and add the copied key into the file:

On the control node

cat .ssh/id_rsa.pub

Copy the outputted public key

On the managed node

vi authorized_keys

⚡ Create Your Inventory

Ansible inventory is a file containing a list of your managed host, these are the servers on which your tasks will be carried out.

You can make use of the default hosts files in the /etc/ansible directory but it’s better to create yours and use that so that in a case where you make a mistake you can use the default host file provided by ansible as a reference for the correct configuration syntax.

To that effect I will make an ansible directory and this is here i will be saving my inventory and playbooks.

mkdir ansible
sudo vi myhosts

In the inventory file add the IP addresses of your managed nodes. You can use the IP a command to get the IP address of the nodes.

⚡ Configure your Ansible Configuration file

The default ansible configuration file is in the ansible.cfg file however when you open that file you will find it almost empty with instructions on how to populate it.

When you run the ansible –version you will see where your current config file is located.

For what we want to do in this post though we want our configuration very basic and so I will create a new ansible.cfg file in the ansible directory I created earlier and populate it with the basic configuration I want to use for this post.

vi ansible.cfg

Enter the below into the file:

[defaults]
inventory = myhosts //(the config file is in the same place as the inventory, hence why I don‘t need to add the full path to the inventory)
remote_user = ansible //(or whatever user you are using)
host_key_checking = false

[privilege_escalation]
become = true
become_method = sudo
become_user = root
become_ack_pass = false //(we don’

t want a password)

Save the file. now if you run the ansible –version command again it will show the new config file path.

⚡ Check Connectivity using adhoc Command

Using ad hoc commands is a quick way to run a single task on one or more managed nodes.

Some examples of valid use cases are rebooting servers, copying files, checking connection status, managing packages, gathering facts, etc.

The pattern for ad hoc commands looks like this:

ansible [host-pattern] -m [module] -a “[module options]”

We will use the ping module to check the connectivity to our servers.

Run the below command:

ansible all -m ping

💡 TIP

Because we specified our inventory file in the ansible.cfg file we do not need to pass the inventory file path along with the -i flag with the adhoc command.

⚡ Prepare Custom Website Files

Apache is a webserver and it serves an apache website by default, this is not the site we want our apache webserver to server and so we would need to retrieve the config file for our custom website.

The files are hosted in my GitHub account and so clone that into a folder on my control node.

First I need to install git on the control node, do that using the command below:

sudo apt update
sudo apt install git

I will create a new directory and it is in this directory that I would clone this repo into (you can use any repo of your choice). The repo contains the html and CSS code for a webpage I designed earlier on.

mkdir webpage

Now I’ll navigate into the directory and clone the project there.

cd webpage
git clone https://github.com/ChigozieCO/assignment-03-WP-Pusher.git

This page will be used in our playbook.

⚡ Create Playbook

Create a playbook directory and navigate into the directory

mkdir playbook
cd playbook

Now we will create our playbook, I will name it serverplay as the playbook will be contain tasks to install apache2 web server on my nodes.

sudo vi serverplay.yml

Copy the below and paste it into your playbook, this is the content of your playbook


– name: Setup webserver and copy custom webpage
hosts: all
become: yes
tasks:
– name: Update apt package cache (Ubuntu) / Update yum package cache (CentOS)
when: ansible_os_family == ‘Debian’
apt:
update_cache: yes

– name: Update yum package cache (CentOS) / Update apt package cache (Ubuntu)
when: ansible_os_family == ‘RedHat’
yum:
update_cache: yes

– name: Install Apache (Ubuntu) / Install Httpd (CentOS)
package:
name: “{{ ‘apache2’ if ansible_os_family == ‘Debian’ else ‘httpd’ }}”
state: latest

– name: Enable and start Apache/Httpd
ansible.builtin.service:
name: “{{ ‘apache2’ if ansible_os_family == ‘Debian’ else ‘httpd’ }}”
enabled: yes
state: started

– name: Copy custom webpage files
ansible.builtin.copy:
src: “~/ansible/webpage/assignment-03-WP-Pusher/”
dest: “/var/www/html/”
mode: ‘0755’

– name: Restart Apache2 (Ubuntu) / Httpd (CentOS)
ansible.builtin.service:
name: “{{ ‘apache2’ if ansible_os_family == ‘Debian’ else ‘httpd’ }}”
state: restarted

⚡ Run Playbook

Run the play book now with the below command:

ansible-playbook playbook/serverplay.yml

💡 Note

Because I am running my playbook from the ansible directory we created earlier, I do not need to specify the location of my inventory as I have done that in my config file already.

My playbook ran successfully and we can see it in the screenshot below:

To see your webpage enter your node’s IP address in a web browser, from the below screen shots you can see the pages displayed on my browser.

managed node 1

managed node 2

Leave a Reply

Your email address will not be published. Required fields are marked *