ansible / proposals

Repository for sharing and tracking progress on enhancement proposals for Ansible.
Creative Commons Zero v1.0 Universal
93 stars 19 forks source link

Define a standard way for roles and playbook documentation #19

Open tonk opened 8 years ago

tonk commented 8 years ago

Proposal: Define a standard way for roles and playbook documentation

Author: Ton Kersten @TonK

Date: 2016/06/21

I think the time is ripe to define and introduce a standard way for documenting playbooks and roles. Including the roles metadata.

At this moment in time everybody is creating a way to embed documentation in playbooks and roles. And everybody has their own way, which could break things like the Galaxy.

Problems

What problems exist that this proposal will solve?


---
"""
Playbook documentation in reStructuredText
"""
    - include: main.yml
      vars:
         var1: val1

Anything else?

We need to be aware that all Ansible commands that read roles or playbooks must be ware of the documentation strings and can ignore them.

bcoca commented 8 years ago

I'm against having this be rst/sphinx as it adds extra dependencies, current module docs are YAML.

The main docs are rst and we do use rst/sphinx to build the Ansible docsite, but this is not required for users.

Another caveat, python docstrings are not a thing in YAML, we would have to strip them for 'normal parsing'. Currently name: fields are the primary documentation of plays and tasks, this works because it is a YAML variable.

bcoca commented 8 years ago
    - name: Playbook documentation not in rst
      include: main.yml
      vars:
         var1: val1
tonk commented 8 years ago

OK. I don't realy mind something like plain YAML, but we then need a program to parse these doc-strings.

My final goal would be to have some kind of program to parse all doc-strings and create HTML or PDF. For those who do not want any dependencies plain text could be displayed.

bcoca commented 8 years ago

ansible-doc already parses module for documentation, I would be fine with extending that to get info from plays/roles

bcoca commented 8 years ago

ansible-playbook --list-tasks already provides a way to see the 'name docs', plays can also have name: in them, there is current limit to the field size.

tonk commented 8 years ago

I would like ansible-doc to be extended for playbook comments. Or a new command with that functionality. I'm open to all kind of suggestions, but I would like to have a good and standard way of documenting playbooks and roles, inline. So that there is no need for a README or something like that.

geerlingguy commented 8 years ago

Another +1 to not using rst for module/playbook docs. YAML can do inline comments, and also supports deeper docs through existing conventions (http://www.yaml.org/spec/1.2/spec.html#id2760395)... we just need to see what's the path of least resistance there.

I also think standardizing on Markdown or CommonMark, but allowing rst, might be the best way forward. Docs have to be extremely simple or many will completely ignore them/not maintain them, and rst is just involved enough, syntax-wise, and not in use in as many common places as MD that I don't think it should be the minimum standard.

Finally, with regard to no need for a README—especially with most SCM tools standardizing on displaying a README (e.g. GitLab, Redmine, GitHub, current Galaxy for roles, etc.), there's always going to be a need for a README, and it should be a good jumping-off point to other parts of the playbooks/roles.

tonk commented 8 years ago

Just a simple idea, in the playbook yaml allow a tag called documentation: (or doc: or whatever) and let the developer add CommonMark documentation.

Something like:

---
doc: >
    role: tralala
    author: tonk
    purpose: Show how documentation works

A simple Ansible doc module could extract all docs and display them neatly.

drybjed commented 8 years ago

Hi, just stumbled on this thread. Perhaps you will be interested in the solution the DebOps project uses for documentation? You can check the (partial) results at http://docs.debops.org/

The documentation is generated from .rst files located in the docs/ directory of each role by Sphinx, the default variables are converted from YAML to .rst using yaml2rst with RST syntax embedded as comments in the YAML file.

Some example roles that can show the source and results:

Let me see what you think about this solution. :-)

bcoca commented 8 years ago

I do like how debops does this, but I would like to add the ability of ansible-doc to also show these in the command line, which makes me balk a bit at the RST dependency (optional?).

bcoca commented 8 years ago

the docs/ dir in roles seems like a no brainer, the "docs in comment" is also fine, but I wish we could 'multiline comment'

drybjed commented 8 years ago

