Verwenden einer Variablen innerhalb einer Ansible-Schleife

Verwenden einer Variablen innerhalb einer Ansible-Schleife

Ich versuche, Daten aus JSON-Daten (unten) mithilfe einer Schleife mit einer Variablen abzurufen (anstatt einen Wert fest zu codieren). In den JSON-Daten (unten) kann sich „Cluster“ ändern, daher kann ich nicht einfach Folgendes verwenden: loop: „{{ drs_rule_jsondata.drs_rule_info.cluster }}“ – was wie erwartet funktioniert und die erwarteten Ergebnisse liefert.

Wenn ich jedoch das folgende Spiel verwende (mithilfe von Variablen in der Schleife und wenn {{ cluster_info.name }} = Cluster), erhalte ich die Meldung: „,dict object‘ hat kein Attribut ,drs_rule_jsondata.drs_rule_info.cluster‘“. Das Verwirrende daran ist, dass es dieselbe Syntax erzeugt wie die, die funktioniert … sollte die Verwendung von Variablen auf diese Weise in der Schleife nicht funktionieren? Gibt es eine andere Möglichkeit, die erwarteten Ergebnisse zu erzielen, wenn sich der ,Cluster‘ ändern kann?

Spielen:

- name: Set drs rule info
  set_fact:
    drs_rule: "{{ drs_rule|default([]) + [ {
      'rule_name': item | json_query('rule_name'),
      'rule_affinity': item | json_query('rule_affinity'),
      'rule_vms': item | json_query('rule_vms[*]')
      } ] }}"
  vars:
    path: drs_rule_jsondata.drs_rule_info
    cluster_name: "{{ cluster_info.name }}"
  loop: "{{ vars[path + '.' + cluster_name] }}"

JSON-Daten:

{
  "ansible_facts": {
    "drs_rule_jsondata": {
      "changed": false,
      "drs_rule_info": {
        "cluster": [
          {
            "rule_affinity": true,
            "rule_enabled": true,
            "rule_key": 1,
            "rule_mandatory": null,
            "rule_name": "DEMO_REP_DRS_1",
            "rule_type": "vm_vm_rule",
            "rule_uuid": "522d41eb-4acb-afbf-9f37-15a1651ccf45",
            "rule_vms": [
              "VM1",
              "VM2",
              "VM3",
              "VM4"
            ]

        ]
      },
      "failed": false
    }
  },
  "_ansible_no_log": false,
  "changed": false
}

Erwartete Ergebnisse:

{
  "drs_rule": [
    {
      "rule_name": "DEMO_REP_DRS_1",
      "rule_affinity": true,
      "rule_vms": [
        "VM1",
        "VM2",
        "VM3",
        "VM4"
      ]
    }
  ]
}

Antwort1

Dieser Ausdruck ergibt keinen Sinn:

vars[path + '.' + cluster_name]

Hier fragen Sie nach einer Variable mit dem wörtlichen Namen drs_rule_jsondata.drs_rule_info.<value of cluster_name>, aber es gibt keine solche Variable – das ist nicht einmal ein gültiger Variablenname.

Sie müssen es hier auf keinen Fall verwenden ; Sie können einfach direkt auf die Variable varsder obersten Ebene verweisen .dns_rule_jsondata

Es ist auch nicht klar, warum Sie in Ihrem Playbook verwenden json_query, da Sie nur nach einzelnen, statischen Schlüsseln fragen.

Ich glaube, Sie versuchen Folgendes:

- hosts: localhost
  gather_facts: false
  vars:
    cluster_info:
      name: cluster
    drs_rule_jsondata:
      changed: false
      drs_rule_info:
        cluster:
          - rule_affinity: true
            rule_enabled: true
            rule_key: 1
            rule_mandatory: null
            rule_name: DEMO_REP_DRS_1
            rule_type: vm_vm_rule
            rule_uuid: 522d41eb-4acb-afbf-9f37-15a1651ccf45
            rule_vms:
              - VM1
              - VM2
              - VM3
              - VM4

  tasks:
  - name: Set drs rule info
    set_fact:
      drs_rule: >-
        {{
           drs_rule + [
             {
            'rule_name': item.rule_name,
            'rule_affinity': item.rule_affinity,
            'rule_vms': item.rule_vms
            }
          ]
        }}
    vars:
      drs_rule: []
      cluster_name: "{{ cluster_info.name }}"
    loop: "{{ drs_rule_jsondata.drs_rule_info[cluster_name] }}"

  - debug:
      var: drs_rule

Wenn Sie das obige Playbook ausführen, wird Folgendes ausgegeben:


PLAY [localhost] ***************************************************************

TASK [Set drs rule info] *******************************************************
ok: [localhost] => (item={'rule_affinity': True, 'rule_enabled': True, 'rule_key': 1, 'rule_mandatory': None, 'rule_name': 'DEMO_REP_DRS_1', 'rule_type': 'vm_vm_rule', 'rule_uuid': '522d41eb-4acb-afbf-9f37-15a1651ccf45', 'rule_vms': ['VM1', 'VM2', 'VM3', 'VM4']})

TASK [debug] *******************************************************************
ok: [localhost] => {
    "drs_rule": [
        {
            "rule_affinity": true,
            "rule_name": "DEMO_REP_DRS_1",
            "rule_vms": [
                "VM1",
                "VM2",
                "VM3",
                "VM4"
            ]
        }
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Antwort2

Folgendes hat am Ende letztendlich funktioniert (und ich dachte, ich hätte es schon ausprobiert):

              set_fact:
                drs_rule: "{{ drs_rule|default([]) + [ {
                  'rule_name': item | json_query('rule_name'),
                  'rule_affinity': item | json_query('rule_affinity'),
                  'rule_vms': item | json_query('rule_vms[*]')
                  } ] }}"
              vars:
                cluster_name: "{{ cluster_info.name }}"
              loop: "{{ drs_rule_jsondata.drs_rule_info[cluster_name] }}"

verwandte Informationen