Configuration Management With Ansible.
Tags: ansible, devops, automation, tutorial
Published: 2023-06-09 08:42:12

**Introduction**
In the world of DevOps where automation is necessary, ansible is one tool used to automate tedious and manual tasks.

**What is Ansible?**
Ansible is a configuration management tool used to automate repetitive tasks like cloud provisioning, and application deployment. 

Ansible connects to nodes and uses the concept of control and managed nodes and push modules to them from a centralized place. This will then execute the modules and automatically remove them when the action is complete.

Ansible is agentless in the sense that no additional software is required to be installed on the target machines, ansible is just executing bash commands or actions over SSH or Windows Remote Management connections.

**Basic Ansible Terms**
- Hosts: a machine (either physical hardware or remote) hosted by ansible.
- Inventory: a collection of all the hosts and groups that Ansible manages.
- Group: Several hosts grouped together that share a common attribute.
- Module: Units of code that Ansible sends to the nodes for execution or actions run by tasks.
- Tasks: Units of action that combine a module and its arguments along with some other parameters.
- Playbooks: An ordered list of tasks along with their necessary parameters that define a recipe to configure a system.
- YAML: A popular and simple data format that is very clean and understandable by humans (Ansible playbooks are written in YAML format).
- Roles: Redistributable units of organization that allow users to share automation code easier.

**Demo**: In this article, I will demo how to use ad hoc commands (a quick way to run a task on one or more managed nodes) and how to use ansible playbook to install an application on a virtual machine.

**Prerequisites**
- A cloud provider (Azure with an active subscription) - to create virtual machines.
- An SSH client (I will be using Mobaxterm) to SSH into my VMs.

**Steps**
- Login to your Azure account and create a virtual machine (for now I will create 1 VM which will be my control node).
- Using an SSH client, I will SSH into my control node

![Mobaxterm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftaq3re6kvsg3yvk5res.png)
![successful SSH](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/czhthzza2oy4vd85fmi8.png)
- To enable me ssh into other machines, I will need to create an ssh key on my control node using `ssh-keygen -t rsa` command

![create ssh key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n64hfzgrvzasgvdjofyv.png)
- After which I will navigate to the directory and get the public key.
![navigate to public key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a1j51jo355znwmcuqto5.png)
- Go to the Azure portal, search for ssh keys and create a key with the public key gotten from the step above.
![upload public key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6k4n7blexedhwkjmyv6y.png)
- I will create 2 VMs that will serve as my managed nodes with the public key so as to enable swift ssh connection between the control node and managed nodes.
- SSH into VM1 using `ssh <ip address of vm>` on the control node.

![ssh to vm 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6gjdcudyas64nzlvmqhx.png)
- And use `exit` to logout out of the machine (I repeated the same process on my second VM).
![exit ssh connection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xpstujifgn2z9egvh6i3.png)
- I will install ansible on the control node (no installation will be done on the managed node because ansible is agentless).

- Firstly, I will run `sudo apt-get update` command to download information for all packages listed in the sources file.
![update package](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f7g1193of0bz5rjk0nby.png)
- Then install ansible with `sudo apt install ansible` command.
![install ansible](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6d406yywk9tos8c53ag.png)
![install ansible](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fku5cx9ueedt1ukywswu.png)
- Checking to see if the installation was successful by using `ansible --version` command. 
![ansible version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fytm7crfh8tn97t6x0j.png)
- I will create an inventory file to store a list of my host and group (I grouped my hosts in a test group); note that the default inventory file is located in `/etc/ansible/hosts`
![inventory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6jft8nl28r5le8033b98.png)
- Using ad hoc command: `ansible test -i inventory -m ping` to execute a ping command on all hosts.

![ad hoc command](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vlpfphxonrtcqc5e1czc.png)
**Using ansible playbook to deploy a website on virtual machines**
Ansible playbooks are the simplest way to automate repeating tasks in the form of reusable and consistent configuration files. They are written in YAML and contain any ordered set of steps to be executed on our managed nodes.

- My playbook which will deploy a website on my target machines is in the [main.yml](https://github.com/KeneOjiteli/getting-started-with-ansible/blob/main/main.yml) file

![ls command](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ac9rcw7zraoiagsk5ed6.png)
- Before executing the play book command, notice that the VMs are empty (not accessible).

![empty vm](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x182yoci03l2neq16sdm.png)
- Using `ansible-playbook -i inventory main.yml` command to run playbook; notice that it runs each task for the 2 managed nodes/target machines I specified in my inventory file.

![run ansible playbook](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6nvpiwr24by6igqckdiv.png)
![run ansible playbook1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nm1dozw5f5cfs083nrug.png)
- After the playbook is run, I can now access the website on both target machines (notice the different IP addresses for both machines on the images below)

![target 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m9qjgkqm0t9t73ii9lgn.png)
![target 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45rmol6nmbd8yqnqwjay.png)
**Things to note**
- Ansible is agentless meaning that no additional software installation is required on the managed nodes.
- Ansible is just executing commands over SSH.
- The default inventory file in ansible is located in /etc/ansible/hosts.
- Ansible modules are idempotent which means that changes are applied only if needed; the current state is checked and nothing is done unless the current state is different from the specified final state.
- Ansible playbooks are written in yaml format

**Challenge Encountered**: the challenge I encountered was the inability to establish an ssh connection between my VMs, but this was resolved by creating an ssh key and passing the public key to the managed nodes while the control node had the private key.

**Conclusion**: through this tutorial, we have learned:
- About ansible and its basic terms.
- How to use a simple ad hoc command to ping host machines.
- How to use a playbook to deploy a website on a virtual machine.

Kindly visit the project [repo](https://github.com/KeneOjiteli/getting-started-with-ansible) and thank you for reading.