Create set_fact variables in one role and use them in an other

15,979

Okay I found the solution myself.

First I create an additional layer (myuser) in my data structure and use a different 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 }}" } }'

This returns me a debug dump like this:

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

Now I'm able to use my data structure values. Remember "user" has been passed to the role by argument.

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

Hope that helps.

Share:
15,979
iamcheko
Author by

iamcheko

Updated on June 27, 2022

Comments

  • iamcheko
    iamcheko almost 2 years

    I have a complicated environment with stages and users for multiple systems.

    The stages are: dev, int, etc.

    Each stage has a user for an application, let's call the user john. That leads to a user johnd for dev and johni for int and so on.

    To abstract the system management, since all systems in the stages are the same, I created this data structure:

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

    Now I have a role "collect_user_information" which collects all kind of informations from LDAP and stores them in a variable with help of set_fact.

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

    And set_fact:

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

    To dump the variable, I use:

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

    The debug output looks promissing.

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

    Now I would like to execute a role to create the users home.

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

    First I dump the entries of my variable:

    - 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"
        }
    }       
    

    Now I would like use this data structure. I would guess I can access the values by referencing "{{user.name}}" or "{{user['name']}}', but neither works.

    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"}
    

    Well, how does it work?

  • techraf
    techraf almost 7 years
    How does it differ from OP's own answer?
  • Chris Lam
    Chris Lam almost 7 years
    He's adding another "layer" of dict which is myuser
  • iamcheko
    iamcheko almost 7 years
    Okay, but how does it work if you have a second or even more users to work with?
  • Chris Lam
    Chris Lam almost 7 years
    Updated my answer.
  • iamcheko
    iamcheko almost 7 years
    Imagine you have hunderts of users in your users data structure and you need only, let's say four of them. So, your solution would query LDAP for all the users every time you run your play. Thanks for trying, but I have allready the solution.