Ansible • Configuration Management • Playbooks • Roles

Ansible Configuration Management & Automation: 13-Day Production Masterclass ⚙️🚀

A complete, hands-on production engineering curriculum taking you from foundational agentless architecture, passwordless SSH keys, and ad-hoc commands to robust YAML playbooks, conditional loops, handlers, error handling, CI/CD pipelines, Vault encryption, and enterprise-grade Ansible Roles.

Published by AHP • cicdclouds.com

Day 1 Introduction to Ansible & Core Architecture

Class Motive

Understand the foundational concepts of Configuration Management (CM), compare popular orchestration frameworks, and grasp Ansible's push-based, agentless architecture[cite: 1].

Explanation & Concepts

Ansible is a configuration management and orchestration tool that allows administrators to manage multiple remote servers from a single controller machine[cite: 1].

Key Advantages:

  • Resource Saving: Saves significant time and reduces human error[cite: 1].
  • Server Provisioning: Automates initial setup and software configuration[cite: 1].
  • Disaster Recovery (DR): Quick automated recovery and environment replication[cite: 1].
  • Snowflake Server Handling: Prevents configuration drift across individual machines[cite: 1].
  • Idempotency: Running the same playbook multiple times only makes changes if the target state differs from the desired state (already configured systems are undisturbed)[cite: 1].

Popular CM Tools:

  1. Ansible[cite: 1]
  2. Chef[cite: 1]
  3. Puppet[cite: 1]
  4. SaltStack[cite: 1]

Architecture & Communication:

Ansible operates using a Controller node and multiple Managed nodes. Communication occurs over passwordless SSH using a push methodology (agentless architecture)[cite: 1].

Day 2 AWS Server Setup, SSH Key Pairing & Inventory Files

Class Motive

Establish passwordless SSH connectivity between an Ansible controller and AWS managed nodes (Ubuntu and RedHat), install Ansible, and configure inventory files[cite: 2].

Explanation & Step-by-Step Configuration

Step 1: Passwordless SSH Setup (Controller to Managed Nodes)

# On Server 1 (Controller)
sudo passwd ubuntu
sudo vim /etc/ssh/sshd_config
# Change PasswordAuthentication NO to YES
sudo service ssh restart
ssh-keygen
ssh-copy-id ubuntu@<private_ip_of_managed_node>
yes

Step 2: Installing Ansible on the Controller

sudo apt-get update
sudo apt-get install -y software-properties-common
sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update
sudo apt-get install -y ansible
ansible --version

Step 3: Inventory File Management

The inventory file defines the managed nodes that Ansible interacts with[cite: 2]. Located at /etc/ansible/hosts:

cd /etc/ansible/
ls
sudo vim hosts
# Paste private IP addresses of managed nodes

Test connectivity using an ad-hoc command[cite: 2]:

ansible all -a 'ls -la'

Step 4: Adding a RedHat Managed Node

RedHat / Amazon Linux distributions use ec2-user and require username specification in the inventory if it differs from the controller user[cite: 2]:

# In /etc/ansible/hosts
<redhat_private_ip> ansible_user=ec2-user

Day 3 Core Ansible Modules (Shell, User, File, Copy, Apt, Service)

Class Motive

Explore fundamental Ansible execution modules to manage shell scripts, user accounts, files, directory structures, software packages, and system services[cite: 3].

Explanation & Syntax Examples

1. Shell & Command Modules

Shell module supports redirection and piping (unlike command module)[cite: 3]:

ansible all -m shell -a "free -m > file10"
ansible all -m shell -a 'curl -fsSL https://get.docker.com -o install-docker.sh'

2. User Module

Manages user accounts across remote nodes. Requires higher privileges (-b for become/sudo)[cite: 3]:

ansible all -m user -a 'name=henry password=cloudsinfo uid=4444 comment="a normal user" home=/tmp/catharine shell=/bin/bash' -b

