Ansible Tutorial for Devops Beginners-2024

Introduction

What is Ansible?

  • Ansible is an open-source configuration management automation tool designed to simplify IT tasks such as configuration management, application deployment, and task automation. 
  • It uses declarative language to describe system configurations, making it easy to understand and implement. 
  • Ansible is agentless, meaning it doesn’t require any software to be installed on the target systems, making it lightweight and easy to set up.

Use Cases

1. System automation (Any system automation)- 

  • If You want to set up web services and database service configuration, start and restart the services. 
  • You can do all those kinds of automation by using Ansible.

2. Change Management (production server change)-  

  • You can manage your production machines, and any changes to your production server through Ansible.
  • If you write a proper Ansible playbook, it can go directly into your documentation. It’s not going to be a very complicated script to understand If you write titles to your task in the Ansible playbook. you can also use that in the documentation.

3. Provisioning (Setup server from scratch/Cloud provisioning)- 

  • Provisioning means you can set up anything from scratch.
  • You can use Ansible to launch cloud instances like an EC2 instance. and then you can set up services on it like any front-end, back-end database, or web services.
  • Complete provisioning you can do through Ansible.

4. Orchestration (Large scale automation framework)- 

  • we can say combining multiple automation tools and scripts together and executing them in a proper order.
  • You can integrate Ansible with various other tools like Jenkins or any other integration tool or cloud services.
  • So, there’s so much integration with different tools and services that Ansible provides. so, you can do complete orchestration.

WHY Ansible?

Why is ansible used?

Ansible is Simple-  

  • Ansible is really a very simple tool compared to other automation tools or scripts. It’s also very clean.

No Agent(Agentless)- (Target machines are accessed by SSH, winrm & API)

  • you don’t have any agent in Ansible like Puppet, Chef, or Salt Stack.
  • So if you’re managing 100 servers through Puppet, Chef, or Salt Stack, you need to install agents in all those 100 machines.
  • But In Ansible you don’t need to do that. Ansible uses existing connections like for Linux, it uses SSH. For Windows, it uses winRM, or it has API-based modules.
  • So based on the target, it will use the right communication methods in its module.
  • So you don’t need to have any agent, you don’t need to do any setup.

No Database(YAML, INI, texts)-

  • There are no databases and complicated storage in Ansible.
  • You have YAML, INI, or text format where You have your playbooks, your scripts, your configuration in these formats, very simple formats. The output is written in the JSON format.

No complex Setup-(it’s just a Python library)

  • The setup is very simple For Ansible.
  • It is just a Python library, so you can say Pip install Ansible.
  • Also, you can install Ansible through package managers if you want to upgrade them again.

YAML- 

  • You don’t need to write programming language to do any automation. 
  • Ansible script or Ansible playbook is written in YAML format, which is very easy to read, and very easy to write. 
  • Its structure has very less complication compared to any programming language. 
  • That’s why we say Ansible is easy to read and write.

How does Ansible connect to its target?

How does Ansible connect to its target?

As a target system, it could be a Linux Server, Windows Server, cloud account, database, or it could be network equipment.

For Linux Server Connection- 

  • As I said, it is going to use SSH to connect to any Linux machine. 
  • Every Linux server will have SSH and you can take any Linux Server.
  • Linux server operating systems like Ubuntu Server, CentOS, and RHEL will have SSH running. So you don’t need to set up anything, you just need SSH detail and Ansible can connect to Linux machines using SSH.

For Windows Connection- 

  • it uses Winrm. Again, there will be WinRM service already there. You just need to enable a remote connection.
  • In Windows PowerShell, you have to enable the remote connection so you can connect to Windows through Winrm connection remotely.

For cloud Connection- 

  • Clouds like AWS, Azure, Google Cloud, or any other cloud, use APIs.
  • Apart from that, you can also manage network devices like switches and routers through Ansible or even databases.

For the database-

  • it’s going to use its own Python libraries. Like MySQL, it has Python MySQL Library.

So my point is you don’t need to set up an agent on the destination or in the server itself.

Well, by the way, there is no server in Ansible. Ansible is called a control machine In general.

NOTE: – We don’t call it Ansible server because it doesn’t run any service Like Puppet Server (it runs a service That’s why it’s a Puppet Server).

Chef Server (because it also runs a service), or Salt Master, Salt Server, runs the service.

But Ansible does not run any service. It just uses the Python modules and Python scripts.

to connect to the target machine, dump the Python script they’re executed, and return the output.

Important points 1: – 

  • Ansible is a pushed-based mechanism means the Ansible server pushes all the changes onto the target system.
  • The target system doesn’t need to do anything to update itself and its a source.

Important points 2: – 

  • For Winrm or SSH, it’s going to send the Python script to the destination, execute, and return the output.
  • But for the API task, it’s going to execute on the control machine locally. There’s no place where it’s going to send the script. It’s going to execute all the scripts locally.
  • So, you have remote execution in Ansible, and you have local execution also, and that’s totally dependent on the target. And you don’t need to really mention anything you just use the module, and you mention the destination. All those things are abstracted from you. Ansible will do all kinds of connections and execution behind the scenes.

Ansible Architecture: -

Ansible Architecture

a.Inventory file: –

Ansible Inventory
  • In the inventory file, you will have the target machine’s information.
  • for example, IP addresses and username passwords will be mentioned in the inventory file.

b.Modules: –

Ansible Module
  • Ansible has lots of modules.
  • In-built modules that are supposed to do a particular task.
  • for example, installing a package or restarting a service, or taking a snapshot of EBS volume.
  • So, like that there are hundreds and more than 1000 modules in Ansible. you write a playbook, and you mention from the inventory file that this is the host and I want to execute so and so module on this host. So, this will be a task in the playbook.

c.Ansible Configuration File: –

  • Then Ansible is going to use the configuration and create Python scripts and Python packages.
  • Python package means the group of Python modules. So when you execute, it’s going to create a Python package, deliver it to the destination(Let’s say the Linux server executes there), and return the output.
  • If the target is not an operating system, probably a cloud account (Let’s say You’re launching an EC2 instance). So it’s going to create a Python package and execute locally.

d.Playbook: –

Ansible Playbook
  • Playbook describes the tasks to be executed.
  • it’s written in simple language i.e., YAML.
  • Playbooks are like instruction manuals.

