Initial Import

This commit is contained in:
2024-01-06 23:02:10 +13:00
commit 80d6d66f43
23 changed files with 399 additions and 0 deletions

55
README.md Normal file
View File

@@ -0,0 +1,55 @@
# Ansible Role Cookiecutter #
This is a [cookiecutter project] for creating [Ansible roles]. It includes tests using [Molecule] and [YAML Lint] to work with [Azure Pipelines].
To use this, first install `cookiecutter`, then run `cookiecutter git+https://hub.cybercinch.nz/guisea/cookiecutter-ansible-role` and answer the prompts.
## Development Workflow ##
Molecule uses Docker by default to spin up local containers for testing. I have created [several containers] work well for testing Ansible roles. Feel free to use them or change to your own in `molecule/default/molecule.yml`.
To test your role, you first need to install Molecule by running `pip install molecule`, or using your package manager of choice. You may also `pip install molecule[docker]` to also install the `docker` Python library, or `pip install molecule[lint]` to install `ansible-lint`, `yamllint`, and `flake8`.
Next, run `molecule test`. This will run the entire default test scenario, which creates a test container, runs the linters, runs the role twice, then destroys the container.
I frequently find I want to interact with the test instance rather than destroying it. To create a test instance, run your role, then leave the container running, run `molecule converge`. You can then interact with the container using `molecule login`. To rerun your role against the existing container, just run `molecule converge` again.
Once you are done with the container, run `molecule destroy` to remove it.
### Customizing the Test ###
The default scenario runs `molecule/default/converge.yml`. You can customize this playbook to suit your needs.
The `molecule.yml` file is setup to accept three environment variables:
`MOLECULE_DISTRIBUTION`: controls the distribution to test against
`MOLECULE_COMMAND`: the command to run inside the container
`MOLECULE_PLAYBOOK`: the name of the playbook to run
Valid values for `MOLECULE_DISTRIBUTION` based on how I name my test containers are:
- centos7
- centos8 (the default)
- ubuntu16
- ubuntu18
- ubuntu20
- debian9
- debian10
- fedora30
- fedora31
For example, to test your role on Debian 10, run `env MOLECULE_DISTRIBUTION=debian10 molecule test`.
## Thanks ##
A special thank you to [Jeff Geerling] for being a trailblazer with Molecule (and Ansible role testing in general). I would be lost without his amazing work.
[cookiecutter project]: https://github.com/audreyr/cookiecutter
[Ansible roles]:https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html
[molecule]: https://molecule.readthedocs.io
[Ansible Lint]: https://docs.ansible.com/ansible-lint/
[YAML Lint]:https://yamllint.readthedocs.io/en/stable/
[Azure Pipelines]: https://dev.azure.com
[several containers]: https://quay.io/user/samdoran
[Jeff Geerling]: https://www.jeffgeerling.com/blog/2018/testing-your-ansible-roles-molecule
[linting behavior changed]: https://molecule.readthedocs.io/en/latest/configuration.html#lint

14
cookiecutter.json Normal file
View File

@@ -0,0 +1,14 @@
{
"role_title": "{{ cookiecutter.role_title }}",
"role_name": "{{ cookiecutter.role_title | lower | replace(' ','_') }}",
"repo_name": "ansible-role-{{ cookiecutter.role_name }}",
"branch_name": "main",
"author": "Aaron Guise",
"short_description": "This role does amazing things",
"company": "Acme, Inc.",
"galaxy_username": "{{ cookiecutter.author | lower | replace(' ', '') }}",
"azp_username": "{{ cookiecutter.author | lower | replace(' ', '') }}",
"azp_branch": "main",
"license": "Apache 2.0",
"min_ansible_version": "2.9"
}

View File

@@ -0,0 +1,9 @@
#!/usr/bin/env python
import os
for dirpath, dirs, files in os.walk(os.getcwd()):
if 'keep' in files:
for file in files:
path = os.path.join(dirpath, file)
os.unlink(path)

View File

@@ -0,0 +1,28 @@
matrix:
include:
- MOLECULE_DISTRO: centos7
- MOLECULE_DISTRO: almalinux8
clone:
git:
image: woodpeckerci/plugin-git
settings:
recursive: true
submodule_update_remote: true
when:
event: [ cron ]
steps:
test:
name: Test on ${MOLECULE_DISTRO}
image: guisea/ansible-molecule
pull: true
environment:
PY_COLORS: '1'
ANSIBLE_FORCE_COLOR: '1'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
commands:
- molecule test --scenario-name ${MOLECULE_SCENARIO:-default}
when:
event: [ cron ]

