Ansible is an open-source IT automation tool used for configuration management, application deployment, and task orchestration. It is agentless, works over SSH/WinRM, and uses YAML-based playbooks to define tasks. Key features include idempotency, modularity (modules & roles), and easy inventory management.
Ansible Basics:
Agentless ---> Ansible doesn’t require agents; works over SSH (Linux/Unix) or WinRM (Windows)
Idempotent ---> Running the same playbook multiple times won’t change system if already in desired state
YAML-based Playbooks ---> Human-readable YAML files define tasks
Modules ---> Perform specific tasks (install packages, copy files, manage services)
Inventory Management ---> Hosts defined in inventory file (static or dynamic)
Roles ---> Modular units of tasks, handlers, variables for reusable playbooks
Collections ---> Bundles of modules, plugins, and roles distributed together
Handlers ---> Tasks triggered by notify (usually used to restart services)
Plugins ---> Extend Ansible functionality (connection, callback, filter, lookup)
Facts ---> System information gathered automatically from hosts
Playbook Variables / Structure:
name: <Playbook name> ---> Description of the playbook
hosts: <host/group> ---> Target machines or groups
become: <yes/no> ---> Use sudo/root privileges
gather_facts: <yes/no> ---> Collect system facts
vars: ---> Define custom variables
<var_name>: <value> ---> Assign value
vars_files: ---> Load variables from external YAML files
- <path/to/vars_file.yml>
register: <variable_name> ---> Capture task output
loop: ---> Iterate over a list of items
with_items: ---> Legacy form of loop
when: <condition> ---> Conditional task execution
name: <Playbook name> ---> Description of the playbook
hosts: <host/group> ---> Target machines or groups
become: <yes/no> ---> Use sudo/root privileges
gather_facts: <yes/no> ---> Collect system facts
vars: ---> Define custom variables
<var_name>: <value> ---> Assign value
vars_files: ---> Load variables from external YAML files
- <path/to/vars_file.yml>
register: <variable_name> ---> Capture task output
loop: ---> Iterate over a list of items
with_items: ---> Legacy form of loop
when: <condition> ---> Conditional task execution
tasks: ---> List of tasks to execute
handlers: ---> Special tasks triggered by notify
notify: <handler_name> ---> Trigger handler if task changes
environment: ---> Set environment variables for task
include_tasks: <file.yml> ---> Include another task file
import_playbook: <file.yml> ---> Import another playbook
Common Playbook Variables:
Linux / Unix:
ansible_user: <username> ---> SSH login user
ansible_password: <password> ---> SSH password
ansible_port: <port> ---> SSH port (default 22)
ansible_become: <yes/no> ---> Run tasks as root/sudo
ansible_become_method: <sudo/su> ---> Privilege escalation method
ansible_python_interpreter: <path> ---> Python interpreter on host
Linux / Unix:
ansible_user: <username> ---> SSH login user
ansible_password: <password> ---> SSH password
ansible_port: <port> ---> SSH port (default 22)
ansible_become: <yes/no> ---> Run tasks as root/sudo
ansible_become_method: <sudo/su> ---> Privilege escalation method
ansible_python_interpreter: <path> ---> Python interpreter on host
ansible_host: <ip/hostname> ---> Target host address
ansible_private_key_file: <path> ---> SSH private key for authentication
ansible_ssh_common_args: <args> ---> Extra SSH arguments
Windows:
ansible_connection: winrm ---> Use WinRM for Windows hosts
ansible_winrm_transport: <ntlm/kerberos> ---> Windows transport type
ansible_winrm_server_cert_validation: <ignore/validate> ---> SSL validation
ansible_connection: winrm ---> Use WinRM for Windows hosts
ansible_winrm_transport: <ntlm/kerberos> ---> Windows transport type
ansible_winrm_server_cert_validation: <ignore/validate> ---> SSL validation
ansible_user: <username> ---> Windows login user
ansible_password: <password> ---> Windows password
ansible_port: 5985 ---> HTTP WinRM
ansible_port: 5986 ---> HTTPS WinRM
VMware:
vcenter_hostname: <hostname> ---> vCenter server
vcenter_user: <username> ---> vCenter login
vcenter_password: <password> ---> vCenter password
vcenter_hostname: <hostname> ---> vCenter server
vcenter_user: <username> ---> vCenter login
vcenter_password: <password> ---> vCenter password
validate_certs: <yes/no> ---> SSL certificate validation
datacenter: <dc_name> ---> VMware datacenter
cluster: <cluster_name> ---> VMware cluster
AWS / Cloud:
aws_access_key: <key> ---> AWS access key
aws_secret_key: <secret> ---> AWS secret key
aws_region: <region> ---> AWS region
aws_access_key: <key> ---> AWS access key
aws_secret_key: <secret> ---> AWS secret key
aws_region: <region> ---> AWS region
aws_profile: <profile_name> ---> AWS CLI profile
aws_session_token: <token> ---> Temporary AWS session token
Control Variables / Execution:
tags: <tag_name> ---> Run only tasks with this tag
ignore_errors: <yes/no> ---> Continue if task fails
timeout: <seconds> ---> Task timeout
retries: <number> ---> Retry task on failure
delay: <seconds> ---> Wait before retrying
run_once: yes ---> Execute task only once
delegate_to: <host> ---> Run task on another host
changed_when: <condition> ---> Custom “changed” status
failed_when: <condition> ---> Custom failure detection
tags: <tag_name> ---> Run only tasks with this tag
ignore_errors: <yes/no> ---> Continue if task fails
timeout: <seconds> ---> Task timeout
retries: <number> ---> Retry task on failure
delay: <seconds> ---> Wait before retrying
run_once: yes ---> Execute task only once
delegate_to: <host> ---> Run task on another host
changed_when: <condition> ---> Custom “changed” status
failed_when: <condition> ---> Custom failure detection
serial: <number> ---> Run playbook on hosts in batches
max_fail_percentage: <percent> ---> Stop play if failure threshold reached
any_errors_fatal: <yes/no> ---> Stop play on first error
throttle: <number> ---> Limit parallel task execution
CLI Commands / Options:
ansible <host/group> -m ping ---> Test connectivity
ansible <host/group> -m command -a "<command>" ---> Run command
ansible <host/group> -m shell -a "<shell_cmd>" ---> Run shell command
ansible <host/group> -m copy -a "src=<src> dest=<dest>" ---> Copy file
ansible-playbook <playbook.yml> ---> Run playbook
ansible-playbook <playbook.yml> --check ---> Dry-run
ansible-playbook <playbook.yml> --diff ---> Show changes
ansible-playbook <playbook.yml> --tags "<tag>" ---> Run tasks with tag
ansible-playbook <playbook.yml> --skip-tags "<tag>" ---> Skip tasks with tag
ansible-inventory -i <inventory_file> --list ---> Show inventory hosts
ansible-doc -l ---> List all modules
ansible-doc <module_name> ---> Show module documentation
ansible-galaxy install <role_name> ---> Install role from Galaxy
ansible-galaxy init <role_name> ---> Create new role
ansible-vault create/edit/view/encrypt/decrypt ---> Vault operations
ansible <host/group> -m ping ---> Test connectivity
ansible <host/group> -m command -a "<command>" ---> Run command
ansible <host/group> -m shell -a "<shell_cmd>" ---> Run shell command
ansible <host/group> -m copy -a "src=<src> dest=<dest>" ---> Copy file
ansible-playbook <playbook.yml> ---> Run playbook
ansible-playbook <playbook.yml> --check ---> Dry-run
ansible-playbook <playbook.yml> --diff ---> Show changes
ansible-playbook <playbook.yml> --tags "<tag>" ---> Run tasks with tag
ansible-playbook <playbook.yml> --skip-tags "<tag>" ---> Skip tasks with tag
ansible-inventory -i <inventory_file> --list ---> Show inventory hosts
ansible-doc -l ---> List all modules
ansible-doc <module_name> ---> Show module documentation
ansible-galaxy install <role_name> ---> Install role from Galaxy
ansible-galaxy init <role_name> ---> Create new role
ansible-vault create/edit/view/encrypt/decrypt ---> Vault operations
ansible-config list ---> Show all configuration options
ansible-config view ---> View active configuration
ansible-playbook <playbook.yml> -i <inventory> ---> Specify inventory
ansible-playbook <playbook.yml> -l <host> ---> Limit execution to host/group
ansible-playbook <playbook.yml> -u <user> ---> Remote user
ansible-playbook <playbook.yml> -b ---> Run with become
ansible-playbook <playbook.yml> -vvv ---> Debug verbosity
Environment Variables:
ANSIBLE_CONFIG: <path> ---> Use custom ansible.cfg
ANSIBLE_INVENTORY: <path> ---> Default inventory
ANSIBLE_ROLES_PATH: <path> ---> Path for roles
ANSIBLE_STDOUT_CALLBACK: <default/json/yaml> ---> Output format
ANSIBLE_HOST_KEY_CHECKING: <True/False> ---> Disable SSH host key check
ANSIBLE_CONFIG: <path> ---> Use custom ansible.cfg
ANSIBLE_INVENTORY: <path> ---> Default inventory
ANSIBLE_ROLES_PATH: <path> ---> Path for roles
ANSIBLE_STDOUT_CALLBACK: <default/json/yaml> ---> Output format
ANSIBLE_HOST_KEY_CHECKING: <True/False> ---> Disable SSH host key check
ANSIBLE_LOG_PATH: <path> ---> Log file location
ANSIBLE_RETRY_FILES_ENABLED: <True/False> ---> Create retry files
ANSIBLE_TIMEOUT: <seconds> ---> SSH timeout
Modules (Examples):
Package Management
apt/yum/dnf/pkg: <package_name> state=<present/absent/latest> ---> Install/remove packages
command ---> Does not process shell operators (|, >, &&)
shell ---> Executes command via shell and supports pipes/redirection
git: repo=<url> dest=<path> version=<branch> ---> Git repowin_package/win_copy/win_command/win_shell ---> Windows tasks
Services
service/win_service: name=<service> state=<started/stopped/enabled> ---> Manage services
Files
copy/file/template: src/dest/owner/group/mode ---> File management
Users / Groups
user/group: name=<name> state=<present/absent> ---> Manage users/groups
Cron / Scheduling
cron: name=<job> minute=<0-59> hour=<0-23> user=<user> job=<command> ---> Schedule jobs
Networking
uri: url=<endpoint> method=<GET/POST> ---> Call REST API
get_url: url=<file_url> dest=<path> ---> Download file
unarchive: src=<file> dest=<path> ---> Extract archive
vmware_guest: hostname/user/password name=<vm> state=<poweredon/poweredoff/present/absent>
amazon.aws.ec2_instance: key_name/instance_type/image_id/region/state
azure.azcollection.azure_rm_virtualmachine: resource_group/name/vm_size/admin_username/image/state
google.cloud.gcp_compute_instance: name/machine_type/zone/image/project/state
Control Flow / Conditions:
Conditional Execution
when: <condition> ---> Run task only if true
register: <variable> ---> Capture task output
loop / with_items: <list> ---> Iterate over items
retries + delay + until: <condition> ---> Retry task until success (do-while)
block/rescue/always: ---> Try-catch-finally
ignore_errors: yes ---> Continue on failure
changed_when / failed_when: <condition> ---> Override status
until: <condition> ---> Retry until condition met
set_fact: <var>=<value> ---> Define runtime variables
include_role: name=<role> ---> Execute role inside task
Examples:
package_name: "{{ 'vim' if ansible_facts['os_family']=='Debian' else 'vim-enhanced' }}"
- name: Install packages with loop
apt: name="{{ item }}" state=present
loop: "{{ debian_packages if ansible_facts['os_family']=='Debian' else redhat_packages }}"
- block:
- command: /usr/bin/do_something
rescue:
- debug: msg="Command failed"
always:
- debug: msg="Always runs"
package_name: "{{ 'vim' if ansible_facts['os_family']=='Debian' else 'vim-enhanced' }}"
- name: Install packages with loop
apt: name="{{ item }}" state=present
loop: "{{ debian_packages if ansible_facts['os_family']=='Debian' else redhat_packages }}"
- block:
- command: /usr/bin/do_something
rescue:
- debug: msg="Command failed"
always:
- debug: msg="Always runs"
Dynamic Variables:
ansible_facts['os_family'] ---> OS family
ansible_facts['distribution'] ---> OS distribution
ansible_facts['distribution_version'] ---> Version
ansible_facts['hostname'] ---> Hostname
ansible_facts['interfaces'] ---> Network interfaces
ansible_facts['memory_mb'] ---> Memory info
ansible_facts['processor'] ---> CPU info
ansible_facts['fqdn'] ---> Fully qualified domain name
ansible_facts['architecture'] ---> CPU architecture
ansible_facts['uptime_seconds'] ---> System uptime
ansible_facts['default_ipv4'] ---> Default IPv4 address
ansible_facts['mounts'] ---> Mounted filesystems
Standard Ansible project directory structure:
ansible-project/
├── ansible.cfg
├── inventory/
│ ├── hosts
│ └── production
├── group_vars/
│ └── all.yml
├── host_vars/
│ └── server1.yml
├── roles/
│ └── webserver/
│ ├── tasks/
│ │ └── main.yml
│ ├── handlers/
│ │ └── main.yml
│ ├── templates/
│ ├── files/
│ ├── vars/
│ │ └── main.yml
│ ├── defaults/
│ │ └── main.yml
│ └── meta/
│ └── main.yml
├── playbooks/
│ └── deploy.yml
└── files/
Explanation:
ansible.cfg ---> Main configuration file
inventory/ ---> Host inventory files
group_vars/ ---> Variables for host groups
host_vars/ ---> Variables for specific hosts
roles/ ---> Reusable automation roles
playbooks/ ---> Playbook YAML files
files/ ---> Static files used by playbooks
templates/ ---> Jinja2 templates
Ansible Vault (Secrets Management):
Ansible Vault is used to encrypt sensitive data such as passwords, API keys, and credentials.
Vault Features:
Encryption ---> Protect sensitive variables
Decryption ---> Access secrets during playbook execution
File-level security ---> Encrypt full YAML files
Variable-level security ---> Encrypt individual variables
Vault Commands:
ansible-vault create <file.yml> ---> Create encrypted file
ansible-vault edit <file.yml> ---> Edit encrypted file
ansible-vault view <file.yml> ---> View encrypted file
ansible-vault encrypt <file.yml> ---> Encrypt existing file
ansible-vault decrypt <file.yml> ---> Decrypt file
ansible-vault rekey <file.yml> ---> Change vault password
Using Vault in Playbook Execution:
ansible-playbook playbook.yml --ask-vault-pass
ansible-playbook playbook.yml --vault-password-file <file>
Example Encrypted Variable:
db_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
6539646533343231646464...
Dynamic Inventory:
Dynamic inventory allows Ansible to automatically fetch hosts from cloud providers or external systems.
Instead of static host lists, inventory is generated dynamically using scripts or plugins.
Dynamic Inventory Sources:
AWS ---> EC2 instances
VMware ---> vCenter virtual machines
Azure ---> Azure VMs
GCP ---> Google Cloud instances
Kubernetes ---> Pods and nodes
Example Dynamic Inventory Plugins:
amazon.aws.aws_ec2 ---> AWS EC2 inventory
vmware.vmware_vm_inventory ---> VMware vCenter inventory
azure.azcollection.azure_rm ---> Azure inventory
google.cloud.gcp_compute ---> Google Cloud inventory
kubernetes.core.k8s ---> Kubernetes resources
Example AWS Dynamic Inventory Configuration:
plugin: amazon.aws.aws_ec2
regions:
- us-east-1
filters:
instance-state-name: running
keyed_groups:
- key: tags.Name
Command to test dynamic inventory:
ansible-inventory -i aws_ec2.yml --graph
ansible-inventory -i aws_ec2.yml --list
Ansible Configuration File (ansible.cfg):
The ansible.cfg file controls Ansible behavior and execution settings.
Ansible checks configuration in the following order:
ANSIBLE_CONFIG (environment variable)
./ansible.cfg (current project directory)
~/.ansible.cfg (user home directory)
/etc/ansible/ansible.cfg (global configuration)
Common Configuration Options:
inventory = <path> ---> Default inventory file
roles_path = <path> ---> Location of roles
forks = <number> ---> Number of parallel hosts
timeout = <seconds> ---> SSH connection timeout
remote_user = <username> ---> Default SSH user
host_key_checking = <True/False> ---> Enable/disable SSH host verification
retry_files_enabled = <True/False> ---> Create retry files on failure
log_path = <path> ---> Log file location
stdout_callback = <default/yaml/json> ---> Output formatting
Example ansible.cfg:
[defaults]
inventory = ./inventory/hosts
roles_path = ./roles
forks = 20
host_key_checking = False
retry_files_enabled = False
log_path = ./ansible.log
Ansible Roles (Best Practices):
Roles allow reusable and modular automation components.
Role Best Practices:
Single Responsibility ---> Each role should manage one component
Use defaults/main.yml ---> Store default variables
Avoid hardcoded values ---> Use variables
Use handlers ---> Restart services only when required
Keep tasks small ---> Maintain readability
Use tags ---> Enable selective execution
Example Role Task with Handler:
- name: Install nginx
apt:
name: nginx
state: present
notify: restart nginx
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
Role Dependencies (meta/main.yml):
dependencies:
- role: common
- role: security
Performance Optimization:
For large infrastructures, tuning Ansible improves execution speed.
Performance Settings:
forks: <number> ---> Increase parallel execution
pipelining: True ---> Reduce SSH operations
ssh_args: ControlMaster options ---> Reuse SSH connections
fact_caching: <method> ---> Cache gathered facts
gather_facts: no ---> Disable if not needed
Example Performance Configuration:
[defaults]
forks = 50
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_cache
[ssh_connection]
pipelining = True
ssh_args = -o ControlMaster=auto -o ControlPersist=60s
Benefits:
Faster execution ---> Parallel task processing
Reduced SSH overhead ---> Persistent connections
Lower API calls ---> Cached system facts
Troubleshooting & Debugging:
Common troubleshooting methods for Ansible failures.
Debugging Commands:
ansible-playbook playbook.yml -vvv ---> Detailed debugging output
ansible-playbook playbook.yml --syntax-check ---> Validate playbook syntax
ansible-playbook playbook.yml --list-tasks ---> Show tasks without executing
ansible-playbook playbook.yml --list-hosts ---> Show targeted hosts
ansible-playbook playbook.yml --start-at-task "<task>" ---> Start from specific task
Debug Module:
- debug:
msg: "Variable value is {{ variable_name }}"
Check Variable Values:
- debug:
var: ansible_facts
Common Issues:
SSH authentication failure ---> Check user, key, and permissions
Python missing on target ---> Install Python on remote host
Permission denied ---> Use become: yes
Host unreachable ---> Verify inventory and network access
Module failure ---> Run with -vvv for detailed logs
Ansible Security Best Practices:
Security practices to protect infrastructure automation and credentials.
Credential Protection:
Use Ansible Vault ---> Encrypt sensitive data such as passwords, API keys, and tokens
Avoid plaintext secrets ---> Never store credentials directly in playbooks
Use vault password file ---> Store vault password securely
Use environment variables ---> Pass sensitive data dynamically
Authentication:
Use SSH keys ---> Prefer key-based authentication instead of passwords
Restrict SSH access ---> Limit login users and disable root login
Rotate credentials ---> Regularly update keys and passwords
Use strong key types ---> RSA 4096 or ED25519 recommended
Privilege Escalation:
become: yes ---> Use privilege escalation only when required
Limit sudo access ---> Restrict commands allowed via sudo
Avoid running entire playbook as root ---> Use become only for specific tasks
Access Control:
Role-Based Access ---> Restrict who can run playbooks
Inventory segmentation ---> Separate environments (dev/test/prod)
Use separate credentials ---> Different credentials for each environment
File & Secret Management:
Protect inventory files ---> Restrict file permissions
Store secrets in vault ---> Avoid exposing credentials in Git
Use secret management tools ---> Integrate with external vault systems
External Secret Integration:
HashiCorp Vault ---> Secure dynamic secrets
AWS Secrets Manager ---> Store cloud credentials
Azure Key Vault ---> Manage Azure secrets
CyberArk ---> Enterprise privileged access management
Repository Security:
Use private repositories ---> Restrict access to automation code
Enable code reviews ---> Validate playbook changes
Use CI/CD security scanning ---> Detect exposed secrets
Audit & Logging:
Enable logging ---> Record automation activity
Centralized logs ---> Send logs to SIEM systems
Track playbook runs ---> Maintain execution history
Example Secure File Permissions:
chmod 600 inventory
chmod 600 group_vars/*
chmod 600 host_vars/*
Ansible Quick Reference:
Connectivity Test:
ansible <host/group> -m ping ---> Test connection to hosts
ansible all -m ping ---> Test all hosts in inventory
Ad-hoc Commands:
ansible <host/group> -m command -a "<command>" ---> Run command on hosts
ansible <host/group> -m shell -a "<command>" ---> Run shell command
ansible <host/group> -m copy -a "src=<src> dest=<dest>" ---> Copy file
ansible <host/group> -m file -a "path=<path> state=directory" ---> Create directory
Playbook Execution:
ansible-playbook playbook.yml ---> Run playbook
ansible-playbook playbook.yml -i inventory ---> Specify inventory
ansible-playbook playbook.yml -l <host/group> ---> Limit execution to hosts
ansible-playbook playbook.yml -u <user> ---> Specify SSH user
ansible-playbook playbook.yml -b ---> Run with sudo/become
Dry Run / Debug:
ansible-playbook playbook.yml --check ---> Dry run (no changes)
ansible-playbook playbook.yml --diff ---> Show file differences
ansible-playbook playbook.yml -vvv ---> Detailed debugging
ansible-playbook playbook.yml --syntax-check ---> Validate playbook syntax
Tags Execution:
ansible-playbook playbook.yml --tags "<tag>" ---> Run specific tagged tasks
ansible-playbook playbook.yml --skip-tags "<tag>" ---> Skip tagged tasks
Inventory Commands:
ansible-inventory -i inventory --list ---> Show inventory details
ansible-inventory -i inventory --graph ---> Show host groups
Module Documentation:
ansible-doc -l ---> List all modules
ansible-doc <module_name> ---> Show module documentation
Role Management:
ansible-galaxy init <role_name> ---> Create role structure
ansible-galaxy install <role_name> ---> Install role from Galaxy
Vault Commands:
ansible-vault create secrets.yml ---> Create encrypted file
ansible-vault edit secrets.yml ---> Edit encrypted file
ansible-vault encrypt secrets.yml ---> Encrypt file
ansible-vault decrypt secrets.yml ---> Decrypt file
Useful Variables:
ansible_facts['hostname'] ---> Hostname
ansible_facts['os_family'] ---> OS family
ansible_facts['distribution'] ---> Linux distribution
ansible_facts['default_ipv4'] ---> Default IP address
No comments:
Post a Comment