Ansible Playbook

Ansible Playbook

Day 58 of 90daysofdevops

What is Ansible Playbook

  • An Ansible playbook is a configuration file written in YAML format that defines a set of tasks and configurations to be executed on remote systems.

  • Playbooks provide a way to automate complex workflows and orchestrate multiple tasks. They can include variables, conditionals, loops, and more, enabling flexible and reusable automation.

  • Ansible Playbook organizes the steps between the assembled machines or servers and gets them organized and running in the way the users need them to.

  • Playbooks are the core building blocks of Ansible and allow for the definition of desired system states, making configuration management and application deployment consistent and repeatable.

Key Features of Ansible Playbooks

  1. Declarative Syntax: Ansible playbooks use a simple YAML-based syntax, making them easy to read, write, and understand.

  2. Task Orchestration: Playbooks allow you to define a sequence of tasks to be executed in a specific order, ensuring a consistent and controlled workflow.

  3. Idempotence: Playbooks are designed to be idempotent, meaning they can be run multiple times without causing unintended changes. This ensures a predictable and reliable deployment process.

  4. Variables and Templating: Playbooks support the use of variables and Jinja2 templating, enabling dynamic and customizable configurations.

  5. Conditionals and Loops: Ansible playbooks offer conditionals and loop structures, allowing you to control task execution based on specific conditions or iterate over lists of values.

  6. Error Handling and Logging: Playbooks provide mechanisms for handling errors gracefully and capturing detailed logs, aiding in troubleshooting and debugging.

  7. Reusability and Modularity: Playbooks can be modularized into roles, allowing for the reuse of tasks across multiple projects, and promoting code organization and maintainability.

How to write Ansible Playbook

1️⃣Inventory

Define the inventory file that lists the target hosts or groups where the playbook will be executed. Ensure the inventory is well-organized and up to date.

2️⃣Playbook Structure

Organize your playbook into plays, which are units of work targeting specific hosts or groups. Each play consists of a set of tasks to be executed.

- name: Deploy Web Application
  hosts: web_servers
  become: true
  tasks:
    # Defined Task

3️⃣Tasks

Define tasks within plays to specify the actions to be performed on the target hosts. Tasks should be atomic, idempotent, and focused on achieving a specific outcome.

tasks:
  - name: Install required packages
    apt:
      name: ['apache2', 'php', 'mysql']
      state: present

4️⃣Variables and Templating

Use variables to make playbooks flexible and reusable. Define variables in separate files or inventories and use Jinja2 templating for dynamic values.

vars:
  app_name: MyWebApp
  app_port: 8080

tasks:
  - name: Configure Apache VirtualHost
    template:
      src: templates/virtualhost.conf.j2
      dest: /etc/apache2/sites-available/{{ app_name }}.conf

5️⃣Handlers

Define handlers for tasks that need to be triggered conditionally. Handlers are actions that run only when notified by tasks and are typically used for service restarts or configuration reloads.

tasks:
  - name: Restart Apache service
    service:
      name: apache2
      state: restarted
    notify: Reload Apache Configuration

handlers:
  - name: Reload Apache Configuration
    service:
      name: apache2
      state: reloaded

6️⃣Conditionals and Loops

Utilize conditionals and loops to make playbooks more dynamic and adaptable. For example, conditionally execute a task based on the presence of a file.

tasks:
  - name: Copy configuration file if it doesn't exist
    copy:
      src: files/config.conf
      dest: /etc/app/config.conf
    when: not ansible_check_mode and not ansible_file_exists|bool

7️⃣Error Handling and Logging

Implement error-handling mechanisms to handle failures gracefully. Use the failed_when parameter to specify conditions that indicate task failure.

tasks:
  - name: Ensure required packages are installed
    apt:
      name: ['package1', 'package2']
      state: present
    failed_when: "'unable to locate' in result.msg"

Task 1: 📂File Creation Ansible playbook

  • Add all the server details in the inventory file.

  • Create an Ansible playbook to create a file on a different server

      - name: A playbook to create a file 
        hosts: all
        become: true
        tasks:
        - name: Create a file
          file:
           path: /home/ubuntu/testfile.txt
           state: touch
    

  • Now to run this playbook use the command ansible-playbook including the filename.

      ansible-playbook create_file.yml
    

  • Once the execution is finished, verify that the file has been created on different servers using the following command.

      ansible all -a "ls /home/ubuntu"
    

Task 2:👤User Creation Ansible playbook

  • Create an Ansible playbook for creating a new user on a different server

      - name: A playbook to create a new user
        hosts: all
        become: true
        tasks:
        - name: to create a user named <user_name>
          user: name=<user_name>
    

  • Run the playbook using the ansible-playbook command

      ansible-playbook create_user.yml
    

  • Once the execution is finished, to check if the user has been created, look for the user's name in the /etc/passwd file where all the user and system file details are stored on servers.

      ansible server1 -a "cat /etc/passwd"
    

Task 3:🐋Docker Installation Ansible playbook

  • Create an Ansible playbook to install docker on a different server

      -
        name: A Playbook to Install Docker
        hosts: my-servers
        become: yes
    
        tasks:
          - name: Add Docker GPG apt Key
            apt_key:
              url: https://download.docker.com/linux/ubuntu/gpg
              state: present
    
          - name: Add Docker Repository
            apt_repository:
              repo: deb https://download.docker.com/linux/ubuntu focal stable
              state: present
    
          - name: Update apt and install docker-ce
            apt:
              name: docker-ce
              state: latest
              update_cache: true
    

  • Run the playbook using the ansible-playbook command.

      ansible-playbook install_docker.yml
    

  • Verify that Docker has been installed on multiple servers using the following command.

      ansible all -a "docker --version"
    

  • To get the Docker status of all the servers, use the following command:

      ansible all -a "sudo systemctl status docker"
    


Thank You,

I want to express my deepest gratitude to each and every one of you who has taken the time to read, engage, and support my journey.

Feel free to reach out to me if any corrections or add-ons are required on blogs. Your feedback is always welcome & appreciated.

~ Abhisek Moharana 🙂