View File

@@ -0,0 +1,43 @@
clone:
git:
image: woodpeckerci/plugin-git
settings:
recursive: true
submodule_update_remote: true
when:
event: [ push, manual ]
steps:
ansible-lint:
group: test
name: "Lint: Ansible-lint"
image: guisea/ansible-molecule
environment:
PY_COLORS: '1'
ANSIBLE_FORCE_COLOR: '1'
commands:
- ansible-lint -c ".ansible-lint"
when:
event: [ push, manual ]
yamllint:
group: test
name: "Lint: Yamllint"
image: guisea/ansible-molecule
commands:
- yamllint -f colored .
when:
event: [ push, manual ]
ntfy:
image: codeberg.org/l-x/woodpecker-ntfy
settings:
url: https://ntfy.cybercinch.nz/ci-status
title: "Lint failed for ${CI_REPO_NAME}"
priority: urgent
icon: https://woodpecker-ci.org/img/logo.svg
tags: robot,warning,rotating_light,${CI_BUILD_EVENT},${CI_REPO_NAME}
message: >
📝 Commit by ${CI_COMMIT_AUTHOR} on ${CI_COMMIT_BRANCH}:
${CI_COMMIT_MESSAGE}
when:
event: [ push, manual ]
status: [ failure ]

View File

@@ -0,0 +1,46 @@
matrix:
include:
# - MOLECULE_DISTRO: almalinux8
- MOLECULE_DISTRO: almalinux9
clone:
git:
image: woodpeckerci/plugin-git
settings:
recursive: true
submodule_update_remote: true
when:
event: [ push, manual ]
steps:
test:
name: Test on ${MOLECULE_DISTRO}
image: guisea/ansible-molecule
pull: true
environment:
PY_COLORS: '1'
ANSIBLE_FORCE_COLOR: '1'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
commands:
- molecule test --scenario-name ${MOLECULE_SCENARIO:-default}
when:
event:
- push
- manual
ntfy:
image: codeberg.org/l-x/woodpecker-ntfy
settings:
url: https://ntfy.cybercinch.nz/ci-status
title: "Test failed for ${CI_REPO_NAME} - Distro: ${MOLECULE_DISTRO} Scenario: ${MOLECULE_SCENARIO:-default}"
priority: urgent
icon: https://woodpecker-ci.org/img/logo.svg
tags: robot,warning,rotating_light,${CI_BUILD_EVENT},${CI_REPO_NAME}
message: >
📝 Commit by ${CI_COMMIT_AUTHOR} on ${CI_COMMIT_BRANCH}:
${CI_COMMIT_MESSAGE}
when:
event: [ push, manual ]
status: [ failure ]
depends_on:
- lint

View File

@@ -0,0 +1,16 @@
skip_clone: true
steps:
ntfy-success:
image: codeberg.org/l-x/woodpecker-ntfy
settings:
url: https://ntfy.cybercinch.nz/ci-status
title: Build succeeded on ${CI_REPO_NAME}
priority: urgent
icon: https://woodpecker-ci.org/img/logo.svg
tags: robot,white_check_mark,${CI_BUILD_EVENT},${CI_REPO_NAME}
message: >
Test success when run by cron for ${CI_REPO_NAME}.
depends_on:
- "cron"
runs_on: [ success ]

View File

@@ -0,0 +1,20 @@
skip_clone: true
steps:
ntfy:
image: codeberg.org/l-x/woodpecker-ntfy
settings:
url: https://ntfy.cybercinch.nz/ci-status
title: "Build completed for ${CI_REPO_NAME}"
priority: urgent
icon: https://woodpecker-ci.org/img/logo.svg
tags: robot,tada,white_check_mark,${CI_BUILD_EVENT},${CI_REPO_NAME}
message: >
📝 Commit by ${CI_COMMIT_AUTHOR} on ${CI_COMMIT_BRANCH}:
${CI_COMMIT_MESSAGE}
when:
event: [ push, manual ]
status: [ success ]
depends_on:
- lint
- test

View File