@bcoca I'm notsure why Markdown is so popular, have you considered switching to reStructuredText instead of using Markdown? I imagine that for smooth transition both would need to be supported. Ansible Galaxy should also support reStructuredText READMEs - if that happened, DebOps could completely eliminate Markdown files from its roles. Right now we use README.md because otherwise Galaxy rejects the imports...

drybjed commented 8 years ago

What do you mean by multiline comment? yaml2rst easily handles comments in multiple lines, with embedded code-block or other sections, lists, etc.

geerlingguy commented 8 years ago

I'm notsure why Markdown is so popular, have you considered switching to reStructuredText instead of using Markdown?

Because it's good enough: https://news.ycombinator.com/item?id=11292280

No matter what happens, we should at a minimum continue to support Markdown (and likely as the default). There's a reason .txt files are still a thing (because they're dead simple and work everywhere, forever), and markdown is kind of like the '.txt file of documentation' now (at least glancing around at pretty much every OSS project I've seen).

/me hides before bikeshedding exponentially accelerates :)

bcoca commented 8 years ago

I'm not proposing markdown at all, currently ansible-doc just uses YAML structures embeded in plugins, and it ignores/removes some 'rst' specific constructs.

bcoca commented 8 years ago

multline comments in YAML, which is NOT supported, every line needs a #

srgvg commented 8 years ago

Partly related idea: how about defining a standard way to let a role define which input parameters it needs and which export parameters it might set? The former might be a formalised way of defining what most people already put (partly or not) in defaults/main.yml

This might help to

Thoughts?

drybjed commented 8 years ago

For the export parameters that @srvg proposes, they would need to be persistent to achieve idempotency, when for example a different playbook does not include the role that has "export parameters".

For this reason, in DebOps I resorted to use Ansible local facts for this type of variables. The code to use these variables is a bit verbose, but it works fine.

One thing that could improve the support for local facts used this way is a method to sign and verify variables using a lookup plugin and a filter, respectively. Using these, Ansible cund ensure that the local facts it reads were set by a particular Ansible Controller and not tampered with.

srgvg commented 8 years ago

To be clear, when a user would choose to define this api, it would be within a specific setup (yes, for example the specific set of roles in the debops project). I don't see this being used in a very generic way for roles being published on galaxy (that would need a very tight set of rules, which I don't see happening there). It would however help people building things in a tightly controlled way within their own project.

To compare with what @drybjed does with local facts to ensure those facts being set, I would use them from a higher level app, that verifies if a set of input vars to a role are available, be it from inventory or as set facts from another previous role.

bcoca commented 8 years ago

for roles I was going to make a proposal that includes that info in the meta/main.yml, I think we should separate general docs from discoverable interfaces.

srgvg commented 8 years ago

@bcoca I was thinking of something in the meta dir yes. Perhaps even a separate file like meta/api.yml

tonk commented 8 years ago

I like the way this is going, but please be aware that my initial proposal was to create a standard for inline documentation in playbooks. We could then adapt the same technique to roles, or add extra files to roles.

abadger commented 8 years ago

Discussed at today's meeting. https://meetbot.fedoraproject.org/sresults/?group_id=ansible_public_core_meeting&type=team

There was a general consensus that a documentation standard and tooling to make it visible would be good but the problemspace doesn't seem well enough defined to implement something yet. We need some use cases to show what it is that we're trying to solve: Who is doing the documenting? Where are they doing it at? Who is reading the documentation? What do they need to learn from reading it?

With some use cases, the Proposal can be updated (just edit the initial comment to include use cases and a new idea of what a solution will look like) which will make it easier to see what we have to implement.

Note: One use case from linuxdynasty:

in my opinion the playbook documentation should be how the playbook works and what globals are set and why are some roles included etc.. and the role explains the tasks, includes, and vars usecase, is the other engineers on my time, use to read my confluence page and they felt it was and overwhelming amount of information But when I broke it down by playbooks, role, vars that made alot more sense to the team

Playbook author was writing it for other playbook maintainers on the team. The other maintainers needed a high level view of what the playbook did and in what ways they could customize it. Wherever the documentation was a written, the reader wants to be able to read the documentation in a single place.

