Fix an Ansible-lint key-order violation#

Ansible allows for structured configurations on how to deploy applications and servers, but also for repetitive tasks. All these actions are defined in YAML files that rely on indentation and this is where Ansible can act in a way that isn’t expected. With yamllint most formatting and layout issues can be found, but with ansible-lint also common mistakes for Ansible can be detected.

Finding the violation#

As ansible-lint is a step in the CI-workflow a dependency upgrade started a CI-workflow to scan all Ansible Playbooks to be scanned with the latest version of Ansible-lint and found a violation that must be resolved before the pull request can be successfully merged. Running Ansible-lint after checking out the code the error shown below was found and indicates that the order of the keys in YAML isn’t in the correct order.

Violation detected by ansible-lint#
$ ansible-lint -f pep8 ansible/site.yml
WARNING  Listing 1 violation(s) that are fatal
ansible/roles/platform/tasks/main.yml:3: key-order[task]: You can improve the task key order to: name, when, block
Read documentation for instructions on how to ignore specific rule violations.

              Rule Violation Summary
count tag             profile rule associated tags
    1 key-order[task] basic   formatting

Failed after min profile: 1 failure(s), 0 warning(s) on 60 files.

The wrong key-order#

The example below is a slimmed-down version of ansible/roles/platform/tasks/main.yml with the key-order violation and is an example used by many to explain a conditional block within Ansible. The offending key is on highlighted line 10, but the playbook works fine for now.

Ansible Playbook with an incorrect key-order#
 1---
 2- hosts: localhost
 3  name: Example playbook
 4  tasks:
 5    - name: A block
 6      block:
 7        - name: Display a message
 8          debug:
 9            msg: "Hello world!"
10      when: true

Solving the violation#

Ansible-lint generates the violation message for the fact that the YAML keys aren’t in the right order as it expects to find name, when, and then block. This is done to improve readability and maintainability as conditional expressions are placed before the block of tasks. This way changes will not lead to indentation errors and have an unexpected outcome.

Ansible Playbook with the correct key-order#
 1---
 2- name: Example playbook
 3  hosts: localhost
 4  tasks:
 5    - name: A block
 6      when: true
 7      block:
 8        - name: Display a message
 9          debug:
10            msg: "Hello world!"

The example above is rewritten in the preferred order and improves the readability as the task name and conditional expression are shown together like in other programming languages. If ansible-lint checks the playbook again with the updated key-order the violation is gone.

No violations detected by ansible-lint#
$ ansible-lint -f pep8 ansible/site.yml

Passed with production profile: 0 failure(s), 0 warning(s) on 60 files.

Note

The examples above described the block key, but the keys block, rescue, and always must always be the last key. This is to improve readability and maintainability, and improve performance as keys don’t have to be sorted anymore.