Ansible as a Configuration Management Tool
Tags: ansible
Published: 2023-10-15 19:20:42

### Ansible as a Configuration Management Tool


Configuration Management has evolved over the years and has been a revelation for solving critical problems in the tech industry that have allowed organisations to have lots of servers in their thousands. As DevOps Engineers, we are required to perform certain functions like installation, updates, upgrades, patches, security fixes and provisioning servers. These servers could be web servers, NFS servers or database servers and when provisioned, these servers are required to be managed properly. There are various configuration tools in the market like Ansible, puppet, salt and Chef but Ansible stands out of all of them because of the major functions and tasks carried out by the tool.

### Advantages of Ansible as a configuration tool.


1) Easy and free to use and it's Python based which makes it the preferred choice to most DevOps Engineers

2) Ansible is Agentless and once installed on the control server, it controls other targeted servers to communicate with them through SSH

3) Ansible is pushed-based and once pushed it can be automatically installed on all servers at once if they are all in the inventory.

4) Ansible uses YAML file which is easy to learn and can be installed in Ubuntu and Linux repos and readily available to be installed.

In this project, we would make most of the routine tasks automated by installing and configuring an Ansible client to act as a Control server and creating a playbook to automate server configuration. Ansible client would be acting as the Bastion Host as an intermediary through which access to the internal network can be provided.

We would also create a simple Ansible playbook to automate server configuration

The pre-requisite for the projects is the following.

1) Fundamental Knowledge of Installing and downloading software

2) Basic Understanding of Linux Commands

3) AWS account login with EC2 instances

4) 3 Ubuntu Webservers

5) Database Server: On Ubuntu 22.04+ MySQL

6) Storage Server: Red Hat Enterprise Linux 9 +NFS Server

7) Load Balancer Server

8) Ansible and Jenkins Server

9) Python Language

### IMPLEMENTATION STEPS: 

Set up all EC-2 instances and ensure you log in with your details to your AWS console via https://aws.amazon.com.

Click on the EC2 link, spin up 7 EC2 instances and make sure they are set up with the operating systems below.
NFS server (Red hat),3 Webservers, Ansible-Jenkins, Load Balancer and Database Server

You can see the instance state that shows all servers are currently running. We would be updating our Jenkins server and naming it Jenkins-Ansible-Server for clarity as we want to use this to run our playbooks.


![Instances Running](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pv89ld54m43dnbgg5k4j.jpeg)



We would navigate to GitHub to create a new repository called ansible-config-mgt.


![Ansible-config-mgt new repo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z1r5f6d6y9purx1dilao.jpeg)


Install Ansible and check its version.


![ansible-version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i622z7cg65lgvl0sy3ay.jpeg)


### JENKINS CONFIGURATION

Now we have to configure Jenkins job to save our repository every time we make changes. Please note that our Jenkins server was configured to use an elastic IP to be able to maintain a dedicated server.

1) Access our Jenkins and create a new project "ansible new" as shown below


![Jenkins](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8jpj3x7k1xfxussn6d3.jpeg)


![Jenkins-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wv2ng0pwk87xwjko4qqr.jpeg)



Fill in the description of your project and select git.

![Jenkins-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4fhi1e30qu0kelkmy7hb.jpeg)


Copy and paste the git repo and ensure it is on the main branch.

![Jenkins-3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ulxjj414z7e0opsz6aey.jpeg)


![Jenkins-4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rockj6krn3le2mmnuouk.png)



Click the build now manually to test it


![Build manually](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lhsq4qgbgtgcfg556ad0.png)


Proceed to configure and set webhook to trigger ansible build .


![Add-Webhook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qv9yqce7g42ipljqwr6n.jpeg)



Insert the Payload URL and the content type and add the webhook.


![Payload](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ewlom7ttdrxklgh2z7a.jpeg)


![Webhooks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4wz9ge2qfzr3qoelg1j.png)




Once added, we proceed to commit new changes.

![Git-Commit](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ijpqqlaewrsry1bu2fej.png)


![Git-Commit2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wuk08h3pf7091zl44di.png)



Navigate back to Jenkins to select the "GitHub hook trigger for GIT Scm polling.
Then Apply and Save

![WebHook-Git](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kix6t23xon185dt6twhz.png)


Click on post-build actions and archive the artefacts by adding a ** and click
Apply and Save

![Post-Build](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a7f2y61zi1u943fkteyt.jpeg)


Once all task is completed, we then proceed to commit more changes but this time it would automatically populate in the Jenkins server.


![Commit-Changes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xsn1njt9mz8tlc8tx9hl.jpeg)


![Git-Commit-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tg0svkduv1lo2iroc1xx.png)

![Build-6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqtwk1j177st07956tmi.jpeg)




Navigate to the terminal and check any of the archived builds using the commands below

![Terminal-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ceq40r8lvxb5224t77dp.png)


Please note: Anytime you try to stop and start your Jenkins-Ansible server. The IP address change. An elastic IP address is used to ensure the ip is still available when the instance is turned and has a static IP


## Prepare your environment using Visual Studio Code


We need the Visual Studio Code to write some codes. We would first clone down our ansible-config repository to our Jenkin instance. You check the content of the Ansible server to confirm it is there as shown below.


![Terminal-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3l3vlb14tuy0l280c6vs.png)

Navigate to the main branch and create a new branch called Feature/ticket-1

![Feature](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bhbi8lb1m52we2beg8i8.png)