Understanding /etc/passwd entry: henry:x:3335:3335::/home/henry:/bin/sh (Username, Encrypted Password placeholder, User ID, Group ID, Comment, Home directory, Shell)[cite: 3].

3. File Module

Creates, deletes, and modifies file/directory permissions[cite: 3]:

ansible all -m file -a 'name=/tmp/file1 state=touch'
ansible all -m file -a 'name=/tmp/dir1 state=directory'
ansible all -m file -a 'name=/tmp/file1 state=touch mode=770 owner=henry group=root' -b
ansible all -m file -a 'name=/tmp/file1 state=absent' -b

4. Copy Module

Transfers files from controller to managed nodes or creates inline content[cite: 3]:

ansible all -m copy -a 'src=file100 dest=/tmp'
ansible all -m copy -a 'content="welcome to cloudsinfo" dest=/tmp/file100'

5. Apt & Service Modules

ansible all -m apt -a 'name=tomcat9 state=present update_cache=yes' -b
ansible all -m service -a 'name=tomcat9 state=started' -b

Day 4 Advanced Modules & Limitations of Ad-Hoc Commands

Class Motive

Learn advanced utility modules (get_url, uri, git, replace, fetch) and understand why ad-hoc commands are insufficient for complex multi-step deployments[cite: 4].

Explanation & Examples

  • get_url: Downloads files from HTTP/HTTPS sources[cite: 4].
    ansible all -m get_url -a 'url=https://get.jenkins.io/war/2.422/jenkins.war dest=/home/ubuntu'
  • uri: Validates web service reachability and HTTP status codes[cite: 4].
    ansible all -m uri -a 'url=http://google.com status_code=200'
  • git: Clones remote repositories into managed nodes[cite: 4].
    ansible all -m git -a 'repo=https://github.com/krishnain/mavennew.git dest=/tmp/mygit'
  • replace: Performs regex-based search and replace inside configuration files[cite: 4].
    ansible all -m replace -a 'regexp=8080 replace=9090 path=/etc/tomcat9/server.xml' -b
  • fetch: Retrieves files from managed nodes back to the controller[cite: 4].
    ansible all -m fetch -a 'src=/etc/passwd dest=/tmp'

Limitations of Ad-Hoc Commands:

Ad-hoc commands execute only one module with one argument at a time and are not reusable[cite: 4]. Complex application setups require multi-step automation using Ansible Playbooks[cite: 4].

Day 5 Introduction to Ansible Playbooks

Class Motive

Transition from ad-hoc command line executions to YAML-based declarative playbooks for structured, repeatable infrastructure orchestration[cite: 5].

Explanation & Playbook Structure

Playbooks are written in YAML and contain plays that map hosts to tasks. Tasks invoke Ansible modules sequentially[cite: 5].

Example 1: User Creation Playbook

---
- name: create User
  hosts: all
  tasks:
    - name: User creation
      user:
        name: ramu
        password: cloudsinfo
        home: /tmp/ramu
        shell: /bin/bash
        uid: 4455
...

Syntax check and execution commands[cite: 5]:

ansible-playbook playbook1.yml --syntax-check
ansible-playbook playbook1.yml -b

Example 2: Apache2 Configuration Playbook

---
- name: Configuring apache2 on all managed node
  hosts: all
  tasks:
    - name: Install apache2
      apt:
        name: apache2
        state: present
        update_cache: yes
    - name: Edit the index.html file
      copy:
        content: Cloudsinfo
        dest: /var/www/html/index.html
    - name: Restart apache2
      service:
        name: apache2
        state: restarted
...

Day 6 Variables & Scope Hierarchies (Global, Play, Host, Group)

Class Motive

Master variable management in Ansible across Global scope, Play scope, Host scope, and Group scope to build flexible, dynamic playbooks[cite: 6].

