To make collaboration easier, we document some rules we want to follow when creating Ansible Playbooks and Roles.
Playbooks have to written to be called by either an automation controller Job Template or from the command line.
Environment Variables (e.g. for Cloud Credentials) are stored in a sub folder “environments” at the root level of the project.
Projects in this group follow these recommendations:
Ansible role: role-xyz
Ansible collection: collection-xyz
Ansible Playbook: playbook-xyz
Tasks names should be short and descriptive. We want to use upper case characters and describe what the task will do, for example:
- name: Install package httpd - name: Enable HTTP firewall rule - name: Start and enable service httpd
- name: check httpd is installed # use upper case instead, don't say "check", say "install httpd" instead - name: Job Template - Apache # instead use something like "Create Job Template Apache"
Roles have reasonable defaults set. Variables which have to be set, but defaults are not applicable, are verified by using ‘assert’ checks (for example unique instance names, IP Addresses, passwords, … ).
Variables should start with a prefix identifying the application or service they are used for. e.g. variables used by automation controller should be prefixed with controller_, variables for Google Cloud with gcp_. Also we should refrain from using acronyms in variable names unless they are very well known (like HTTP, YML, or IPv4). Since all modern Code Editors provide ways of automatic completion there is no gain in forcing short variable names.
A few good variable names:
controller_gcp_username: # the user name for GCP controller_http_port: # the web server port gcp_template: # the name of the instance template gcp_region: # the region to use gcp_zone: # and the zone
Those would be bad choices:
usr: # the user name for GCP controller_user: # the user name for GCP tgu: # the user name for GCP controller_http: # the web server port tpl: # the name of the instance template region: # the region to use gzone: # and the zone
The content provided in this project should be modular when it makes sense. We introduce the concept of “Use Cases” which allows the end user to deploy additional optional features. Use Cases should be used if one or all of the the following criteria are met:
enabling the use case causes additional cost, e.g. it requires additional VMs or instances (for example the Satellite Use Case is quite expensive)
it causes significant additional deployment time, e.g. the Playbook deploying the Use Case runs for additional several minutes
it introduces a conflict, e.g. Use Case A and Use Case B can not be enabled at the same time
When none of the above criteria applies, the necessary tasks should be in a separate task file or role, but within the existing structure.
When using Ansible Collections we use version pinning to provide stable, reliable and predictable deployments. Playbooks and rules which require Ansible Collections should use the
collections/requirements.yml file to list their dependencies. These files should not list or pin to any particular version of the collections. All version pinning is consolidated in the EE definition. This simplifies dependency management by consolidating version pinning in one file.
To keep track of Ansible Collection dependencies, we use renovate which provides automatic scan for outdated Collections. Currently renovate can only scan Ansible Galaxy though and therefore sometimes creates Merge Requests for Collections not yet available on Automation Hub.
When reviewing the automatically generated Merge Requests, manual checks have to be used to make sure the Collections is in fact available on Automation Hub or the automatic build of the execution environment will fail.