Ansible – Ansible Playbook (Part-5)

Posted by

An Ansible playbook is a YAML file that defines a set of tasks to be executed on a group of hosts. Playbooks are designed to be human-readable and allow you to manage configurations, deployments, and other tasks in an automated and repeatable manner. Here’s an in-depth look at each aspect of an Ansible playbook:

Ansible Playbook Structure

Ansible playbooks are written in YAML and contain one or more plays. Each play specifies a set of tasks to be executed on a group of hosts.

Breakdown of Playbook Components

YAML Syntax:

  • Ansible playbooks are written in YAML, a human-readable data serialization format.

Document Start:

    ---

    Play:

    • A play is a collection of tasks that are run on a set of hosts. Each play can have different hosts, tasks, variables, and handlers.

    Play Name:

      - name: Ensure Apache is installed and running

      A descriptive name for the play. This helps in understanding what the play does when reading logs and outputs.

      Hosts:

      hosts: webservers
      

      Specifies the target hosts or group of hosts on which the play will run. The group webservers would be defined in the inventory file.

      Become:

      become: yes
      

      Enables privilege escalation (sudo). Tasks in this play will be run with elevated privileges.

      Tasks:

      tasks:
      

      A list of tasks to be executed on the target hosts. Each task is executed sequentially.

      Task Components

      Task Name:

      - name: Install Apache
      

      A descriptive name for the task. This helps in understanding what each task does when reading logs and outputs.

      Module:

      ansible.builtin.apt:
      

      Specifies the Ansible module to be used for the task. In this case, the apt module is used to manage packages on Debian-based systems.

      Module Arguments:

      name: apache2
      state: present
      

        Arguments for the module. Here, the apt module installs the apache2 package and ensures it is present.

        Playbook Example

        Here is the playbook for local machine

        ---
        - name: Update web servers
          hosts: localhost
          tasks:
            - name: Install Apache httpd (state=present is optional)
              ansible.builtin.apt:
                name: apache2
                state: present
        
            - name: Copy file with owner and permissions
              ansible.builtin.copy:
                src: index.html
                dest: /var/www/html/index.html
        
            - name: Start service httpd, if not started
              ansible.builtin.service:
                name: apache2
                state: started
        

        Explanation of the Playbook

        Playbook Header:

          ---
          

          Indicates the beginning of a YAML document.

          Play Definition:

          - name: Update web servers
            hosts: localhost
            tasks:
          
          • name: A descriptive name for the play.
          • hosts: Specifies the target hosts for the play. Here, localhost is used.
          • tasks: A list of tasks to be executed on the specified hosts.

          Task 1: Install Apache httpd

          https://docs.ansible.com/ansible/latest/collections/ansible/builtin/apt_module.html
          - name: Install Apache httpd (state=present is optional)
            ansible.builtin.apt:
              name: apache2
              state: present
          
          • name: A descriptive name for the task.
          • ansible.builtin.apt: The Ansible module used to install packages via apt.
          • name: The package to be installed (apache2).
          • state: Ensures the package is present. This is optional as present is the default state.

          Task 2: Copy index.html

          https://docs.ansible.com/ansible/latest/collections/ansible/builtin/copy_module.html
          - name: Copy file with owner and permissions
            ansible.builtin.copy:
              src: index.html
              dest: /var/www/html/index.html
          
          • name: A descriptive name for the task.
          • ansible.builtin.copy: The Ansible module used to copy files.
          • src: Source file path (index.html).
          • dest: Destination file path (/var/www/html/index.html).

          Task 3: Start Apache Service

          https://docs.ansible.com/ansible/latest/collections/ansible/builtin/service_module.html
          - name: Start service httpd, if not started
            ansible.builtin.service:
              name: apache2
              state: started
          
          • name: A descriptive name for the task.
          • ansible.builtin.service: The Ansible module used to manage services.
          • name: The name of the service (apache2).
          • state: Ensures the service is started.

          Example Usage with Groups

          To target a group of hosts defined in an inventory file, you can modify the hosts parameter in the playbook.

          Inventory File (inventory):

          [web]
          18.208.198.47
          172.22.240.232
          
          [db]
          18.208.198.4
          172.22.240.2d
          

          Modified Playbook:

          ---
          - name: Update web servers
            hosts: web
            tasks:
              - name: Install Apache httpd (state=present is optional)
                ansible.builtin.apt:
                  name: apache2
                  state: present
          
              - name: Copy file with owner and permissions
                ansible.builtin.copy:
                  src: index.html
                  dest: /var/www/html/index.html
          
              - name: Start service httpd, if not started
                ansible.builtin.service:
                  name: apache2
                  state: started
          

          Running the Playbook:

          ansible-playbook -i inventory playbook.yml -u ubuntu -k
          

          This command runs the playbook against the hosts in the web group, using the ubuntu user and prompting for the SSH password.

          Ansible Playbook Command

          Basic Command:

          ansible-playbook web.yaml
          
          • ansible-playbook: The command to run Ansible playbooks.
          • web.yaml: The playbook file to execute.

          Options Explained

          Basic Playbook Execution:

            ansible-playbook web.yaml
            
            • Runs the specified playbook web.yaml on the hosts defined within the playbook or the inventory file specified in the playbook.

            Check Mode (Dry Run):

            ansible-playbook -C web.yaml
            
            • -C or –check: Runs the playbook in check mode. This simulates the changes that would be made by the playbook without actually applying them. It’s useful for testing what changes would be made without affecting the system.

            Check Mode with Verbosity:

            ansible-playbook -C web.yaml -vvvvvv
            

            -vvvvvv: Adds verbosity to the output. More v characters increase the level of verbosity, providing more detailed output about what Ansible is doing. This is useful for debugging and getting more insight into the playbook execution.

            Specify Inventory, Remote User, and Privilege Escalation:

            ansible-playbook -i inventory web.yaml -u ubuntu -k -b
            
            • -i inventory: Specifies the inventory file to use. The inventory file contains the list of hosts to target.
            • -u ubuntu: Specifies the remote user to use for connecting to the hosts. In this case, ubuntu.
            • -k: Prompts for the SSH password of the remote user.
            • -b: Uses privilege escalation (sudo) to run the tasks with elevated privileges.

            Summary of Options

            • -i: Specifies the inventory file.
            • -u: Specifies the remote user.
            • -k: Prompts for the SSH password.
            • -b: Uses privilege escalation (sudo).
            • -C: Runs in check mode (dry run).
            • -v, -vv, -vvv, -vvvv, -vvvvv, -vvvvvv: Sets the verbosity level of the output.

            Additional Ansible Playbook Options

            –syntax-check

            • Checks the syntax of the playbook without executing it.
            ansible-playbook web.yaml --syntax-check
            

            –list-tasks

            • Lists all tasks that would be executed by the playbook without running them.
            ansible-playbook web.yaml --list-tasks
            

            –list-hosts

            • Lists all hosts that the playbook would run against without executing any tasks.
            ansible-playbook web.yaml --list-hosts
            

            –step

            • Prompts the user for confirmation before running each task.
            ansible-playbook web.yaml --step
            

            –start-at-task

            • Starts the playbook run at the task matching the given name.
            ansible-playbook web.yaml --start-at-task="Install Apache"
            

            –tags and –skip-tags

            • Runs only tasks with the specified tags or skips tasks with the specified tags.
            ansible-playbook web.yaml --tags "install,config"
            ansible-playbook web.yaml --skip-tags "debug"
            

            –limit

            • Limits the execution to the specified hosts or groups.
            ansible-playbook web.yaml --limit web
            ansible-playbook web.yaml --limit "web:&prod"

            –diff

            • Shows differences when files are changed by Ansible.
            ansible-playbook web.yaml --diff
            

            –vault-id and –ask-vault-pass

            • Used for encrypting and decrypting secrets with Ansible Vault.
            ansible-playbook web.yaml --vault-id @prompt
            ansible-playbook web.yaml --ask-vault-pass
            

            –extra-vars

            • Passes additional variables to the playbook.
            ansible-playbook web.yaml --extra-vars "var1=value1 var2=value2"
            

            Live Practical

            Create inventory

            [web]
            51.8.106.65
            51.8.106.109
            

            Create web.yaml file

            ---
            - name: Update web servers
              hosts: web
              tasks:
                - name: Install Apache httpd (state=present is optional)
                  ansible.builtin.apt:
                    name: apache2
                    state: present
            
                - name: Copy file with owner and permissions
                  ansible.builtin.copy:
                    src: /home/jami/index.html
                    dest: /var/www/html/index.html
            
                - name: Start service httpd, if not started
                  ansible.builtin.service:
                    name: apache2
                    state: started
            ~
            

            Run the ansible playbook

             ansible-playbook -i inventory web.yaml -u jami -k -b
            

            if getting below error

            TASK [Install Apache httpd (state=present is optional)] ****************************************************************************************************************
            fatal: [51.8.106.65]: FAILED! => {"cache_update_time": 1717269140, "cache_updated": false, "changed": false, "msg": "'/usr/bin/apt-get -y -o \"Dpkg::Options::=--force-confdef\" -o \"Dpkg::Options::=--force-confold\"       install 'apache2=2.4.41-4ubuntu3.17'' failed: E: Unable to correct problems, you have held broken packages.\n", "rc": 100, "stderr": "E: Unable to correct problems, you have held broken packages.\n", "stderr_lines": ["E: Unable to correct problems, you have held broken packages."], "stdout": "Reading package lists...\nBuilding dependency tree...\nReading state information...\nSome packages could not be installed. This may mean that you have\nrequested an impossible situation or if you are using the unstable\ndistribution that some required packages have not yet been created\nor been moved out of Incoming.\nThe following information may help to resolve the situation:\n\nThe following packages have unmet dependencies:\n apache2 : Depends: apache2-bin (= 2.4.41-4ubuntu3.17) but it is not going to be installed\n           Depends: apache2-utils (= 2.4.41-4ubuntu3.17) but it is not going to be installed\n           Recommends: ssl-cert but it is not installable\n", "stdout_lines": ["Reading package lists...", "Building dependency tree...", "Reading state information...", "Some packages could not be installed. This may mean that you have", "requested an impossible situation or if you are using the unstable", "distribution that some required packages have not yet been created", "or been moved out of Incoming.", "The following information may help to resolve the situation:", "", "The following packages have unmet dependencies:", " apache2 : Depends: apache2-bin (= 2.4.41-4ubuntu3.17) but it is not going to be installed", "           Depends: apache2-utils (= 2.4.41-4ubuntu3.17) but it is not going to be installed", "           Recommends: ssl-cert but it is not installable"]}
            fatal: [51.8.106.109]: FAILED! => {"cache_update_time": 1717269139, "cache_updated": false, "changed": false, "msg": "'/usr/bin/apt-get -y -o \"Dpkg::Options::=--force-confdef\" -o \"Dpkg::Options::=--force-confold\"       install 'apache2=2.4.41-4ubuntu3.17'' failed: E: Unable to correct problems, you have held broken packages.\n", "rc": 100, "stderr": "E: Unable to correct problems, you have held broken packages.\n", "stderr_lines": ["E: Unable to correct problems, you have held broken packages."], "stdout": "Reading package lists...\nBuilding dependency tree...\nReading state information...\nSome packages could not be installed. This may mean that you have\nrequested an impossible situation or if you are using the unstable\ndistribution that some required packages have not yet been created\nor been moved out of Incoming.\nThe following information may help to resolve the situation:\n\nThe following packages have unmet dependencies:\n apache2 : Depends: apache2-bin (= 2.4.41-4ubuntu3.17) but it is not going to be installed\n           Depends: apache2-utils (= 2.4.41-4ubuntu3.17) but it is not going to be installed\n           Recommends: ssl-cert but it is not installable\n", "stdout_lines": ["Reading package lists...", "Building dependency tree...", "Reading state information...", "Some packages could not be installed. This may mean that you have", "requested an impossible situation or if you are using the unstable", "distribution that some required packages have not yet been created", "or been moved out of Incoming.", "The following information may help to resolve the situation:", "", "The following packages have unmet dependencies:", " apache2 : Depends: apache2-bin (= 2.4.41-4ubuntu3.17) but it is not going to be installed", "           Depends: apache2-utils (= 2.4.41-4ubuntu3.17) but it is not going to be installed", "           Recommends: ssl-cert but it is not installable"]}
            
            

            solution:

            If the playbook still fails, you can manually connect to the remote machines and perform the following steps to identify and resolve the issues.

            Update Package List:

              sudo apt update
              

              Upgrade Installed Packages:

              sudo apt upgrade
              

              Fix Broken Packages:

              sudo apt --fix-broken install
              

              Run again

              guest
              0 Comments
              Inline Feedbacks
              View all comments
              0
              Would love your thoughts, please comment.x
              ()
              x