Advantages of ansible

  • Easy to learn.
  • Written in Python.
  • Easy installation and Configuration steps.
  • No need to install ansible on slave (managed-node or client node).
  • Highly scalable

Problem Statement: Example

Problem Statement: Say, Josh runs an enterprise,wants to install a new version of Apache Tomcat in all systems.

Ansible Problem Statement

Problem Solution with Ansible: Instead of going to each system , manually updating, Josh can use Ansible  to automate the installation using Ansible Playbooks

Problem solution using Ansible..

How Ansible works with Nodes: Lab Example

Here, I am taking one lab example to make it easy to understand. And on this example, we are going to see how Ansible works.

How does ansible work ?
  • If you see the above image here, we have a system called the control node and a few other client nodes.
  • So, the control node is where we usually install Ansible. So, wherever Ansible is installed, we call it a control node.
  • And this control node is going to manage so many clients (client nodes).
  • The controls node is going to manage these nodes using SSH.
  • Control Node should have access to these client nodes or managed nodes. And it is possible through Password-less authentication.
  • So, to manage these nodes, we should enable Password-less authentication.
  • If once Password-less authentication is enabled, then only the control node can be able to manage these nodes.

Components in Ansible-Control-Node

Now we will see what components are there in Ansible

1.Inventory: –

Ansible Inventory component
  • Inventory is a list of the servers’ information or managed nodes’ information.
  • Assume that three nodes we have over here.
  • These three nodes’ information is updated in the inventory.
  • If these three nodes’ information is not updated in the inventory, it cannot be able managed.
  • So, all the nodes that are managed by the control node should be updated in the inventory.
  • If it is not updated, even though you enable Passwordless authentication, it cannot be managed.

2.Playbook: –

component: Ansible Playbook
  • The next component is playbooks.
  • Playbooks are the actual tasks that you need to execute on the target systems.
  • Let’s take an example, we want to create a user on all client systems or managed nodes.
  • So how to create a user, Which user you should create? That information is updated in the “playbook”. And on which servers we should update That information is available in “inventory”.

3.Module: –

Component: Ansible Module
  • The next component is the module.
  • modules are usually used by tasks.
  • So, tasks are nothing but the activity like What do you want to do?
  • These modules are shipped with Ansible while you are installing Ansible. Most of the useful modules come while you are installing Ansible.
  • And so these modules are used by Ansible playbooks.

So these are the major components on the control node or Ansible master server.

Resources to start

Prepared Ansible LAB

Agenda for this lab:

We will cover the below topics  in this hands-on lab in further steps

  1. Ansible Playbooks
  2. Multitask Ansible playbooks
  3. Ad-hoc commands
  4. Inventory
  5. Modules
  6. Notify and Handlers
  7. Gather facts
  8. Conditions
  9. Ansible variables
  10. Additional concepts
  11. Ansible Vaults
  12. Ansible Roles

Ansible Lab Overview-

In this election, we are going to talk about how we are going to set up our lab environment for Ansible.

Ansible Hands-on Lab
  • We will create this lab environment on the AWS cloud where we will launch four EC2 instances.
  • one EC2 instance will be for ansible-control-node and the other three EC2 instances will be for managed-nodes (RHEL, Amazon, and Ubuntu) as you can see in the above images.
  • we are going to set up a control node that runs on Amazon Linux and it is going to help client nodes( managed-nodes ) i.e. RHEL-managed-node, Amazon-managed-node, and Ubuntu-managed-node systems.
  • I’m using three different flavors because Ansible can able to do or perform tasks on any of these operating systems, and we can still set up a control node on our actual server itself.

Prepare Ansible System (control-node) on AWS-

We will do the following steps to set up the Ansible System on AWS.

STEP 1:-Setup EC2 instance

EC2 instance-Ansible system
Ansible system
Ansible system
Ansible system
ansible key pair
security group
ansible system (control-node)

NOTE: – Don’t forget to add the 8080 port in the security policy of ansible-server(ansible-control-node)

adding port 8080
adding port 8080
adding port 8080

Now, connect this EC2 instance before doing further steps

connecting EC2 with terminal

STEP2:- Setup hostname

				
					sudo su -
vi /etc/hostname
init 6   (for reboot)
				
			

NOTE:-

  • press ‘i = to go inside the insert mod
  • Press ‘Esc’ =to come out from insert mode and 
  • Then type :wq = to save & Exit
setting up hostname
rebooting

STEP 3:- create ‘ansadmin’ user

				
					useradd ansadmin
passwd ansadmin      (set password)

				
			
creating user

STEP 4:- Add the user to the ‘sudoers’ file

				
					 visudo
				
			

Put below line

ansadmin ALL=(ALL)                NOPASSWD: ALL
sudoer file
Enable Password

STEP 5:- Login as ‘ansadmin’ user and Generate SSH keys after 

				
					ssh-keygen     ( which will generate keys pair public keys & private keys )

				
			
Generate SSH keys

STEP 6:- Enable Password-based login

				
					vi /etc/ssh/sshd_config
  service sshd restart
				
			
Enable Password-based login
Enable Password-based login

Video Recording

Still, if you have any doubt about any steps, please go through this video again

Install Ansible on AWS EC2 instance

Please do the following steps to install Ansible on EC2 instance

Step 1: – Install Python and Python-pip.

				
					yum install python
yum install python-pip

				
			

Step 2: – install ansible using pip and check version.

				
					pip install ansible
ansible –version   #( To check the version of ansible )

				
			

Step 3: – create two files inside ‘/etc/ansible’.

				
					cd /etc/ansible
vi ansible.cfg
touch hosts   #( we will update client nodes here when will create client nodes. As of                     now, we haven't created any client nodes )

				
			

NOTE: – To get started with Ansible, you need to install it on your control node. Ansible supports Linux, macOS, and Windows. Detailed installation instructions for each platform can be found on the official Ansible website.

Video Recording

Still, if you have any doubt about any steps, please go through this video to install ansible again

Setup RHEL as an ansible managed-node (client node)

We will do the following steps to set up the RHEL Managed node (Client node) on AWS as almost similar, we did in previous step to setup ansible control-node.

Step 1: -Setup EC2 instance

setup RHEL-EC2
setup RHEL-EC2
setup RHEL-EC2
setup RHEL-EC2-key-pair
setup RHEL-EC2-launching
RHEL_Managed_Node

