Ansible Refactoring Part 4 - Roles Refactor First Pass

Ansible Refactoring Part 4 - Roles Refactor First Pass

Part 4 - Roles Refactor

This is Part 4 of an Ansible Refactoring Series - Start Here

In our second pass through the project we will take the now more modular solution a step further and break it into roles. In this case we will basically map each of the 3 playbooks from Part 3 into 1 role each

Process
  1. Create a new branch refactor-pass-02-roles

  2. Create a roles sub-directory in the repo

  3. Create each role

    1. Copy the tasks from your playbook into the roles tasks/main.yml

    2. Consider moving some/all vars into the roles defaults/main.yml or vars/main.yml

Turning the Postgres Play into a Role

We will start here and document the steps for our first role. The remainimg 2 roles for flask and HAProxy will basically repeat the same pattern.

  1. Create a new branch refactor-pass-02-roles

    git checkout -b refactor-pass-02-roles
    Sample Output
    Switched to a new branch 'refactor-pass-02-roles'
  2. Make a roles sub-directory

    mkdir roles
  3. Use ansible-galaxy to create the skeleton for the postgres role

    ansible-galaxy init roles/postgres
    Sample Output
    - Role roles/postgres was created successfully
    Tip

    The tree command, not always installed, is useful to visualize directory structures. Try this, sudo yum install tree -y then tree roles to see your role:

    Sample Output
    roles
    └── postgres
        ├── defaults
        │   └── main.yml
        ├── files
        ├── handlers
        │   └── main.yml
        ├── meta
        │   └── main.yml
        ├── README.md
        ├── tasks
        │   └── main.yml
        ├── templates
        ├── tests
        │   ├── inventory
        │   └── test.yml
        └── vars
            └── main.yml
  4. Start by creating your roles tasks/main.yml

    The easiest starting place is to copy your provision_database_tier.yml into the roles tasks/main.yml.

    cp provision_database_tier.yml roles/postgres/tasks/main.yml
  5. Now edit and fix the tasks/main.yml

    Delete everything except the tasks themselves, no need for to keep the tasks: directive and fix the indentation by moving everything left (vim is extremely good for this with commands like << and n`<<` where n is the count operator. eg 5<< outdents 5 lines)

    Note

    Don’t forget to delete the handler section at the bottom of the play.

    Your top 10 lines should now look like this:

    head roles/postgres/tasks/main.yml
    Sample Output
    ---
    - name: Install Postgres packages
      package:
        name: "{{ __package }}"
        state: present
      loop:
        - "{{ postgres_rhel7_repo }}"
        - "{{ postgres_packages }}"
        - "{{ postgres_library }}"
      loop_control:
  6. Now repeat a similar process to steps 4 and 5 above except this time with the roles handlers/main.yml

    Once you have finished your roles/postgres/handlers.yml should look like this:

    ---
    - name: restart_postgres
      service:
        name: "{{ postgres_service }}"
        state: restarted
  7. Roles have in-built support for templates and your postgres playbook referenced templates/pg_hba.conf.j2

    1. Move your templates/pg_hba.conf.j2 to roles/postgres/templates/

    2. Update your roles/postgres/tasks/main.yml to remove the path to the pg_hba.conf.j2 template as the role knows "where to look"

      Your roles template task in roles/postgres/tasks/main.yml should now look like this

      - name: Setup Postgres for remote password auth
        template:
          src: pg_hba.conf.j2
          dest: "{{ postgres_10_data_dir }}/pg_hba.conf"
        notify: restart_postgres
  8. Update your provision_database_tier.yml playbook to use the role postgres and delete the old tasks and handlers code

    Your provision_database_tier.yml should look like this:

    ---
    - name: Deploy, configure, and populate Postgres 10
      hosts: database_servers
      become: true
      gather_facts: false
      tags:
        - database_servers
    
      roles:
    
        - postgres
  9. Finally test your new role by running the provision_database_tier.yml either directly or via site.yml

    You mean want to delete your application first via ansible-playbook teardown-app.yml

    Success (hopefully)

    If not debug your issues until you can successfully deploy and configure Postgres by your role.

  10. Commit your changes

    git add roles
    git commit -am "Moved postgres playbook to use new postgres role"
  11. Push your changes to your repo

    If you have set up your own fork git push

    Note

    git may ask you to perform some adminstrative commands and if it is your first push on this branch git push --set-upstream origin refactor-pass-02-roles

Repeat the above Process for your remaining playbooks

Once you have converted both provision_app_tier.yml and provision_load_balancer_tier.yml to roles based playbooks re-run the whole deploy end to end

ansible-playbook teardown-app.yml
ansible-playbook site.yml

Solution

One possible solution can be seen here in the solution refactor-pass-02-roles branch, either:

  1. Browse to the refactor-pass-02-roles branch

  2. Download the solution and checkout the refactor-pass-02-roles branch

    git clone https://github.com/tonykay/solution_ansible_flask_app_loader_all_in_one
    cd solution_ansible_flask_app_loader_all_in_on
    git checkout refactor-pass-02-roles

Next Steps

Unfortunately your roles, whilst working, are not complete. At this point they cannot be used standalone as they lack the necessary variables which are all being acquired through your group_vars. In the next lab we will look at what variables belong inside the roles, and where, and what variables should remain external. Then we will also clean up your roles, removing redundant files etc.

In Part 5 we will continue to work with roles and enhance them to be re-usable across multiple projects with sensible default behavior "out of the box".