Overview
Creating your own role template is a simple 3-step process:
- Copy molecule templates
- Customize them
- Call molecule with your templates
Copy molecule templates
The easiest way to get started is to simply copy the existing molecule template folders. They’re based on a templating system called Cookiecutter.
Clone the molecule repository (or alternatively search for the templates in your local python packages path: find ${search_base} -type d -name '*cookiecutter*'
)
# create our template folder
CUSTOM_TEMPLATE_DIR="corp-molecule-templates"
mkdir -p "$HOME/projects/${CUSTOM_TEMPLATE_DIR}"
# copy templates
git clone https://github.com/ansible/molecule.git
cp -r ./molecule/molecule/cookiecutter "$HOME/projects/${CUSTOM_TEMPLATE_DIR}"
Customization
Then modify them as you see fit - here are a number of suggestions:
- add company and department/team information
- add copyright or set software license
- add CI relevant files
- add .gitignore file
- offer sensible defaults for the platforms and galaxy tags in the metadata
Cookiecutter uses the file cookiecutter.json
to set default values and prompts.
# cd "$HOME/projects/${CUSTOM_TEMPLATE_DIR}" && find . -name "*.json"
./cookiecutter/role/cookiecutter.json
./cookiecutter/scenario/driver/openstack/cookiecutter.json
./cookiecutter/scenario/driver/docker/cookiecutter.json
./cookiecutter/scenario/driver/azure/cookiecutter.json
./cookiecutter/scenario/driver/vagrant/cookiecutter.json
./cookiecutter/scenario/driver/delegated/cookiecutter.json
./cookiecutter/scenario/driver/gce/cookiecutter.json
./cookiecutter/scenario/driver/lxc/cookiecutter.json
./cookiecutter/scenario/driver/lxd/cookiecutter.json
./cookiecutter/scenario/driver/ec2/cookiecutter.json
./cookiecutter/scenario/verifier/goss/cookiecutter.json
./cookiecutter/scenario/verifier/inspec/cookiecutter.json
./cookiecutter/scenario/verifier/testinfra/cookiecutter.json
./cookiecutter/molecule/cookiecutter.json
Cookiecutter templates are Jinja capable which means you can modify input values (reference)…
{
"project_name": "My New Project",
"project_slug": "{{ cookiecutter.project_name|lower|replace(' ', '-') }}",
"project_slug2": "{{ cookiecutter.project_name.lower().replace(' ', '_') }}",
"pkg_name": "{{ cookiecutter.project_slug|replace('-', '') }}"
}
… or even define collections of nested objects in your cookiecutter.json and iterate over them (reference):
{
"project_slug": "new_project",
"file_types": {
"png": {
"name": "Portable Network Graphic",
"library": "libpng",
"apps": [
"GIMP"
]
},
"bmp": {
"name": "Bitmap",
"library": "libbmp",
"apps": [
"Paint",
"GIMP"
]
}
}
}
The above file_type dictionary variable creates cookiecutter.file_types, which can be used like this:
{% for extension, details in cookiecutter.file_types|dictsort %}
<dl>
<dt>Format name:</dt>
<dd>{{ details.name }}</dd>
<dt>Extension:</dt>
<dd>{{ extension }}</dd>
<dt>Applications:</dt>
<dd>
<ul>
{% for app in details.apps -%}
<li>{{ app }}</li>
{% endfor -%}
</ul>
</dd>
</dl>
{% endfor %}
Invoke your template with Molecule
$ molecule init template --help
Usage: molecule init template [OPTIONS]
Initialize a new role from a Cookiecutter URL.
Options:
--url TEXT URL to the Cookiecutter templates repository.
[required]
--no-input / --input Do not prompt for parameters and only use
cookiecutter.json for content. (false)
-r, --role-name TEXT Name of the role to create.
--help Show this message and exit.
A real-world invocation looks like this:
# interactive - will ask for confirmation of values defined in cookiecutter.json
molecule init template --url "$HOME/projects/${CUSTOM_TEMPLATE_DIR}/cookiecutter/role" --role-name "ansible-role-apache-permissions"
# unattended - uses the values from cookiecutter.json
molecule init template --url "$HOME/projects/${CUSTOM_TEMPLATE_DIR}/cookiecutter/role" --role-name "ansible-role-apache-permissions" --no-input
From now on, remember to use your template when working on a new role or scenario to save time and standardize your roles.