Skip to main content

DocSmith for Ansible: automating role documentation (using argument_specs.yml)

Project description

DocSmith for Ansible

Automating role documentation (using argument_specs.yml)

DocSmith is a documentation generator. It reads a role's meta/argument_specs.yml and produces up‑to‑date variable descriptions for the README.md as well as inline comment blocks for defaults/main.yml (or other role entry-point files). It works with roles in both stand‑alone form and within collections.



Logo: DocSmith for Ansible

⭐ Found this useful? Support open-source and star this project:

GitHub repository


Table of contents

Demo

Roles using DocSmith

Screenshots

Screenshot: DocSmith CLI, help   Screenshot: DocSmith CLI, validate; Results for foundata.sshd.run   Screenshot: DocSmith CLI, generate dry run; Results for foundata.sshd.run   Screenshot: DocSmith CLI, generate; Results for foundata.sshd.run   Screenshot: Part of a README.md ToC, generated with DocSmith   Screenshot: Part of a README.md's main content describing role variables, generated with DocSmith

Features

  • Efficient and simple: Uses the argument_specs.yml from Ansible's built‑in role argument validation as the single source of truth, generating human‑readable documentation in multiple places while maintaining just one file.
  • Built-in validation: Verifies that argument specs are complete, correct, and in sync with entry-point defaults/.
  • Automation‑friendly: Works seamlessly in CI/CD pipelines and pre‑commit hooks.
  • Supports Markdown and reStructuredText.
  • Understands Ansible markup: Constructs like C(...), O(...), V(...) or M(...) in descriptions are converted to the target format.

Installation

PyPI package version

DocSmith needs Python ≥ v3.11. It is available on PyPI and can be installed with the package manager of your choice.

Using uv (recommended):

uv tool install ansible-docsmith

Using pip or pipx:

pip install ansible-docsmith
pipx install ansible-docsmith

Usage

