Avoid Hardcoding Download URLs and Paths in Tasks

Guidelines and examples on how to make Ansible flexible and easy to use.

Projects: c2platform/rws/ansible-gis, c2platform.gis


Don’t put path or URL logic / conventions in tasks, use a new default variable.


Problem

When developing Ansible roles, it’s essential to make them flexible and easy to use for a wide range of scenarios. One common anti-pattern is hardcoding file paths and naming conventions directly into Ansible tasks, limiting the role’s adaptability.

Context

In many Ansible roles, tasks are designed to work with specific file structures and naming conventions. However, enforcing these conventions in tasks can hinder the role’s usability and reusability.

Solution

To create flexible Ansible roles, consider the following guidelines:

  1. Use Variables for Conventions: Instead of hardcoding file paths and naming conventions in tasks, define them as variables in the defaults/main.yml file of your role. This allows users to easily customize these parameters to match their needs.
  2. Encourage Overrides: Encourage users to override these default variables in their own group_vars or host_vars when using your role. This ensures they can tailor the role to their specific environment without modifying the role itself.
  3. Document the Variables: Clearly document the variables in your role’s README or documentation, explaining their purpose and how users can modify them. Providing examples of common customizations can be especially helpful.

Example and Implementation

Let’s illustrate these guidelines with an example:

Avoid Hardcoding Download URLs in Tasks

Consider the following Ansible task code snippet, which might be found in a tasks file for the c2platform.gis.arcgis_server role. It hardcodes the download URL for a license file using three variables. This enforces a specific naming convention for the license file, limiting flexibility.

- name: Download License file
  ansible.windows.win_get_url:
    url: "{{ arcgis_server_base_url }}/{{ arcgis_server_role }}{{ arcgis_server_license_file_extension }}"
    dest: "{{ arcgis_server_install_temp_base }}"
    force: false

This practice restricts the role’s flexibility and user-friendliness. Users may not have permission to modify the role, or it may be undesirable. Additionally, it’s unnecessary. The same functionality can be achieved by creating a new variable, for instance, arcgis_server_license_url, in the defaults/main.yml file of the role:

arcgis_server_license_url: "{{ arcgis_server_base_url }}/{{ arcgis_server_role }}{{ arcgis_server_license_file_extension }}"

With this setup, we can change the Download License file task to use arcgis_server_license_url:

- name: Download License file
  ansible.windows.win_get_url:
    url: "{{ arcgis_server_license_url }}"
    dest: "{{ arcgis_server_install_temp_base }}"
    force: false

With this improved approach, users can choose to accept the default naming convention for the license file using the Ansible role. However, they also have the flexibility to adopt an alternative convention by defining or deriving a different value for arcgis_server_license_url within their inventory project, all without the need to modify the Ansible role itself.