NOTE: – Don’t forget to add the 8080 ports in the security policy of RHEL_Manged_Node (ansible-managed-node) as we did in ansible-control-node

Now, connect this EC2 instance with the help of Mobaxterm Terminal

Connecting RHEL-Managed-node
RHEL-Managed-Node

Step 2: – Setup hostname

				
					sudo su -
vi /etc/hostname    ( put the hostname inside this as RHEL-Managed-Node )
init 6

				
			

Step 3: – create ‘ansadmin’ user.

				
					useradd ansadmin
passwd ansadmin      (set the password to this user )

				
			

Step 4: – Add the user to the ‘sudoers’ file

				
					visudo
				
			

Put the below line inside the above ‘sudoers’ file

ansadmin ALL=(ALL)                NOPASSWD: ALL

Step 5: – Enable Password-based login

				
					 vi /etc/ssh/sshd_config
service sshd restart

				
			

NOTE: – press i= for insert mode

             Press ‘Esc” = to exit from insert mode

             Press ‘SHIFT+G’=to go at the end of the terminal

Video Recording

Still, if you have any doubt about any steps, please go through this video to Setup RHEL-Managed-Node again

Add RHEL-managed node to Ansible.

connection between control-node and managed-node
  • So far, we have set up our Ansible control node and our managed node (Client Node).
  • Now we should establish a connection between these two.
  • For that purpose, we should update the RHEL server IP address on the control node side.
  • We have created a file called ‘/etc/ansible/hosts’. That is the inventory file we should update there.
  • Once we update there and after that, we should copy the SSH key (public keys) onto our RHEL server (client node).
  • Then we can be able to manage our server.

NOTE: – Don’t copy your private keys into your client node. Always copy your only public keys onto client node.

Step1: – login into both the servers- control node & RHEL managed node

Ansible-control-node

ansible-control-node

RHEL-Managed-Node

RHEL-Managed-Node

Step2: – copy the IP address of RHEL managed node into the control node’s inventory file “/etc/ansible/hosts”

Step3: – Copy Public SSh keys into the RHEL server from the control node

				
					sudo su - ansadmin
    ssh-copy-id <ip address of destination>

				
			
SSH to RHEL-managed-node

Video Recording

Still, if you have any doubt about any steps, please go through this video to Add RHEL-Managed-Node to ansible-control-node again.

Introduction to ad-hoc commands

Introduction

  • Ansible is a powerful open-source automation tool used by IT professionals and system administrators to manage and configure systems, deploy applications, and perform various tasks on remote servers.
  • While Ansible playbooks are commonly used for defining and executing automation tasks. Ansible also offers a feature called “Ad-Hoc Commands” for quick, one-off tasks. 
  • Here, we will explore Ansible Ad-Hoc Commands, their usage, and how they can simplify and expedite routine administrative tasks.

What are Ansible Ad-Hoc Commands?

  • Ansible Ad-Hoc Commands are one-liner commands that allow you to perform simple tasks on remote hosts without the need to write elaborate playbooks.
  • They are especially handy for tasks that don’t require a structured playbook or for quick troubleshooting and system maintenance. 
  • Ad-hoc commands offer a straightforward and efficient way to interact with remote systems using Ansible.

Usage and Syntax

The basic syntax for an Ansible Ad-Hoc Command is as follows:

ansible <target_hosts> -m <module_name> -a “<module_arguments>”

  • <target_hosts>: Specifies the target hosts or groups of hosts where you want to run the command.
  • -m <module_name>: Specifies the Ansible module you want to use for the task.
  • -a “<module_arguments>”: Provides the module-specific arguments needed to complete the task.

Examples of Ansible Ad-Hoc Commands

1. Gathering System Facts: To gather facts about remote systems, use the “ansible” module with the “setup” module.

ansible <target_hosts> -m setup

This command fetches information about the target hosts, including hardware details, network configuration, and more

2. Installing Packages: Use the “ansible” module with the “yum” or “apt” module to install packages on remote systems.

ansible <target_hosts> -m yum -a “name=<package_name> state=present”

Replace <package_name> with the desired package name.

3. Restarting Services: To restart a service on remote hosts, use the “service” module:

ansible <target_hosts> -m service -a “name=<service_name> state=restarted”

Replace <service_name> with the name of the service.

4. Creating Files: You can create files on remote systems using the “ansible” module with the “file” module.

ansible <target_hosts> -m file -a “path=</path/to/file> state=touch”

Replace ‘/path/to/file’ with the desired file path

Some Useful Ad-Hoc Commands-

For the time being, we are going to use  these modules to execute our commands.

we are going to use the below modules in our lab as Ad-Hoc commands.

  • ping
  • command
  • stat
  • yum
  • user
  • setup

PING: –

  • This module is going to execute on the systems which are in the inventory file.
  • So, as of now, in our inventory file, we have one host. So, in that one host, it is going to perform a ping test.
  • So, whenever it does the ping, it gets the response as a ping-pong if the server is fine.
				
					ansible all -m ping
#where -m= for module
#all= Means all hosts inside the inventory file

				
			
Ansible Ping

command

  • While executing the “command” module, we should provide an argument that is ‘-a’.
  • So, assume that I want to just see the uptime of my system.
				
					ansible all -m command -a “uptime”
				
			
Ansible 'command' Module

stat

  • Whether the file exists or not, it is going to show us. So, I just want to see the path where the file exists.
  • This file exists under /etc/ansible/hosts, so I just want to see whether /etc/ansible/hosts file exists or not.
				
					Ansible all –m stat -a “PATH=/etc/ansible/hosts”
#It gives the information about this file.
				
			
ansible 'stat' Module

yum

  • I want to install “git” on the target system (RHEL Managed node)
				
					ansible all –m yum -a “name=git” -b
				
			
ansible 'yum' Module
  • To check Git version on the target system

user 

  • I want to create a user on target system.
				
					ansible all –m user -a “name=devopsaura” -b
				
			
ansible 'user' module
  • To check user on the target system,
				
					cat /etc/passwd/                  #(run on the target system)

				
			

Video recording

Still, if you have any doubt about any steps, please go through this video again.

Inventory:-

