Question

I'm using some AWS modules to develop a role which will create users, groups, roles and manage managed policies on AWS.

I would like to have some TDD practice while developing this role.

For example, I have the following task:

- name: Create or delete an user
  iam:
    iam_type: user
    name: "{{ item.name }}"
    state: "{{ item.state }}"
  when: >
    item.state == 'present' or item.state == 'absent'
    and item.new_name is not defined
  with_items: "{{ iam_users }}"

And this is how I'm doing integration test for this task:

---

- hosts: localhost
  connection: local
  gather_facts: false

  vars:
    iam_users:
      - name: test-user-0
        state: present

  roles:
    - aws-iam

- hosts: localhost
  connection: local
  gather_facts: false

  vars:
    iam_users:
      - name: test-user-0
        state: absent

  roles:
    - aws-iam

So once I run this test it should run without any fail. It works, but I'm not confident that this is the right way to go within the Ansible realm.

Did anyone face the same situation before? I don't want to test the module itself, I want to test the results of my tasks using the module.

Was it helpful?

Solution

Ansible uses a declarative programming paradigm for configuration management. Basic programming units (tasks) perform complex operations in background and transform the target system state to desired value.

So to further add complexity, the initial state of the target system must be reset between TDD cycles.

In a sense TDD can be implemented using Ansible code alone where the same code is used for tests and execution:

  • reset the target system state;
  • add a task to an Ansible playbook specifying the desired state;
  • execute Ansible playbook in check mode - the task shall return changed status, indicating red,
  • execute Ansible playbook in regular mode - the task shall return changed;
  • execute Ansible playbook in regular (stressing: regular not check) mode again - all tasks shall return ok status indicating green,
  • refactor.

For a more full-fledged TDD, frameworks for automated tests already exist:

  • Molecule - a complete, ready-to-use testing system for Ansible roles, which allows TDD implementation using external testing frameworks like Serverspec (Ruby/RSpec world) or TestInfra (Python world).

    These tests are stored in a separate project subdirectory and you can develop a role in the TDD cycle by:

    • writing a test,
    • running full Molecule process for red,
    • writing an Ansible task,
    • running full Molecule cycle for green,
    • refactoring.

    To refer to your specific IAM user example, there are Serverspec tests for IAM (example test).

  • Test Kitchen (Chef/Ruby world)

    I can't provide details, I guess it's similar to Molecule.

Licensed under: CC-BY-SA with attribution
scroll top