Preparations

  1. If not already existing, simply create an argument_specs.yml for Ansible’s role argument validation. Try to add description: to your variables. The more complete your specification, the better the argument validation and documentation.
  2. Add simple markers in your role's README.md where DocSmith shall maintain the human-readable documentation. All content between these markers will be removed and updated on each ansible-docsmith generate run:
    <!-- ANSIBLE DOCSMITH MAIN START -->
    <!-- ANSIBLE DOCSMITH MAIN END -->
    
    where the variable descriptions shall be placed (mandatory) and
    <!-- ANSIBLE DOCSMITH TOC START -->
    <!-- ANSIBLE DOCSMITH TOC END -->
    
    for putting list entries for a table of contents (ToC) (optional). These list only the DocSmith-managed variable documentation and are designed to be placed inside a hand-written ToC list. Alternatively, use
    <!-- ANSIBLE DOCSMITH TOC-FULL START -->
    <!-- ANSIBLE DOCSMITH TOC-FULL END -->
    
    to generate a complete ToC of all headings of the README, including hand-written ones (optional). Headings with an explicit anchor (like ## Usage<a id="usage"></a>) are linked exactly; for other headings, the anchor is derived from the heading text and validate emits a notice, as the derivation cannot be guaranteed to match your rendering platform for exotic titles.

That's it. The entry-point variable files below the /defaults directory of your role do not need additional preparations. The tool will automatically (re)place formatted inline comment blocks above variables defined there.

Example files:

  • Markdown: README.md
  • reStructuredText: README.rst (difference to Markdown: .. comments, .. contents:: **Table of Contents** directive)

Generate or update documentation

Basic usage:

# Safely preview changes without writing to files. No modifications are made.
ansible-docsmith generate /path/to/role --dry-run

# Check whether the documentation is up to date without writing files:
# exit code 1 (and a diff) if a run would change anything, 0 otherwise.
# Useful for CI/CD pipelines and pre-commit hooks.
ansible-docsmith generate /path/to/role --check

# Generate / update README.md and comments in entry-point files (like defaults/main.yml)
ansible-docsmith generate /path/to/role

# Show help
ansible-docsmith --help
ansible-docsmith generate --help

Advanced parameters:

# Generate / update only the README.md, skip comments for variables in
# entry-point files (like defaults/main.yml).
ansible-docsmith generate /path/to/role --no-defaults

# Generate / update only the comments in entry-point files (like defaults/main.yml),
# skip README.md
ansible-docsmith generate /path/to/role --no-readme

# Do not document nested options ("dict attributes") in the comments of
# entry-point files (like defaults/main.yml)
ansible-docsmith generate /path/to/role --no-defaults-comments-nested

# Verbose output for debugging
ansible-docsmith generate /path/to/role --verbose

Collections

generate and validate also accept a collection path. All roles found via roles/*/meta/argument_specs.yml are then processed like single roles. Additionally, DocSmith maintains role-named marker sections in the collection's README.md (or README.rst), so the collection README can reference the role documentation without manual upkeep:

### My role: foo

<!-- ANSIBLE DOCSMITH TOC foo START -->
<!-- ANSIBLE DOCSMITH TOC foo END -->

### My role: bar

<!-- ANSIBLE DOCSMITH TOC-FULL bar START -->
<!-- ANSIBLE DOCSMITH TOC-FULL bar END -->

<!-- ANSIBLE DOCSMITH MAIN bar START -->
<!-- ANSIBLE DOCSMITH MAIN bar END -->
  • TOC <role> lists the role's variable documentation, TOC-FULL <role> lists all headings of the role's README. Both link into roles/<role>/README.* using relative paths.
  • MAIN <role> embeds the role's complete variable documentation directly in the collection README. All anchors get a <role>- prefix so several embedded roles cannot collide on variable names. If a TOC <role> section exists in the same (Markdown) document, it links to the embedded documentation instead of the role's README.
  • Role-named sections are opt-in per role: roles without markers are simply not referenced in the collection README (validate emits a notice listing them). Markers referencing an unknown role produce a warning.
ansible-docsmith generate /path/to/collection
ansible-docsmith validate /path/to/collection
ansible-docsmith generate /path/to/collection --check

Validate argument_specs.yml and /defaults

# Validate argument_specs.yml structure as well as role entry-point files in /defaults/.
# These validation checks include:
#
# - ERROR:   Variables present in "defaults/" but missing from "argument_specs.yml".
# - ERROR:   Variables with "default:" values defined in "argument_specs.yml" but
#            missing from the entry-point files in "defaults/".
# - WARNING: Unknown keys in "argument_specs.yml".
# - WARNING: Invalid Ansible markup in descriptions (like "M()" without a FQCN).
# - NOTICE:  Potential mismatches, where variables are listed in "argument_specs.yml"
#            but not in "defaults/", for user awareness.
ansible-docsmith validate /path/to/role

# Treat warnings as errors (exit code 1). Useful for CI/CD pipelines and
# pre-commit hooks. Notices do not fail validation.
ansible-docsmith validate /path/to/role --strict

# Validate only parts of a role:
#
# Skip the README checks (markers and ToC). Useful when only maintaining
# comments in entry-point files.
ansible-docsmith validate /path/to/role --no-readme
# Skip the argument_specs.yml checks (consistency, unknown keys, ...).
# The file must still be parseable YAML.
ansible-docsmith validate /path/to/role --no-argument-specs

# Show help
ansible-docsmith --help
ansible-docsmith validate --help

# Verbose output for debugging
ansible-docsmith validate /path/to/role --verbose

Custom templates

You can customize the generated Markdown output by providing your own Jinja2 template. The rendered content will be inserted between the <!-- ANSIBLE DOCSMITH MAIN START --> and <!-- ANSIBLE DOCSMITH MAIN END --> markers in the role's README.md file.

# Use a custom template for README generation
ansible-docsmith generate /path/to/role --template-readme /path/to/custom-template.md.j2

# Combined with other options
ansible-docsmith generate /path/to/role --template-readme ./templates/my-readme.md.j2 --dry-run

Template files must use the .j2 extension (for example, simple-readme.md.j2) and follow Jinja2 syntax. Below is a basic example:

# {{ role_name | title }} Ansible Role

{% if has_options %}
## Role variables

{% for var_name, var_spec in options.items() %}
- **{{ var_name }}** ({{ var_spec.type }}): {{ var_spec.description }}
{% endfor %}
{% else %}
The role has no configurable variables.
{% endif %}

Check out the readme/default.md.j2 template that DocSmith uses as an advanced example with conditional sections. Copying this file is often the easiest way to get started.

Most important available template variables:

  • role_name: Name of the Ansible role.
  • has_options: Boolean indicating if variables are defined.
  • options: Dictionary of all role variables with their specifications.
  • entry_points: List of all Ansible role entry-point names.

Most important available Jinja2 filters:

  • ansible_escape: Escapes characters for Ansible/YAML contexts.
  • code_escape: Escapes content for code blocks.
  • format_default: Formats default values appropriately.
  • format_description: Formats multi-line descriptions.
  • format_table_description: Formats descriptions for table cells.

If you are creative, you may even maintain non-obvious parts of your README.md between the markers:

## Example Playbook

```yaml
[...]
- ansible.builtin.include_role:
    name: "{{ role_name }}"
  vars:
{% for var_name, var_spec in options.items() %}
{% if var_spec.default is not none %}
    {{ var_name }}: {{ var_spec.default }}
{% else %}
    # {{ var_name }}: # {{ var_spec.description }}
{% endif %}
{% endfor %}
```

## Author Information

{% if primary_spec.author %}
{% for author in primary_spec.author %}

- {{ author }}
{% endfor %}
{% endif %}

Licensing, copyright

Copyright (c) 2025, 2026 foundata GmbH (https://foundata.com)

This project is licensed under the GNU General Public License v3.0 or later (SPDX-License-Identifier: GPL-3.0-or-later), see LICENSES/GPL-3.0-or-later.txt for the full text.

The REUSE.toml file provides detailed licensing and copyright information in a human- and machine-readable format. This includes parts that may be subject to different licensing or usage terms, such as third-party components. The repository conforms to the REUSE specification. You can use reuse spdx to create a SPDX software bill of materials (SBOM).

REUSE status

Trademarks

  • Red Hat® is a trademark of Red Hat, Inc., registered in the US and other countries.
  • Ansible® is a trademark of Red Hat, Inc., registered in the US and other countries.

Author information

This project was created and is maintained by foundata. If you like it, you might buy us a coffee.

The Ansible DocSmith project is not associated with Red Hat nor the Ansible project.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ansible_docsmith-2.1.0.tar.gz (62.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ansible_docsmith-2.1.0-py3-none-any.whl (68.6 kB view details)

Uploaded Python 3

File details

Details for the file ansible_docsmith-2.1.0.tar.gz.

File metadata

  • Download URL: ansible_docsmith-2.1.0.tar.gz
  • Upload date:
  • Size: 62.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ansible_docsmith-2.1.0.tar.gz
Algorithm Hash digest
SHA256 8417da1b7c7464729a032ae560906423d2244380c6cf7b3cf3a6f1dac907304f
MD5 5b71bf0dfef698ef74c3457d5c570984
BLAKE2b-256 6000a99f9b4e5bb5227e502829952bf68112c0a6429ec7a7a8c07378c9abe86c

See more details on using hashes here.

File details

Details for the file ansible_docsmith-2.1.0-py3-none-any.whl.

File metadata

  • Download URL: ansible_docsmith-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 68.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for ansible_docsmith-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f19e153f7fa4b0d4d33ba92cdbd1f6a74552ecdaf7a638de18853891f632f756
MD5 bfda6ccbfc9b63b77e5a82ad52952e5a
BLAKE2b-256 31ac8d92dafafe8f6de32aa3b870bd50dc84c661745671480d767ccb959152ee

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page