Search code examples
jsonansiblejinja2ansible-role

How to populate parameters for an ansible role dynamically from a json file?


I'm working on passing parameters/vars to an ansible role dynamically by reading them from a JSON file.

Consider the following role call (with optional parameters like phone, address, email, city)

- name: Ansible role | Create
  include_role:
    name: ansible-role-create-user
  vars:
    persons:
    - name: "john"
      phone:
      - name: "home"
        number: 9999
      - name: "mobile"
        number: "9898"
- name: Ansible role | Create
  include_role:
    name: ansible-role-create-user
  vars:
    persons:
    - name: "Doe"
      email: "johndoe@home.com"
      city: "Skyland"

Above mentioned code is two variants of calling the role. With its optional params, I'm trying to read that data from a JSON and feed it to the role

JSON eg: for call 1:

{
  "name": "John",
  "phone": 
  {
    {"name": "home",   number: "9999"},
    {"name": "mobile",   number: "9898"}
  }  
}

for call 2:

{
  "name": "Doe",
  "email": "johndoe@home.com",
  "city": "skyland"
}

As stated earlier, I would like to read the example JSON files and pass them as params to the role dynamically. Have tried an approach of reading the file to a register and sending the var to the role, but I'm facing the error of

{ "msg" "'unicode object' has no attribute 'name'"}

sample of how I'm sending it

- name: cat json to file
  shell: cat jsonfile.json
  register: register_with_json
- name: Ansible role | Create
  include_role:
    name: ansible-role-create-user
  vars: "{{ register_with_json.stdout | from_json }}"

Solution

  • There are more options. For example, use include_vars. The role and the files

    shell> cat roles/ar_create_user/tasks/main.yml
    - debug:
        var: persons
    
    shell> cat call1.yml 
    persons:
      - name: "john"
        phone:
          - name: "home"
            number: 9999
          - name: "mobile"
            number: "9898"
    
    shell> cat call2.yml 
    persons:
      - name: "Doe"
        email: "johndoe@home.com"
        city: "Skyland"
    

    with the playbook

    shell> cat playbook.yml
    - hosts: localhost
      tasks:
    
        - include_vars: call1.yml
        - name: Ansible role | Create
          include_role:
            name: ar_create_user
    
        - include_vars: call2.yml
        - name: Ansible role | Create
          include_role:
            name: ar_create_user
    

    give (abridged)

    shell> ansible-playbook playbook.yml
    
    ok: [localhost] => 
      persons:
      - name: john
        phone:
        - name: home
          number: 9999
        - name: mobile
          number: '9898'
    
    ok: [localhost] => 
      persons:
      - city: Skyland
        email: johndoe@home.com
        name: Doe
    

    Q: "I need to get the var(persons) from JSON."

    A: The files below in JSON give the same results

    shell> cat call1.yml
    {"persons": [
       {"name": "john",
        "phone": [
          {"name": "home",
           "number": 9999},
          {"name": "mobile",
           "number": "9898"}]
           }]
        }
    
    shell> cat call2.yml
    {"persons": [
       {"name": "Doe",
        "email": "johndoe@home.com",
        "city": "Skyland"}]
        }