Release Pipeline for Ansible

Use Github Actions to automate the build, test, and release stages of the release pipeline for Ansible.

You will be using Github actions to automate the build, test, and release stages of the release pipeline. The idea is to have all the stages run after a commit or pull request is made to the master branch.

What makes up each stage?

Build

Ansible isn’t a compiled language, but it does have environmental requirements. Because the code will be running on a hosted agent provided by Github, Ansible won’t be installed. You will create an action that uses a Docker container to set up the build environment.

Test

You will start testing by using a linter. Ansible has a command-line utility called ansible-lint used to analyze your code and flag issues based on rules. After linting, other types of tests could be added to this stage. However, to start linting will be the only step in the test stage.

Release

The work that you did in the Building Reusable Configuration chapter has set you up for an easy release stage. All you need to do is run the site.yml playbook, and Ansible will take care of the rest. However, there are a few differences when running Ansible in the release pipeline. You will figure out how to populate environment variables that connect Ansible to your cloud provider. Also, you will learn how to pass the vault password into the ansible-playbook command.

Linting Ansible code

Ansible has a command-line tool for linting Ansible playbooks. Linter tools have the following functions:

  • Analyze source code
  • Flag programming errors, bugs, stylistic errors, and suspicious constructs

Let’s lint the configure_nginx_web_server.yml playbook. Click on the Run button and wait for the environment to set up.

---
  - hosts: linux
    gather_facts: false
  
    vars:
      ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
      
    tasks:
    - name: install nginx
      package:
        name:
          - nginx
        state: latest
      become: yes

    - name: copy index.html
      copy:
        src: index.html
        dest: /usr/share/nginx/html/index.html
      become: yes
    
    - name: start nginx service
      service:
          name: nginx
          state: started
      become: yes
Lint Ansible playbook

Once set up, execute the following command:

ansible-lint configure_nginx_web_server.yml
ansible-lint

Let’s review the output’s contents:

  • Line-1 represents rule tag and description.
  • Line-2 represents playbook and line number of flagged code.

Ansible lint flags the usage of using the latest. It suggests not to use the latest but instead use a specific version. This would lock the version of Nginx. Version locking would prevent unintended upgrades. However, sometimes you just need to "ship" it.

Ignoring lint rules

Some rules are easier to follow than others. Other rules, however, might require development hours that you can’t immediately sink into the codebase. In these instances, you can choose to ignore the rule.

You can use the -x parameter to ignore the rule package-latest.

Press + to interact
ansible-lint configure_nginx_web_server.yml -x package-latest

Notice that only one flag is thrown by ansible-lint now that rule package-latest is ignored.

Ignoring rules using the -x parameter is problematic when trying to automate it in a pipeline. Instead of updating command-line arguments, you can create a lint configuration.

Let’s create a lint configuration .ansible-lint file.

Press + to interact
touch .ansible-lint

Add rule package-latest to the skip list in the .ansible-lint file.

Press + to interact
skip_list:
- 'package-latest'

Run ansible lint without -x flag. Click on the Run button and wait for the environment to set up.

skip_list:
 - package-latest
Lint Ansible Playbook

Once set up, execute the following command in the terminal:

Press + to interact
ansible-lint configure_nginx_web_server.yml -c .ansible-list

Ignoring rules entirely has some drawbacks. It ignores all offenses of the rule, not just the ones that you don’t care about. Another option is to add comments in the playbook to ignore specific tasks.

Update the configure_nginx_web_server.yml playbook and click on the Run button again. Review the highlighted change below:

---
  - hosts: linux
    gather_facts: false
  
    vars:
      ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
      
    tasks:
    - name: install nginx
      package:
        name:
          - nginx
        state: latest
      become: yes # noqa package-latest

    - name: copy index.html
      copy:
        src: index.html
        dest: /usr/share/nginx/html/index.html
      become: yes
    
    - name: start nginx service
      service:
          name: nginx
          state: started
      become: yes
Lint Ansible Playbook

You removed the Ansible lint configuration using the following command:

Press + to interact
rm .ansible-lint

Lint the configure_nginx_web_server.yml playbook.

Press + to interact
ansible-lint configure_nginx_web_server.yml

Using # noqa is all you need to ignore the rule. Adding the rule tag that you’re ignoring is the best practice to help identify the skipped rule.

Try it yourself

Ignore the risky-file-permissions rule in the widget above on your own.

Troubleshooting tips

To use linting with Ansible, you need to install the ansible-lint module.

Press + to interact
pip3 install ansible-lint

In this lesson, we introduced linting and how you can lint your playbooks using the ansible-lint module. We looked at the following methods to deal with errors outputted by the ansible-lint command:

  • Fix the error.
  • Ignore the rule using either:
    • -x flag.
    • Adding comments to the playbook.

Get hands-on with 1300+ tech skills courses.