Ansible Comprehensive Guide-1
Ansible Comprehensive Guide-1
2
o Core Modules Overview
o Using Modules for System Management
o Exploring Popular Modules (e.g., file, copy, yum, service,
command)
7. Roles and Reusability
o Introduction to Ansible Roles
o Creating and Using Roles
o Best Practices for Modular and Reusable Code
8. Advanced Ansible Features
o Ansible Vault for Secrets Management
o Ansible Variables, Facts, and Templates
o Handlers and Conditional Task Execution
9. Ansible for Orchestration
o Managing Multi-Tier Applications
o Working with Docker and Kubernetes
o Integrating with CI/CD Pipelines
10.Troubleshooting and Best Practices
o Debugging Ansible Playbooks
o Common Issues and Their Solutions
o Optimizing Playbook Performance and Efficiency
3
1. Introduction to Ansible
Ansible is an open-source IT automation tool that simplifies the management
of complex IT environments. It enables organizations to automate the
configuration, deployment, and orchestration of systems in a scalable and
efficient manner. Developed by Michael DeHaan and first released in 2012,
Ansible has grown to become one of the most popular automation tools due to
its simplicity and agentless architecture.
What is Ansible?
At its core, Ansible is a tool that enables IT professionals to define
infrastructure as code (IaC). This means you can automate processes and
manage systems using human-readable configuration files written in YAML.
Ansible can perform a wide range of tasks, including:
Automating repetitive system administration tasks.
Configuring servers and deploying applications.
Orchestrating multi-tier applications across complex environments.
Key Features and Benefits
Ansible offers several features that make it stand out among other automation
tools like Puppet and Chef:
1. Agentless Architecture
Ansible does not require any agent software to be installed on managed
nodes (the systems being automated). Instead, it uses SSH for
communication, which reduces overhead and simplifies setup.
2. Human-Readable Language
Ansible playbooks are written in YAML, a straightforward, human-
readable markup language. This makes it easy for teams to collaborate
without requiring deep programming knowledge.
3. Idempotency
Ansible ensures that tasks are executed only when necessary. If a system
is already in the desired state, Ansible skips the task, avoiding
unnecessary operations.
4. Extensibility
With its modular design, Ansible supports an extensive library of
4
modules for managing various systems, including Linux, Windows, cloud
services, and container platforms.
5. Cross-Platform Support
Ansible works seamlessly across a variety of operating systems and
environments, making it ideal for heterogeneous IT infrastructures.
6. Scalability
Whether you're managing ten servers or ten thousand, Ansible scales
effortlessly with minimal resource consumption.
Use Cases in IT Automation
Ansible is versatile and finds applications in numerous IT scenarios:
1. Configuration Management
Automating the configuration of operating systems, software, and
services. For instance, you can use Ansible to ensure all servers in a
cluster are configured identically.
2. Application Deployment
Simplifying the deployment process for multi-tier applications. Ansible
can manage dependencies, deploy application code, and configure
servers in one go.
3. Orchestration
Coordinating complex workflows, such as provisioning servers,
configuring networks, and deploying applications, in a specific order.
4. Infrastructure as Code (IaC)
Defining infrastructure configurations in code format to ensure
consistency and reproducibility.
5. Continuous Integration and Continuous Deployment (CI/CD)
Integrating Ansible with CI/CD pipelines to automate testing,
deployment, and rollback processes.
Why Use Ansible?
Organizations choose Ansible for several compelling reasons:
Ease of Use: Ansible’s simplicity allows even non-experts to start
automating tasks quickly.
5
Cost-Effective: Being open-source, Ansible eliminates the need for
expensive licensing fees.
Security: Ansible uses secure protocols like SSH and minimizes
vulnerabilities by not requiring agent software.
Community Support: With a vibrant community and extensive
documentation, finding help and resources is easy.
6
2. Setting Up Ansible
Setting up Ansible is a straightforward process that requires minimal
installation steps and resources. This simplicity is one of Ansible’s key
strengths, enabling users to start automating tasks quickly. The setup process
primarily involves configuring a control node and managed nodes, ensuring
connectivity, and customizing Ansible’s configuration file.
Control Node and Managed Nodes
Ansible operates using a control node and one or more managed nodes:
Control Node: The system where Ansible is installed and from which
automation tasks are executed. This node can be any Linux or macOS
system. For Windows, Ansible can run within a Linux-based virtual
machine or WSL (Windows Subsystem for Linux).
Managed Nodes: These are the target systems that Ansible automates.
They can be Linux, Windows, or network devices. Managed nodes do not
require any agent installation as Ansible communicates with them via
SSH (for Linux) or WinRM (for Windows).
Installing Ansible
1. Prerequisites
o A Linux-based control node.
o Python installed on the control node and managed nodes.
2. Installation Steps
o On Red Hat/CentOS-based Systems:
sudo yum install epel-release -y
sudo yum install ansible -y
o On Ubuntu/Debian-based Systems:
sudo apt update
sudo apt install ansible -y
o Using Python’s pip:
pip install ansible
7
3. Verifying Installation After installation, verify the version of Ansible to
ensure it’s set up correctly:
ansible --version
Ansible Configuration File
Ansible’s configuration file (ansible.cfg) allows customization of its behavior. It
is typically located in the following locations (searched in order):
1. The current directory.
2. The user’s home directory (~/.ansible.cfg).
3. The /etc/ansible/ansible.cfg file.
Important settings in ansible.cfg include:
Inventory: Specifies the path to the inventory file.
Remote User: Defines the user account used to log into managed nodes.
Private Key File: Specifies the path to the SSH key for authentication.
For example, a basic ansible.cfg might look like this:
[defaults]
inventory = /etc/ansible/hosts
remote_user = ansible_user
private_key_file = ~/.ssh/id_rsa
Setting Up SSH for Managed Nodes
1. Generate an SSH Key Pair Run the following command on the control
node to generate a key pair:
ssh-keygen -t rsa -b 2048
Save the key pair in the default location (~/.ssh/id_rsa).
2. Copy the Public Key to Managed Nodes Use the ssh-copy-id command
to copy the public key to a managed node:
ssh-copy-id user@managed_node_ip
8
Replace user and managed_node_ip with the username and IP address of the
managed node.
3. Test Connectivity Verify that you can SSH into the managed node
without a password:
ssh user@managed_node_ip
Setting Up Windows Managed Nodes
For Windows systems, Ansible uses WinRM (Windows Remote Management)
instead of SSH. Setting up a Windows managed node involves:
1. Enabling WinRM: Open PowerShell as Administrator and run:
winrm quickconfig
2. Installing Python and Dependencies: Install Python and the pywinrm
library on the control node:
pip install pywinrm
Validating the Setup
Once Ansible is installed and connectivity is configured, test the setup by
running an ad-hoc command. For instance:
ansible all -m ping
This command pings all hosts listed in the inventory file and verifies that
Ansible can communicate with them.
Upgrading Ansible
To ensure access to the latest features and bug fixes, regularly upgrade Ansible.
Use the following command:
pip install --upgrade ansible
9
3. Ansible Inventory
The Ansible inventory is a critical component that defines the systems
(managed nodes) Ansible will target for automation tasks. It is essentially a list
of hosts and groups of hosts, specified in a structured format. Ansible uses this
inventory to determine where tasks should be executed.
Static Inventory
A static inventory is a simple text file that lists hosts and groups. By default,
Ansible looks for the inventory file at /etc/ansible/hosts, but you can specify a
custom inventory file using the -i option in your commands.
1. Basic Format
The inventory file lists hosts either by IP address or hostname:
192.168.1.10
server1.example.com
2. Grouping Hosts
Hosts can be grouped using square brackets ([]):
[webservers]
192.168.1.11
192.168.1.12
[dbservers]
db1.example.com
db2.example.com
3. Defining Variables
You can assign variables to groups or individual hosts:
[webservers]
192.168.1.11 ansible_user=ubuntu ansible_port=22
192.168.1.12 ansible_user=ubuntu ansible_port=22
10
[dbservers]
db1.example.com ansible_user=root ansible_password=securepass
db2.example.com ansible_user=root ansible_password=securepass
Dynamic Inventory
A dynamic inventory is generated dynamically using scripts or plugins. This is
useful for environments where the infrastructure is constantly changing, such
as in cloud or containerized environments.
1. Supported Plugins
Ansible supports a variety of dynamic inventory plugins, including AWS,
Azure, Google Cloud, and Kubernetes. These plugins allow Ansible to
fetch the inventory directly from the respective environment.
2. Using a Dynamic Inventory Script
To use a dynamic inventory, create or obtain a script compatible with
your environment. For example, to use an AWS inventory:
ansible -i aws_ec2.yaml all -m ping
3. Custom Dynamic Inventory Script
You can create your own dynamic inventory script in Python or any other
language. The script must output JSON in the following format:
{
"webservers": {
"hosts": ["192.168.1.11", "192.168.1.12"],
"vars": {
"ansible_user": "ubuntu"
}
},
"dbservers": {
"hosts": ["db1.example.com", "db2.example.com"],
"vars": {
"ansible_user": "root",
11
"ansible_password": "securepass"
}
}
}
4. Testing Dynamic Inventory
Test the inventory script using:
ansible-inventory -i inventory_script.py --list
Host Patterns
Ansible supports host patterns for targeting specific hosts or groups in the
inventory:
1. All Hosts Target all hosts:
ansible all -m ping
2. Specific Groups Target specific groups:
ansible webservers -m ping
3. Excluding Groups Exclude certain groups using a !:
ansible all:!dbservers -m ping
4. Combining Patterns Combine multiple patterns:
ansible webservers:dbservers -m ping
Host Variables and Group Variables
1. Host Variables
Define variables for a specific host:
[webservers]
192.168.1.11 ansible_user=ubuntu
[192.168.1.11:vars]
app_name=my_web_app
12
2. Group Variables
Assign variables to an entire group:
[webservers:vars]
ansible_user=ubuntu
ansible_port=22
3. Group Variable File
Use a separate file for group variables under group_vars/:
group_vars/webservers.yml
Content:
ansible_user: ubuntu
ansible_port: 22
Best Practices for Inventory
1. Use meaningful group names to organize hosts effectively.
2. Keep sensitive information out of static inventories; use Ansible Vault for
secure storage.
3. Leverage dynamic inventories for cloud or containerized environments.
4. Maintain separate inventories for different environments (e.g., Dev, QA,
Prod).
13
4. Ansible Ad-Hoc Commands
Ansible ad-hoc commands are simple, one-liner commands used to perform
quick tasks without writing a playbook. These commands are particularly useful
for testing, troubleshooting, or executing tasks on the fly. They leverage Ansible
modules to interact with managed nodes.
Understanding Ad-Hoc Commands
Ad-hoc commands are executed directly from the command line, targeting one
or more hosts or groups. They typically follow this structure:
ansible [host-pattern] -m [module] -a "[module arguments]"
host-pattern: Specifies the hosts or groups to target, defined in the
inventory.
-m [module]: Specifies the Ansible module to use (e.g., ping, shell, copy).
-a "[module arguments]": Provides arguments for the module.
Common Use Cases
1. Pinging Hosts
The ping module tests connectivity between the control node and
managed nodes:
ansible all -m ping
2. Executing Shell Commands
Use the shell or command module to execute commands on remote
systems:
ansible all -m shell -a "uptime"
ansible webservers -m command -a "df -h"
3. Managing Files
The file module can create, delete, or modify files and directories:
ansible all -m file -a "path=/tmp/example state=touch"
ansible all -m file -a "path=/tmp/example state=absent"
4. Copying Files
The copy module copies files from the control node to managed nodes:
14
ansible all -m copy -a "src=/etc/hosts dest=/tmp/hosts"
5. Package Management
Install, remove, or update software packages using modules like yum,
apt, or dnf:
ansible all -m yum -a "name=httpd state=present"
ansible all -m apt -a "name=nginx state=latest"
6. Service Management
Start, stop, restart, or enable services using the service module:
ansible all -m service -a "name=nginx state=started"
ansible all -m service -a "name=httpd enabled=yes"
7. User Management
Add or remove users using the user module:
ansible all -m user -a "name=john state=present"
ansible all -m user -a "name=john state=absent"
Examples of Ad-Hoc Commands
1. Rebooting Systems
Use the reboot module to restart systems:
ansible all -m reboot
2. Fetching Files
The fetch module retrieves files from managed nodes to the control
node:
ansible all -m fetch -a "src=/etc/hosts dest=/tmp/hosts"
3. Gathering Facts
Use the setup module to collect detailed information about managed
nodes:
ansible all -m setup
4. Executing Multiple Commands
Chain multiple commands using && or ; in the shell module:
ansible all -m shell -a "mkdir /tmp/test && echo 'Hello' > /tmp/test/file.txt"
15
5. Checking Disk Usage
Monitor disk usage on all hosts:
ansible all -m shell -a "df -h | grep '/dev/sda1'"
Best Practices for Ad-Hoc Commands
1. Use Playbooks for Complex Tasks
While ad-hoc commands are powerful, use playbooks for tasks requiring
detailed logic, multiple steps, or reusability.
2. Run with Caution
Be careful when running commands like reboot or rm -rf to avoid
accidental disruptions.
3. Test in Staging
Test commands in non-production environments before applying them
to critical systems.
4. Document Frequent Commands
Maintain a record of frequently used ad-hoc commands for quick
reference.
5. Specify User Privileges
Use the -b flag (become) to run commands with elevated privileges:
ansible all -m shell -a "mkdir /secure" -b
Advantages of Ad-Hoc Commands
Ideal for quick troubleshooting and testing.
Eliminates the need to create a playbook for simple tasks.
Offers immediate feedback and results.
16
5. Understanding Ansible Playbooks
Ansible Playbooks are the heart of Ansible automation, allowing users to define
infrastructure as code in a human-readable YAML format. They provide a
structured way to execute multiple tasks in a sequence, making them ideal for
repeatable and complex automation processes.
What are Playbooks?
A playbook is a YAML file that describes a series of tasks to be executed on
managed nodes. Each play within a playbook targets a group of hosts and
specifies tasks to be performed. Playbooks are flexible, reusable, and can
include variables, handlers, and conditionals for advanced logic.
Structure of a Playbook
An Ansible playbook consists of the following main components:
1. Hosts: Specifies the target hosts or groups.
2. Tasks: Defines actions to be executed on the hosts.
3. Modules: Used within tasks to perform specific actions (e.g., copy, yum,
service).
4. Variables: Custom values that can be reused across tasks.
5. Handlers: Special tasks triggered by other tasks for state changes (e.g.,
restarting a service).
6. Facts: System information gathered by Ansible for dynamic task
execution.
Here’s an example of a simple playbook:
---
- name: Install and configure Apache
hosts: webservers
become: true
tasks:
- name: Install Apache
17
yum:
name: httpd
state: present
18
3. Handlers Section Handlers are tasks triggered by other tasks using the
notify directive:
tasks:
- name: Update configuration
copy:
src: /path/to/config
dest: /etc/myapp/config
notify: Restart myapp service
handlers:
- name: Restart myapp service
service:
name: myapp
state: restarted
4. Variables Section Variables allow parameterization for reusability:
vars:
app_name: myapp
config_path: /etc/myapp/config
5. Loops Loops execute tasks multiple times with different inputs:
tasks:
- name: Create multiple users
user:
name: "{{ item }}"
state: present
loop:
- alice
- bob
19
- charlie
6. Conditionals Conditionals control task execution based on conditions:
tasks:
- name: Install on RHEL systems
yum:
name: nginx
state: present
when: ansible_os_family == "RedHat"
Writing Your First Playbook
To create a playbook:
1. Step 1: Open a text editor and create a YAML file (e.g., site.yml).
2. Step 2: Define a play with hosts, tasks, and modules.
3. Step 3: Save the file and run it with Ansible:
ansible-playbook site.yml
Best Practices for Playbooks
1. Use Descriptive Names
Give meaningful names to plays and tasks for better readability.
2. Organize with Roles
Break playbooks into smaller, reusable roles for better modularity.
3. Leverage Variables
Avoid hardcoding values; use variables and defaults for flexibility.
4. Test in Staging
Validate playbooks in non-production environments before applying
them to critical systems.
5. Use Version Control
Store playbooks in Git repositories to track changes and collaborate
effectively.
:
20
6. Ansible Modules
Ansible modules are the core components used to execute tasks on managed
nodes. They are small, reusable scripts that perform specific actions, such as
installing software, managing files, or configuring networks. Modules enable
Ansible to be both powerful and extensible, supporting a wide variety of tasks
across multiple platforms.
What are Ansible Modules?
Modules are often referred to as "task plugins" or "library plugins." They are
executed by Ansible during playbook runs or ad-hoc commands. Modules are
written in Python but can also be executed in any language that supports JSON.
Key characteristics:
Modules run remotely on managed nodes.
Results from module execution are returned as JSON.
Modules are idempotent, ensuring that the desired state is achieved
without redundant changes.
Types of Modules
Ansible provides hundreds of built-in modules categorized by functionality.
Here are the most common categories:
1. System Modules
Used to manage operating systems, packages, and services:
o yum, apt: Package management for RedHat and Debian-based
systems.
o service: Managing services.
o user: Managing user accounts.
Example:
- name: Install nginx
yum:
name: nginx
state: present
21
2. File and Directory Modules
Handle file and directory operations:
o copy: Copy files from the control node to managed nodes.
o file: Manage file/directory states (create, delete, etc.).
o fetch: Retrieve files from managed nodes.
Example:
- name: Create a directory
file:
path: /tmp/mydir
state: directory
3. Cloud Modules
Automate provisioning and management of cloud resources:
o AWS: ec2, s3, rds.
o Azure: azure_rm_virtualmachine.
o GCP: gcp_compute_instance.
Example:
- name: Launch an EC2 instance
ec2:
instance_type: t2.micro
image: ami-12345678
wait: yes
4. Network Modules
Manage network devices and configurations:
o Cisco: ios_config, nxos_config.
o Juniper: junos_config.
Example:
- name: Configure a Cisco switch
22
ios_config:
lines:
- hostname Switch1
5. Database Modules
Manage databases like MySQL, PostgreSQL, and MongoDB:
o mysql_user, postgresql_db.
Example:
- name: Create a MySQL database
mysql_db:
name: my_database
state: present
6. Utility Modules
Perform miscellaneous tasks:
o command: Run commands on managed nodes.
o debug: Print debugging information.
o shell: Execute shell commands.
Example:
- name: Check system uptime
shell: uptime
Using Modules in Playbooks
Modules are used within tasks to specify actions. Each module may require
specific parameters. Here’s an example:
- name: Install Apache
yum:
name: httpd
state: present
Commonly Used Modules
23
1. Ping Module Tests connectivity between the control node and managed
nodes:
ansible all -m ping
2. Service Module Manages system services:
- name: Start and enable nginx
service:
name: nginx
state: started
enabled: yes
3. Template Module Dynamically generates files from Jinja2 templates:
- name: Deploy nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
4. Lineinfile Module Ensures a specific line exists in a file:
- name: Add a line to hosts file
lineinfile:
path: /etc/hosts
line: "192.168.1.10 myserver"
5. Cron Module Manages cron jobs:
- name: Add a daily cron job
cron:
name: "Daily backup"
job: "/usr/bin/backup.sh"
minute: "0"
hour: "2"
Creating Custom Modules
24
If built-in modules don’t meet specific requirements, you can create custom
modules. Custom modules are written in Python and follow Ansible’s module
development guidelines.
Basic structure of a custom module:
#!/usr/bin/python
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(type='str', required=True),
state=dict(type='str', choices=['present', 'absent'], default='present'),
)
)
result = dict(changed=False, message='')
name = module.params['name']
state = module.params['state']
if state == 'present':
result['message'] = f"Created {name}"
result['changed'] = True
else:
result['message'] = f"Removed {name}"
result['changed'] = True
module.exit_json(**result)
25
if __name__ == '__main__':
main()
Best Practices for Using Modules
1. Read Documentation
Understand the module's parameters and usage to avoid errors.
2. Use Idempotency
Choose modules that support idempotency to ensure consistent results.
3. Use Templates for Complex Files
Replace copy with template for dynamically generated files.
4. Leverage Loops and Variables
Avoid repetitive tasks by combining modules with loops and variables.
26
7. Roles and Reusability
Ansible roles provide a structured way to organize and reuse automation tasks.
They enable modularization by breaking down complex playbooks into smaller,
reusable components. By using roles, you can create a consistent and
maintainable approach to managing your infrastructure.
What are Ansible Roles?
Roles are a collection of files and directories that define tasks, variables,
handlers, templates, and other resources required to automate a specific
function. For example, you can create a role to configure a web server, deploy
an application, or manage a database.
Roles help:
Simplify complex playbooks by dividing them into smaller, logical
components.
Promote reusability across multiple projects or environments.
Maintain a standardized structure for better collaboration and scalability.
Role Directory Structure
Roles have a predefined directory structure that organizes related files. This
structure is automatically recognized by Ansible. Below is the default layout:
my_role/
├── defaults/ # Default variables
│ └── main.yml
├── vars/ # Non-overridable variables
│ └── main.yml
├── files/ # Static files to copy to remote systems
├── templates/ # Jinja2 templates
├── tasks/ # List of tasks to execute
│ └── main.yml
├── handlers/ # Handlers triggered by tasks
27
│ └── main.yml
├── meta/ # Role metadata (dependencies, author info)
│ └── main.yml
├── tests/ # Test playbooks for role validation
│ └── test.yml
└── README.md # Documentation about the role
Key Components of a Role
1. Tasks
The core of the role, defining the actions to execute. Tasks are listed in
tasks/main.yml:
---
- name: Install nginx
yum:
name: nginx
state: present
28
name: nginx
state: restarted
3. Templates
Templates are dynamic configuration files written using Jinja2 syntax.
They are placed in the templates/ directory. Example:
server {
listen 80;
server_name {{ domain_name }};
root /var/www/html;
}
Used in tasks:
- name: Deploy nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
4. Variables
Variables allow parameterization of roles. They can be defined in
defaults/main.yml (overridable) or vars/main.yml (non-overridable):
# defaults/main.yml
nginx_port: 80
5. Files
Static files (e.g., binaries, scripts) are stored in the files/ directory and
can be copied using the copy module:
- name: Copy custom script
copy:
src: custom_script.sh
dest: /usr/local/bin/custom_script.sh
29
mode: 0755
6. Meta
Role metadata defines dependencies and additional information about
the role. Example meta/main.yml:
---
dependencies:
- { role: common, vars: { some_var: value } }
Creating an Ansible Role
1. Generate a Role Structure
Use the ansible-galaxy command to create a new role:
ansible-galaxy init my_role
2. Define Tasks
Populate the tasks/main.yml file with automation tasks.
3. Add Variables, Handlers, and Templates
Include necessary variables, handlers, and templates in their respective
directories.
4. Use the Role in a Playbook
Reference the role in a playbook:
---
- name: Configure web servers
hosts: webservers
roles:
- my_role
Using Roles with Dependencies
Roles can have dependencies on other roles, which are specified in
meta/main.yml. Ansible automatically resolves these dependencies:
dependencies:
- role: common
- role: firewall
30
vars:
allowed_ports:
- 80
- 443
Best Practices for Roles
1. Keep Roles Focused
Each role should address a specific purpose or service.
2. Use Defaults for Variables
Define default values in defaults/main.yml and override them as needed.
3. Follow Directory Structure
Adhere to the default structure to maintain consistency and
compatibility.
4. Document Roles
Include a README.md file to explain the role’s purpose and usage.
5. Test Roles
Validate roles using the tests/ directory or tools like Molecule for
automated testing.
6. Use Ansible Galaxy for Sharing
Share and reuse roles through Ansible Galaxy, a community repository of
Ansible roles.
Benefits of Using Roles
Simplifies complex playbooks by organizing tasks into modular
components.
Enhances reusability across projects and environments.
Encourages consistency and standardization in automation workflows.
Makes collaboration easier in teams by providing a clear structure.
31
8. Advanced Ansible Features
Ansible offers a range of advanced features to tackle complex automation
scenarios. These features enhance flexibility, security, and efficiency, making
Ansible suitable for large-scale and production-ready environments.
1. Ansible Vault for Secrets Management
Ansible Vault allows you to encrypt sensitive data, such as passwords, API keys,
or certificates, directly within your playbooks or inventory files. This ensures
that sensitive information remains secure while being accessible during
execution.
Encrypt a File:
ansible-vault encrypt secrets.yml
Decrypt a File:
ansible-vault decrypt secrets.yml
Edit an Encrypted File:
ansible-vault edit secrets.yml
Using Vault in Playbooks: Include the encrypted file in your playbook
and provide the vault password:
---
- name: Use vault secrets
vars_files:
- secrets.yml
tasks:
- name: Print secret value
debug:
msg: "{{ secret_value }}"
Run the playbook:
ansible-playbook site.yml --ask-vault-pass
2. Variables and Facts
32
Custom Variables: Define variables in playbooks, inventory files, or
external files for reusability:
vars:
app_name: my_app
version: 1.0
Gathering Facts: Ansible collects system information (facts) from
managed nodes using the setup module. These facts can be used
dynamically:
- name: Gather facts
debug:
msg: "The operating system is {{ ansible_os_family }}"
Dynamic Variables: Use hostvars or group_vars for variables scoped to
specific hosts or groups.
3. Handlers and Notifications
Handlers are special tasks triggered by the notify directive in regular tasks. They
are useful for executing actions like restarting a service only when a
configuration changes.
Example:
tasks:
- name: Update nginx configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
handlers:
- name: Restart nginx
service:
33
name: nginx
state: restarted
4. Conditionals
Conditionals allow tasks to execute only when certain conditions are met. Use
the when keyword to define these conditions.
Example:
tasks:
- name: Install nginx on RedHat systems
yum:
name: nginx
state: present
when: ansible_os_family == "RedHat"
5. Loops
Loops help execute a task multiple times with different inputs. Ansible provides
several loop constructs:
Basic Loop:
tasks:
- name: Install multiple packages
yum:
name: "{{ item }}"
state: present
loop:
- nginx
- httpd
- mariadb
Loop with Dictionaries:
tasks:
34
- name: Create multiple users
user:
name: "{{ item.name }}"
state: present
loop:
- { name: alice }
- { name: bob }
6. Tags for Selective Execution
Tags allow you to run specific parts of a playbook. This is useful for debugging
or rerunning specific tasks.
Assigning Tags:
tasks:
- name: Install nginx
yum:
name: nginx
state: present
tags: install
35
Templates are dynamic files that can include variables, loops, and conditionals.
They are written using the Jinja2 templating language.
Example Template (nginx.conf.j2):
server {
listen 80;
server_name {{ domain_name }};
root /var/www/html;
}
Using the Template:
- name: Deploy nginx configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
8. Dynamic Includes
Dynamic includes allow you to include tasks, roles, or playbooks based on
conditions or variables.
Including Tasks Dynamically:
- name: Include OS-specific tasks
include_tasks: "{{ ansible_os_family }}.yml"
9. Ansible Galaxy
Ansible Galaxy is a community hub for sharing and downloading roles. You can
use it to import prebuilt roles and speed up automation.
Install a Role:
ansible-galaxy install geerlingguy.nginx
Using the Role:
- hosts: all
roles:
36
- geerlingguy.nginx
10. Debugging and Troubleshooting
Ansible provides several tools and strategies for debugging playbooks:
Debug Module: Print variables or messages during playbook execution:
- name: Print debug information
debug:
msg: "The value of my_var is {{ my_var }}"
Verbose Mode: Run playbooks with increased verbosity for detailed logs:
ansible-playbook site.yml -vvv
Check Mode: Test playbooks without making changes to the system:
ansible-playbook site.yml --check
37
9. Ansible for Orchestration
Ansible is not just a configuration management tool; it also excels at
orchestrating complex workflows across multi-tier applications and distributed
systems. Orchestration involves automating processes and managing
dependencies between tasks, ensuring they execute in the correct sequence.
Understanding Orchestration
Orchestration refers to the coordination of multiple tasks to achieve a specific
outcome. This often involves deploying multi-tier applications, provisioning
cloud resources, configuring networks, and managing services. Ansible's
simplicity and modularity make it an ideal tool for orchestrating workflows in
diverse IT environments.
Common Orchestration Scenarios
1. Deploying Multi-Tier Applications Ansible can deploy applications
involving web servers, databases, and load balancers in a coordinated
manner.
2. Provisioning Cloud Infrastructure Orchestrate the provisioning of
servers, networks, and storage on platforms like AWS, Azure, and Google
Cloud.
3. Configuring Network Devices Automate network device configurations
and manage changes across switches, routers, and firewalls.
4. Container Orchestration Manage Docker containers and orchestrate
deployments on Kubernetes clusters.
Orchestrating Multi-Tier Applications
A typical multi-tier application may include a load balancer, application servers,
and a database. Ansible playbooks can orchestrate the deployment and
configuration of each tier.
Example:
---
- name: Deploy Multi-Tier Application
hosts: all
38
roles:
- loadbalancer
- appserver
- database
Load Balancer Role:
- name: Install and configure HAProxy
yum:
name: haproxy
state: present
notify: Restart HAProxy
handlers:
- name: Restart HAProxy
service:
name: haproxy
state: restarted
App Server Role:
- name: Deploy application code
src: /path/to/code
dest: /var/www/html
Database Role:
- name: Set up MySQL database
mysql_db:
name: app_db
state: present
Orchestrating Cloud Infrastructure
39
Ansible includes modules for provisioning cloud resources on platforms like
AWS, Azure, and Google Cloud.
Provisioning an AWS EC2 Instance:
- name: Launch EC2 instance
hosts: localhost
gather_facts: false
tasks:
- name: Launch instance
ec2:
key_name: my_key
instance_type: t2.micro
image: ami-12345678
wait: yes
region: us-east-1
Creating an Azure Virtual Machine:
- name: Create Azure VM
azure_rm_virtualmachine:
name: myVM
resource_group: myResourceGroup
vm_size: Standard_B1s
admin_username: azureuser
admin_password: password123
Managing Dependencies in Orchestration
Dependencies between tasks can be managed using:
Handlers: Trigger specific actions like restarting services.
Dependencies in Roles: Specify role dependencies in meta/main.yml:
dependencies:
40
- { role: common }
- { role: firewall }
Using pre_tasks and post_tasks: Execute tasks before or after the main
play:
pre_tasks:
- name: Prepare environment
command: mkdir -p /tmp/setup
post_tasks:
- name: Clean up temporary files
file:
path: /tmp/setup
state: absent
Orchestrating Docker and Kubernetes
1. Docker: Use Ansible’s docker_container and docker_image modules to
manage containers.
o Example:
- name: Start a Docker container
docker_container:
name: my_app
image: nginx:latest
state: started
2. Kubernetes: Use the k8s module to manage Kubernetes resources.
o Example:
- name: Deploy to Kubernetes
k8s:
41
state: present
namespace: default
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: nginx
image: nginx:latest
Error Handling and Recovery
In orchestration, error handling is crucial for ensuring smooth operations.
Ansible provides features to manage errors and recover from failures:
Ignoring Errors: Use the ignore_errors parameter:
- name: Proceed even if this fails
command: /bin/false
ignore_errors: yes
42
Retries: Retry tasks on failure using the retries and delay parameters:
- name: Retry on failure
command: curl http://myapp
retries: 5
delay: 10
Using Blocks for Error Handling: Encapsulate tasks in a block and define
rescue and always sections:
- name: Handle errors gracefully
block:
- name: Attempt risky operation
command: /bin/false
rescue:
- name: Perform cleanup
command: rm -f /tmp/tempfile
always:
- name: Log the outcome
debug:
msg: "Task completed"
Best Practices for Orchestration
1. Plan Dependencies:
Clearly define dependencies and the order of task execution.
2. Use Roles:
Modularize orchestration tasks using roles for better reusability.
3. Test in Staging:
Validate playbooks in a staging environment before applying them to
production.
4. Use Tags:
Assign tags to tasks for selective execution during debugging.
43
5. Enable Logging:
Configure Ansible logging to capture detailed execution data.
44
Troubleshooting Ansible Issues
1. Debugging Playbooks
o Use the debug module to inspect variables and execution:
- name: Print debug information
debug:
msg: "The value of my_var is {{ my_var }}"
o Run playbooks with increased verbosity to see detailed logs:
ansible-playbook site.yml -vvv
o Use ansible-inventory to validate inventory files:
ansible-inventory -i inventory_file --list
2. Check Mode Test your playbooks without making actual changes using
the --check option:
ansible-playbook site.yml --check
3. Common Errors and Solutions
o SSH Connection Issues:
Ensure SSH keys are configured correctly.
Use the ping module to test connectivity:
ansible all -m ping
o Undefined Variables:
Ensure all required variables are defined.
Use set_fact to define variables dynamically:
- name: Define a variable
set_fact:
dynamic_var: value
o Module Failures:
Review module documentation to ensure correct usage.
Check for missing dependencies on managed nodes.
45
o YAML Syntax Errors:
Validate playbooks with a YAML linter:
yamllint playbook.yml
Best Practices for Using Ansible
1. Use Roles for Modularity Break down playbooks into reusable roles. This
improves organization, scalability, and maintainability.
2. Employ Variables and Templates Use variables for flexibility and
templates for dynamic configurations.
3. Secure Sensitive Data Encrypt sensitive information using Ansible Vault
to prevent unauthorized access.
4. Leverage Version Control Store playbooks in Git or another version
control system for collaboration and change tracking.
5. Test Before Deployment Validate playbooks in a staging or testing
environment before applying them to production systems.
6. Use Tags for Selective Execution Tags allow you to run specific tasks or
parts of playbooks, saving time during debugging and reruns.
7. Adopt Idempotency Ensure tasks are idempotent, meaning they achieve
the desired state without unintended side effects when run multiple
times.
8. Enable Logging Configure Ansible to log output for auditing and
debugging:
[defaults]
log_path = /var/log/ansible.log
Conclusion
Ansible’s simplicity, flexibility, and wide-ranging capabilities make it an
indispensable tool for IT automation. From provisioning cloud infrastructure to
deploying multi-tier applications, Ansible excels in automating repetitive tasks
and orchestrating complex workflows. Its agentless architecture and human-
46
readable YAML syntax ensure ease of adoption for beginners while providing
advanced features for seasoned professionals.
This comprehensive guide has covered the foundational concepts, installation
and setup, inventory management, ad-hoc commands, playbooks, modules,
roles, orchestration, and troubleshooting techniques. By following best
practices and leveraging Ansible’s powerful features, you can create robust,
scalable, and efficient automation pipelines tailored to your organization’s
needs.
Automation is no longer a luxury but a necessity in today’s fast-paced IT
environments. Ansible empowers you to embrace automation confidently,
enabling you to focus on innovation and solving critical business challenges.
47