Skip to content

Your First Playbook

Basic Playbook Structure

---
- name: Configure web server
  hosts: webservers
  become: true

  vars:
    http_port: 80
    domain: example.com

  tasks:
    - name: Install nginx
      apt:
        name: nginx
        state: present
        update_cache: yes

    - name: Start nginx service
      service:
        name: nginx
        state: started
        enabled: yes

    - name: Configure website
      template:
        src: website.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: Restart nginx

  handlers:
    - name: Restart nginx
      service:
        name: nginx
        state: restarted

Step-by-Step Breakdown

1. Playbook Header

---
- name: Configure web server    # Descriptive name
  hosts: webservers            # Target hosts group
  become: true                 # Run as sudo

2. Variables

vars:
  http_port: 80               # Port for web server
  domain: example.com         # Website domain
  doc_root: /var/www/html     # Document root

3. Tasks

tasks:
  - name: Install required packages
    apt:
      name:
        - nginx
        - php-fpm
        - curl
      state: present
      update_cache: yes

  - name: Create document root
    file:
      path: "{{ doc_root }}"
      state: directory
      mode: '0755'

  - name: Copy website files
    copy:
      src: files/website/
      dest: "{{ doc_root }}"
      mode: '0644'

4. Templates

# templates/website.conf.j2
server {
    listen {{ http_port }};
    server_name {{ domain }};
    root {{ doc_root }};

    location / {
        index index.html index.php;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php-fpm.sock;
    }
}

5. Handlers

handlers:
  - name: Restart nginx
    service:
      name: nginx
      state: restarted

  - name: Reload nginx
    service:
      name: nginx
      state: reloaded

Running the Playbook

1. Create Directory Structure

first-playbook/
├── inventory
│   └── hosts
├── files/
│   └── website/
│       ├── index.html
│       └── style.css
├── templates/
│   └── website.conf.j2
└── site.yml

2. Create Inventory

# inventory/hosts
[webservers]
webserver1 ansible_host=192.168.1.10
webserver2 ansible_host=192.168.1.11

[webservers:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/id_rsa

3. Execute Playbook

# Check syntax
ansible-playbook -i inventory/hosts site.yml --syntax-check

# Dry run
ansible-playbook -i inventory/hosts site.yml --check

# Execute playbook
ansible-playbook -i inventory/hosts site.yml

Error Handling

Adding Error Handling

tasks:
  - name: Install nginx
    apt:
      name: nginx
      state: present
    register: nginx_install
    ignore_errors: true

  - name: Check nginx installation
    debug:
      msg: "Nginx installation failed: {{ nginx_install }}"
    when: nginx_install.failed

Using Blocks

tasks:
  - name: Website deployment
    block:
      - name: Copy website files
        copy:
          src: files/website/
          dest: "{{ doc_root }}"

      - name: Configure nginx
        template:
          src: website.conf.j2
          dest: /etc/nginx/sites-available/default
    rescue:
      - name: Restore backup
        copy:
          src: backup/website/
          dest: "{{ doc_root }}"
    always:
      - name: Ensure nginx is running
        service:
          name: nginx
          state: started

Verifying Deployment

Add Verification Tasks

tasks:
  - name: Verify nginx is running
    command: systemctl status nginx
    register: nginx_status
    changed_when: false

  - name: Check website accessibility
    uri:
      url: "http://{{ domain }}"
      return_content: yes
    register: website_check
    failed_when: website_check.status != 200

Example Complete Playbook

---
- name: Deploy Web Application
  hosts: webservers
  become: true

  vars:
    http_port: 80
    domain: example.com
    doc_root: /var/www/html

  tasks:
    - name: Install required packages
      apt:
        name:
          - nginx
          - php-fpm
        state: present
        update_cache: yes

    - name: Create document root
      file:
        path: "{{ doc_root }}"
        state: directory
        mode: '0755'

    - name: Copy website files
      copy:
        src: files/website/
        dest: "{{ doc_root }}"
        mode: '0644'

    - name: Configure nginx
      template:
        src: templates/website.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: Restart nginx

    - name: Enable site
      file:
        src: /etc/nginx/sites-available/default
        dest: /etc/nginx/sites-enabled/default
        state: link

    - name: Verify deployment
      uri:
        url: "http://localhost"
        return_content: yes
      register: website_check
      failed_when: website_check.status != 200

  handlers:
    - name: Restart nginx
      service:
        name: nginx
        state: restarted