Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Advanced Ansible Techniques

1. Ansible Roles

Roles are a way of organizing playbooks and other files in order to facilitate reuse and sharing. Roles are simple and allow you to break a playbook into multiple reusable components.

Creating a role:

$ ansible-galaxy init my_role

This will create a directory structure for your role:

my_role/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml

2. Dynamic Inventory

Ansible can use a dynamic inventory script to generate a list of hosts at runtime, rather than using a static inventory file. This is particularly useful for cloud environments where the list of servers can change frequently.

Example of a dynamic inventory script:

#!/usr/bin/env python
import json

inventory = {
    'group': {
        'hosts': ['host1', 'host2'],
        'vars': {
            'ansible_user': 'user'
        }
    },
    '_meta': {
        'hostvars': {
            'host1': {
                'ansible_host': '192.168.1.1'
            },
            'host2': {
                'ansible_host': '192.168.1.2'
            }
        }
    }
}

print(json.dumps(inventory))

To use this dynamic inventory script, specify it with the -i option:

$ ansible-playbook -i my_inventory_script.py my_playbook.yml

3. Ansible Vault

Ansible Vault is a feature that allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plaintext in playbooks or roles.

Encrypting a file with Ansible Vault:

$ ansible-vault encrypt secrets.yml

Creating an encrypted variable within a playbook:

---
- name: Ansible Vault example
  hosts: localhost
  vars:
    secret_password: !vault |
      $ANSIBLE_VAULT;1.1;AES256
      6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435
  tasks:
    - debug: msg="The password is {{ secret_password }}"

Running a playbook with an encrypted file:

$ ansible-playbook --ask-vault-pass my_playbook.yml

4. Ansible Tags

Tags in Ansible allow you to run specific parts of your playbooks. This is useful when you want to run or skip certain tasks.

Using tags in a playbook:

---
- hosts: all
  tasks:
    - name: Install a package
      apt: name=package state=present
      tags:
        - install

    - name: Configure a service
      service: name=service state=started
      tags:
        - configure

Running a playbook with specific tags:

$ ansible-playbook my_playbook.yml --tags "install"

Skipping specific tags:

$ ansible-playbook my_playbook.yml --skip-tags "configure"

5. Ansible Callbacks

Callbacks are a way to hook into the events that happen during the execution of an Ansible playbook. They can be used to send notifications, log events, or integrate with other systems.

Creating a custom callback plugin:

# callback_plugins/my_callback.py
from ansible.plugins.callback import CallbackBase

class CallbackModule(CallbackBase):
    def v2_runner_on_ok(self, result):
        host = result._host
        print("{} is OK".format(host.name))

Enabling the custom callback plugin in ansible.cfg:

[defaults]
callback_plugins = /path/to/callback_plugins

6. Ansible Filters

Ansible Filters allow you to manipulate data within playbooks. Filters are typically used in Jinja2 templates to transform data.

Using a filter in a playbook:

---
- hosts: localhost
  vars:
    my_list: [1, 2, 3, 4, 5]
  tasks:
    - name: Show reversed list
      debug:
        msg: "{{ my_list | reverse }}"

Creating a custom filter plugin:

# filter_plugins/my_filters.py
def to_uppercase(value):
    return value.upper()

class FilterModule(object):
    def filters(self):
        return {
            'to_uppercase': to_uppercase
        }

Using the custom filter in a playbook:

---
- hosts: localhost
  vars:
    my_string: "hello"
  tasks:
    - name: Show uppercase string
      debug:
        msg: "{{ my_string | to_uppercase }}"