@@ -0,0 +1,16 @@
skip_clone: true
steps:
ntfy-failed:
image: codeberg.org/l-x/woodpecker-ntfy
settings:
url: https://ntfy.cybercinch.nz/ci-status
title: Build failed on ${CI_REPO_NAME}
priority: urgent
icon: https://woodpecker-ci.org/img/logo.svg
tags: robot,rotating_light,no_entry,${CI_BUILD_EVENT},${CI_REPO_NAME}
message: >
Test failed when run by cron for ${CI_REPO_NAME}.
depends_on:
- "cron"
runs_on: [ failure ]

View File

@@ -0,0 +1,36 @@
.PHONY: clean virtualenv lint test docker dist dist-upload
clean:
find . -name '*.py[co]' -delete
virtualenv:
virtualenv --prompt '|> ansible-role-common <| ' .venv
.venv/bin/pip install --upgrade pip
.venv/bin/pip install -r requirements.txt
.venv/bin/ansible-galaxy collection install -r requirements.yml
@echo
@echo "VirtualENV Setup Complete. Now run: source .venv/bin/activate"
@echo
test:
for distro in almalinux9 ; do \
MOLECULE_DISTRO=$$distro molecule test --all ; \
done
lint:
@echo "Linting with Ansible-lint"
@echo
ansible-lint -c ".ansible-lint" --exclude ".venv"
@echo
@echo "Linting with Yamllint"
@echo
yamllint .
@echo
dist: clean
rm -rf dist/*
python setup.py sdist
python setup.py bdist_wheel
dist-upload:
twine upload dist/*

View File

@@ -0,0 +1,35 @@
{{ cookiecutter.role_title | title }}
=========
[![Galaxy](https://img.shields.io/badge/galaxy-{{ cookiecutter.galaxy_username }}.{{ cookiecutter.role_name }}-blue.svg?style=flat)](https://galaxy.ansible.com/{{ cookiecutter.galaxy_username }}/{{ cookiecutter.role_name }})
[![Build Status](https://dev.azure.com/{{ cookiecutter.azp_username }}/{{ cookiecutter.repo_name }}/_apis/build/status/CI?branchName={{ cookiecutter.azp_branch }})](https://dev.azure.com/{{ cookiecutter.azp_username }}/{{ cookiecutter.repo_name }}/_build/latest?definitionId=3&branchName={{ cookiecutter.azp_branch }})
A brief description of the role goes here.
Requirements
------------
Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
Role Variables
--------------
| Name | Default Value | Description |
|-------------------|---------------------|----------------------|
| `` | `` | |
Dependencies
------------
A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
Example Playbook
----------------
- hosts: all
roles:
- {{ cookiecutter.galaxy_username }}.{{ cookiecutter.role_name }}
License
-------
{{ cookiecutter.license }}

View File

@@ -0,0 +1 @@

View File

View File

@@ -0,0 +1,17 @@
galaxy_info:
role_name: {{ cookiecutter.role_name | lower | replace(' ', '_') }}
author: {{ cookiecutter.author }}
description: {{ cookiecutter.short_description }}
company: {{ cookiecutter.company }}
license: {{ cookiecutter.license }}
min_ansible_version: {{ cookiecutter.min_ansible_version }}
platforms:
- name: EL
versions:
- 8
galaxy_tags:
- system
dependencies: []

View File

@@ -0,0 +1,7 @@
---
- name: Converge
hosts: all
tasks:
- name: "Include common"
include_role:
name: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}"

View File

@@ -0,0 +1,18 @@
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: {{ cookiecutter.role_name }}-test-${MOLECULE_DISTRO:-almalinux8}
image: "cybercinch/docker-${MOLECULE_DISTRO:-almalinux8}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true
pre_build_image: true
provisioner:
name: ansible
env:
MOLECULE_NO_LOG: true

View File

@@ -0,0 +1,6 @@
- name: Verify role
hosts: all
become: yes
gather_facts: no
tasks: []

View File

@@ -0,0 +1,6 @@
collections:
- name: ansible.posix
- name: community.general
- name: community.docker
roles: []

View File

@@ -0,0 +1,25 @@
extends: default
ignore: .cache
rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
comments-indentation: disable
document-start: disable
line-length: disable
truthy:
allowed-values:
- 'yes'
- 'on'
- 'true'
- 'True'
- 'no'
- 'off'
- 'false'
- 'False'
check-keys: no

View File

@@ -0,0 +1 @@