Explanation & Variable Scopes

  1. Global Scope (Extra Vars): Passed via command line using --extra-vars. Has the highest precedence[cite: 6].
    ansible-playbook playbook5.yml -b --extra-vars "a=tree b=present c=yes"
  2. Play Scope: Defined directly inside the playbook under the vars: block[cite: 6].
    ---
    - name: Implementing playscop variables
      hosts: all
      vars:
        a: tomcat9
        b: present
        c: yes
      tasks:
        - name: Install/uninstall
          apt:
            name: "{{ a }}"
            state: "{{ b }}"
            update_cache: "{{ c }}"
    ...
  3. Host & Group Scope Variables: Organized in directory structures under group_vars/ and host_vars/ matching inventory group names or server IP addresses[cite: 6].
    # host_vars/172.31.18.136
    ---
    a: radha
    b: cloudsinfo
    c: /tmp/Radha
    d: 6789
    e: /bin/bash
    f: "A normal user"
    ...

Day 7 Loops, Tags, and Fact Gathering

Class Motive

Optimize playbooks using loops (with_items), selectively run tasks using tags, and manage fact gathering performance[cite: 7].

Explanation & Syntax

1. Implementing Loops (`with_items`)

---
- name: Implementing loops
  hosts: all
  tasks:
    - name: Install s/w application
      apt:
        name: "{{ item }}"
        state: present
        update_cache: yes
      with_items:
        - tree
        - git
        - maven
...

2. Implementing Tags

Tags allow executing specific sections of a playbook without running the entire file[cite: 7]:

---
- name: Implementing tags
  hosts: all
  gather_facts: false
  become: yes
  tasks:
    - name: Install tree
      apt:
        name: tree
        state: present
        update_cache: yes
      tags: 
        - install_tree
    - name: Create user
      user:
        name: Ramesh
        password: "{{ 'cloudsinfo' | password_hash('sha512') }}"
      tags: 
        - user_creation
...

Execution with tags[cite: 7]:

ansible-playbook playbook14.yml -b --tags=user_creation

Day 8 Handlers & Error Handling (Blocks, Rescue, Always)

Class Motive

Learn conditional triggers using handlers, implement robust error handling with block-rescue-always structures, and handle multi-OS package managers[cite: 8].

Explanation & Rules of Handlers

  • Trigger Condition: Handlers execute only if the task with the notify keyword is successful and reports a change[cite: 8].
  • Deferred Execution: Handlers are executed only after all modules in the task section are completed[cite: 8].
  • Ordering: Handlers are executed in the order given in the handlers: section, not the order called in tasks[cite: 8].
  • Idempotency: If notified multiple times, a handler executes only once[cite: 8].

Error Handling with Block, Rescue, Always

---
- name: Error handling and OS-specific install
  hosts: all
  become: yes
  tasks:
    - block:
        - name: Install git using apt on Debian/Ubuntu servers
          ansible.builtin.apt:
            name: git
            state: present
            update_cache: yes
          when: ansible_facts['os_family'] == "Debian"

      rescue:
        - name: Install git using yum on RedHat/CentOS servers
          ansible.builtin.yum:
            name: git
            state: present
          when: ansible_facts['os_family'] == "RedHat"

      always:
        - name: Display Success msg
          ansible.builtin.debug:
            msg: "Git installation attempt completed."
...

Day 9 Conditional Execution & Stat Module

Class Motive

Perform conditional file checks using the stat module, register variables, and dynamically configure multi-distribution environments[cite: 9].

Explanation & Examples

Using the Stat Module & Registering Variables

---
- name: check if a file f1 is present if not create a dir f1
  hosts: all
  tasks:
    - name: check for f1 file
      stat:
        path: /home/ubuntu/f1
      register: a
    - name: Dislay output of the above module
      debug:
        var: a 
    - name: Create 1 folder if f1 file is not present
      file:
        name: /home/ubuntu/f1
        state: directory
      when: a.stat.exists == false
...

Capturing OS Information and Applying Conditions