What is inventory?

  • The inventory file is where you define your target hosts and group them for easier management. Ansible uses this file to know where and how to execute tasks.
  • You can create an inventory file manually or use dynamic inventory scripts for more complex environments i.e we can say that 
  • “An inventory file is a collection of hosts or nodes that are managed by an Ansible control node”.
  • We can use a default inventory file or we can create a custom inventory file.
  • Let’s see how many ways we can define our inventory file.

Types of Ansible Inventory

Hosts’ information can be defined in the following way

1)Default inventory:-

  • The default location of hosts inventory is “/etc/ansible/hosts”

2) Custom inventory:-

  • we can use, our custom hosts file. 
  • Hosts file nothing, but we can create our own inventory file in any location that we can apply while running our command by using the ‘-i’ option.

NOTE:- ‘-i’ stands for inventory over here

				
					sudo su - ansadmin
vi my_hosts  #put here private ips of your managed-nodes
ansible all -m ping -i my_hosts   
#if you dont use '-i' then it will take default inventory file i.e '/etc/ansible/hosts'
				
			

3) Define in the “ansible.cfg” file:-

 

  • If you remember we have created an ansible.cfg file.
  • in that, we can define our inventory file so that it will treat whatever file you have specified in this configuration file.
  • While executing any Ansible command, Your Ansible command requires some inputs and if you haven’t specified, it is going to take the default values from this Ansible.cfg file.

Playbooks: -

Ansible Playbook Structure:-

  • Playbooks are at the heart of Ansible automation. 

  • They are written in YAML format and contain a series of tasks that should be executed on the target hosts. 

  • Playbooks allow you to automate tasks like software installation, configuration changes, and more.

Ansible Playbook Structure

Creating Ansible Playbook-

  • A Playbook is a Text File written in YAML format, And it is normally saved as .yml.
  • The playbook begins with a line consisting of three dashes ( – – – ) as the start of the document marker.
  • An item in the YAML list starts with a single dash [ – ] followed by a space.
  • hosts and tasks are mandatory items in a Playbook
  • The playbook primarily uses indentation with space characters to indicate the structure of its data.
  • Modules are used to perform tasks.
  • Comment start with #

Example:- We will create a “user” with the help of the playbook.

On Ansible-control-node

				
					sudo su - ansadmin
cd /opt
sudo mkdir ansible
ls
sudo chown ansadmin:ansadmin ansible
cd ansible
vi create_user.yml

				
			
---

- hosts: all

  become: true          #true because we can only create a user as root)

  tasks:

  - user: name=john     #where “user” is a module)

Now execute the playbook

				
					ansible-playbook create_user.yml
				
			

Video recording

Still, if you have any doubt about any steps to create Ansible playbook to create a user, please go through this video again.

Now, We are going to create two more servers

  1. One is Amazon Linux, 
  2. Another one is the Ubuntu system.

And we are going to execute the same playbook on those and we’ll see how it works.

Setup Additional Managed Nodes: -

Setup Additional Managed Nodes

1.Amazon Linux Managed node setup:

Step 1: -Setup EC2 instance.

Step 2: – Setup hostname

				
					sudo su -
vi /etc/hostname  #put Private Ip address of amzon Linux managed node
init 6   #for rebooting node to get effect of hostname
				
			
Amazon-managed-node

Step 3: – create ‘ansadmin’ user

				
					useradd ansadmin
passwd ansadmin      #set password
				
			

Step 4: – Add the user to the ‘sudoers’ file

				
					visudo
				
			
ansadmin ALL=(ALL)                NOPASSWD: ALL
visudo

Step 5:- Enable Password-based login

				
					vi /etc/ssh/sshd_config

				
			
				
					service sshd reload
service sshd restart
				
			

Step 6: – Now add this Node to “ansible server (control node)” inside “/opt/ansible/hosts”

Login ansible-control-node

				
					sudo su -
sudo su - ansadmin
cd /opt/ansible/
vi hosts
				
			
ansible inventory file

NOTE:-I have created groups in this inventory file(hosts) so that I can put multiple hosts in the same groups if we need them. And I am creating three groups. 

  1. [webservers]  for RHEL-managed-node
  2. [appservers]  for Amazon-managed-node <ipadress>
  3. [dbservers]   for ubuntu-managed-node

Step 7: – Now Enable its password-less authentication.

  • For this we will copy ssh-id of Ansible-control-node to “amazon-managed-node” system

Video Recording

2.Ubuntu Managed node setup:-

Step 1: -Setup EC2 instance for Ubuntu Managed Node

Step2: – Setup hostname

  • Do as we have done in previous steps
				
					sudo su -
vi /etc/hostname   #give hostname inside this as ubuntu-managed-node
init 6
				
			

Step 3: – create ‘ansadmin’ user.

				
					sudo su  -
cd /home/
useradd -m -d /home/ansadmin ansadmin
passwd ansadmin      (set password)

				
			

Step 4:- Add the user to the ‘sudoers’ file

				
					visudo
				
			

Step 5: – Enable Password-based login.

				
					vi /etc/ssh/sshd_config
service sshd reload
service sshd restart

				
			
				
					service sshd reload
				
			

Step 6:- Now add this Node to “ansible server(control node)” inside “/opt/ansible/hosts”

				
					sudo su - ansadmin
cd /opt/ansible
vi hosts    #put private IP Address of Ubuntu-managed-node
				
			

Step 7: – Now Enable its password-less authentication.

				
					ssh-copy-id 172.31.14.176   #private ip adress of target systme means ubunutu
				
			

NOTE:- On Ubuntu: Why do we need /home/ directory? Because the keys get copied into /home/ansadmin.

if the home directory doesn’t exist, it creates a problem. That is why we should have the home directory of /home/ansadmin.

Video Recording

Run ansible-playbook: -

Before running our playbook, first, we will verify that our ansible control-nod can communicate to all managed nodes(RHEL, Amazon, Ubuntu)

				
					ansible all -m ping -i hosts
				
			
  • Now, we will run our ansible-playbook on the control node for our lab’s remaining managed node (amazon-managed-node and ubuntu-managed-node) to create a user.
  • And we had already created a Playbook in previous steps.
				
					ansible-playbook -i hosts create_user.yml
				
			

Video Recording

Modules

  • Ansible modules are small programs that Ansible uses to perform tasks on managed hosts(nodes).
  • There are hundreds of built-in modules, covering everything from package management to network configuration.
  • You can also write custom modules to suit your specific needs.

“Yum” module-

