Ansible

Introduction

Ansible is an open-source automation tool that provides configuration management, application deployment, task automation, and IT orchestration. It uses YAML syntax and is agentless, communicating over SSH.

Key Features:

  • Agentless architecture
  • YAML-based playbooks
  • Extensive module library
  • Idempotent operations
  • Role-based organization
  • Dynamic inventory

Playbooks

Basic Playbook

Example of a simple playbook:

---
- name: Configure web servers
  hosts: webservers
  become: yes
  
  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present
        update_cache: yes
    
    - name: Start nginx service
      service:
        name: nginx
        state: started
        enabled: yes
    
    - name: Copy website files
      copy:
        src: files/website/
        dest: /var/www/html/
        mode: '0644'

Variables and Templates

Example using variables and templates:

---
- name: Configure application
  hosts: app_servers
  vars:
    app_port: 8080
    app_environment: production
    
  tasks:
    - name: Create app configuration
      template:
        src: templates/app.conf.j2
        dest: /etc/app/config.conf
      vars:
        max_connections: 1000
        
# templates/app.conf.j2
server {
    listen {{ app_port }};
    environment: {{ app_environment }}
    max_connections: {{ max_connections }}
}

Roles

Role Structure

Example of a role directory structure:

roles/
  webserver/
    tasks/
      main.yml
    handlers/
      main.yml
    templates/
      nginx.conf.j2
    files/
      index.html
    vars/
      main.yml
    defaults/
      main.yml
    meta/
      main.yml

Role Usage

Example of role implementation:

# roles/webserver/tasks/main.yml
---
- name: Install required packages
  apt:
    name: "{{ item }}"
    state: present
  loop:
    - nginx
    - php-fpm
    
# playbook.yml
---
- hosts: webservers
  roles:
    - role: webserver
      vars:
        nginx_port: 80
        php_version: 7.4

Inventory Management

Static Inventory

Example of inventory file:

[webservers]
web1.example.com ansible_host=192.168.1.10
web2.example.com ansible_host=192.168.1.11

[dbservers]
db1.example.com ansible_host=192.168.1.20
db2.example.com ansible_host=192.168.1.21

[production:children]
webservers
dbservers

[production:vars]
ansible_user=deploy
ansible_ssh_private_key_file=/path/to/key

Dynamic Inventory

Example of AWS dynamic inventory script:

#!/usr/bin/env python

import boto3
import json

def get_hosts():
    ec2 = boto3.client('ec2')
    instances = ec2.describe_instances()
    inventory = {'_meta': {'hostvars': {}}}
    
    for reservation in instances['Reservations']:
        for instance in reservation['Instances']:
            if 'Tags' in instance:
                for tag in instance['Tags']:
                    if tag['Key'] == 'Group':
                        group = tag['Value']
                        if group not in inventory:
                            inventory[group] = []
                        inventory[group].append(
                            instance['PrivateIpAddress']
                        )
    
    return inventory

if __name__ == '__main__':
    print(json.dumps(get_hosts()))

Modules

Common Modules

Popular Modules:

  • apt/yum - Package management
  • service - Service management
  • copy/template - File operations
  • user/group - User management
  • git - Source control
  • docker - Container management

Custom Modules

Example of a custom module:

#!/usr/bin/python

from ansible.module_utils.basic import AnsibleModule

def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True, type='str'),
            state=dict(default='present', choices=['present', 'absent'])
        )
    )
    
    name = module.params['name']
    state = module.params['state']
    
    # Module logic here
    
    module.exit_json(changed=True, name=name, state=state)

if __name__ == '__main__':
    main()

Best Practices

Organization

Best Practices:

  • Use roles for reusability
  • Keep playbooks simple
  • Use version control
  • Document your code
  • Test your playbooks
  • Use tags effectively

Security

Security Tips:

  • Use Ansible Vault
  • Limit sudo access
  • Use SSH keys
  • Regular updates
  • Audit playbooks