---
- name: capture Os info all servers
  hosts: all
  gather_facts: yes
  tasks:
    - name: capture Os name
      debug:
        msg: "{{ansible_distribution}}"
    - name: install git on ubuntu using apt
      apt:
        name: git
        state: present
        update_cache: yes
      when: ansible_distribution == "Ubuntu"
...

Day 10 Multi-Tier Deployments & Playbook Inclusion

Class Motive

Manage multi-tier infrastructure (Jenkins, QA, and Production servers) and modularize playbooks using the include module for maximum reusability[cite: 10].

Explanation & Modular Playbooks

Instead of writing monolithic playbooks, split tasks into child playbooks and include them in a parent orchestrator[cite: 10]:

---
- name: Configure apache using multiple child playbooks
  hosts: all
  tasks:
    - name: call playbook for install
      include: install.yml
    - name: call playbook for edit index.html
      include: edit_index.yml
    - name: call playbook for restart apache2
      include: restart.yml
    - name: call playbook for apache response
      include: check_url_response.yml
...

Day 11 CI/CD Pipelines with Ansible & Ansible Vault

Class Motive

Implement a complete Continuous Integration and Continuous Deployment (CI/CD) workflow across Dev, QA, and Prod servers using Ansible, and secure sensitive playbooks using Ansible Vault[cite: 11].

Explanation & CI/CD Workflow

  • Dev Server: Downloads source code from Git, builds the artifact using Maven (mvn package), and fetches the .war file to the controller[cite: 11].
  • QA Server: Deploys the artifact to Tomcat, pulls functional Selenium test scripts from GitHub, and executes automated testing[cite: 11].
  • Prod Server: Performs continuous delivery by deploying the verified artifact to production Tomcat servers[cite: 11].

Ansible Vault Commands for Sensitive Data

ansible-vault create playbook_name.yml
ansible-vault view playbook_name.yml
ansible-vault edit playbook_name.yml
ansible-vault encrypt playbook_name.yml
ansible-vault decrypt playbook_name.yml
ansible-vault rekey playbook_name.yml

Day 12 Advanced Variables Refactoring & Scheduled Automation (Crontab)

Class Motive

Refactor playbooks to leverage external group variables, structure modular task inclusions, and automate playbook execution using Linux cron jobs[cite: 12].

Explanation & Implementation

Using Group Variables (`group_vars/webservers`)

---
a: tomcat9
b: present
c: yes
d: tomcat9-admin
e: no
f: tomcat-users.xml
g: /etc/tomcat9
h: 8080
i: 9090
j: /etc/tomcat9/server.xml
k: restarted
...

Automating Playbook Execution with Crontab

crontab -e
# Run playbook every day at 3:00 AM
0 3 * * * ansible-playbook /home/ubuntu/ansible_8pm/playbook1.yml -b

Day 13 Enterprise Roles & Ansible Galaxy

Class Motive

Master Ansible Roles—the industry-standard predefined directory structure for organizing playbooks, tasks, variables, files, templates, and handlers for maximum scalability[cite: 13].

Explanation & Directory Structure

Initialize a new role using Ansible Galaxy[cite: 13]:

cd /etc/ansible/roles
ansible-galaxy init tomcat --offline
sudo apt-get install tree
tree tomcat

Standard Role Directory Layout:

  • defaults/main.yml - Default variables.
  • files/ - Static files (e.g., tomcat-users.xml).
  • handlers/main.yml - Service restart handlers.
  • meta/main.yml - Role metadata and dependencies.
  • tasks/main.yml - Main execution tasks and child inclusions.
  • templates/ - Jinja2 templates.
  • vars/main.yml - Role-specific variables.

Calling Roles from a Playbook (`configure_tomcat.yml`)

---
- name: Configuring tomcat using roles
  hosts: all
  roles:
    - tomcat
...

Run the role-based playbook[cite: 13]:

ansible-playbook configure_tomcat.yml -b