Skip to content

Commit 6f5094d

Browse files
authored
Playbook and monolith support, better tests (#3)
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.
1 parent cfe0de2 commit 6f5094d

File tree

22 files changed

+505
-112
lines changed

22 files changed

+505
-112
lines changed

.github/workflows/publish.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
3+
name: Deploy Collection
4+
5+
on: {}
6+
# release:
7+
# types:
8+
# - created
9+
10+
jobs:
11+
deploy:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Build and Deploy Collection
17+
uses: artis3n/ansible_galaxy_collection@v2
18+
with:
19+
api_key: '${{ secrets.GALAXY_API_KEY }}'
20+

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 Vincent
3+
Copyright (c) 2024 InfluxData
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@ It provides tooling to create Molecule testing scenarios via the `init` role, an
88

99
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.
1010

11+
# Table of Contents
12+
13+
- [Ansible Collection - syndr.molecule](#ansible-collection---syndrmolecule)
14+
- [What is Molecule?](#what-is-molecule)
15+
- [Using this collection](#using-this-collection)
16+
- [Host Requirements](#host-requirements)
17+
- [Project requirements](#project-requirements)
18+
- [Standalone roles](#standalone-roles)
19+
- [Collections](#collections)
20+
- [Monoliths](#monoliths)
21+
- [Testing roles and playbooks within a monolithic project](#testing-roles-and-playbooks-within-a-monolithic-project)
22+
- [Playbooks](#playbooks)
23+
- [Using Molecule](#using-molecule)
24+
- [Ansible Tags](#ansible-tags)
25+
- [Contributing](#contributing)
26+
1127
# What is Molecule?
1228

1329
> Molecule project is designed to aid in the development and testing of Ansible roles.
@@ -27,6 +43,8 @@ Some resources on Molecule can be found here:
2743
>
2844
> 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!
2945
46+
More tips on using Molecule can be found [below](#using-molecule).
47+
3048
# Using this collection
3149

3250
The following roles are provided:
@@ -65,9 +83,10 @@ Docker CE can be installed by following the appropriate [installation instructio
6583
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.
6684

6785
Supported project types:
68-
* `role`
6986
* `collection`
7087
* `monolith`
88+
* `playbook`
89+
* `role`
7190

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

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

189208
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`).
190209

191-
> [!WARNING]
192-
> 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!
193-
194210
Running the `molecule list` command will provide you an overview of the available scenarios
195211

196212
```bash
@@ -203,6 +219,7 @@ INFO Running pb-example_playbook > list
203219
╵ ╵ ╵ ╵ ╵
204220
```
205221

222+
206223
And running the full test suite for this playbook would be done as:
207224

208225
```bash
@@ -216,7 +233,64 @@ molecule converge -s pb-example_playbook
216233
```
217234

218235
> [!TIP]
219-
> 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!
236+
> 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!
237+
238+
### Playbooks
239+
240+
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.
241+
242+
A playbook project configuration may look like:
243+
244+
```
245+
playbooks
246+
├── your_playbook
247+
│   ├── main.yml
248+
│   ├── README.md
249+
│   ├── tasks
250+
│   │   ├── asserts.yml
251+
│   │   ├── main.yml
252+
│   │   └── standard.yml
253+
│   └── vars
254+
└── [...]
255+
```
256+
257+
Playbook configuration adds the following directories to the role path configuration (paths relative to the playbook `main.yml` or equivilant file):
258+
259+
* `./roles`
260+
* `./../roles`
261+
* `./../../roles`
262+
263+
It also adds the following directories to the collection path configuration (paths relative to the playbook `main.yml` or equivilant file):
264+
* `./collections`
265+
* `./../collections`
266+
* `./../../collections`
267+
268+
# Using Molecule
269+
270+
The most common Molecule commands that you will likely use are:
271+
272+
```bash
273+
molecule create # Create the test infrastructure, as defined in molecule.yml
274+
molecule converge # Run the plays from converge.yml (launch your role/playbook)
275+
molecule verify # Run the plays from verify.yml (test for desired state)
276+
molecule test # Run the full test sequence
277+
```
278+
279+
## Ansible Tags
280+
281+
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`.
282+
283+
For example:
284+
285+
```bash
286+
molecule test -- --tags the-cheese
287+
```
288+
289+
Or running `converge` using a non-default scenario:
290+
291+
```bash
292+
molecule converge -s pb-the_toaster -- --tags sourdough
293+
```
220294

221295
# Contributing
222296

galaxy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace: influxdata
88
name: molecule
99

1010
# The version of the collection. Must be compatible with semantic versioning
11-
version: 1.2.2
11+
version: 1.3.1
1212

1313
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
1414
readme: README.md

molecule/default/collections.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
---
22

33
collections:
4+
- name: community.general
45
- name: community.docker
56
- name: git+https://github.com/influxdata/ansible-collection-molecule.git
67
type: git
7-
version: main
8+
version: latest
89

molecule/default/converge.yml

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
1919
- name: Converge
2020
hosts: molecule
21+
vars:
22+
ansible_user: molecule_runner
2123
tasks:
2224
- name: Check uname
2325
ansible.builtin.raw: uname -a
@@ -42,11 +44,81 @@
4244
var: ansible_facts.ansible_local
4345
verbosity: 1
4446

45-
- name: Load preparation facts
46-
ansible.builtin.set_fact:
47-
test_prepare_fact: "{{ ansible_local.molecule.test_prepare_fact }}"
47+
- name: Test local fact exists
48+
ansible.builtin.assert:
49+
that:
50+
- ansible_local.molecule.test_prepare_fact is defined
51+
fail_msg: Something went wrong with storing local facts!
52+
success_msg: Local fact exists
4853

49-
- name: Add your project test configuration here
50-
ansible.builtin.debug:
51-
msg: Typically this will be via the ansible.builtin.include_role module or via import_playbook
54+
- name: Run the init role
55+
vars:
56+
test_dir: /tmp/molecule-init
57+
test_init_wget_path: "https://raw.githubusercontent.com/influxdata/ansible-collection-molecule/main/roles/init/files/init.yml"
58+
test_collection_dir: "{{ test_dir }}/ci_testing/test_collection"
59+
test_role_dir: "{{ test_dir }}/ci_testing/test_collection"
60+
block:
61+
- name: Local work dir exists
62+
ansible.builtin.file:
63+
path: "{{ test_dir }}"
64+
state: directory
65+
66+
- name: Test with a collection
67+
block:
68+
- name: Test collection is created
69+
ansible.builtin.command:
70+
chdir: "{{ test_dir }}"
71+
cmd: ansible-galaxy collection init ci_testing.test_collection
72+
creates: "{{ test_collection_dir }}"
73+
74+
- name: Molecule scenario dir exists for collection
75+
ansible.builtin.file:
76+
path: "{{ test_collection_dir }}/molecule/default"
77+
state: directory
78+
79+
- name: Molecule init playbook exists for collection
80+
ansible.builtin.command:
81+
chdir: "{{ test_collection_dir }}"
82+
cmd: wget -P molecule/default {{ test_init_wget_path }}
83+
creates: "{{ test_collection_dir }}/molecule/default/init.yml"
84+
85+
- name: Run init playbook on collection
86+
# TODO: Actually check idempotence on this
87+
ansible.builtin.command:
88+
chdir: "{{ test_collection_dir }}"
89+
cmd: ansible-playbook molecule/default/init.yml
90+
changed_when: false
91+
92+
- name: Test with a role
93+
block:
94+
- name: Test role is created
95+
ansible.builtin.command:
96+
chdir: "{{ test_dir }}"
97+
cmd: ansible-galaxy role init test_role
98+
creates: "{{ test_role_dir }}"
99+
100+
- name: Molecule scenario dir exists for role
101+
ansible.builtin.file:
102+
path: "{{ test_role_dir }}/molecule/default"
103+
state: directory
104+
105+
- name: Molecule init playbook exists for role
106+
ansible.builtin.command:
107+
chdir: "{{ test_role_dir }}"
108+
cmd: wget -P molecule/default {{ test_init_wget_path }}
109+
creates: "{{ test_role_dir }}/molecule/default/init.yml"
110+
111+
- name: Run init playbook on role
112+
# TODO: Actually check idempotence on this
113+
ansible.builtin.command:
114+
chdir: "{{ test_role_dir }}"
115+
cmd: ansible-playbook molecule/default/init.yml
116+
changed_when: false
117+
118+
- name: Test with a monolith
119+
block:
120+
# TODO: Find/create a public monolith repo we can use to test this
121+
- name: "TODO: Write monolith test"
122+
ansible.builtin.debug:
123+
msg: This test hasn't been written! You get a cookie if you can fix that! 🍪
52124

molecule/default/create.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
docker_platform_image: "{{ item.image }}"
1212
docker_platform_systemd: "{{ item.systemd | default(false) }}"
1313
docker_platform_modify_image: "{{ item.modify_image | default(false) }}"
14+
docker_platform_modify_image_buildpath: "{{ item.modify_image_buildpath | default(molecule_ephemeral_directory + '/build') }}"
1415
docker_platform_privileged: "{{ item.privileged | default (false) }}"
16+
docker_platform_hostvars: "{{ item.hostvars | default({}) }}"
1517
docker_platform_state: present
18+
when: item.type == 'docker'
1619
loop: "{{ molecule_yml.platforms }}"
1720
loop_control:
1821
label: item.name
@@ -31,3 +34,29 @@
3134
ansible.builtin.debug:
3235
msg: "{{ result.stdout }}"
3336

37+
- name: Load system facts
38+
ansible.builtin.setup:
39+
filter:
40+
- ansible_service_mgr
41+
42+
- name: Check on Systemd
43+
block:
44+
- name: Wait for systemd to complete initialization.
45+
ansible.builtin.command: systemctl is-system-running
46+
register: systemctl_status
47+
until: >
48+
'running' in systemctl_status.stdout or
49+
'degraded' in systemctl_status.stdout
50+
retries: 30
51+
delay: 5
52+
changed_when: false
53+
failed_when: systemctl_status.rc > 1
54+
55+
- name: Check systemd status
56+
ansible.builtin.assert:
57+
that:
58+
- systemctl_status.stdout == 'running'
59+
fail_msg: Systemd-enabled container does not have a healthy Systemd!
60+
success_msg: Systemd is running
61+
when: ansible_service_mgr == 'systemd'
62+

molecule/default/molecule.yml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,27 @@ driver:
88
managed: true
99
login_cmd_template: 'docker exec -ti {instance} bash'
1010
platforms:
11-
- name: instance
12-
image: geerlingguy/docker-${MOLECULE_GEERLINGGUY_DISTRO:-rockylinux9}-ansible:latest
11+
- name: docker-rockylinux9
12+
type: docker
13+
image: geerlingguy/docker-rockylinux9-ansible:latest
1314
systemd: True
1415
modify_image: False
1516
privileged: False
17+
hostvars: {}
18+
- name: docker-fedora39
19+
type: docker
20+
image: geerlingguy/docker-fedora39-ansible:latest
21+
systemd: True
22+
modify_image: False
23+
privileged: False
24+
hostvars: {}
25+
- name: docker-ubuntu2204
26+
type: docker
27+
image: geerlingguy/docker-ubuntu2204-ansible:latest
28+
systemd: True
29+
modify_image: False
30+
privileged: False
31+
hostvars: {}
1632
provisioner:
1733
name: ansible
1834
log: True

0 commit comments

Comments
 (0)