Passer des commandes de forme libre à Ansible en utilisant un formulaire d'arguments complexes

9

J'utilise des playbooks Ansible générés par programmation. En général, parce que les playbooks ne sont que du YAML, c'est simple. Cependant, lorsque vous utilisez le key=valueformulaire "simple" , les playbooks ne sont pas du pur YAML - ils incluent du contenu intégré sous une shlexforme comparable.

Pour éviter l'ambiguïté sous cette forme (est-ce que cette key=valuepaire est un argument de la commande ou un argument pour ansible?), Et n'ai qu'un seul format à analyser et à générer, j'utilise inconditionnellement le mécanisme d'arguments complexes démontré par l'exemple dans l'ansible -exemple de référentiel .

Cela utilise une syntaxe du type suivant:

action: module-name
args:
  key1: value1
  key2: value2

... ce qui est bien et bon. Cependant, lorsque vous essayez d'utiliser ce formulaire pour les modules shellou command( dont la documentation décrit la commande réelle comme passée dans un argument nommé free_form), cela ne fonctionne pas si bien:

action: shell
args:
  free_form: echo hello_world >/tmp/something
  creates: /tmp/something

Lorsqu'elle est invoquée, elle exécute ce qui suit:

/bin/sh -c " free_form='echo hello_world >/tmp/something'  "

... ce qui n'est pas du tout ce que j'essaie d'accomplir.

Quelle est la bonne façon d'utiliser les modules Ansible en prenant des commandes "de forme libre" en utilisant la pure syntaxe YAML?

Charles Duffy
la source

Réponses:

5

Réponse courte: Ne pas utiliser les command, raw, scriptou shellmodules. Écrivez votre propre module qui accepte la commande comme argument "normal".

Longue réponse:

Dans la plupart des cas, vous pouvez le faire:

- shell: echo hello_world > /tmp/something
  args:
    creates: /tmp/something

Cependant, cela échoue dans certains cas marginaux:

- shell: echo hello_world > creates=something
  args:
    creates: creates=something  # The file is named "creates=something"

Je ne connais pas de manière générale de gérer cela, mais une solution spécifique à bash est:

- shell: echo hello_world > "creates=something"
  args:
    creates: creates=something
Boule de neige
la source
Existe-t-il une structure de données que je peux transmettre à n'importe quel générateur YAML conforme pour le faire émettre - shell: ...? Si cette structure est quelque chose qui ne peut être généré de manière fiable qu'à la main, cela va quelque peu à l'encontre du point de la question.
Charles Duffy
@CharlesDuffy: Je ne pense pas que vous puissiez échapper à la ...partie en général. Si vous regardez library/commands/command, vous trouverez une correspondance des expressions rationnelles assez généreux creates=, removes=, chdir=et ainsi de suite. Si vous devez garantir que n'importe quelle commande peut être transmise, vous devrez écrire votre propre module.
Snowball
Nuff juste. C'est, à mon avis, une erreur importante de conception ... mais, bien, c'est ce que c'est.
Charles Duffy
0

Ceci est résolu dans la documentation Ansible maintenant.

# You can also use the 'args' form to provide the options. This command
# will change the working directory to somedir/ and will only run when
# /path/to/database doesn't exist.
- command: /usr/bin/make_database.sh arg1 arg2
  args:
    chdir: somedir/
    creates: /path/to/database

Notez qu'il n'y a pas de paramètre nommé 'free_form'.

Christian Long
la source
La présence de paires argsempêche- t-elle l' k=vanalyse command, devrait-elle exister? (Si tel est le cas, cela résout clairement l'ambiguïté; sinon, il semblerait qu'il existe toujours).
Charles Duffy