Here, we are going to write ansible-playbook using the “yum” module to install packages

				
					vi install_packages.yml
				
			
- - -

- name: this playbook is to install packages

  hosts: webservers           (want to install on specific servers so i have given group name here)

  become: true

  tasks:

  - name: install package

    yum: 

       name: git

       state: installed

Now run ansible-playbook on ansible-control-node-

				
					ansible-playbook -i hosts install_packages.yml
#where, hosts=inventory file
#install_packages.yml=our ansible-playbook
				
			

NOTE1: – if you don’t use the option “-i” in the command then it will take the default inventory file which is inside “/etc/ansible/hosts/” where our group “webservers” is not mentioned.

NOTE2: – if you don’t use “become: true” in the playbook script then it will not install the packages because we need to install them as root user. Without a root user, we can’t install packages

Video recording

“File” module-

  • Here, we will create a File or directory on our target system (managed nodes)
				
					vi create_file.yml 
				
			
- - -

- name: this playbook is to create a file or directory

  hosts: all       

  become: true

  tasks:

  - name: creating a file or directory

    file: 

       path: /home/ansadmin/demofile

       state: touch
ansible playbook to create file
				
					cat hosts
				
			

Now we will run our playbook-

				
					ansible-playbook -i hosts create_file.yml
				
			

“Copy” module-

  • Here, we will copy a file onto managed nodes.
  • So first I’m going to create a file called index.html, which I’m going to use in my later steps.
				
					vi index.html            (inside /opt/ansible)
				
			
<h1> ansible playbook to copy a file </h1>
  • Now, we will create a playbook
---

- name: ansible playbook to copy a file

  hosts: all

  become: true

  tasks:

  - name: copy a file

    copy:

      src: /opt/ansible/index.html

      dest: /home/ansadmin

      mode: 0600

      owner: john
  • First, we will verify our playbook script syntax is correct or not?
				
					ansible-playbook  -i hosts copy_file.yml –check
				
			
  • Now, we will execute our ansible playbook to copy file on managed-nodes as below
				
					ansible-playbook  -i hosts copy_file.yml
				
			

Video Recording

Multitask ansible-playbook

Install Apache on RHEL-

First, I am copying the script of install_packages.yml to the newly created playbook “install_httpd.yml” to save our time.

				
					sudo su - ansadmin
cd /opt/ansible
cp install_packages.yml install_httpd.yml

				
			
copying Playbook

And now I will modify and add another task to “install_httpd.yml

				
					vi install_httpd.yml
				
			
---

- name: this playbook is to install httpd packages

  hosts: webservers

  become: true

  tasks:

  - name: install package

    yum:

     name: httpd

     state: installed

  - name: start httpd service

    service:

      name: httpd

      state: started
Install Apache on RHEL

Now, verify syntax and run this Ansible playbook install_httpd.yml

				
					ansible-playbook  -i hosts install_httpd.yml –check
ansible-playbook  -i hosts install_httpd.yml
				
			

we have successfully installed Apache server on managed-nodes.

To check the status of hhtpd on managed nodes

				
					ps -ef | grep httpd
rpm -qa | grep httpd

				
			

Verify On browser-

  • Now, we will access and verify whether the Apache server from the browser is working or not.
  • For this, please Copy the public DNS ip and paste the browser

Video Recording

How to remove these packages.

  • Now, we are going to remove these packages.
  • So, we will copy the content from install_httpd.yml to save time and create a new ansible-playbook “uninstall_httpd.yml” to remove the packages.
				
					cp install_httpd.yml uninstall_httpd.yml
vi install_httpd.yml

				
			
---

- name: this playbook is to uninstall httpd packages

  hosts: webservers

  become: true

  tasks:

  - name: stop httpd service

    service:

      name: httpd

      state: stopped

  - name: uninstall package

    yum:

     name: httpd

     state: removed

Now, verify syntax and run this Ansible playbook “uninstall_httpd.yml

				
					ansible-playbook  -i hosts uninstall_httpd.yml –check
ansible-playbook  -i hosts uninstall_httpd.yml
				
			

Install Apache on Ubuntu-

  • we are going to see how to install Apache on the Ubuntu system(ubuntu-managed-node) with the help of ansible-playbook.
  • In the previous steps, we have installed Apache on RHEL and Amazon Linux because both the systems run with the ‘yum’ command.
  • But to install it on the Ubuntu system, we cannot use the ‘yum’ module m is not identified.
  • Usually, we use the ‘apt install’ package name.
				
					vi install_apache2.yml
				
			
---

- name: install apache2 on ubuntu server

  hosts: dbservers

  become: true

  tasks:

  - name: install apache2

    apt:

     name: apache2

     state: present

  - name: start apache2

    service:

      name: apache2

      state: started
  • Now execute the ansible-playbook on control-node
				
					ansible-playbook -i hosts install_apache2.yml
				
			

Verify On browser-

  • Now, we will access and verify whether the Apache server from the browser is working or not.
  • For this, please Copy the public DNS ip and paste the browser

Video Recording

Notify and Handlers in playbook

  • Suppose I want to start the httpd service on the managed nodes (if httpd is already installed on the managed node), which means I want to skip the task of httpd installation.
  • But if httpd is not installed, I don’t want to start the service. means i want to skip the task of starting the service here. So, for this case, we will use ‘notify’ and ‘handlers’ in the playbook script.
  • This means if httpd is not installed, then ‘handlers’ skip the task of ‘starting service’

In the previous steps, we have seen how to install Apache on our servers.

In this step, we are going to talk about how we can use notify and handlers.

NOTE: –

  • If ‘hhtpd’ is not installed on the system, you cannot start the service. This means service is dependent on the package.
  • And also, your target server is already installed and up and running with httpd, then you should not install it. in this case, we need to skip the next tasks itself.
  • And This can be possible by using the Notify and Handlers.

Let’s use ‘notify and handlers’ in the existing playbook “install_httpd.yml” to skip the task of starting the service (because httpd is already installed and running up.)

				
					vi install_httpd.yml
				
			
---

- name: this playbook is to install httpd packages

  hosts: webservers

  become: true

  tasks:

  - name: install package

    yum:

     name: httpd

     state: installed

     notify: start the httpd service

  handlers: 

  - name: start the httpd service

    service:

      name: httpd

      state: started

