Skip to content

Ansible_playbooks

This chapter covers Ansible playbooks, tasks, modules, and playbook structure.

Playbooks are Ansible’s configuration, deployment, and orchestration language.

┌─────────────────────────────────────────────────────────────────────────────┐
│ Ansible Playbook Structure │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Playbook Anatomy │ │
│ │ │ │
│ │ --- │ │
│ │ - name: Play name │ │
│ │ hosts: webservers # Target hosts │ │
│ │ become: yes # sudo/privilege escalation │ │
│ │ vars: # Variables for this play │ │
│ │ nginx_port: 80 │ │
│ │ tasks: # List of tasks │ │
│ │ - name: Task name # Task description │ │
│ │ module: # Module to execute │ │
│ │ args... │ │
│ │ handlers: # Triggered by tasks │ │
│ │ - name: Handler name │ │
│ │ module: │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
basic_playbook.yml
---
- name: Install and configure nginx
hosts: webservers
become: yes
tasks:
- name: Install nginx
apt:
name: nginx
state: present
notify: Start nginx
- name: Copy nginx configuration
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart nginx
- name: Ensure nginx is enabled
service:
name: nginx
enabled: yes
handlers:
- name: Start nginx
service:
name: nginx
state: started
- name: Restart nginx
service:
name: nginx
state: restarted
# Package modules
- name: Install packages
apt:
name:
- nginx
- vim
- curl
state: present
update_cache: yes
- name: Remove package
apt:
name: nginx
state: absent
- name: Install specific version
yum:
name: httpd-2.4.6
state: present
# Service modules
- name: Start and enable service
service:
name: nginx
state: started
enabled: yes
- name: Stop service
service:
name: nginx
state: stopped
# Copy file
- name: Copy file
copy:
src: /local/file.conf
dest: /remote/file.conf
owner: root
group: root
mode: '0644'
# Template file
- name: Render template
template:
src: config.j2
dest: /etc/app/config.conf
mode: '0600'
# Create directory
- name: Create directory
file:
path: /opt/myapp
state: directory
owner: appuser
group: appuser
mode: '0755'
# Create symlink
- name: Create symlink
file:
src: /opt/myapp/current
dest: /var/www/html/myapp
state: link
# Create user
- name: Create user
user:
name: appuser
comment: "Application User"
shell: /bin/bash
groups: www-data
append: yes
# Create SSH key
- name: Generate SSH key
user:
name: appuser
generate_ssh_key: yes
ssh_key_bits: 4096
# Clone repository
- name: Clone git repository
git:
repo: https://github.com/example/app.git
dest: /opt/myapp
version: main
force: yes
# Update repository
- name: Update git repository
git:
repo: https://github.com/example/app.git
dest: /opt/myapp
update: yes
force: no
multi_playbook.yml
---
- name: Configure webservers
hosts: webservers
become: yes
tasks:
- name: Install nginx
apt:
name: nginx
state: present
- name: Configure nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
- name: Start nginx
service:
name: nginx
state: started
- name: Configure databases
hosts: databases
become: yes
tasks:
- name: Install PostgreSQL
apt:
name:
- postgresql
- postgresql-contrib
state: present
- name: Start PostgreSQL
service:
name: postgresql
state: started
- name: Configure application
hosts: all
become: yes
tasks:
- name: Deploy application
synchronize:
src: ./app/
dest: /opt/app/
- name: Install dependencies
pip:
requirements: /opt/app/requirements.txt
variables_playbook.yml
---
- name: Deploy application
hosts: webservers
become: yes
vars:
app_version: "2.1.0"
app_port: 8080
app_user: appuser
tasks:
- name: Create application user
user:
name: "{{ app_user }}"
system: yes
create_home: no
- name: Download application
get_url:
url: "https://example.com/app-{{ app_version }}.tar.gz"
dest: "/tmp/app-{{ app_version }}.tar.gz"
- name: Extract application
unarchive:
src: "/tmp/app-{{ app_version }}.tar.gz"
dest: "/opt/"
remote_src: yes
creates: "/opt/app"
- name: Configure application
template:
src: config.yml.j2
dest: "/opt/app/config.yml"
- name: Start application
systemd:
name: myapp
state: started
daemon_reload: yes
conditional_playbook.yml
---
- name: OS-specific configuration
hosts: all
become: yes
tasks:
- name: Install nginx on Debian
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: Install nginx on RedHat
yum:
name: nginx
state: present
when: ansible_os_family == "RedHat"
- name: Configure for production
template:
src: app-prod.conf.j2
dest: /etc/app.conf
when: environment == "production"
- name: Install Python 3 on Ubuntu 20.04
apt:
name: python3
state: present
when: ansible_distribution == "Ubuntu" and ansible_distribution_version == "20.04"
loop_playbook.yml
---
- name: Install multiple packages
apt:
name: "{{ item }}"
state: present
loop:
- nginx
- vim
- curl
- git
- name: Create multiple users
user:
name: "{{ item.name }}"
shell: "{{ item.shell | default('/bin/bash') }}"
create_home: yes
loop:
- { name: 'alice', shell: '/bin/bash' }
- { name: 'bob', shell: '/bin/zsh' }
- { name: 'charlie' }
- name: Create directories
file:
path: "/opt/{{ item }}"
state: directory
mode: '0755'
loop:
- app
- logs
- data
- config
handler_playbook.yml
---
- name: Configure web server
hosts: webservers
become: yes
tasks:
- name: Copy nginx config
copy:
src: nginx.conf
dest: /etc/nginx/nginx.conf
notify: Restart nginx
- name: Copy ssl certificate
copy:
src: server.crt
dest: /etc/nginx/ssl/server.crt
notify: Reload nginx
handlers:
- name: Restart nginx
service:
name: nginx
state: restarted
- name: Reload nginx
service:
name: nginx
state: reloaded
tagged_playbook.yml
---
- name: Configure web server
hosts: webservers
become: yes
tasks:
- name: Install nginx
apt:
name: nginx
state: present
tags: [packages, nginx]
- name: Configure nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
tags: [configuration, nginx]
- name: Setup firewall
ufw:
rule: allow
port: '{{ item }}'
loop: [80, 443]
tags: [firewall]
Terminal window
# Run only tagged tasks
ansible-playbook -i inventory playbook.yml --tags packages
# Skip specific tags
ansible-playbook -i inventory playbook.yml --tags firewall
# List tags
ansible-playbook -i inventory playbook.yml --list-tags
command_playbook.yml
---
- name: Run commands
hosts: webservers
tasks:
- name: Run simple command
command: uptime
- name: Run with arguments
command: ls -la /opt
- name: Run shell command
shell: cat /etc/os-release
- name: Run and check
command: systemctl is-active nginx
register: result
failed_when: result.rc == 2
- name: Use command with creates (idempotent)
command: /opt/scripts/setup.sh
args:
creates: /opt/.setup_complete

In this chapter, you learned:

  • Playbook Structure: Anatomy of a playbook
  • Common Modules: apt, service, file, user, git, template
  • Multiple Plays: Running tasks on different hosts
  • Variables: Using vars in playbooks
  • Conditionals: when statements
  • Loops: loop and item
  • Handlers: notify and handlers
  • Tags: Organizing and filtering tasks