jhawkesworth commented 8 years ago

Ok, well as a playbook author I want to document: The goal(s) / purposes of the playbook. Any optional parameters that can be set (with -e ) to change its behavior (I don't use tags right now but if I did I'd like to be to document what tags were relevant too).

In my case the users of the playbooks are deployment engineers and operational support staff. Deployment engineers maintain and modify playbooks, operational support stuff typically just run playbooks. The ulitimate aim for documenting is to give users who are not intimately familiar with a playbook the confidence to select the correct playbook and run it with a clear idea of what changes it will attempt.

ypid commented 8 years ago

Adding to the comments from @drybjed, there is now a Python3 tool (ref: yaml4rst) which can reformat defaults/main.yml files to prepare them for documentation generating using yaml2rst. If people want to give the docs format of @DebOps a try, it just got easier :wink:

linsomniac commented 7 years ago

Re: ReST, I want to like it, I've known David Goodger forever, but I find the advanced constructs getting in the way of simple use.

I could imagine something that just pulls out the comments into some sort of structure that an external tool then builds using ReST, PDF tools, Markdown, Sphinx, pandoc, whatever. Can the structure be something that is an external decision?

I was thinking about documentation yesterday and I imagined something that would build a structure using the ansible run information including the host, roles run, dependencies of the role. It would be neat to be able to provide a document to my coworkers that says "These roles are applied to this host" and "this role has been run on these hosts".

I was imagining a plugin that would build a directory structure or database that recorded what hosts a role was run on, and what roles ran on a host, maybe even with sequencing information (maybe time-based?) so that you could look at it and see who ran before who. With some rich documentation available for that role/task.

hypery2k commented 6 years ago

any progress on this?

gundalow commented 6 years ago

@hypery2k nothing that I'm aware of.

Some thoughts to get this moving...

I'd suggest we move the discussion. Away from implementation details (RST, markdown, yaml) and just focus on what we've like the rendered documentation to have included, once that's agreed we can work backwards through possible implementations.

Would it just be tasks that have documentation? Is there anything special needed to link from an include to the documentation for what's been included?

ymartin59 commented 6 years ago

I come from Perl and my reference is POD format with perldoc tool: https://perldoc.perl.org/perlpod.html which allows to provide a man page like documentation from the single script file itself - but also to technically document reusable code (functions, classes with methods)

My expectations are: to be able to document

For playbook/role maintainers, it is more obvious to document variable "inline" where it is set, to reduce risk to miss one or add variable without documenting it (wherever "elsewhere" is expected)

Inspired from perl/POD, I imagine a tool that can extract documentation parts and/or comments from playbook/role YAML files (tasks, defaults, handler) and generate some kind of human readable "man page" with synopsis, preconditions, aims, usage examples, variables, tags, impacted services

Just my opinion and ideas. Hope this helps

tonk commented 6 years ago

@ymartin59 That is what I mean, but it should never break YAML. So the documentation should be either YAML syntax (multiline variable) or comment with start or end-tags or special docu signs (like #@ or similar)

walterdolce commented 5 years ago

Interesting discussion. I think READMEs are a must have for roles. Whether or not those are automatically generated or what format they follow, I don't personally mind.

Here's what I value/look for when it comes to looking at other people's roles is the following:

When it comes to looking at the code directly within a 3rd party role, I value var/tasks files which don't have many comments on them. For example:

With regards to a role tasks, I am not sure. If it's true that a role would/should do one thing and do it well (i.e. only install Apache, or PHP, or MySQL, etc), then one would expect to have only tasks with logic to achieve that goal. And if so, why document it? The variables would be the documentation explaining the behaviour of the role['s tasks], wouldn't it?

With regards to how to document playbooks, I am also not sure. Playbooks are a collection of roles and tasks in the end. So perhaps having documentation on the variables that can be used could be enough. They are the ones which will drive the behaviour of the overall playbook and tasks/roles defined in it.

In general, I tend to follow geerlingguy's way of documenting roles as is very concise, not noisy. On the other hand, drybjed's way of documenting roles is really good and very comprehensive . But it seems a lot of work and when I take a peek inside the variable/tasks files I feel comments distract me a lot.

