2
votes

Ansible débutant - L'objet de liste n'a pas d'attribut 'nom'

J'ai un problème avec le bouclage sur vars,

vars:
    user:
      {
        name: "neito",
        pubkey: "{{ lookup('file', '~/.ssh/vsphere_vm.pub') }}",
        privkey: "{{ lookup('file', '~/.ssh/vsphere_vm') }}",
      }

lors de l'exécution de ce playbook, j'ai l'erreur suivante: The error was: 'list object' has no attribute 'name'

Le {{ item.name }} semble être indéfini pour Ansible, je suppose qu'il me manque quelque chose d'évident ici mais je ne trouve pas quoi. (Je suivais ce post de démarrage

Modifier 1:

En déclarant les vars comme suit, cela fonctionne:

- hosts: all
  become: yes
  vars:
    user: 
      - name: "neito"
        pubkey: "{{ lookup('file', '~/.ssh/vsphere_vm.pub') }}"
        privkey: "{{ lookup('file', '~/.ssh/vsphere_vm') }}"
  tasks:
    - name: "Add SSH public key"
      authorized_key:
        user: "{{ item.name }}"
        key: "{{ item.pubkey }}"
      loop:
        - "{{ user }}"

Quelqu'un pourrait-il encore me dire pourquoi la première syntaxe n'a pas fonctionné?


0 commentaires

3 Réponses :


4
votes

Veuillez consulter la documentation des boucles :

Vous pouvez définir la liste dans un fichier de variables, ou dans la section «Var» de votre jeu, puis vous référer au nom de la liste dans la tâche:

tasks:
  - name: "Add SSH public key"
    authorized_key:
      user: "{{ item.name }}"
      key: "{{ item.pubkey }}"
    loop: "{{ user }}"

Si vous modifiez votre tâche d'origine pour:

loop: "{{ somelist }}"

vous devriez être prêt à partir.


3 commentaires

Cette réponse ne montre pas la raison du problème. Le code fonctionne cependant.


Puisque la documentation suggère que l'utilisation de - "{{ a list }}" n'est pas la bonne manière, je suppose qu'il est inutile de l'analyser davantage. Peut-être que la loop est plus stricte sur la syntaxe de la variable d'entrée que with_items est with_items .


with_items: "{{ whatever }}" équivaut à loop: "{{ whatever | flatten(levels=1) }}" . C'est pourquoi cela fonctionnera si vous passez une liste de listes. Loop n'acceptera pas cela seul. Voir docs.ansible.com/ansible/latest/user_guide/...



0
votes

À l'origine, vous avez défini l' user comme une liste à 1 élément. Le petit tiret ( - ) au début désignait un élément d'une liste.

user:
  name: "neito"
  pubkey: "{{ lookup('file', '~/.ssh/vsphere_vm.pub') }}"
  privkey: "{{ lookup('file', '~/.ssh/vsphere_vm') }}" """)

Les crochets sont une syntaxe alternative aux tirets. Sur une note similaire, les accolades sont également une alternative à la spécification de chaque propriété sur une nouvelle ligne, avec une indentation accrue. Vous pouvez donc réécrire votre deuxième exemple de la manière suivante:

user:
  - name: "neito"
    pubkey: "{{ lookup('file', '~/.ssh/vsphere_vm.pub') }}"
    privkey: "{{ lookup('file', '~/.ssh/vsphere_vm') }}"
# in YAML, the below is equivalent to the above
user:
  [
    {
      name: "neito",
      pubkey: "{{ lookup('file', '~/.ssh/vsphere_vm.pub') }}",
      privkey: "{{ lookup('file', '~/.ssh/vsphere_vm') }}"
    }
  ]

Grâce au fait que les crochets et les accolades sont également valides dans YAML, vous pouvez réellement analyser les fichiers JSON en tant que YAML et cela fonctionnera à 100% (mais pas l'inverse).


3 commentaires

Merci pour l'explication détaillée et les infos supplémentaires.


Cette réponse ne résout pas le problème. En plus de cela, le dictionnaire proposé ne sert pas à itérer les utilisateurs.


@VladimirBotka merci pour vos commentaires. Je suis d'accord que l'itération des utilisateurs aurait probablement un sens ici, mais il n'était pas clair d'après la question qu'OP voulait que l' user soit une liste (peut-être que dans ce cas, cela aurait dû être appelé users ?). Si vous jetez un œil au didacticiel OP est le suivant, ce didacticiel utilise loop: ... - '"{{ user }}"' partout.



2
votes

Le problème était le - tiret devant "{{ user }}" :

loop: "{{ user }}"

Doit être:

loop:
  - "{{ user }}"


1 commentaires

Cette réponse met en évidence le vrai problème. Celui-ci sera la réponse acceptée.