Now, run this playbook-

				
					ansible-playbbok -i hosts install_httpd.yml –check
ansible-playbbok -i hosts install_httpd.yml

				
			

Now we will execute the same playbook again . And it will not notify the handlers and skip  the task to start the httpd service

				
					ansible-playbbok -i hosts install_httpd.yml

				
			

Gather facts

Here, we are going to talk about gathering facts.

I am going to take one of our ansible playbooks that is create_file.yml and let me execute this

Ansible playbook.

What exactly gathering facts is going to do?

  • Usually gathering facts is going to retrieve the system information from your remote system.
  • In our case, we have three managed nodes, right?
  • So, these three manager nodes information, it is going to gather, then it is going to execute the task.
  • But to delete a file or create a file, you don’t require gather your system information.

Why should you need to do? And when it is going to be useful?

  • Whenever we are doing some installations on the target system, you want to check out what is the status of your current operating system. Then you can do that one.
  • So, during the installations gathering facts is going to perform the major task.

Now, i would like to disable your gathering facts.

For that, I’m going to edit this playbook create_file.yml

				
					vi create_file.yml
				
			
---

- name: this playbook create file or directory

  hosts: all

  become: true

  gather_facts: no

  tasks:

  - name: creating a file

    file:

      path: /home/ansadmin/dir1

      state: absent

Now run playbook

				
					ansible-playbook -i hosts create_file.yml
				
			

why should we need to restrict gathering facts?

  • Assume that your environment has around 100 plus systems.
  • If you are collecting each system information from 100 systems, it will take a little longer time to run your Ansible playbook.
  • Moreover, if you are using that information well & good if you are not using it, it’s also fine because it’s unnecessary.
  • That’s how we can use the gathering facts.

Conditions

How ‘when’ condition works?

  • we are going to see how the ‘when’ condition does work with our Ansible playbooks.
  • If you do remember, we were trying to install Apache on our servers as well as Ubuntu systems, but we have created two different files for a similar kind of task. It doesn’t look good. Right?
  • Also, it is not a good way of handling it.
  • So, you should write a single ansible playbook and depending upon your operating system, It should take a decision. Whether should I need to run ‘yum’ or ‘apt’.
  • This is possible by using a ‘When’ condition.

NOTE:

  • We had created multiple ansible-playbook for the same task (install Apache)
  • We created two files (ansible playbooks) because the OS flavors of the systems were different ( i.e. Amazon Linux, RedHat, and Debian Ubuntu ).
  • And ‘yum‘ and ‘apt‘ modules work depending on the operating system like the ‘apt’ module is used for Ubuntu OS. The ” yum module is used for RedHat OS and Amazon Linux OS.

so now, we will create a single ansible-playbook to do the same task for different OS flavors using the ‘when’ condition in the playbook.

and this ‘When” condition will decide whether the “yum” or “apt” module will run.

Install Apache using the ‘when’ condition:-

So now, we will create a single ansible-playbook to do the same task for different OS flavors using the ‘when‘ condition in the playbook.

				
					vi install_apache_httpd.yml
				
			
---

- name: this playbook is to install packages on servers

  hosts: all

  become: true

  tasks:

  - name: install package

    yum:

     name: httpd

     state: installed

    when : ansible_os_family == “RedHat”




  - name: start apache service

    service:

      name: httpd

      state: started

    when : ansible_os_family == “RedHat”

  - name: install apache2

    apt:

     name: apache2

     state: present

    when : ansible_os_family == “Debian”




  - name: start apache2

    service:

      name: apache2

      state: started

    when : ansible_os_family == “Debian”

Now verify and execute the ansible playbook

				
					ansible-playbook -i hosts install_httpd_apache.yml –check
ansible-playbook -i hosts install_httpd_apache.yml

				
			

Uninstall Apache using ‘when’ condition:-

Here, I am going to uninstall the server from all managed nodes (amazon, ubuntu, and RHEL managed nodes) by Ansible playbook using ‘when’ condition.

And I am editing the existing ansible-playbook ‘uninstall_httpd.yml’

				
					sudo su -
sudo su - ansdamdin
cd /opt/ansible
vi uninstall_httpd.yml

				
			
---

- name: this playbook is to install packages

  hosts: webservers

  become: true

  tasks:

    - name: stop httpd service

      service:

       name: httpd

       state: stopped

      When: ansible_os_family == ‘RedHat’

    - name: uninstall package

      yum:

       name: httpd

       state: removed

      when: ansible_os_family == ‘RedHat’

 - name: stop apache2 service

      service:

       name: apache2

       state: stopped

   when: ansible_os_family == ‘Debian’

  - name: uninstall apache2

      apt:

       name: apache2

       state: absent

     when: ansible_os_family == ‘Debian’

Now verify and execute the ansible playbook

				
					ansible-playbook -i hosts uninstall_httpd_apache.yml –check
ansible-playbook -i hosts uninstall_httpd_apache.yml

				
			

Adding 'copy' task to apache playbook:-

  • Here, We are going to copy this ‘index.html’ onto our /var/www/html location then we will modify our install_apache_httpd.yml ansible playbook.
  • So whenever we refresh our pages, we are going to get whatever content is there in that file.

NOTE: – Before copying the ‘index.html’ file onto our /var/www/html location, we will modify the content of ‘index.html’ first.

Content can be anything. we will modify the file for our verification purposes only.

Before copying, let me modify this file ‘index.html’ file.

				
					vi index.html
				
			
<h1> Welcome to Apache Tomcat </h1>

Now I am going to modify our Ansible playbook to copy this file “index.html” to the ‘/var/www/html’ location on all managed-nodes

				
					vi install_apache_httpd.yml
				
			
---

- name: this playbook is to install packages on servers

  hosts: all

  become: true

  tasks:

  - name: install package

    yum:

     name: httpd

     state: installed

    when: ansible_os_family == "RedHat"

  - name: start httpd service

    service:

      name: httpd

      state: started

    when: ansible_os_family == "RedHat"

  - name: install apache2

    apt:

     name: apache2

     state: present

    when: ansible_os_family == "Debian"

  - name: start apache2

    service:

      name: apache2

      state: started

    when: ansible_os_family == "Debian"

 - name: coppy index.html

   copy: 

    src: /opt/ansible/index.html

    dest: /var/www/html

    Mode: 0666

