Skip to content

Commit

Permalink
Playbook and monolith support, better tests (#3)
Browse files Browse the repository at this point in the history
The `init` role now supports playbooks - use by following the `mkdir -p molecule/pb-<playbook_name>` etc. commands in the role README.

The `init` role now supports monolithic repositories - IE creating your `molecule` folder in the root of the monolith repo

The `docker_platform` role now supports adding Ansible inventory vars to the created test hosts

Add more complete tests for this role itself, specifically tests for the `init` role.
  • Loading branch information
syndr committed Apr 12, 2024
1 parent cfe0de2 commit 6f5094d
Show file tree
Hide file tree
Showing 22 changed files with 505 additions and 112 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---

name: Deploy Collection

on: {}
# release:
# types:
# - created

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Build and Deploy Collection
uses: artis3n/ansible_galaxy_collection@v2
with:
api_key: '${{ secrets.GALAXY_API_KEY }}'

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2024 Vincent
Copyright (c) 2024 InfluxData

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
84 changes: 79 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ It provides tooling to create Molecule testing scenarios via the `init` role, an

When utilizing an image with systemd support (systemd packages are installed, etc.), the `docker_platform` role supports the creation of Docker containers with a functional Systemd implementation, which can be used to test Ansible code that makes use of Systemd services or related functionality.

# Table of Contents

- [Ansible Collection - syndr.molecule](#ansible-collection---syndrmolecule)
- [What is Molecule?](#what-is-molecule)
- [Using this collection](#using-this-collection)
- [Host Requirements](#host-requirements)
- [Project requirements](#project-requirements)
- [Standalone roles](#standalone-roles)
- [Collections](#collections)
- [Monoliths](#monoliths)
- [Testing roles and playbooks within a monolithic project](#testing-roles-and-playbooks-within-a-monolithic-project)
- [Playbooks](#playbooks)
- [Using Molecule](#using-molecule)
- [Ansible Tags](#ansible-tags)
- [Contributing](#contributing)

# What is Molecule?

> Molecule project is designed to aid in the development and testing of Ansible roles.
Expand All @@ -27,6 +43,8 @@ Some resources on Molecule can be found here:
>
> When reading the above referenced articles, keep in mind their publishing dates, and that there may have been breaking changes to Molecule's functionality since that time!
More tips on using Molecule can be found [below](#using-molecule).

# Using this collection

The following roles are provided:
Expand Down Expand Up @@ -65,9 +83,10 @@ Docker CE can be installed by following the appropriate [installation instructio
The `init` role from this collection will attempt to discover what type of project it is being utilized in. This is enabled by setting the `init_project_type` configuration variable to `auto`. The project type can also be explicitly specified if this is desired.

Supported project types:
* `role`
* `collection`
* `monolith`
* `playbook`
* `role`

When used with a role or collection, the Galaxy meta information for the role must be configured!

Expand Down Expand Up @@ -188,9 +207,6 @@ ansible-playbook molecule/role-$ROLE_NAME/init.yml

Note that in this circumstance, you will need to specify the scenario name in order to run molecule against it (as it is not named `default`).

> [!WARNING]
> Creating more than one `default` scenario within a repository (IE: within individual roles) will cause Molecule to fail to run at the outer project level!
Running the `molecule list` command will provide you an overview of the available scenarios

```bash
Expand All @@ -203,6 +219,7 @@ INFO Running pb-example_playbook > list
╵ ╵ ╵ ╵ ╵
```


And running the full test suite for this playbook would be done as:

```bash
Expand All @@ -216,7 +233,64 @@ molecule converge -s pb-example_playbook
```

> [!TIP]
> The `molecule list` command will show multiple scenarios when run in the root of a monolithic project that also has molecule configured on individual playbooks or roles contained within it. Note that you will, however, still need to be in the appropriate role or playbook directory in order to successfully run these scenarios!
> The `molecule list` command will show multiple scenarios when run in the root of a monolithic project that also has molecule configured on individual playbooks or roles contained within it. Note that you will, however, still need to be in the appropriate role or playbook directory in order to successfully run these!
### Playbooks

Playbook configurations are similar to the `monolith` project type noted above, and are typically contained within monolithic projects. A project directory is considered a playbook if it contains a `tasks/` folder, but no role `meta/main.yml` configuration, and no `playbooks/` subdirectory.

A playbook project configuration may look like:

```
playbooks
├── your_playbook
│   ├── main.yml
│   ├── README.md
│   ├── tasks
│   │   ├── asserts.yml
│   │   ├── main.yml
│   │   └── standard.yml
│   └── vars
└── [...]
```

Playbook configuration adds the following directories to the role path configuration (paths relative to the playbook `main.yml` or equivilant file):

* `./roles`
* `./../roles`
* `./../../roles`

It also adds the following directories to the collection path configuration (paths relative to the playbook `main.yml` or equivilant file):
* `./collections`
* `./../collections`
* `./../../collections`

# Using Molecule

The most common Molecule commands that you will likely use are:

```bash
molecule create # Create the test infrastructure, as defined in molecule.yml
molecule converge # Run the plays from converge.yml (launch your role/playbook)
molecule verify # Run the plays from verify.yml (test for desired state)
molecule test # Run the full test sequence
```

## Ansible Tags

If [tags](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_tags.html) are used in your code to enable/disable certian functionality, they must be specified on the command line when running Molecule commands. To do so, use the `--` [command line option](https://ansible.readthedocs.io/projects/molecule/usage/#test-sequence-commands) to pass commands through to `ansible-playbook`.

For example:

```bash
molecule test -- --tags the-cheese
```

Or running `converge` using a non-default scenario:

```bash
molecule converge -s pb-the_toaster -- --tags sourdough
```

# Contributing

Expand Down
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace: influxdata
name: molecule

# The version of the collection. Must be compatible with semantic versioning
version: 1.2.2
version: 1.3.1

# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
readme: README.md
Expand Down
3 changes: 2 additions & 1 deletion molecule/default/collections.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---

collections:
- name: community.general
- name: community.docker
- name: git+https://github.com/influxdata/ansible-collection-molecule.git
type: git
version: main
version: latest

84 changes: 78 additions & 6 deletions molecule/default/converge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
- name: Converge
hosts: molecule
vars:
ansible_user: molecule_runner
tasks:
- name: Check uname
ansible.builtin.raw: uname -a
Expand All @@ -42,11 +44,81 @@
var: ansible_facts.ansible_local
verbosity: 1

- name: Load preparation facts
ansible.builtin.set_fact:
test_prepare_fact: "{{ ansible_local.molecule.test_prepare_fact }}"
- name: Test local fact exists
ansible.builtin.assert:
that:
- ansible_local.molecule.test_prepare_fact is defined
fail_msg: Something went wrong with storing local facts!
success_msg: Local fact exists

- name: Add your project test configuration here
ansible.builtin.debug:
msg: Typically this will be via the ansible.builtin.include_role module or via import_playbook
- name: Run the init role
vars:
test_dir: /tmp/molecule-init
test_init_wget_path: "https://raw.githubusercontent.com/influxdata/ansible-collection-molecule/main/roles/init/files/init.yml"
test_collection_dir: "{{ test_dir }}/ci_testing/test_collection"
test_role_dir: "{{ test_dir }}/ci_testing/test_collection"
block:
- name: Local work dir exists
ansible.builtin.file:
path: "{{ test_dir }}"
state: directory

- name: Test with a collection
block:
- name: Test collection is created
ansible.builtin.command:
chdir: "{{ test_dir }}"
cmd: ansible-galaxy collection init ci_testing.test_collection
creates: "{{ test_collection_dir }}"

- name: Molecule scenario dir exists for collection
ansible.builtin.file:
path: "{{ test_collection_dir }}/molecule/default"
state: directory

- name: Molecule init playbook exists for collection
ansible.builtin.command:
chdir: "{{ test_collection_dir }}"
cmd: wget -P molecule/default {{ test_init_wget_path }}
creates: "{{ test_collection_dir }}/molecule/default/init.yml"

- name: Run init playbook on collection
# TODO: Actually check idempotence on this
ansible.builtin.command:
chdir: "{{ test_collection_dir }}"
cmd: ansible-playbook molecule/default/init.yml
changed_when: false

- name: Test with a role
block:
- name: Test role is created
ansible.builtin.command:
chdir: "{{ test_dir }}"
cmd: ansible-galaxy role init test_role
creates: "{{ test_role_dir }}"

- name: Molecule scenario dir exists for role
ansible.builtin.file:
path: "{{ test_role_dir }}/molecule/default"
state: directory

- name: Molecule init playbook exists for role
ansible.builtin.command:
chdir: "{{ test_role_dir }}"
cmd: wget -P molecule/default {{ test_init_wget_path }}
creates: "{{ test_role_dir }}/molecule/default/init.yml"

- name: Run init playbook on role
# TODO: Actually check idempotence on this
ansible.builtin.command:
chdir: "{{ test_role_dir }}"
cmd: ansible-playbook molecule/default/init.yml
changed_when: false

- name: Test with a monolith
block:
# TODO: Find/create a public monolith repo we can use to test this
- name: "TODO: Write monolith test"
ansible.builtin.debug:
msg: This test hasn't been written! You get a cookie if you can fix that! 🍪

29 changes: 29 additions & 0 deletions molecule/default/create.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
docker_platform_image: "{{ item.image }}"
docker_platform_systemd: "{{ item.systemd | default(false) }}"
docker_platform_modify_image: "{{ item.modify_image | default(false) }}"
docker_platform_modify_image_buildpath: "{{ item.modify_image_buildpath | default(molecule_ephemeral_directory + '/build') }}"
docker_platform_privileged: "{{ item.privileged | default (false) }}"
docker_platform_hostvars: "{{ item.hostvars | default({}) }}"
docker_platform_state: present
when: item.type == 'docker'
loop: "{{ molecule_yml.platforms }}"
loop_control:
label: item.name
Expand All @@ -31,3 +34,29 @@
ansible.builtin.debug:
msg: "{{ result.stdout }}"

- name: Load system facts
ansible.builtin.setup:
filter:
- ansible_service_mgr

- name: Check on Systemd
block:
- name: Wait for systemd to complete initialization.
ansible.builtin.command: systemctl is-system-running
register: systemctl_status
until: >
'running' in systemctl_status.stdout or
'degraded' in systemctl_status.stdout
retries: 30
delay: 5
changed_when: false
failed_when: systemctl_status.rc > 1

- name: Check systemd status
ansible.builtin.assert:
that:
- systemctl_status.stdout == 'running'
fail_msg: Systemd-enabled container does not have a healthy Systemd!
success_msg: Systemd is running
when: ansible_service_mgr == 'systemd'

20 changes: 18 additions & 2 deletions molecule/default/molecule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,27 @@ driver:
managed: true
login_cmd_template: 'docker exec -ti {instance} bash'
platforms:
- name: instance
image: geerlingguy/docker-${MOLECULE_GEERLINGGUY_DISTRO:-rockylinux9}-ansible:latest
- name: docker-rockylinux9
type: docker
image: geerlingguy/docker-rockylinux9-ansible:latest
systemd: True
modify_image: False
privileged: False
hostvars: {}
- name: docker-fedora39
type: docker
image: geerlingguy/docker-fedora39-ansible:latest
systemd: True
modify_image: False
privileged: False
hostvars: {}
- name: docker-ubuntu2204
type: docker
image: geerlingguy/docker-ubuntu2204-ansible:latest
systemd: True
modify_image: False
privileged: False
hostvars: {}
provisioner:
name: ansible
log: True
Expand Down
Loading

0 comments on commit 6f5094d

Please sign in to comment.