Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible variable in dictionary key

Tags:

ansible

I am trying to execute playbook for setting Dell servers and I have some problems with dictionary in module idrac_redfish_config. I need enable SOL for specific user, but for this I want use key in dictionary with variable because ID of user can be different from server to server.
How I make send variable to dictionary key here:

    - name: Store id test-user
      set_fact:
        ID: "{{ result.redfish_facts.user.entries | json_query(\"[?UserName=='test-user'].Id\") }}"
    - name: Enable SOL for test-user
      community.general.idrac_redfish_config:
        category: Manager
        command: SetManagerAttributes
        resource_id: iDRAC.Embedded.1
        manager_attributes:
          Users.{{ ID[0] }}.SolEnable: "Enabled" <---
          Users.{{ ID[0] }}.IpmiLanPrivilege: "Administrator" <---
        baseuri: "testhost"
        username: "admin"
        password: "admin"

I get this error:

TASK [Store id test-user] **************************************************************************************************************************************************************************************
ok: [localhost] => {
    "ansible_facts": {
        "ID": [
            "8"
        ]
    },
    "changed": false
}

TASK [Enable SOL for test-user] ********************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "baseuri": "testhost",
            "category": "Manager",
            "command": [
                "SetManagerAttributes"
            ],
            "manager_attribute_name": null,
            "manager_attribute_value": null,
            "manager_attributes": {
                "Users.{{ ID[0] }}.IpmiLanPrivilege": "Administrator",
                "Users.{{ ID[0] }}.SolEnable": "Enabled"
            },
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "resource_id": "iDRAC.Embedded.1",
            "timeout": 10,
            "username": "admin"
        }
    },
    "msg": "SetManagerAttributes: Manager attribute Users.{{ ID[0] }}.SolEnable not found"
}

If I do this:

        manager_attributes: "{
          'Users.{{ ID[0] }}.SolEnable': Enabled
          'Users.{{ ID[0] }}.IpmiLanPrivilege': Administrator
        }"

I get:

fatal: [localhost]: FAILED! => {
    "changed": false,
    "invocation": {
        "module_args": {
            "baseuri": "testhost",
            "category": "Manager",
            "command": [
                "SetManagerAttributes"
            ],
            "manager_attributes": "{ 'Users.8.SolEnable': Enabled 'Users.8.IpmiLanPrivilege': Administrator }",
            "password": "VALUE_SPECIFIED_IN_NO_LOG_PARAMETER",
            "resource_id": "iDRAC.Embedded.1",
            "timeout": 10,
            "username": "admin"
        }
    },
    "msg": "argument manager_attributes is of type <class 'str'> and we were unable to convert to dict: unable to evaluate string as dictionary"
}

I didn't find in Ansible documentation how do this correctly.

like image 514
akashavkin Avatar asked Dec 15 '20 10:12

akashavkin


1 Answers

According to documentation, manager_attributes should be a dict of key/value pairs to set on your device. The keys have dots in their names and you cannot "statically" create dynamic key names as you tried above (i.e. "prefix{{ dynamic_value }}suffix": "some content" does not work as you experienced by yourself since the key name does not go through jinja2 templating).

Below is a solution. It's far from being the only one but that's the first that came to my mind and I could setup an example for you quickly. In this case, I create a list of {key: X, value: Y} dicts with your dynamic names as keys and use the items2dict filter to transform this back to a dict itself.

I don't have a network device to play this against so I could not verify that the final result is actually accepted by the module. My example simply uses a debug with your input data to illustrate and outputs a dictionary as the module expects. You will have to tune the exact key names if they are wrong but at least you should be able to move forward.

- name: Dynamic dict
  hosts: localhost
  gather_facts: false

  vars:
    ID:
      - "8"

    my_attributes:
      - key: "Users.{{ ID[0] }}.IpmiLandPrivilege"
        value: Administrator
      - key: "Users.{{ ID[0] }}.SolEnable"
        value: Enabled

  tasks:
    - name: construct a dynamic dict and debug
      vars:
        manager_attributes: "{{ my_attributes | items2dict }}"
      debug:
        var: manager_attributes

Which gives:

PLAY [Dynamic dict demo] ***************************************************************************************************************************************************************************************************************

TASK [construct a dynamic dict and debug] **********************************************************************************************************************************************************************************************
ok: [localhost] => {
    "manager_attributes": {
        "Users.8.IpmiLandPrivilege": "Administrator",
        "Users.8.SolEnable": "Enabled"
    }
}

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

Edit: An additional (out of many others) example to achieve the same goal. The output is exactly the same as above:

- name: Dynamic dict
  hosts: localhost
  gather_facts: false

  vars:
    ID:
      - "8"

    manager_attributes: "{{
      {
       'Users.' + ID[0] + '.IpmiLandPrivilege': 'Administrator',
       'Users.' + ID[0] + '.SolEnable': 'Enabled'
      }
    }}"

  tasks:
    - name: construct a dynamic dict and debug
      debug:
        var: manager_attributes
like image 89
Zeitounator Avatar answered Oct 18 '22 05:10

Zeitounator