Bookmark this page

Guided Exercise: Implementing Recommended Ansible Practices

  • Apply recommended practices to an existing Ansible automation project.

Outcomes

  • Set up a web server on servera.lab.example.com and serverb.lab.example.com.

  • Set up a database server on serverc.lab.example.com and serverd.lab.example.com.

  • Identify points of improvement on Ansible projects.

  • Implement recommended practices.

As the student user on the workstation machine, use the lab command to prepare your system for this exercise.

This command creates a project directory for the exercise.

[student@workstation ~]$ lab start develop-practices

Procedure 1.3. Instructions

  1. The lab start command creates an Ansible project in the ~/develop-practices directory. The deploy.yml playbook deploys the Apache HTTPD web server and the MariaDB database server.

    Change to the project directory and review the deploy.yml playbook.

    [student@workstation ~]$ cd ~/develop-practices/
    [student@workstation develop-practices]$ cat deploy.yml
    ---
    - name: Deploy a web application
      hosts: webservers
      vars:
        service: httpd
        fw_service: http
        package:
          - httpd
    
      tasks:
    
        - name: Install the webserver
          ansible.builtin.yum: name={{ package }} state=latest
    
        - name: Deploy web content
          ansible.builtin.template:
            src: templates/index.html.j2
            dest: "{{ web_dest }}"
    
        - name: Start the webserver
          ansible.builtin.service:
              name: "{{ service }}"
              state: started
              enabled: true
    
        - name: Enable the {{ fw_service }} service in the firewall
          ansible.posix.firewalld:
              service: "{{ fw_service }}"
              state: enabled
              permanent: true
              immediate: true
    
    - hosts:
        - serverc.lab.example.com
        - serverd.lab.example.com
      vars:
        service: mariadb
        fw_service: mysql
        package:
          - mariadb-server
    
      tasks:
    
        - name: Install the database server
          ansible.builtin.yum:
            name: "{{ package }}"
            state: latest
    
        - name: Start the database server
          ansible.builtin.shell:
            cmd: systemctl enable --now {{ service }}
    
        - name: Enable the {{ fw_service }} service in the firewall
          ansible.posix.firewalld:
            service: "{{ fw_service }}"
            state: enabled
            permanent: true
            immediate: true
    
    - name: Test web application
      hosts: webservers
    
      tasks:
    
        #TODO: Add test
  2. The second play installs the MariaDB database server on the serverc.lab.example.com and serverd.lab.example.com hosts. Create a name for that play, and replace its list of hosts with a group so that it can be updated more easily, as follows:

    1. In the ~/develop-practices/inventory file, create the dbservers group, consisting of serverc.lab.example.com and serverd.lab.example.com. The updated ~/develop-practices/inventory file should now consist of the following content:

      ...output omitted...
      [webservers]
      servera.lab.example.com
      serverb.lab.example.com
      
      [dbservers]
      serverc.lab.example.com
      serverd.lab.example.com
    2. In the ~/develop-practices/deploy.yml playbook, change the second play to run against the dbservers group, and give that unnamed play the name Deploy database servers. The beginning of the updated second play in ~/develop-practices/deploy.yml should now contain the following content:

      ...output omitted...
      - name: Deploy database servers
        hosts: dbservers
        vars:
          service: mariadb
          fw_service: mysql
          package:
            - mariadb-server
      ...output omitted...
  3. Update the variables used in the first two plays of the deploy.yml playbook so that how they are defined and named follow better practices.

    1. In the first play in the ~/develop-practices/deploy.yml playbook, move the service, fw_service, and package variables to the ~/develop-practices/group_vars/webservers group variable file. Rename them to web_service, web_fw_service, and web_package, respectively.

      The ~/develop-practices/group_vars/webservers file should now contain the following content:

      ---
      web_dest: /var/www/html/index.html
      web_service: httpd
      web_fw_service: http
      web_package:
        - httpd
    2. In the first play in the ~/develop-practices/deploy.yml file, remove the definitions of the service, fw_service, and package variables in vars.

      The ~/develop-practices/deploy.yml file should now consist of the following content:

      ---
      - name: Deploy a web application
        hosts: webservers
      
        tasks:
      
          - name: Install the webserver
            ansible.builtin.yum: name={{ package }} state=latest
      ...output omitted...
    3. In the first play in the ~/develop-practices/deploy.yml file, update the variable names used in the following tasks:

      • Install the webserver

      • Start the webserver

      • Enable the {{ fw_service }} service in the firewall

      The updated tasks should now consist of the following content:

          - name: Install the webserver
            ansible.builtin.yum: name={{ web_package }} state=latest
      
      ...output omitted...
      
          - name: Start the webserver
            ansible.builtin.service:
                name: "{{ web_service }}"
                state: started
                enabled: true
      
          - name: Enable the {{ web_fw_service }} service in the firewall
            ansible.posix.firewalld:
                service: "{{ web_fw_service }}"
                state: enabled
                permanent: true
                immediate: true
    4. Create the ~/develop-practices/group_vars/dbservers file.

      Move the service, fw_service, and package variables from the second play into the ~/develop-practices/group_vars/dbservers file with the names db_service, db_fw_service, and db_package, respectively.

      The ~/develop-practices/group_vars/dbservers file should now contain the following content:

      ---
      db_service: mariadb
      db_fw_service: mysql
      db_package:
        - mariadb-server
    5. In the ~/develop-practices/deploy.yml playbook, remove the service, fw_service, and package variables from vars in the second play, because they are now defined in the dbservers group variable file using new names.

      The ~/develop-practices/deploy.yml file should now consist of the following content:

      ...output omitted...
      - name: Deploy database servers
        hosts: dbservers
      
        tasks:
      ...output omitted...
    6. In the ~/develop-practices/deploy.yml playbook, in the second play, update the variable names used in the following tasks:

      • Install the database server

      • Start the database server

      • Enable the {{ fw_service }} service in the firewall

      The updated tasks should now consist of the following content:

          - name: Install the database server
            ansible.builtin.yum:
              name: "{{ db_package }}"
              state: latest
      
          - name: Start the database server
            ansible.builtin.shell:
              cmd: systemctl enable --now {{ db_service }}
      
          - name: Enable the {{ db_fw_service }} service in the firewall
            ansible.posix.firewalld:
              service: "{{ db_fw_service }}"
              state: enabled
              permanent: true
              immediate: true
  4. The Install the webserver task in the first play uses folded syntax for the ansible.builtin.yum module. Change the task to use native YAML syntax.

    The updated task should now consist of the following content:

        - name: Install the webserver
          ansible.builtin.yum:
            name: "{{ web_package }}"
            state: latest
  5. The Start the webserver and Enable the {{ web_fw_service }} service in the firewall tasks both use indentation that is not standard with the rest of the playbook. Update the indentation in the tasks.

    The updated tasks should now consist of the following content:

        - name: Start the webserver
          ansible.builtin.service:
            name: "{{ web_service }}"
            state: started
            enabled: true
    
        - name: Enable the {{ web_fw_service }} service in the firewall
          ansible.posix.firewalld:
            service: "{{ web_fw_service }}"
            state: enabled
            permanent: true
            immediate: true
  6. The Start the database server task uses the ansible.builtin.shell module to run the systemctl command to enable and start a service. Change this task to use the ansible.builtin.service module instead.

    The updated task should now consist of the following content:

        - name: Start the database server
          ansible.builtin.service:
            name: "{{ db_service }}"
            state: started
            enabled: true
  7. The third play in the ~/develop-practices/deploy.yml playbook has no tasks. Add block and rescue directives to that play that restart the web service on the hosts in the webservers group if the web application is unavailable.

    The updated third play should now consist of the following content:

    - name: Test web application
      hosts: webservers
    
      tasks:
    
        - name: Web application test
          block:
            - name: Check web application
              ansible.builtin.uri:
                url: http://{{ item }}
              loop: "{{ groups['webservers'] }}"
    
          rescue:
            - name: Restart web server
              ansible.builtin.service:
                name: "{{ web_service }}"
                state: restarted
  8. Review your playbook. The completed ~/develop-practices/deploy.yml playbook should consist of the following content:

    ---
    - name: Deploy a web application
      hosts: webservers
    
      tasks:
    
        - name: Install the webserver
          ansible.builtin.yum:
            name: {{ web_package }}
            state: latest
    
        - name: Deploy web content
          ansible.builtin.template:
            src: templates/index.html.j2
            dest: "{{ web_dest }}"
    
        - name: Start the webserver
          ansible.builtin.service:
            name: "{{ web_service }}"
            state: started
            enabled: true
    
        - name: Enable the {{ web_fw_service }} service in the firewall
          ansible.posix.firewalld:
            service: "{{ web_fw_service }}"
            state: enabled
            permanent: true
            immediate: true
    
    - name: Deploy database servers
      hosts: dbservers
    
      tasks:
    
        - name: Install the database server
          ansible.builtin.yum:
            name: "{{ db_package }}"
            state: latest
    
        - name: Start the database server
          ansible.builtin.service:
            name: "{{ db_service }}"
            state: started
            enabled: true
    
        - name: Enable the {{ db_fw_service }} service in the firewall
          ansible.posix.firewalld:
            service: "{{ db_fw_service }}"
            state: enabled
            permanent: true
            immediate: true
    
    - name: Test web application
      hosts: webservers
    
      tasks:
    
        - name: Web application test
          block:
            - name: Check web application
              ansible.builtin.uri:
                url: http://{{ item }}
              loop: "{{ groups['webservers'] }}"
    
          rescue:
            - name: Restart web server
              ansible.builtin.service:
                name: "{{ web_service }}"
                state: restarted
  9. Run the deploy.yml playbook using automation content navigator.

    [student@workstation develop-practices]$ ansible-navigator run deploy.yml \
    > --eei ee-supported-rhel8 --pp missing
    
      Play name                 Ok Changed ... Failed ... Task count  Progress
    0│Deploy a web application  10       8 ...      0 ...         10  Complete
    1│Deploy database servers    8       6 ...      0 ...          8  Complete
    2│Test web application       4       0 ...      0 ...          4  Complete
    
    ^b/PgUp page up  ^f/PgDn page down  ↑↓ scroll  esc ...         Successful

    Press ESC to exit from the ansible-navigator command.

Finish

On the workstation machine, change to the student user home directory and use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish develop-practices

This concludes the section.

Revision: do374-2.2-82dc0d7