Variabelen prefixen en woorden scheiden in Ansible

Prefix publieke rolvariabelen met de rolnaam, interne rolvariabelen met __role_name_, inventarisvariabelen met een projectvoorvoegsel, en scheid woorden in variabelenamen met underscores.

Probleem

Zonder een duidelijke naamgevingsregel is het niet altijd duidelijk of een variabele hoort bij de publieke interface van een rol, bij interne rollogica, of alleen bij het inventarisproject.

Daardoor nemen botsingen, onbedoelde overschrijvingen en onduidelijke rolcontracten toe. Samengevoegde namen zoals iis_apppools zijn bovendien moeilijker scanbaar dan gescheiden vormen zoals iis_web_app_pools.

Context

Ansible-variabelen zijn niet per rol of per inventarisbestand namespaced. Variabelen uit rollen, group_vars, host_vars, geregistreerde resultaten en vars op taakniveau delen tijdens uitvoering dezelfde naamruimte.

De Ansible-documentatie staat in variabelenamen alleen letters, cijfers en underscores toe. In de praktijk beperkt ansible-lint dit verder tot lowercase alfanumerieke namen met underscores en verwacht het binnen rollen ook een rolprefix.

De Red Hat CoP-richtlijn adviseert om publieke rolvariabelen te prefixen met de rolnaam en interne variabelen met een dubbele underscore. In die richtlijn vallen daar expliciet ook waarden onder die met register en set_fact worden aangemaakt, omdat ze na afloop van de rol ook in de runtime-naamruimte blijven staan.1 Die dubbele underscore is alleen een naamgevingsconventie, geen privacy- of beveiligingsgrens.2

Projectvariabelen die alleen in group_vars of host_vars bestaan, hebben nog steeds een duidelijk projectvoorvoegsel nodig, zoals c2_ of gs_.

Oplossing

Beslisregel: als een variabele niet bedoeld is om door gebruikers van de rol via inventaris of rolparameters te worden gezet, overschreven of direct gebruikt, behandel die dan als intern en prefix die met __rolnaam_.

  1. Prefix elke publieke rolvariabele met de rolnaam, bijvoorbeeld haproxy_frontends.
  2. Prefix elke interne rolvariabele met __role_name_, bijvoorbeeld __haproxy_frontends_rendered.
  3. Prefix elke projectvariabele die alleen in group_vars of host_vars bestaat met een projectvoorvoegsel, bijvoorbeeld c2_cacerts2_ca_dir.
  4. Schrijf variabelenamen met meerdere woorden in lowercase snake case en scheid woorden met underscores.
  5. Volg waar nuttig module- of domeinterminologie, bijvoorbeeld iis_web_app_pools in plaats van iis_apppools.
  6. Gebruik gedocumenteerde upstream ansible_*-variabelen alleen voor door Ansible gedefinieerde instellingen zoals ansible_become_user.
  7. Als je project een aangepast ansible-lint-naamgevingspatroon afdwingt, breid het dan uit zodat zowel publieke als interne rolvariabelen worden geaccepteerd.

Voordelen

  • Maakt eigenaarschap en bereik van variabelen zichtbaar.
  • Onderscheidt ondersteunde rolinvoer van interne hulpvariabelen.
  • Vermindert botsingen tussen rollen, inventaris en tijdelijke variabelen.
  • Maakt namen beter scanbaar doordat woordgrenzen expliciet zichtbaar blijven.
  • Helpt spellingcontrole in editors om verdachte woorden duidelijker te markeren.3

Voorbeelden en implementatie

Publieke, interne en projectvariabelen

# defaults/main.yml
haproxy_frontends: []

# task vars of set_fact-doelen
__haproxy_frontends_rendered: "{{ haproxy_frontends }}"

# group_vars/all/smallca.yml
c2_cacerts2_ca_dir: /etc/pki/ca-trust/source/anchors

Interne variabelen uit register en set_fact

- name: Lees HAProxy servicestatus
  ansible.builtin.command: systemctl is-active haproxy
  register: __haproxy_service_state
  changed_when: false

- name: Leid effectieve backendlijst af
  ansible.builtin.set_fact:
    __haproxy_backends_effective: >-
      {{ haproxy_backends
      | selectattr('enabled', 'equalto', true)
      | list }}

Dit zijn interne variabelen wanneer ze de rolimplementatie ondersteunen en geen onderdeel zijn van de ondersteunde interface waarmee gebruikers de rol configureren of overschrijven.

Aangepaste loop_var-namen kunnen ook intern zijn

Voor algemene richtlijnen over wanneer je item houdt en wanneer je een aangepaste loop_var introduceert, zie

Gebruik van item en loop_var in Ansible-loops .

Wanneer een aangepaste loop_var over een include_tasks-grens gaat of anders te veel op ondersteunde rolinvoer lijkt, heeft de interne vorm de voorkeur.

- name: Configureer IIS web application pools
  ansible.builtin.include_tasks: web_app_pool.yml
  loop: "{{ iis_web_app_pools }}"
  loop_control:
    loop_var: __iis_web_app_pool
    label: "{{ __iis_web_app_pool['name'] }}"
# web_app_pool.yml
- name: Zorg dat IIS web application pool bestaat
  microsoft.iis.web_app_pool:
    name: "{{ __iis_web_app_pool['name'] }}"
    state: "{{ __iis_web_app_pool['state'] | default(omit) }}"

Een naam zoals iis_web_app_pool is technisch geldig, maar __iis_web_app_pool maakt duidelijker dat deze waarde een interne hulpvariabele is die tussen task-bestanden wordt doorgegeven, en geen publieke rolvariabele.4

Scheid woorden expliciet

iis_web_app_pools:
  - name: HelloWorld
    state: started

Vermijd samengevoegde vormen zoals:

iis_apppools:
  - name: HelloWorld
    state: started

De gescheiden vorm is duidelijker omdat die de gebruikelijke snake case-conventie volgt, de moduleterm web_app_pool uit microsoft.iis.web_app_pool weerspiegelt, en duidelijk maakt dat de variabele meerdere resources bevat.

ansible-lint-patroon voor strengere projecten

# markdownlint-disable-next-line MD013
var_naming_pattern: "^(__)?(haproxy|guacamole|ansible)_[a-z0-9_]*$|^ansible_[a-z0-9_]*$"

Dit patroon accepteert publieke variabelen zoals haproxy_frontends, interne variabelen zoals __haproxy_frontends_rendered, en gedocumenteerde upstream variabelen zoals ansible_become_user.

Aanvullende informatie


  1. Red Hat CoP is hiervoor de duidelijkste bron. Daar wordt de interne-variabelenregel expliciet toegepast op waarden uit register en set_fact, juist omdat Ansible-variabelen niet rol-lokaal zijn zoals veel lezers verwachten. ↩︎

  2. Ansible staat variabelenamen toe die beginnen met een underscore, maar behandelt ze niet als privé. Zie

    Using variables — Ansible Community Documentation  . ↩︎

  3. In editors met spellingcontrole worden gescheiden woorden vaker afzonderlijk gecontroleerd. In de praktijk maakt dit tikfouten visueel beter zichtbaar, bijvoorbeeld als een gekleurde kringellijn in VS Code, afhankelijk van de gebruikte spell-check configuratie. ↩︎

  4. Ansible documenteert loop_control.loop_var en de speciale variabele ansible_loop_var voor loopafhandeling. De opt-in ansible-lint-regel loop-var-prefix ondersteunt ook conventies zoals ^(__|{role}_), wat past bij het idee dat hulpvariabelen die over task-bestandsgrenzen gaan de interne __-vorm kunnen gebruiken. ↩︎