Role names in collections should be able to begin with a underscore

According to the Collection structure chapter of the docs:

Role names are now limited to contain only lowercase alphanumeric characters, plus _ and start with an alpha character.

However, I’ve observed that role names can start with an underscore _ character without causing any issues. I have tried this with Ansible versions 2.9, 2.10, 2.11, 2.12, 2.13, 2.14, 2,15, 2.16 and 2.17, and none of them had problems consuming a role with such a name. Ansible Galaxy also imports the role without any issues.

I understand that a role name like this might not be aesthetically pleasing, but there is a good reason for it. We recently added an Ansible role for common shared tasks to the prometheus ansible collection. The role is named _common (fqcn prometheus.prometheus._common) to distinguish it from the other roles in the collection, as it is an internal role that’s only supposed to be used by the other roles and not directly by a user.

Originally posted this as a issue at Role names should be able to begin with a underscore. · Issue #2035 · ansible/ansible-documentation · GitHub but posting it here as well by the suggestion of @samccann

1 Like

You’re not the only one using roles whose name starts with an underscore, community.sops has an internal role as well: community.sops/roles at main · ansible-collections/community.sops · GitHub

(Leading underscores used to indicate deprecated content in Ansible 2.9 and before, still do in ansible-core’s internal collection ansible.builtin I think, and for some time ansible-core’s tooling couldn’t decide what a leading underscore meant in a collection. (Now it’s just a regular part of the name.) I proposed at some point to use a leading underscore in collections for internal names that shouldn’t be exposed to the user, but that proposal was rejected, though it’s still often used as an indicator that something is private, since there is no other way except writing in the docs DON'T USE THIS! or something like that… But that all was for plugins, not roles; I think for roles the leading underscore was always OK, except maybe for ansible-doc, which might have also mishandled it for roles in collections. In any case, that should be fine now for some years, or so.)

1 Like

Personally I think private things should be put in a reasonably named subdirectory ( prometheus.prometheus.internal.common), instead of using an unintuitive convention.

1 Like

@nitzmahone - as the current SC core rep - any opinions on this one? Should we change the docs to say _rolename is allowed and that some collections use this to indicate roles for internal-use only etc?

I’ve said before that Ansible feels more like a bizarre extension of Python than an application written in Python. The convention in Python is that leading underscores on identifiers indicate some unenforced local scoping. That convention seems to be exactly what we’re talking about for role names.

The document is demonstrably wrong. It’s a lot easier to change a document to match reality than it is to change code to match a document, even if the document reflected “the plan” at the time it was written. In practice, the recommendation is that all identifiers should be lower-case (although why that is has never been justified as far as I know), and that identifiers should not start with a digit. I haven’t tried making collection role names or any other identifiers that start with a digit, but I don’t expect it to work - mostly because the parser probably breaks. If so, that no-leading-digits thing is a de facto enforced prohibition, in contrast to the other bits.

If you think of “_” as the lowest of the lower-case r'\w' characters, all the guideline really says is that role names can’t start with a digit. I would be happy with the documentation making distinctions among recommendations, conventions, best practices, and prohibitions. If it’s the latter, and code doesn’t enforce it, that’s a bug.

The restriction in ansible-core is that content use valid Python identifiers (which is a technical limitation caused by how collection content is loaded) ; all other restrictions are arbitrary and enforced (if at all) at other points.

TASK [flowerysong.test._한글 : debug] ******************************************
ok: [localhost] => 
    msg: Hello world!

Galaxy will refuse to import some content that the engine itself is perfectly fine with, but I think that this documentation does not correctly reflect those restrictions either.