Ansible Real Time Project On Loop: The Best Project For Beginners

Ansible Real Time Project

This is 2nd Exercise of Ansible and in this exercise we will explain real time example based on Ansible loop and Handlers.

Table of Contents

Outcomes:

You should be able to define conditionals in Ansible Playbooks, set up loops that iterate over elements, define handlers in playbooks, and handle task errors.

To SetUp Ansible control machine and hosts machine please refer the previous real time project article Ansible Real-Time Project for Beginners. Once you compete Lab setup please proceed further.

Vars File:

min_ram_mb: 256

ssl_cert_dir: “/etc/ssl/certs”

ssl_key_dir: “/etc/ssl/private”

domain_name: “vm2.example.com”

packages: 

– apache2

– mariadb-server

– php

services: 

– apache2

web_config_files:

– src: “/home/vagrant/ansible_lab/vm2.example.com.crt”

  dest: “/etc/ssl/certs/” 

– src: “/home/vagrant/ansible_lab/vm2.example.com.key”

  dest: “/etc/ssl/private”

Steps to Complete This Ansible Real Time Project:

  1. The Ansible Real Time Project directory contains a partially completed playbook, playbook.yml. Using a text editor, add a task that uses the fail module under the #Fail Fast Message comment. Be sure to provide an appropriate name for the task. This task should only be executed when the remote system does not meet the minimum requirements.

    The minimum requirements for the remote host are listed below:

    • Has at least the amount of RAM specified by the min_ram_mb variable. The min_ram_mb variable is defined in the vars.yml file and has a value of 256.

    • Is running Ubuntu running on Remote machine.

    The completed task matches:

    tasks: 

      # Fail Fasts Message

      – name: Show Failed System Requirements Message

        fail: 

         msg: “The {{ inventory_hostname }} did not meet minimum reqs.”

        when: >

         ansible_memtotal_mb < min_ram_mb or

         ansible_distribution != “Ubuntu” 

  2. Add a single task to the playbook of Ansible Real Time Project under the #Install all Packages comment to install the latest version of any missing packages. Required packages are specified by the packages variable, which is defined in the vars.yml file. The task name should be Ensure required packages are present.

    The Complete task matches: 

    – name: Ensure required packages are present

        apt: 

         name: “{{ packages }}”

         state: latest

  3. Add a single task to the playbook of Ansible Real Time Project under the #Enable and start services comment to start all services. All services specified by the services variable, which is defined in the vars.yml file, should be started and enabled. Be sure to provide an appropriate name for the task.

    The Complete task matches: 

    – name: Ensure services are started and enabled

        service: 

         name: “{{ item }}”

         state: started

         enabled: yes

        loop: “{{ services }}

  4. Add a task block to the playbook of Ansible Real Time Project under the #Block of config tasks comment. This block contains three tasks:

    • A task to create a private key on Local Machine
    • A task to Create a CSR on Local Machine
    • A Tasks to Create Generate Self Sign Certificates on Local hosts
    The Complete Task Matches

    #Block For Self sign CRT generation. 

      – name: Setting up the SSL cert directory and config files

        delegate_to: localhost

        block: 

        – name:  Create Priavte Key

          community.crypto.openssl_privatekey:

            path: “{{ domain_name }}.key”

            size: 2048

        – name: Create CSR (Certificate Signing Request)

          community.crypto.openssl_csr:

            path: “{{ domain_name }}.csr”

            privatekey_path: “{{ domain_name }}.key”

            common_name: “{{ domain_name }}”

        – name: Generate Self-Signed Certificate

          community.crypto.x509_certificate:

            path: “{{ domain_name }}.crt”

            privatekey_path: “./{{ domain_name }}.key”

            csr_path: “{{ domain_name }}.csr”

            provider: selfsigned

     

  5.  Add another task block to the playbook of Ansible Real Time Project under the # Block To Deploy Self sign CRT on Remote host.

    This block contains two tasks:

    •  A task to ensure the directory specified by the ssl_cert_dir variable exists on the remote host. This directory stores the web server’s certificates.

    • A task to copy all files specified by the web_config_files variable to the remote host. Examine the structure of the web_config_files variable in the vars.yml file. Configure the task to copy each file to the correct destination on the remote host.

    Additionally, a debug task is executed if either of the two tasks above fail. In this case, the task prints the message: One or more of the configuration changes failed, but the web service is still active

    The complete task matches: 

    # Block to Deploy Self sign Certificate. 

    – name: Deploy to Remote Host (vm2)

        block: 

        – name: Ensure remote directories exist

          file:

           path: “{{ item }}”

           state: directory

           mode: ‘0755’

          loop:

          – “{{ ssl_cert_dir }}”

          – “{{ ssl_key_dir }}”

        – name: Copy Web Configuration files to vm2

          copy: 

           src: “{{ item.src }}”

           dest: “{{ item.dest}}”

           mode: ‘0644’

          loop: “{{ web_config_files }}”

        rescue:

        – name: Configuration Error Message

          debug:

           msg: >

             One or more of the configuration

             changes failed, but the web service

             is still active.

     

  6. The playbook configures the remote host to listen for standard HTTP, HTTPS and SSH  requests. Add a single task to the playbook under the #Configure the firewall comment to configure ufw. This task should ensure that the remote host allows standard HTTP, SSH and HTTPS connections. These configuration changes should be effective immediately and persist after a system reboot. Be sure to provide an appropriate name for the task.

    The complete task matches:

    #Configure the firewall to configure ufw.

      name: Ensure web server ports are open (UFW)

        ufw:

          rule: allow

          port: “{{ item }}”

          proto: tcp

        loop:

          22

          80

          443

      name: Enable Firewall

        ufw:

          state: enabled

  7. Add two tasks in playbook  one is for copy index.php template to remote Machine and another is for Remove html.index file from Control node to Remote host and also add notify to add handlers in next task.
    The Complet task matches:

    name: copy index.php from local to remote machine

        copy:

         src: index.php

         dest: /var/www/html/index.php

         owner: www-data

         group: www-data

         mode: ‘0644’

        notify: restart web service

    – name: Remove html.index file from Control node to Remote host

        file:

         path: /var/www/html/index.html

         state: absent

  8. Define the restart web service handler. When triggered, this task should restart the web service defined by the web_service variable, defined in the vars.yml file.

    The complete task matches:

    handlers:

      name: restart web service

        service:

           name: apache2

           state: restarted

  9. From the project directory, ~/control-review, run the playbook.yml playbook. The playbook should execute without errors, and trigger the execution of the handler task.

  10. Verify that the web server now responds to HTTPS requests, using the self-signed custom certificate to encrypt the connection. The web server response should match the string Configured for both HTTP and HTTPS.

  11. The complete Playbook Contains:

    – name: Complete lab on loop handlers and error control

      hosts: remote_hosts

      vars_files:

      – vars/vars.yml

      tasks: 

      # Fail Fasts Message

      – name: Show Failed System Requirements Message

        fail: 

         msg: “The {{ inventory_hostname }} did not meet minimum reqs.”

        when: >

         ansible_memtotal_mb < min_ram_mb or

         ansible_distribution != “Ubuntu” 

      – name: Ensure required packages are present

        apt: 

         name: “{{ packages }}”

         state: latest

      – name: Ensure services are started and enabled

        service: 

         name: “{{ item }}”

         state: started

         enabled: yes

        loop: “{{ services }}” 

      #Block of config tasks

      – name: Setting up the SSL cert directory and config files

        delegate_to: localhost

        block: 

        – name:  Create Priavte Key

          community.crypto.openssl_privatekey:

            path: “{{ domain_name }}.key”

            size: 2048

        – name: Create CSR (Certificate Signing Request)

          community.crypto.openssl_csr:

            path: “{{ domain_name }}.csr”

            privatekey_path: “{{ domain_name }}.key”

            common_name: “{{ domain_name }}”

        – name: Generate Self-Signed Certificate

          community.crypto.x509_certificate:

            path: “{{ domain_name }}.crt”

            privatekey_path: “./{{ domain_name }}.key”

            csr_path: “{{ domain_name }}.csr”

            provider: selfsigned

      – name: Deploy to Remote Host (vm2)

        block: 

        – name: Ensure remote directories exist

          file:

           path: “{{ item }}”

           state: directory

           mode: ‘0755’

          loop:

          – “{{ ssl_cert_dir }}”

          – “{{ ssl_key_dir }}”

        – name: Copy Web Configuration files to vm2

          copy: 

           src: “{{ item.src }}”

           dest: “{{ item.dest}}”

           mode: ‘0644’

          loop: “{{ web_config_files }}”

        rescue:

        – name: Configuration Error Message

          debug:

           msg: >

             One or more of the configuration

             changes failed, but the web service

             is still active.

      – name: Ensure web server ports are open (UFW)

        ufw:

          rule: allow

          port: “{{ item }}”

          proto: tcp

        loop:

          – 22

          – 80

          – 443

      – name: Enable Firewall

        ufw: 

          state: enabled

      – name: copy index.php from local to remote machine

        copy: 

         src: index.php

         dest: /var/www/html/index.php

         owner: www-data

         group: www-data

         mode: ‘0644’

        notify: restart web service
      
    – name: Remove html.index file from Control node to Remote host

        file:

         path: /var/www/html/index.html

         state: absent

      handlers:

      – name: restart web service

        service:

           name: apache2

           state: restarted

     

Conclusion: Mastering the Ansible Real Time Project

This Ansible Real Time project demonstrated how loops, handlers can be used together to build efficient and production-ready automation. By leveraging loops, we reduced repetitive code, while handlers ensured services were restarted only when configuration changes occurred. The use of blocks, rescue, and fail-fast checks helped make the playbook more reliable and easier to troubleshoot.

This project is an excellent starting point for beginners to understand real-world Ansible automation, and it lays a strong foundation for managing services, security, and configurations in larger infrastructure environments.

You can also get the  playbook of Ansible Real Time Project on Github Repo and link is GitHub Repo for Ansible Real time project based on loop
 
 

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top