Now, validate and execute the ansible playbook

				
					ansible-playbook -i hosts install_apache_httpd.yml –check
ansible-playbook -i hosts install_apache_httpd.yml

				
			

Video Recording

List and with_items

we are going to see how to install multiple packages with a single task.

				
					vi install_packages.yml
				
			
---

- name: this playbook is to install packages

  hosts: webservers

  become: true

  tasks:

  - name: install package

    yum:

     name: [ ‘git’,  ‘make’,  ‘gcc’, ‘wget’, ‘telnet’, ‘gzip’ ]

     state: installed

Now, validate and execute the ansible playbook.

				
					ansible-playbook -i hosts install_packages.yml –check
ansible-playbook -i hosts install_packages.yml

				
			

Video Recording

Variables

  • Here, we are going to talk about ansible variables.
  • Ansible allows you to define variables that can be used in your playbooks and roles. These variables make your automation more flexible and reusable. You can set variables in playbooks, inventory files, or external sources.
  • There are various ways we can use ansible variables, but I am going to use a few of the ways that most of the industry does use.

Ways are-

Define within the playbook-Ansible variables can be defined within the Ansible playbook. So this is one of the ways we can use  

Passing from external filespassing from the external files means we can define Ansible variables in the external file and call it in our playbook by referring to that

Passing from hosts inventory- we have created host inventory right even there. Also, we can define Ansible variables.

Passing while running playbook-While running our Ansible playbook, we can still pass the variables.

Using group_vars or hosts_vars-We can use group_vars or hosts_vars while we are using Ansible roles.

Using Variables — Ansible Documentation

Example:-

  • We are creating a user called ‘John’ by using this ‘create_user.yml’ playbook. Already we have this playbook, and we will modify this existing playbook ‘create_user.yml’ 
  • But assume that in your team, a new guy has joined.
  • Now you would like to create his user. So again, you need to go inside the playbook and change his user ID.
  • If you have a hardcode, it is quite difficult.
  • Also, if you are using the same value again and again in your playbook, you need to modify it in all these locations whenever a new joiner comes into your team.
  • To overcome this problem, we can use variables instead of hard coding values like this.
  • So, I’m going to use variables within the file, and we’ll replace this value with the variable.

Define within the playbook-(vars)

				
					vi create_user.yml
				
			
---

- name: this playbook is to create user

  hosts: all

  become: true

  vars:

    user: john

  tasks:

  - name: creating user john

    user:

      name: “{{ user }}”

Now run playbook.

				
					ansible-playbook -i hosts create_user.yml –check
ansible-playbook -i hosts create_user.yml

				
			

Passing from external files– (vars_files)

  • Now, whenever there is a new user, we are modifying our ansible playbook. Right?
  • But I don’t want to modify our ansible playbook. I would like to get this variable value from the external source means we can create a separate file and from there we can pass this username.
				
					vi user.yml
				
			
user: modi

Now, I need to tell my playbook that the variable is coming from this file ‘user.yml’.

So, let’s modify our file.

				
					vi create_user.yml
				
			
---

- name: this playbook is to create user

  hosts: all

  become: true

  vars_files:

    - user.yml

  tasks:

  - name: creating user john

    user:

      name: “{{ user }}”

Now run playbook

				
					ansible-playbook -i hosts create_user.yml –check
ansible-playbook -i hosts create_user.yml

				
			

NOTE: – Please remember that while running your ansible command, if you pass any variables, those have highest priority.

Means wherever you have defined, all those are ignored and whatever you are passing while running your ansible playbook, that will be taken it as a variable value.

Currently, variable username Modi is there, but I’m providing it as ‘–extra_vars’ or -e “user=Abhishek upadhyay” and this username “abhishekupadhyay” will be taken on priority

				
					ansible-playbook -i hosts create_user.yml -e “user=abhishekupadhyay”
				
			

Video recording

Additional Concept

Convert shell command into an ansible playbook-

Here, I am going to show you how can we convert our shell or Unix commands into Ansible playbook?

				
					vi setup-tomcat.yml
				
			
---

- name: setup tomcat

  hosts: all

  become: true

  tasks: 

  - name: install java

    yum: 

      name: java

      state: installed

    when: ansible_os_family == "RedHat"




  - name: install java on ubuntu

    apt: 

      name: default-jdk

      state: present

    when: ansible_os_family == "Debian"




  - name: download tomcat packages

    get_url:

      url: https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.13/bin/apache-tomcat-10.1.13.tar.gz

      dest: /opt




  - name: untar apache packages

    unarchive:

      src: /opt/apache-tomcat-10.1.13.tar.gz

      dest: /opt

      remote_src: yes




  - name: add execution permissions on startup.sh file

    file: 

      path: /opt/apache-tomcat-10.1.13/bin/startup.sh

      mode: 0777




  - name: start tomcat services

    shell: nohup ./startup.sh

    args: 

      chdir: /opt/apache-tomcat-10.1.13/bin

Now run playbook

				
					ansible-playbook -i hosts setup-tomcat.yml –check
ansible-playbook -i hosts setup-tomcat.yml
				
			

Video Recording

Using Tags in ansible playbook:-

  • we are going to talk about tags.
  • Usually, tags are useful if you want to segregate only specific tasks from your playbook.
  • So how does it work?
  • We are going to see in the existing playbook ‘install_apache_httpd.yml

Example: –

  • So, in my case, I just want to install packages only. I don’t want to start the service.
  • Other tasks should not be executed.
  • In that case, we are going to modify our playbook by using tags.
				
					vi install_apache_httpd.yml
				
			
---

- name: this playbook is to install packages on servers

  hosts: all

  become: true

  tasks:

  - name: install package

    yum:

     name: httpd

     state: installed

    when: ansible_os_family == "RedHat"

    tags: install_apache




  - name: start httpd service

    service:

      name: httpd

      state: started

    when: ansible_os_family == "RedHat"

    tags: start_apache




  - name: install apache2

    apt:

     name: apache2

     state: present

    when: ansible_os_family == "Debian"

    tags: install_apache




  - name: start apache2

    service:

      name: apache2

      state: started

    when: ansible_os_family == "Debian"

    tags: start_apache




  - name: copy index.html file

    copy:

     src: /opt/ansible/index.html

     dest: /var/www/html

     mode: 0666

Now install only packages-

