Installing and using Pre-commit with Ansible-lint

About Pre-commit: https://pre-commit.com/

Pre-commit is an open source tool used to help ensure code quality in a software project. It is an automation tool that allows you to run a series of checks or tasks automatically before committing to a version control repository, such as Git.

Tasks that can be executed with pre-commit include:

  • Code style verification
  • Code quality analysis
  • Syntax error detection
  • Detection of security issues
  • Reviewing documentation and code comments
  • Verification of development environment configuration

By running these tasks automatically before each commit, you can reduce the number of code errors, improve code quality, and facilitate team collaboration. Pre-commit can also help ensure that code changes are consistent with established project standards and policies.

About Ansible-lint: https://ansible-lint.readthedocs.io/

Ansible-lint is a command-line tool for linting playbooks, roles and collections. Its main goal is to promote proven practices, patterns and behaviors while avoiding common pitfalls that can easily lead to bugs or make code harder to maintain. Its philosophy is that ansible playbooks, roles, and collections should read like documentation, be production ready, unambiguous, and provide consistent results.


Using Pre-commit and Ansible-lint:

We are gonna install and configure pre-commit and ansible-lint in order to verify the code quality of our Ansible code base, before committing changes to the repository. For our example we will be using a git repository called “ansible-repo” and Debian as operating system.

Installation:

Since we are using Debian and we want to install the most up to date versions of these tools, we are gonna install them using Python Pip3 instead of using APT.

ansible-repo (git)$: sudo pip3 install pre-commit ansible-lint
ansible-repo (git)$: pre-commit --version && ansible-lint --version
   pre-commit 2.20.0
   ansible-lint 6.10.0 using ansible 2.14.0

Ansible-lint configuration:

In order to configure ansible-lint, we need to create a configuration file called “.ansible-lint" (using yaml format) in the root directory of our repository (optionally you could create such file as “.config/ansible-lint.yml" and it will work too). After that, we will populate it with some basic config.

You can check official documentation to see all the configuration options available in https://ansible-lint.readthedocs.io/configuring/.

---
# Profiles gradually increase the strictness of rules as your Ansible content lifecycle. 
# We set it to "production" in order to ensure that content meets requirements for inclusion in Ansible Automation Platform (AAP) as validated or certified content.

profile: production 

# exclude_paths included in this file are parsed relative to this file's location and not relative to the CWD of execution.
exclude_paths:
  - .cache/
  - .github/
  - excludethis/

# Ansible-lint does not fail on warnings from the rules or tags listed below
warn_list: 
  - command-instead-of-module
  - command-instead-of-shell

# Ansible-lint will skip and ignore the rules or tags listed below
# Uncomment next two lines in order to disable YAML syntax violations
#skip_list:
#  - yaml

Yamllint configuration:

Ansible-lint also includes a Yamllint implementation that we can use and extend, or ignore entirely using the “skip_list” directive in the configuration file in case we decide so.

For our scenario, we will use and extend it by creating in the root directory of our repository another file called “.yamllint.yml” (again using the yaml format) with our custom extended configuration.

You can check the official documentation to see all the configuration options available in https://yamllint.readthedocs.io/en/stable/rules.html.

---
extends: default

rules:
  line-length:
    max: 260

  truthy:
    allowed-values: ["true", "false", "yes", "no"]
    check-keys: true

  comments:
    min-spaces-from-content: 1

Pre-commit configuration:

The next step is to create a “.pre-commit-config.yaml” file (guess in which format 😉 in the root directory of our repository where we will specify and configure the hooks that pre-commit will run before each commit. In our scenario there will only be the ansible-lint hook.

---
repos:
  - repo: https://github.com/ansible/ansible-lint.git
    rev: v6.10.0
    hooks:
      - id: ansible-lint
        files: \.(yaml|yml)$
        name: Ansible Lint
        description: Run configurations on .ansible-lint file
        verbose: true
        # args: [-p, ./ansible/*]

Ok, so far our ansible-repo project root directory should look something like this:

.
├── .git
├── .gitignore
├── .ansible-lint
├── .pre-commit-config.yaml
└── .yamllint.yml

As last step, standing in the root directory of our ansible-repo repository, we will install and setup the related pre-commit git hook scripts by running the next command:

ansible-repo (git)$: pre-commit install
   pre-commit installed at .git/hooks/pre-commit

And that’s it!, the next time you make changes to your ansible-repo code and do a commit, pre-commit will automatically run the hooks specified in the configuration file and ansible-lint will run evaluating our code and showing errors, improvements advices, or the approval of such changes.

Example run results:

                         Rule Violation Summary
 count tag                       profile rule associated tags
     1 command-instead-of-module basic   command-shell, idiom (warning)
     2 command-instead-of-shell  basic   command-shell, idiom (warning)

Passed with min profile: 0 failure(s), 3 warning(s) on 13 files.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.