We’ll be diving straight into the core concepts and components that will help you become proficient in Ansible. This tutorial assumes that you have already installed Ansible on your system and have a basic understanding of what Ansible is.

Setting Up the Environment#

SSH Key Generation#

If you haven’t already, generate an SSH key pair on your Ansible control node.

ssh-keygen -t rsa

SSH Key Distribution#

Copy the SSH public key to all your target nodes.

ssh-copy-id username@target_host

Replace username with the appropriate user and target_host with the IP address or hostname of the target node.

Inventory Files#

Simple Inventory#

Create a simple inventory file with the .ini extension.

# my_inventory.ini
[web]
192.168.1.2

[db]
192.168.1.3

Dynamic Inventory#

You can also use dynamic inventory scripts. Ansible supports scripts that output JSON.

#!/usr/bin/python
import json
inventory = {
  "web": ["192.168.1.2"],
  "db": ["192.168.1.3"]
}
print(json.dumps(inventory))

Ad-hoc Commands#

Execute commands directly on your nodes.

ansible web -i my_inventory.ini -m ping

This will run the ping module on all nodes under the [web] group in my_inventory.ini.

Writing Playbooks#

Your First Playbook#

Create a YAML file named my_first_playbook.yml.

---
- name: My First Playbook
  hosts: web
  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present

Run the playbook with the ansible-playbook command.

ansible-playbook -i my_inventory.ini my_first_playbook.yml

Multi-Task Playbook#

You can have multiple tasks in a playbook.

---
- name: Web Server Setup
  hosts: web
  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present
    - name: Start Nginx Service
      service:
        name: nginx
        state: started

Roles and Role-based Playbooks#

Roles allow you to organise your playbooks into reusable components.

ansible-galaxy init web-server

This will generate a web-server role directory with various subdirectories (tasks, vars, templates, etc.).

Using Roles in Playbook#

---
- name: Web Server Role-based Playbook
  hosts: web
  roles:
    - web-server

Role Variables#

In web-server/vars/main.yml, define some variables.

http_port: 80
https_port: 443

In web-server/tasks/main.yml, use those variables.

---
- name: Configure Nginx
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  vars:
    http_port: "{{ http_port }}"
    https_port: "{{ https_port }}"

Variables and Facts#

Playbook Variables#

Define variables in your playbooks.

---
- name: Variable Example
  hosts: web
  vars:
    my_variable: "Hello, World!"

Gathering Facts#

Ansible can gather facts (system information) about target nodes.

---
- name: Gather Facts
  hosts: all
  tasks:
    - setup:

Conditionals and Loops#

Conditionals#

Execute tasks conditionally.

---
- name: Conditional Playbook
  hosts: all
  tasks:
    - name: Install Apache if system is Ubuntu
      apt:
        name: apache2
        state: present
      when: ansible_facts['os_family'] == "Debian"

Loops#

Execute tasks in a loop.

---
- name: Loop Example
  hosts: all
  tasks:
    - name: Install multiple packages
      apt:
        name: "{{ item }}"
        state: present
      loop:
        - git
        - vim
        - curl

Templates and Files#

Template Basics#

Ansible uses Jinja2 for templating. Create a template file with the .j2 extension.

# my_template.j2
Hello, {{ my_variable }}!

Using Templates in Tasks#

---
- name: Template Example
  hosts: web
  tasks:
    - name: Deploy template
      template:
        src: my_template.j2
        dest: /tmp/my_template.txt
  vars:
    my_variable: "World"

Advanced Concepts#

Tags#

Use tags to selectively run specific tasks.

---
- name: Tag Example
  hosts: all
  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present
      tags: ["web"]

Run only the tagged tasks.

ansible-playbook -i my_inventory.ini my_playbook.yml --tags "web"

Error Handling#

Add error handling to your playbooks.

---
- name: Error Handling Example
  hosts: all
  tasks:
    - name: Attempt to install package
      apt:
        name: some-nonexistent-package
        state: present
      ignore_errors: true

Troubleshooting and Debugging#

Verbose Output#

Run Ansible commands with -vvv for verbose output.

ansible-playbook -i my_inventory.ini my_playbook.yml -vvv

Debug Module#

Use the debug module to print variables.

---
- name: Debug Example
  hosts: all
  tasks:
    - debug:
        var: my_variable

And that concludes our in-depth tutorial on mastering Ansible. Hopefully, this guide has helped you navigate through the various components and intricacies of Ansible, enabling you to manage and automate your infrastructure with ease.