webentwicklung-frage-antwort-db.com.de

Erstellen Sie set_fact-Variablen in einer Rolle und verwenden Sie sie in einer anderen Rolle

Ich habe eine komplizierte Umgebung mit Stufen und Benutzern für mehrere Systeme.

Die Stufen sind: dev, int usw.

Jede Stufe hat einen Benutzer für eine Anwendung, nennen wir den Benutzer john. Das führt Zu einem Benutzer, der für dev und johni für int und so weiter verwendet wird.

Um die Systemverwaltung zu abstrahieren, da alle Systeme in den Stufen gleich sind, habe ich diese Datenstruktur Erstellt:

users:
  john:
    dev:
      name: "johnd"
    int:
      name: "johni"

Jetzt habe ich eine Rolle "collect_user_information", die alle Arten von Informationen aus LDAP sammelt und mit Hilfe von set_fact in einer Variablen speichert.

- name: Get the userhome out of LDAP
  Shell: 'getent passwd {{ users[ user ][ stage ].name }} | cut -d: -f6'
  register: user_home

Und set_fact:

- name: set facts for LDAP user
  set_fact:
    "{{user}}":
      name: "{{ users[ user ][ stage ].name }}"
      home: "{{ user_home.stdout }}"

Um die Variable zu sichern, verwende ich:

- name: debug output for myuser
  debug: var="{{user}}"

Die Debug-Ausgabe sieht vielversprechend aus.

TASK [collect_user_information : debug output for user] *******
ok: [Host1] => {
  "john": {
     "home": "/home/johni",-
     "name": "johni"
  }
}

Jetzt möchte ich eine Rolle ausführen, um die Benutzer zu Hause zu erstellen.

- { role: create_user_home, user: "john" }

Zuerst mache ich die Einträge meiner Variablen:

- name: debug role create_user_home output for variable user
  debug: var=user

TASK [create_user_home : debug role create_user_home output for variable user] ***********
ok: [Host1] => {
    "user": "john"
}

- name: debug role create_user_home output for variable john
  debug: var={{ user }}

TASK [create_user_home : debug role create_user_home output for variable john] **********
ok: [Host1] => {
    "john": {
        "home": "/home/johni",-
        "name": "johni"
    }
}       

Nun möchte ich diese Datenstruktur verwenden. Ich würde vermuten, dass ich auf die Werte zugreifen kann, indem ich auf "{{user.name}}" oder "{{user ['name']}}" verweise.

TASK [create_user_home : Create home directories for john] ***********************
fatal: [Host1]: FAILED! => {"failed": true, "msg": "the field 'args' has an invalid value, which appears to include a variable that is undefined. The error was: 'ansible.parsing.yaml.objects.AnsibleUnicode object' has no attribute 'home'\n\nThe error appears to have been in '/etc/ansible/roles/create_user_home/tasks/main.yml': line 37, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n#-------------------------------------------------------------------------------\n- name: Create home directories for john\n  ^ here\n"}

Nun, wie funktioniert das?

4
iamcheko

Okay, ich habe die Lösung selbst gefunden.

Zuerst erstelle ich eine zusätzliche Schicht (myuser) in meiner Datenstruktur und verwende eine andere Notation.

- name: set facts for LDAP user
  set_fact:
  myuser: '{ "{{user}}": { "name": "{{ users[ user ][ stage ].name }}", "home": "{{ user_home.stdout }}", "gid": "{{ user_gid.stdout}}", "group": "{{ user_primarygroup.stdout }}" } }'

Dies gibt mir einen Debug-Dump wie folgt zurück:

TASK [collect_user_information : debug output for myuser] ***********
ok: [Host1] => {
    "myuser": {
        "john": {
            "home": "/home/johni",
            "name": "johni"
        }
    }
}

Jetzt kann ich die Werte meiner Datenstruktur verwenden. Denken Sie daran, dass "Benutzer" bin durch Argument an die Rolle übergeben wurde.

- name: Create home directories for user
  user:
    name: "{{ myuser[ user ].name }}"
    home: "{{ myuser[ user ].home }}"
    Shell: "/bin/bash"
  register: "create_user_home"
  tags: [ 'user' ]

Hoffentlich hilft das.

1
iamcheko

Das Ganze ist hier zu knifflig - Sie möchten eine dynamische Variable definieren, bei der der Variablenname der Benutzername ist, z. john, während john ein Dikt ist, das zwei Schlüssel enthält, nämlich .name und .home.

Ihr erster Versuch ist fehlgeschlagen, weil Sie versucht haben, auf user.name zu verweisen, die sich auf den Schlüssel name eines Diktiers user beziehen, jedoch nicht auf ein Diktum namens john.

Da Sie irgendwo ein goldenes Diktum users definiert haben, müssen Sie die Dinge nicht wirklich kompliziert machen. Sie können den Namen immer mit users[user][stage].name und user_home.stdout für das Heimatverzeichnis referenzieren.

Wenn Sie der Meinung sind, dass die Syntax zu lästig ist. Wir können zu Ihrem ursprünglichen Ansatz zurückkehren, indem Sie ein weiteres Diktat erstellen, um den Namen und das Heimatverzeichnis zu speichern. Im folgenden Fall bezieht sich user immer auf den aktuellen Benutzer, den Sie bereitstellen:

- name: set facts for LDAP user
  set_fact:
    user:
      name: "{{ users[username][stage].name }}"
      home: "{{ user_home.stdout }}"

Damit können Sie user.name und user.home in allen nachfolgenden Aufgaben verwenden. Beachten Sie die vierte Zeile. Ich habe die Variable, die Sie der Rolle übergeben, in username umbenannt, um eine Kollision zu vermeiden.


Update:

Unterstützung für mehrere Benutzer:

- name: Get the user home out of LDAP
  Shell: 'getent passwd {{ users[item][stage].name }} | cut -d: -f6'
  register: homes
  with_items: "{{ users }}"

# item.item is the username, item.stdout is the home dir
- debug: msg="{{ users[item.item][stage].name }}'s home is {{ item.stdout }}"
  with_items: "{{ homes.results }}"

Lesen Sie mehr aus Verwenden Sie das Register mit einer Schleife .

0
Chris Lam