Overview of Ansible and Ansible Playbooks


































In this article, you will get a brief idea about ansible, ansible playbooks, roles and how to use include module in your playbooks and we will be showing how to automate the process of creating a small application using database – mysql and webserver – flask by using ansible playbooks.


 

Why Do We Need Ansible?

Ansible is an open source IT Configuration Management, Deployment & Orchestration tool. It aims to provide large productivity gains to a wide variety of automation challenges. This tool is very simple to use yet powerful enough to automate complex multi-tier IT application environments. It models your IT infrastructure by describing how all of your systems inter-relate, rather than just managing one system at a time.

 

For an example : Assume that if you want to install some software in a large number of servers , you will not install those softwares one by one into the server right ….. It will take a hell lot of time !! .  

 

Advantages of using Ansible 

 

1.   Execute tasks from your one Control Machine where Ansible is installed.

 

2.   Configuration and Installation and Deployment steps in a single yaml file.

 

3.   Re-use same file multiple times and for different environments.

 

4.   It uses no agents and no additional custom security infrastructure, so it's easy to deploy - and most importantly, it uses a very simple language (YAML, in the form of Ansible Playbooks)

 

5.   More reliable and less likely for errors

 

 

Ansible Architecture 





The Ansible Orchestration Engine has a direct interaction with the users who write playbooks to execute the Ansible Orchestration engine. It also interacts with cloud services and Configuration Management Databases.

 

Inventory --> A list where we mention the hosts or nodes along with their IP Addresses, servers, databases which the control machine gets connected to .

 

API --> APIs in Ansible are used as transport for Cloud services, public or private.

 

Modules --> These are the small tasks or programs that get executed in target servers. The modules can control system resources, like services, packages, or files (anything really), or execute system commands. 

 

Plugins --> It is a piece of code that expends the core functionality of Ansible. There are many useful plugins, and you also can write your own.

Playbook --> The sequential modules are grouped together in tasks where each task contains module name, arguments and description of task. Also, you can launch the tasks synchronously and asynchronously with playbooks.

Hosts -->  The hosts in the Ansible architecture are just node systems which are getting automated by Ansible. It can be any kind of machine – Windows, Linux,….etc

 

 

 Ansible Terms:

  • Controller Machine: The machine where Ansible is installed, responsible for running the provisioning on the servers you are managing.
  • Inventory: An initialization file that contains information about the servers you are managing.
  • Playbook: The entry point for Ansible provisioning, where the automation is defined through tasks using YAML format.
  • Task: A block that defines a single procedure to be executed, e.g. Install a package.
  • Module: A module typically abstracts a system task, like dealing with packages or creating and changing files. Ansible has a multitude of built-in modules, but you can also create custom ones.
  • Role: A pre-defined way for organizing playbooks and other files in order to facilitate sharing and reusing portions of a provisioning.
  • Play: A provisioning executed from start to finish is called a playIn simple words, execution of a playbook is called a play.
  • Facts: Global variables containing information about the system, like network interfaces or operating system.
  • Handlers: Used to trigger service status changes, like restarting or stopping a service.

 

Installation of Ansible 


Controller Machine – CentOs OS Used


$sudo dnf makecache









$sudo dnf install epel-release



$sudo dnf makecache














$sudo dnf install ansible
















To check ansible version —> $ansible --version











Steps to write a playbook – Copy a file from control machine to target servers




















This is the structure we are following . We are first creating an inventory file where all target servers are mentioned , which we want to connect through the controller machine.




In this inventory file we have added host names for 2 target machines (target 1 and target 2) and ansible_host is a parameter where we define IP address of the target machine.





We have created 2 target servers named as ansible-target1 and ansible-target2 with 2 CPU’s and 2 GB Memory and have taken Debian 10 OS.

 

These are 2 target machines which we have created in GCP.



Here, we are creating a user named “devtest” and assigned a password to that user . Then we are creating a ssh key file using ssh-keygen and paste that .ssh file to 2 target servers. We have also created the same user “devtest” in the 2 target servers.

$sudo useradd devtest —> Create devtest user

$sudo passwd devtest —> Assign password to devtest user

$su – devtest —> Change to devtest user

$ssh-keygen -t rsa  —> Create .ssh file for devtest user


Create same user “devtest” in target 1 server and target 2 server.






























First we are logging into the controller server where we have installed Ansible, in our terminal using the below ssh command :

$ssh -i <Path where private key is present> username@IP 















In this playbook we are copying files from controller machine to target servers. Here, “name” parameter at the first is giving a name to your playbook , “hosts” parameter is the host(target servers) where your ansible playbook will run on . Here, “all” means every host mentioned in inventory file. “name” parameter mentioned below the tasks field is giving a name to your specific task . The “copy” module here has some paramaters like “src” —> the source location where your file is present in controller machine  and “dest” —> the destination location where your file should be copied in your target machines.































To run the playbook using the command :

 

$ansible-playbook <Name of playbook file> -i inventory.txt –private-key <path of private key through you can connect to target machine>

 