Hope this helps shaping things up around the future standard for this kind of documentation.

lukepafford commented 5 years ago

Thinking slightly outside the box

While i think a standard documentation interface would absolutely be beneficial (and is something I've wanted for a long time), I think that we already have a better solution to our real problem: Specifying required role variables

Writing Ansible is so easy (and admittedly sometimes a bit fun) that I don't want to use someone elses role unless it is also just as easy to use. This means I don't want to read any docs to learn how to use a role, I should just be able to use it. I've personally found the technique of asserting your required variables to be extremely effective in making a role that is highly flexible through use of variables, yet still easy to use by someone who isn't familiar with it.

Don't know how to use the role? It doesn't matter, just run it, and if you are missing any required variables, then the role should plainly tell you what it needs to make it happy.

Pattern

You can add as much documentation as you want inside of the fail_msg and success_msg options, and you keep your docs in the same place as your code.

decentral1se commented 5 years ago

@lukepafford regarding having something "native" to specify these vars in the meta/main.yml without having to do all this assertion boilerplate, please see https://github.com/ansible/proposals/issues/39#issuecomment-467030338. I haven't been following up on that lately but it would be nice to see people making a move there. "role spec" is the way forward for having a clear required variables API.

RE: this ticket and the situation in general - we need to push this forward to inform the standardisation process back in core land (RE: https://github.com/ansible/proposals/issues/19#issuecomment-240776376). My contribution (for now) is the freshly cut https://github.com/pycontribs/ansible-readme.

ssbarnea commented 4 years ago

I do agree with @decentral1se about using meta.yaml to document arguments. it does make a lot of sense. Still there is the aspect of extra text explaining what a role does, which most people would want to put inside a README.md file at the root of the folder (sphinx can load md too, which is more popular and less complex than sphinx).

But having documentation split in two is not really helping with creating a good user experience.

I hope some Ansible cores will step in and help use pick a direction. Help is needed here not so much about implementation but more about deciding on how it should work.

PS. Theoretically we could parse meta.yaml and display it as a documentation in any format. In fact we could even make the file executable and put a shebang that does that. Ruamel is good at reading comments so is technically possible. Maybe if the meta.yaml would generate the readme when run we can have that duplication. The readme would be always generated from meta.yaml, but also stored in repo, for convenience. We would still have a single place to write documentation. Having arguments documented in YAML means that we could even detect at runtime if someone missed to call a role without undefined arguments that where required.

geerlingguy commented 4 years ago

Attaching https://github.com/ansible/galaxy/issues/2225 here — that's a similar issue in the ansible/galaxy repo suggestion module/plugin docs be rendered for Collections. It would be nice to have a uniform standard for docs, and also to have a central place for the docs to be rendered.

vsadhav02 commented 4 years ago

Is there way to just get example section of ansible-doc for a particular module? I usually want to see example section of documentation. There is -s flag to get snippet but may be have -e flag to get to examples section like below

ansible-doc -e ios_facts

bcoca commented 3 years ago

@vsadhav02 no, but you can use --json to get a data structure and then use JSON tools to filter out the other keys

bcoca commented 3 years ago

set 'in progress' as role arg_spec is a partial implementation of this idea and it shipped in 2.11

bcoca commented 2 days ago

Role argument specs https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html#specification-format

Warkdev commented 2 days ago

Role argument specs https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html#specification-format

Which is good and very great but it doesn't solve the galaxy import error that requires a readme.md for each role when uploading collections.

Either galaxy needs to enforce that and use it as source documentation or readme's :)

bcoca commented 2 days ago

specs help, but do not cover all possible docs on roles, also galaxy falls under a different team and any requests for galaxy should be done at https://github.com/ansible/galaxy/issues

briantist commented 2 days ago

Which is good and very great but it doesn't solve the galaxy import error that requires a readme.md for each role when uploading collections.

Either galaxy needs to enforce that and use it as source documentation or readme's :)

I might suggest the workaround of having a README that consists of only a link to the published Ansible documentation for the role (which comes from the argspec). If your collection is not in the ansible docsite, consider generating and publishing the docs in your collection's CI.