Theory:
Ansible is an open-source automation tool used for configuration management, application deployment, and task automation.
It uses SSH to connect to remote machines and requires no agents.
Written in Python and uses YAML for Playbooks.
Practical:
# Install Ansible on Ubuntu
sudo apt update
sudo apt install ansible -y
# Verify installation
ansible --version
Theory:
Ansible operates through inventory files and playbooks.
Inventory: Defines your target hosts.
Playbooks: YAML files with a list of tasks to run.
Practical:
# /etc/ansible/hosts or custom inventory file
[web]
192.168.1.100
# test-playbook.yml
- name: Ping all web servers
hosts: web
tasks:
- name: Ping the server
ansible.builtin.ping:
ansible-playbook -i inventory.ini test-playbook.yml
Theory:
Use dynamic inventory (e.g. AWS, GCP).
Organize hosts with groups and group_vars.
Use roles and tags for modularity.
Practical:
[web]
web1.example.com
[db]
db1.example.com
[all:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/id_rsa
Directory structure:
group_vars/
web.yml # Variables for web group
db.yml # Variables for db group
roles/
webserver/
database/
Theory:
Quick one-liners, no playbook needed.
Syntax: ansible [host-pattern] -m [module] -a [arguments]
Practical:
# Ping all hosts
ansible all -i inventory.ini -m ping
# Run a shell command
ansible all -i inventory.ini -m shell -a "uptime"
# Install a package
ansible web -m apt -a "name=nginx state=present" -b
Theory:
Playbooks are structured YAML files.
Define tasks, variables, handlers, roles, and more.
Practical:
# install-nginx.yml
- name: Install and start Nginx
hosts: web
become: yes
tasks:
- name: Install nginx
apt:
name: nginx
state: present
- name: Ensure nginx is running
service:
name: nginx
state: started
enabled: yes
ansible-playbook -i inventory.ini install-nginx.yml
Theory:
Variables defined in:
vars:
section
host_vars/
, group_vars/
Extra vars (-e
)
Facts
Practical:
# Example with vars:
- name: Create a user
hosts: all
vars:
username: johndoe
tasks:
- name: Create user {{ username }}
user:
name: "{{ username }}"
ansible-playbook create-user.yml -e "username=janedoe"
Theory:
Use when
statements to control task execution.
Combine with facts or variables.
Practical:
- name: Conditional task
hosts: all
tasks:
- name: Install Nginx only on Ubuntu
apt:
name: nginx
state: present
when: ansible_facts['os_family'] == "Debian"
Theory:
Modules:
copy
: Copy files to target.
template
: Jinja2 templating.
file
: Manage permissions/ownership.
lineinfile
: Modify lines.
Practical:
- name: Manage files
hosts: all
tasks:
- name: Copy config file
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
- name: Add line to hosts file
lineinfile:
path: /etc/hosts
line: "192.168.1.100 web.local"
Theory:
Roles organize playbooks into reusable units.
Each role has tasks/
, handlers/
, files/
, vars/
, templates/
.
Structure:
roles/
webserver/
tasks/
main.yml
templates/
index.html.j2
vars/
main.yml
Practical:
# site.yml
- name: Apply roles
hosts: web
roles:
- webserver
ansible-playbook -i inventory.ini site.yml
Theory:
Structure your project with clear directory hierarchy.
Avoid repetition using roles, includes, and import_tasks
.
Use variables smartly: prefer group_vars/
and host_vars/
.
Use handlers
and notify
to manage idempotence.
Enable fact_caching
for performance in large inventories.
Practical:
# ansible.cfg
[defaults]
inventory = ./inventory.ini
roles_path = ./roles
fact_caching = jsonfile
fact_caching_connection = ./facts
Project Layout:
production/
inventory.ini
group_vars/
all.yml
roles/
web/
tasks/
handlers/
templates/
Theory:
Filters allow manipulation of data in Jinja2 templates.
Common filters: default
, replace
, regex_replace
, to_nice_json
.
Practical:
- name: Use filters in templates
hosts: all
vars:
userlist: ['John', 'Jane', 'Mike']
tasks:
- debug:
msg: "{{ userlist | join(', ') }}"
Or in templates:
# template.j2
{{ user | default('default_user') }}
Theory:
Ansible uses plugins: callback, lookup, filter, inventory, etc.
You can also write custom plugins in Python.
Practical:
# Use lookup plugin
- name: Use file lookup
debug:
msg: "{{ lookup('file', 'myfile.txt') }}"
# Callback plugin (e.g., yaml output)
ansible-playbook site.yml -i inventory.ini -v --callback yaml
Custom filter plugin example:
# custom_filter.py
def to_uppercase(value):
return value.upper()
Theory:
Ansible Tower (now AWX) is the enterprise GUI/API for Ansible.
Features:
Role-based access control
Job templates
Scheduling
REST API
Workflows
Smart Inventory
Practical:
Install AWX via Docker or Kubernetes.
Create:
Organization
Inventory
Credentials
Project (linked to Git)
Job Template (bind playbook to hosts)
Launch Job!
# CLI job launch example
awx job_templates launch --name "Install Apache"
Theory:
Requires PowerShell Remoting over WinRM.
Use win_*
modules (e.g., win_command
, win_service
, win_feature
).
Practical:
Install Python WinRM:
pip install "pywinrm>=0.3.0"
Inventory example:
[windows]
192.168.1.50
[windows:vars]
ansible_connection=winrm
ansible_winrm_transport=basic
ansible_user=Administrator
ansible_password=YourPass123
Playbook:
- name: Install IIS on Windows
hosts: windows
tasks:
- name: Install IIS
win_feature:
name: Web-Server
state: present
Theory:
Requires azure.azcollection
via Ansible Galaxy.
Uses Azure SDK and CLI credentials or service principal.
Practical:
ansible-galaxy collection install azure.azcollection
az login
Playbook to create VM:
- name: Create Azure VM
hosts: localhost
tasks:
- name: Create resource group
azure_rm_resourcegroup:
name: myResourceGroup
location: eastus
Theory:
Use community.docker
or containers.podman
collections.
Manage Docker hosts and containers.
Practical:
ansible-galaxy collection install community.docker
- name: Run a container
hosts: dockerhost
tasks:
- name: Ensure container is running
community.docker.docker_container:
name: nginx
image: nginx:latest
state: started
ports:
- "80:80"
Theory:
Use amazon.aws
and community.aws
collections.
Requires AWS credentials and boto3.
Practical:
pip install boto boto3
ansible-galaxy collection install amazon.aws
- name: Launch EC2
hosts: localhost
tasks:
- name: Launch instance
amazon.aws.ec2_instance:
name: webserver
key_name: mykey
instance_type: t2.micro
image_id: ami-0abcdef1234567890
region: us-east-1
state: present
Theory:
Use platform-specific collections (e.g., cisco.ios
, arista.eos
).
Connect via SSH or APIs.
Practical:
ansible-galaxy collection install cisco.ios
- name: Backup Cisco Config
hosts: switches
gather_facts: no
tasks:
- name: Get config
cisco.ios.ios_command:
commands:
- show running-config
Inventory example:
[switches]
10.0.0.1 ansible_user=admin ansible_password=cisco ansible_network_os=ios ansible_connection=network_cli
Theory:
Manage VMs on:
Libvirt (community.libvirt
)
VMware (community.vmware
)
VirtualBox (via shell commands)
Practical (VMware):
- name: Create VM on vSphere
hosts: localhost
tasks:
- name: Create VM
community.vmware.vmware_guest:
hostname: vcenter.local
username: administrator@vsphere.local
password: mypassword
validate_certs: no
datacenter: DC1
name: test-vm
state: poweredon
guest_id: ubuntu64Guest
disk:
- size_gb: 20
type: thin
networks:
- name: VM Network
hardware:
memory_mb: 1024
num_cpus: 1
Theory:
Use kubernetes.core
collection.
Useful for automating deployments, namespace creation, scaling, etc.
Practical:
ansible-galaxy collection install kubernetes.core
- name: Deploy app to Kubernetes
hosts: localhost
tasks:
- name: Apply deployment
kubernetes.core.k8s:
state: present
namespace: default
definition: "{{ lookup('file', 'deployment.yml') }}"