πŸ”„ Ansible Intermediate: Roles, Variables, and Templates

Intermediate Ansible: Beyond the Basics

Building on our previous tutorial, we’ll explore intermediate Ansible concepts by creating a more complex deployment: a load-balanced web application with customizable configurations.

Prerequisites

  • Basic Ansible knowledge
  • Understanding of YAML syntax
  • Familiarity with web servers and load balancing
  • Multiple target servers for testing

Concepts Covered

  1. Roles
  2. Variables
  3. Templates
  4. Handlers
  5. Conditionals
  6. Tags

Project Structure

webapp-deployment/
β”œβ”€β”€ inventory/
β”‚   β”œβ”€β”€ production
β”‚   └── staging
β”œβ”€β”€ group_vars/
β”‚   β”œβ”€β”€ all.yml
β”‚   β”œβ”€β”€ webservers.yml
β”‚   └── loadbalancers.yml
β”œβ”€β”€ roles/
β”‚   β”œβ”€β”€ common/
β”‚   β”œβ”€β”€ webapp/
β”‚   └── loadbalancer/
└── site.yml

Working Example: Load Balanced Web App

Let’s create a deployment that:

  • Sets up multiple web servers
  • Configures Nginx as a load balancer
  • Uses templates for configuration
  • Implements handlers for service restarts

1. Inventory Setup

Create inventory/staging:

[webservers]
web1 ansible_host=192.168.1.11
web2 ansible_host=192.168.1.12

[loadbalancers]
lb1 ansible_host=192.168.1.10

[all:vars]
ansible_python_interpreter=/usr/bin/python3

2. Group Variables

Create group_vars/all.yml:

---
app_name: mywebapp
app_version: "1.0.0"
app_port: 8080
domain: example.com

Create group_vars/webservers.yml:

---
app_user: webapp
app_path: /var/www/
app_config_template: webapp.conf.j2

3. Role Structure

Create the webapp role:

ansible-galaxy init roles/webapp

4. Role Implementation

Create roles/webapp/tasks/main.yml:

---
- name: Ensure app user exists
  user:
    name: ""
    shell: /bin/bash
    createhome: yes

- name: Create application directories
  file:
    path: ""
    state: directory
    owner: ""
    mode: '0755'
  with_items:
    - ""
    - "/config"

- name: Copy application configuration
  template:
    src: ""
    dest: "/config/app.conf"
    owner: ""
    mode: '0644'
  notify: restart webapp

- name: Deploy application files
  copy:
    src: files/webapp/
    dest: ""
    owner: ""
    mode: '0644'
  notify: restart webapp

Create roles/webapp/handlers/main.yml:

---
- name: restart webapp
  service:
    name: ""
    state: restarted

5. Templates

Create roles/webapp/templates/webapp.conf.j2:

# Application Configuration
app_name = 
version = 
port = 

# Environment specific settings

debug = true
log_level = DEBUG


# Dynamic server list
servers = [

]

6. Main Playbook

Create site.yml:

---
- name: Configure common settings
  hosts: all
  become: yes
  roles:
    - common

- name: Deploy web application
  hosts: webservers
  become: yes
  roles:
    - webapp
  tags:
    - webapp
    - deploy

- name: Configure load balancer
  hosts: loadbalancers
  become: yes
  roles:
    - loadbalancer
  tags:
    - loadbalancer

Running the Deployment

  1. Test syntax:
    ansible-playbook -i inventory/staging site.yml --syntax-check
    
  2. Dry run:
    ansible-playbook -i inventory/staging site.yml --check
    
  3. Deploy to staging:
    ansible-playbook -i inventory/staging site.yml
    
  4. Deploy specific roles:
    ansible-playbook -i inventory/staging site.yml --tags webapp
    

Advanced Features Used

  1. Templates with Conditionals: ```jinja

# Development settings


2. **Dynamic Inventories**:
```yaml

  1. Handlers for Service Management:
    handlers:
      - name: restart webapp
     service:
       name: ""
       state: restarted
    

Best Practices

  1. Role Organization:
    • Keep roles focused and single-purpose
    • Use dependencies for shared functionality
    • Document role variables
  2. Variable Management:
    • Use group_vars for common settings
    • Override variables at multiple levels
    • Use vault for sensitive data
  3. Template Usage:
    • Keep templates simple
    • Use comments for clarity
    • Test template rendering separately

Debugging Tips

  1. Check template rendering:
    ansible-playbook site.yml --check -vv
    
  2. Debug variables:
    - debug:
     var: some_variable
    
  3. Use tags for targeted runs:
    ansible-playbook site.yml --tags "config,deploy"
    

Conclusion

You’ve now learned how to create a modular, reusable Ansible deployment using roles, variables, and templates. This foundation will help you tackle more complex automation scenarios.

Stay tuned for our advanced Ansible tutorial where we’ll explore custom modules, dynamic inventories, and complex orchestration patterns.

Written on July 10, 2025