NOTE: – We are going to perform only specific task on managed nodes with the help of mentioning the ‘–tags” and tags name in our command as below-

				
					ansible-playbook -i hosts install_apache_httpd.yml --tags "install_apache"
				
			

Now start only services

				
					ansible-playbook -i hosts install_apache_httpd.yml --tags "start_apache"
				
			

Video Recording

Error Handling in the playbook

NOTE: – So usually while running Ansible, it executes all the tasks in the sequential. If it finds any particular task has failed, it cannot proceed with further tasks.

So here, we will take the existing playbook “install_apache_httpd.yml” and will modify it to ignore(skip) the error and proceed with further tasks with the help of ‘ignor_errors’ in the playbook.

Before that, we will edit the file ‘/etc/httpd/conf/httpd.conf‘ in the RHEL server(rhel-managed-node). And we are doing this only just to understand this concept.

On RHEL managed-node-

				
					vi /etc/httpd/conf/httpd.conf
#(write anything inside)

				
			
Error handling

On ansible-control node-

				
					vi install_apache_httpd.yml
				
			
---

- name: this playbook is to install packages on servers

  hosts: all

  become: true

  tasks:

  - name: install package

    yum:

     name: httpd

     state: installed

    when: ansible_os_family == "RedHat"




  - name: start httpd service

    service:

      name: httpd

      state: started

    when: ansible_os_family == "RedHat"

    ignore_errors: yes

  - name: install apache2

    apt:

     name: apache2

     state: present

    when: ansible_os_family == "Debian"




  - name: start apache2

    service:

      name: apache2

      state: started

    when: ansible_os_family == "Debian"




  - name: copy index.html file

    copy:

     src: /opt/ansible/index.html

     dest: /var/www/html

     mode: 0666

Now Execute playbook to ignore error

				
					ansible-playbook -i hosts install_apache_httpd.yml
				
			

You can see in above image that the playbook is ignoring the error and doing further steps(tasks).

That’s how we can handle the error.

Video Recording

Ansible Vault

  • Ansible vault is a feature of Ansible that allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plain text in playbooks or roles.
  • So Ansible vault is one of the features of Ansible, which will help us to protect our sensitive data 
  • Sensitive data is Nothing, but it may be a password or keys or some other information that you should not expose to others.

Example-

  • Let’s take an example that you would like to connect to your GitHub. But while connecting to your GitHub, either you need to provide username and password or your keys should be passed to enable the passwordless authentication.
  • In this kind of situation, we cannot keep our sensitive data within the playbook because we may need to share our playbook with others which will create a problem.
  • So, to overcome this kind of problem, we are going to use Ansible Vault.

We have a few commands to encrypt our data, decrypt our data, and view our data.

Let’s see what those are.

1)create: –

  • Assume that you are creating a new file, and you would like to encrypt your data.
  • Then we can use Ansible Vault create
  • This will help us to encrypt our data while creating our file.

NOTE: – Please remember that while using Ansible Vault, we need to protect our files with passwords, and we should remember those passwords.

2)view: – To view data of encrypted file.

  • View Command is to see the data in the encrypted file. So, in the above step, we have created a file. Now I would like to see the data.
  • Then we should use Ansible vault view similar way.

3)edit: –To edit the encrypted file

4)encrypt: – To encrypt the unencrypted file.

  • Assume that you have created a file, but it has some sensitive data. Now you would like to encrypt that file. Then we can use the encrypt option. 
  • This will create a file with an encrypted format means This will convert your file into an encrypted format.

5)decrypt: – To decrypt an encrypted file.

  • Decrypt is the option to convert your file as a normal file which is in the encrypted format.
  • Assume that we have created a file in encrypted format. And we are not keeping any sensitive data i mean there is no sensitive data. Then there is no point of keeping it in encrypted format so we can decrypt it
  • The same thing applicable for the encrypted file.

6)–ask-vault-pass: – To provide password while running playbook.

  • Now, if we want to use an encrypted format file while running our Ansible playbook, we need to pass this password, but it won’t ask for a password directly.
  • We need to use an option called –ask-vault-pass.
  • So, this is the option we should use. So, whenever we provide this option, it will prompt for the password.
  • If we provide that password, it takes that password and decrypts the file.

7)–vault-password-file: – To pass a vault password through a file

  • we have one more option which is –vault-password-file.
  • So, this will be helpful for us to pass the password through a file.

NOTE: –All your vault commands start with ‘ansible-vault’.While running our playbooks we use the ansible-playbook. Similar way, vault commands start with ansible-vault.

So, let’s jump into our Ansible server(ansible-control-node) and check out These commands.

On ansible control-node-

To create encrypted file

				
					ansible-vault create vault-pass.yml
cat vault-pass.yml
				
			

To view data-

				
					ansible-vault view vault-pass.yml
				
			

To Edit encrypted file-

				
					ansible-vault edit vault-pass.yml
				
			

To decrypt data-

				
					ansible-vault decrypt vault-pass.yml
				
			

Video Recording

Ansible Roles

  • Roles are a way to organize and reuse Ansible code.
  • They encapsulate tasks, variables, and files into a directory structure, making it easier to manage and share automation code.
  • Roles promote code reusability and maintainability.

Understanding Ansible Roles

  • An Ansible Role is a logical collection of tasks, variables, files, templates, and other Ansible artifacts bundled together to automate specific functions or configurations.
  • Roles are designed to be reusable, making it easier to share and apply automation code across different projects and environments.

Role Structure

A typical Ansible Role has a well-defined directory structure that helps organize and encapsulate its components:

  • roles/
    • my_role/
      • tasks/
      • defaults/
      • templates/
      • files/
      • vars/
      • meta/

Creating Your First Role:-

To create a new Ansible Role, you can use the ansible-galaxy command-line tool:

				
					ansible-galaxy role init setup-apache
				
			

This command ansible-galaxy will create the basic directory structure for your role, allowing you to populate it with tasks, variables, and other necessary files.

Role Best Practices

To make the most of Ansible Roles, consider the following best practices:

  • Keep roles focused on specific tasks or configurations for better reusability.
  • Use meaningful and descriptive role names.
  • Document your roles thoroughly, explaining their purpose and usage.
  • Leverage version control systems like Git to manage your roles.
  • Test your roles in isolation before integrating them into larger playbooks.

Video Recording

Leave a Comment

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

Scroll to Top