![Terminal-3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9m1kz76v2blkzijpw7r4.png)



Connect via SSH the Jenkins-Ansible-Server

![VSCode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7o732muaooxha869eb4i.png)


![VSCode-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cit7edzdguvruriz1kmn.png)


![VSCode-3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pl9nbrp9pfz6h7445r2i.png)





Create the folders and .yml files directly as shown below.
Inventory folder: contains dev.yml prod.yml staging.yml uat.yml files
Playbook folder: contains common.yml file


![Inventory-Playbooks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u7dcfbxfm0k0cmdrqmro.png)


Set up an ansible inventory where all the host private IP addresses are kept and executed all at once. The 3 webservers' private IPs are kept in this inventory as shown below.


![Inventory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c8alu72tnwcqasc6l33f.png)


Ansible uses port: 22 as its default and it needs to SSH target servers from the Jenkins- Ansible server using the SSH-AGENT concept. We navigate into the Jenkins-Ansible server using the Termius terminal and try to perform the ansible operation to ping the target-server-A using the command below.


![Terminal-4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/larf6lvo7wlmgemjwx49.jpeg)


![Terminal-5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/51j5ogtu4kuzecm7o2r2.jpeg)

Or Using the SSH to successfully as seen below with the command

"ssh ubuntu@ipaddress"


![Terminal-6](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ifsn4zb7xk8d4xcvnxjk.jpeg)


![Terminal-7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1oc9y0aepp6qys8q4m83.png)



Please note that we have also connected to the target 3 servers to ensure the public key file of the Jenkins- Ansible server is added in the authorized keys file .ssh/ file as shown below

Firstly, we retrieve the public key from the Jenkins-Ansible server as shown below. Add them into each server as seen below


![Terminal-8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1o4s4myndbap48pnug7g.jpeg)


![Terminal-9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tzmgfgh6i36d6m15pbr3.png)


![Terminal-10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/20xp9q5dihln73943b5m.png)


![Terminal-11](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/52ha1i9exvbtda96yts1.png)


Create the agent ID and confirm the path where the .pem file key is located. Perform the ssh-add operation and confirm the identity is added and listed.

![ssh](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d3bjkxyzfg2g3833ojd8.png)


![pem](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ai6ne4rko7qe4sk369c5.png)


We can see that the Jenkins-Ansible Server has SSH into the target servers.


![Terminal-12](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uoarx11lhgstaddkyi5k.png)


![Terminal-13](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l3ky2qly84aq0udbge24.png)


![Terminal-14](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/czpgmzszf4rs9812zaef.png)



Update the Inventory/dev.yml file and take note that we have 1 ec-2 user and 5 ubuntu servers

![Inventory-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x8gb74wrbpbpdogehewk.jpeg)



Change the directory to the playbooks folder and update the common.yml file as shown below. It can be seen that all servers should be executed from the playbooks


![Playbooks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rw321dxz6hkcf61gen97.jpeg)


Run some shell script commands by using the Ansible command to ping the dev.yml file as shown below and success depicts all is working as expected.

ansible all -m ping -i dev.yml


![Ping-Success](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5apbcuujrfn8uvq5d8d.jpeg)



With the Ansible-playbook command, Install the wireshark from the Jenkins-Ansible server to all other target servers and confirm that each servers received those changes.


![Ansible-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lvdwj2xwq5bic37be41o.jpeg)


![Ansible-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tf118dr1c9vatrrfaim7.jpeg)



Check each server to be sure wireshark is installed on them as shown below

![WS1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x22qb5hk9rulrxsh20r9.png)


![WS2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/padaiitfhr33q1sxyzha.png)


![WS3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gi9pfo6415x8yb7i87x8.png)


![WS4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6cwle7fziwroktarndr3.png)


Now that we confirmed this, we will be pushing our commit into the github and creating a PR and expect Jenkins server to be triggered automatically and builds and artefacts generated.


Use the "git branch" to know the branch we are one and "git status " to check the status of the untracked files we have. They are shown below


![GIT-1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vusah9lpb3jc7lfl8yps.jpeg)

Use "git add inventory" and check to status to confirm the new files have been added.


![GIT-2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ccmqxpmkpqmqudt0u9iv.jpeg)

Add playbooks as they still shows untracked files


![GitHub-3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dn7qi0ys7dprb1zcu3ed.png)

Run the git commit with a message tag and set out the git account to be accepted on the terminal. This would require the use of a classic token from git as a password would not be allowed



![Git-7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6v248u65bnudqqdqv1u2.jpeg)

Set up the Url origin and check the remote.

![Git-7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1kku1fsv2ab2nm3it6hd.png)



Navigate to GitHub. Create and merge the PR to the main.

![Git-8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ssn3qxfo8lxz1vjgxhqs.jpeg)


![Git-9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uz6ne3r5bqqegv4tpab.jpeg)


![Git-10](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c1mxd7abw82wsmicw6jt.jpeg)


![Git-11](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cr1cli846l66uhkqysci.jpeg)


PR successfully merged and the Jenkins build would be automatically triggered as shown below. 2 jobs were created

![Git-12](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lpz8shk8haiur0iwjlqu.jpeg)


![Git-13](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ld76ub4yc8piju7036ym.png)


![Git-14](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/afe43xfsqqvo932ku4yd.png)

Check the server and view where the build is located

![Terminal-9](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aks0nzucrnu8wxftih9d.png)

Congratulations!!!! You have just automated your routine tasks by implementing an Ansible project