02 - Ansible Advanced
I am an aspiring DevOps Engineer proficient with containers and container orchestration tools like Docker, Kubernetes along with experienced in Infrastructure as code tools and Configuration as code tools, Terraform, Ansible. Well-versed in CICD tool - Jenkins. Have hands-on experience with various AWS and Azure services. I really enjoy learning new things and connecting with people across a range of industries, so don't hesitate to reach out if you'd like to get in touch.
Playbook run options
Dry Run (Check Mode)
The
--checkoption runs the playbook without making changes to the target systems.$ ansible-playbook playbook.yml --check
Start at
The
--start-at-taskoption is use to specify a name of a task that the playbook should start at.This skips all the other tasks that come before it and the playbook will start running at the task specified.

$ ansible-playbook playbook.yml –-start-at-task “Start httpd service”
Tags
We can optionally tag the plays or tasks using tag option to the playbook or task.
Using this, we can choose to run or skip specific tasks from all the tasks.

$ ansible-playbook playbook.yml –-tags "install" $ ansible-playbook playbook.yml –-skip-tags "install"
Install and Configure Ansible
Control Node
A control node is a machine where the core Ansible software is installed and configured. We store all our code and playbooks on this control node only.
The Ansible software can only be installed on a Linux machine, we cannot have a Windows machine as a control node of Ansible.
However, Windows machines can be a target nodes or managed nodes in Ansible.
Install Ansible on Control Node
$ sudo yum install ansible # RedHat or CentOS
$ sudo apt-get install ansible # Ubuntu
$ sudo dnf install ansible # Fedora
$ sudo pip install ansible # Python (PIP)
Install Ansible via PIP (RedHat or CentOS)
PIP gives the latest version of ansible as some of package managers may not as they are not updated.
# install pip if not present
$ sudo yum install epel-release # use this command while installing with package manager as well
$ sudo yum install python-pip
# install ansible
$ sudo pip install ansible
# upgrade ansible
$ sudo pip install --upgrade ansible
#install specific version of ansible
$ sudo pip install ansible==2.4
Note
- The default inventory hosts file (
/etc/ansible/hosts) and the default ansible configuration file (/etc/ansible/ansible.cfg) are only created when Ansible is installed using the package managers like yum or apt-get. They are not created by default if Ansible is installed using Python (pip).
Create and distribute SSH keys to managed nodes
On control node, create a pair of SSH keys (public and private key-pair) and transfer the public key to the target machines.
$ ssh keygen -t rsa id_rsa id_rsa.pub # private and public key (default location is ~/.ssh)To transfer, there are 2 options:
Copy the contents of the public key at the location
~/.ssh/authorized_keyson target machines using username and password for the first time, and after this disable the password-based authentication.Make use of ssh-copy-id tool, it needs the path of private key.
$ ssh-copy-id -i id_rsa user1@server1
Now, we can login into the target machines using SSH private key.
$ ssh -i rsa_pub user1@server1
Inventory File
Ansible assumes that the user is root by default.
If we have configured SSH keys using other user (like user1), they we have to explicitly mentioned that inside the inventory file using
ansible_userparameter.Ansible picks up the SSH private key from the default location (
~/.ssh). If it is present at some other location, then we have to specify the path that usingansible_ssh_private_key_fileparameter.web1 ansible_host=172.20.1.100 ansible_user=user1 ansible_ssh_private_key_file=/some-path/private-key
Ad-hoc commands
Ad-hoc commands in Ansible are single-line commands executed directly from the command line without the need to create a playbook.
$ ansible <host-pattern> -m <module-name> -a "<arguments>"
Examples:
- Ping All Hosts:
Check connectivity to all hosts in the inventory using the
pingmodule:$ ansible all -m ping
- Run a Command on Remote Hosts:
Use the
commandmodule to run a command:$ ansible webservers -m command -a "uptime"
- Copy a File to Remote Hosts:
Copy a file using the
copymodule:$ ansible all -m copy -a "src=/tmp/test.txt dest=/tmp/test.txt"
- Restart a Service:
Restart the Apache service using the
servicemodule:$ ansible webservers -m service -a "name=httpd state=restarted"
Privilege Escalation
- Privilege escalation in Ansible refers to the process of executing tasks on managed nodes with elevated privileges, such as
rootor another administrative user.
Key Parameters for Privilege Escalation
become:Enables privilege escalation.
Equivalent to using
sudoin a shell.
become_user:Specifies the user to switch to when escalating privileges.
Default is
root.
become_method:Defines the method used for privilege escalation. Default is
sudo.Other options include
su,pbrun, ordoas.
become_flags:- Adds additional flags or options for the privilege escalation method.
become_password:Used if the privilege escalation method requires a password.
Use
--ask-become-passparameter while running a playbook or module in a command line.
Dynamic Inventory
Dynamic Inventory is a inventory information that Ansible retrieves programmatically when the Ansible playbook is run (as opposed to us defining it in a static inventory file).
Dynamic inventory in Ansible refers to a method of dynamically generating a list of managed hosts (inventory) at runtime, instead of using a static inventory file.
Inventory Script or Plugin:
A script or plugin fetches host information from an external source (e.g., AWS, Azure, GCP, etc.).
The script generates inventory data in JSON format.
Static Inventory:
web1 ansible_host=172.20.1.100 ansible_ssh_pass=Passw0rd
web2 ansible_host=172.20.1.101 ansible_ssh_pass=Passw0rd
[web_servers]
web1
web2
$ ansible-playbook playbook.yml –i inventory.txt
Inventory Script (Dynamic Inventory):
#!/usr/bin/env python
import json
import argparse
# Get inventory data from source - CMDB or any other API
def get_inventory_data():
return {
"web_servers": {
"hosts": ["web1", "web2"]
},
"_meta": {
"hostvars": {
"web1": {
"ansible_host": "172.20.1.100",
"ansible_ssh_pass": "Passw0rd"
},
"web2": {
"ansible_host": "172.20.1.101",
"ansible_ssh_pass": "Passw0rd"
}
}
}
}
# Default main function
if __name__ == "__main__":
read_cli_args();
inventory_data = get_inventory_data()
if args.list:
print(json.dumps(inventory_data))
<Code Hidden>
Command to run a playbook:
$ ansible-playbook playbook.yml –i inventory.py--list: output the entire inventory information in JSON format./inventory.py --list { "web_servers": { "hosts": [ "web1", "web2" ] }, "_meta": { "hostvars": { "web2": { "ansible_host": "172.20.1.101", "ansible_ssh_pass": "Passw0rd" }, "web1": { "ansible_host": "172.20.1.100", "ansible_ssh_pass": "Passw0rd" } } } }--host: print the parameters defined for the given host in a JSON format$ ./inventory.py –-host web1 { "ansible_host": "172.20.1.100", "ansible_ssh_pass": "Passw0rd" }There are multiple inventory script (
.py) readily available to use on ansible repo. For ex:$ ansible-playbook playbook.yml –i ec2.py