Pages

Ansible

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
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
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_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
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_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
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-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_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 repo
win_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

Cloud / VMware
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"

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