Lab Guide: Adding a Module to a Collection

A guide to adding a custom module to your Ansible collection and using it in a playbook.

Lab briefing

In this challenge, you will be adding content in the form of a Ansible module plugin to the collection you created, and then using the module for a new playbook, which you will fix with ansible-lint before running it with ansible-navigator.

Learning objectives

After completing this module, you will be able to:

  • Add a custom Python module to an Ansible collection

  • Create a playbook that uses your custom module

  • Use ansible-lint to detect and auto-fix playbook issues

  • Run playbooks with both ansible-playbook and ansible-navigator


Lab guide: Hands-on tasks

In this exercise, you will copy an existing Python module into your collection’s plugins/modules directory. While you can develop your own modules from scratch, we will use a pre-written one for simplicity.

Task 1: Add a custom module to the collection

First, you will create a new Python file and add the code for a simple cowsay module.

  1. Create the module file. In the VS Code file explorer on the left, expand the plugins directory, then right-click on the modules directory and select New File. Name the file cowsay.py.

  2. Add the Python code. Copy the following Python code and paste it into the cowsay.py file you just created.

    from ansible.module_utils.basic import AnsibleModule
    import subprocess
    
    def run_cowsay(message):
        result = subprocess.run(['cowsay', '-t', message], capture_output=True, text=True)
        return result.stdout
    
    def main():
        module_args = dict(
            message=dict(type='str', required=True)
        )
    
        module = AnsibleModule(
            argument_spec=module_args,
            supports_check_mode=True
        )
    
        message = module.params['message']
        result = run_cowsay(message)
    
        module.exit_json(changed=False, message=result.split('\n'))
    
    if __name__ == '__main__':
        main()

Task 2: Create a playbook to use the new module

Now, you will switch to your playbook project folder and create a new playbook that calls your custom module.

  1. Open the playbook project folder. In the VS Code top menu, select FileOpen Folder…​.

  2. Enter the correct path. In the prompt, enter the path /home/rhel/myansibleproject and click the blue OK button.

    Open Ansible Playbook Project
  3. After the window reloads, create a new playbook file. In the file explorer on the left, right-click in the empty space below site.yml and select New File. Name the file mycowsay.yml.

  4. Add the playbook content. Copy and paste the following content into the mycowsay.yml file:

    ---
    - hosts: localhost
      tasks:
        - name: test the cowsay module
          mynamespace.mycollection.cowsay:
            message: Hello, Ansible!
          register: result
    
        - name: Display the result
          ansible.builtin.debug:
            msg: "{{ result.message }}"

Task 3: Use ansible-lint to fix the playbook

You will notice red curly lines under parts of your playbook. These are warnings from ansible-lint. You will now use its auto-fix capabilities.

Ansible Lint warnings in VS Code
  1. Open the Ansible extension settings. Click the Ansible icon in the left sidebar then the Settings option in the menu.

    Ansible Extension Settings
  2. Enable the linter and auto-fix. In the search bar at the top, type lint to filter the settings.

    • Make sure the checkbox for Ansible › Validation › Lint: Enabled is checked.

    • In the Ansible › Validation › Lint: Arguments field below, enter --fix. This tells the linter to automatically fix issues it finds.

      Ansible Lint settings
  3. Trigger the auto-fix. Go back to the mycowsay.yml playbook tab and save the file (Ctrl + S or Cmd + S). Wait a few seconds for ansible-lint to run. It should automatically fix several formatting issues.

  4. Apply the final manual fix. One warning will remain. Hover your mouse over it to see the reason: "All plays should be named." The linter cannot fix this for you. To fix it, add a - name: line to the play. The final, correct playbook should look like this:

    ---
    - name: Using our cowsay module
      hosts: localhost
      tasks:
        - name: Test the cowsay module
          mynamespace.mycollection.cowsay:
            message: Hello, Ansible!
          register: result
    
        - name: Display the result
          ansible.builtin.debug:
            msg: "{{ result.message }}"
            verbosity: 0

Task 4: Run the playbook

Now that your playbook is lint-free, let’s run it using both ansible-playbook and ansible-navigator. Go back to the VS Code file Explorer view.

  1. Run with ansible-playbook. In the VS Code file explorer, right-click your mycowsay.yml playbook. From the context menu, select Run Ansible Playbook. The output in the terminal should display a friendly cow saying "Hello, Ansible!".

    Playbook output with cowsay message
  2. Run with ansible-navigator. Right-click the playbook again, but this time select Run with Ansible Navigator. This will launch the Terminal User Interface (TUI).

    Ansible Navigator TUI
  3. Explore the Navigator output. You are now inside the ansible-navigator TUI.

    • To the left of the play name, you will see the number 0. Press 0 to drill down into the details for that play.

    • You can now see the 3 tasks from your playbook. Press 2 to see the output of the final "Display the result" task.

    • You may need to scroll down to find the cow message.

      Viewing task output in Ansible Navigator
  4. Exit Ansible Navigator. Press the ESC key 3 times to exit the TUI and return to the normal terminal prompt.


Next steps

You have successfully added and tested a custom module in your collection. Please click the Next button below to proceed to the next module.