Here, we can see that after executing the playbook the task is successfully completed (ok=2 and changed=1) where ok means that part of execution is already present in server and changed means that change has occurred . Ansible has idempotent feature which means if some part of the task is already present ….it will not reinstall it…it will rather go to the next part of the task.










Here, in the target machine 2 you can see that in /tmp/ directory test-file.txt is created .

 

Steps to write a playbook – Ping target machines







In this playbook we have used ping module which will test the connectivity from controller machine to target servers.












After executing the playbook you can see that we are successfully able to achieve the task.

 

Create a small application using MySQL database and Flask Webserver – Playbook



















This is the structure we are following . We are first creating an inventory file where all target servers are mentioned , which we want to connect through the controller machine. Then we have an app.py file which has some contents for application.











This is the inventory file which contains 2 target servers with their IP addresses. Their host names are db_and_web_server1 and 2.














































































This is the playbook where we are creating a small application using MySQL , Flask , Python. In the first module we are using “apt” module where we are installing Dependent packages for our application . 



Here, we have used loop condition . Since, we have many packages to install like python ,pip , python-setuptools and more….we are using loop to iterate among the list . The {{ item }} is Jinja2 templating format which we are using in ansible to work as a dynamic variable where values changes. 

In the second module we are using “get_url” module to download a .deb file from MySQL repository to install MySQL and “url” is the link where MySQL is present in repository and “dest” is where you want to install it in target servers. We have used “become”: yes because we wanted to execute the task with root privileges .

In the third module we are using apt module with deb which is help to execute that .deb file.

In the fourth module we are using apt module for Installing more packages for MySQL client and server .

In the fifth module we are using service module to start the MySQL database service.

In the sixth module we are using mysql_db module to create an application database “employee_db” and login_unix_socket is the path to a Unix domain socket for local connections.

 

In the seventh module we are using mysql_user module where we are creating a user “db_user” with password as “Passw0rd” with all database privileges.

 

In the eighth module we are using pip module to install packages of python flask dependencies.

 

In the nineth module we are using copy module to copy the app.py file from source machine to target machine “/opt/app.py” path 

 

In the tenth module we are using shell module to run the flask application in target machines.










































We are able to see that the playbook is executed successfully in both the target servers.

 

$ansible-playbook -i inventory.txt playbook.yaml –private-key <path of the file> -e “ansible_python_interpreter=/usr/bin/python3”


Where ansible_python_interpreter is set to python3 , otherwise by default it takes python(2.x) which is installed by default.



Now if we go to the IP address of the target 1 and 2 machines we can see that at 5000 port we are able to see welcome message.


And in the /how are you —> I am good, how about you ? message
























We can see that in target machines MySQL service is active and running .


















In target 1 machine —> We are able to see the database “employee_db” and user “db_user”









In target 2 machine —> We are able to see the database “employee_db” and user “db_user”


How to use include module in the same application and use host_vars directory to store all host file (not in inventory)





This is the directory structure we are following. In the host_vars we are creating different  yaml files for each hosts. It contains data models that apply to individual hosts/devices in the hosts.ini file. Hence, there is a YAML file created per device containing specific information about that device.

 

For 2 target machines we have different .yaml files 









Here, we can see that how inventory and db_and_web_server1 and 2 yaml file are present. The host names present in inventory files should be same name present in host_vars directory .










In the tasks we are assigning include module as an Array  where we are giving the path where the yaml files are present for database and flask webserver . This structure we have done to add more granularity and flexibility to the code. The complexity is reduced and in single playbook file we are not defining everything.





Here, we are adding the database tasks -MySQL tasks only










Here, we are adding the flask webserver tasks only.





















The playbook is successfully executed in target servers

How to use roles in the same application and use host_vars directory to store all host file (not in inventory)


Roles --> Ansible Roles allow you to develop reusable automation components by grouping and encapsulating related automation artifacts like configuration , templating , tasks and handle.


We are following this directory structures here. For 3 parts (python dependencies, MySQL, and flask webserver) we are creating 3 roles here.

 

Ansible Galaxy is a repository for Ansible Roles that are available to drop directly into your Playbooks to streamline your automation projects.

 

Execute this command for creating roles for each task

 

$ansible-galaxy init python —> It will create role directory structure for python 

 

$ansible-galaxy init mysql_db —> It will create role directory structure for mysql_db

 

$ansible-galaxy init flask_web —> It will create role directory structure for flask_web

 

In each of the role directory we have a subdirectory named tasks where in main.yaml you need to put your modules there.

 

In this yaml file we are adding all dependencies we require in python --> main.yaml 








In this yaml file we are Installing MySQL and adding databases and users in it.
















In this yaml file we are Installing Flask Webserver and running that using app.py













In this we have created some variables like db_name for Database Name , db_user for Database user and db_user_password for Database User Password in host_vars directory.



































The playbook for role is successfully executed in target servers.


For Code Reference , check my Github Repo : Learning Ansible

Comments

Popular posts from this blog

Getting Started with ArgoCD

DevSecOps — Implementing Secure CI/CD Pipelines