skip to Main Content

I am trying to write ansible code first time to handle json.

I have a file in my /home/ which has following json data.

here is the input json

  "acl": [
    {
      "browse": true,
      "create": false
    },
    {
      "browse": false,
      "create": true
    }
  ],
  "groups": [
    {
      "name": "abc",
      "location": "texas"
    },
    {
      "name": "def",
      "location": "austin"
    }
  ],
  "users": [
    {
      "name": "admin",
      "description": "administrator",
      "password": "windows2011"
    },
    {
      "name": "testuser",
      "description": "guest",
      "password": "testpassword"
    }
  ]
}

I want to update password of the user in user’s object where name is admin

so i that output file has updated password for user admin. the output file should be located in /home/location with _updated.json extension.

the output json should like this

{
  "acl": [
    {
      "browse": true,
      "create": false
    },
    {
      "browse": false,
      "create": true
    }
  ],
  "groups": [
    {
      "name": "abc",
      "location": "texas"
    },
    {
      "name": "def",
      "location": "austin"
    }
  ],
  "users": [
    {
      "name": "admin",
      "description": "administrator",
      "password": "updatedpassword"
    },
    {
      "name": "testuser",
      "description": "guest",
      "password": "testpassword"
    }
  ]
}

ansible code which i have written so far-

---
- name: Update admin user password in JSON file
  hosts: localhost
  gather_facts: no
  tasks:
    - name: Read the JSON file
      ansible.builtin.command:
        cmd: cat /home/conf.json
      register: json_content

Thank you.

2

Answers


  1. What you can do is use the template module and use "variable interpolation" to put in the password you wish to use. First update your conf.json file:

    {
      "acl": [
        {
          "browse": true,
          "create": false
        },
        {
          "browse": false,
          "create": true
        }
      ],
      "groups": [
        {
          "name": "abc",
          "location": "texas"
        },
        {
          "name": "def",
          "location": "austin"
        }
      ],
      "users": [
        {
          "name": "admin",
          "description": "administrator",
          "password": "{{ admin_password }}"
        },
        {
          "name": "testuser",
          "description": "guest",
          "password": "testpassword"
        }
      ]
    }
    

    Then update your Ansible script to replace the variable with the new password:

    ---
    - name: Update admin user password in JSON file
      hosts: localhost
      gather_facts: no
      vars:
        admin_password: 'updatedpassword'
      tasks:
        - name: Update the JSON configuration
          ansible.builtin.template:
            src: /home/conf.json
            dest: /home/updated_conf.json
    

    https://docs.ansible.com/ansible/latest/collections/ansible/builtin/template_module.html

    You could also do the same with the testuser account by replacing the password with {{ testuser_password }} and then adding the variable and value to the Ansible script.

    Login or Signup to reply.
    • Declare the input file
      input_file: data.json
    

    and read it into a dictionary

        - include_vars:
            file: "{{ input_file }}"
            name: data
    

    gives

      data:
        acl:
        - browse: true
          create: false
        - browse: false
          create: true
        groups:
        - location: texas
          name: abc
        - location: austin
          name: def
        users:
        - description: administrator
          name: admin
          password: windows2011
        - description: guest
          name: testuser
          password: testpassword
    
    • Declare the updated users
      users:
        - name: admin
          password: updatedpassword
    

    and merge them

      update: "{{ [data.users, users] | community.general.lists_mergeby('name')
                                      | community.general.dict_kv('users') }}"
    

    gives

      update:
        users:
        - description: administrator
          name: admin
          password: updatedpassword
        - description: guest
          name: testuser
          password: testpassword
    
    • Update data
      data_update: "{{ [data, update] | combine }}"
    

    gives

      data_update:
        acl:
        - browse: true
          create: false
        - browse: false
          create: true
        groups:
        - location: texas
          name: abc
        - location: austin
          name: def
        users:
        - description: administrator
          name: admin
          password: updatedpassword
        - description: guest
          name: testuser
          password: testpassword
    
    • Declare the output file and write it
        - copy:
            dest: "{{ output_file }}"
            content: |
              {{ data_update | to_nice_json }}
          vars:
            arr: "{{ input_file | splitext | list }}"
            output_file: "{{ arr.0 }}_updated{{ arr.1 }}"
    

    gives what you want

    shell> diff data.json data_updated.json 
    26c26
    <             "password": "windows2011"
    ---
    >             "password": "updatedpassword"
    

    Example of a complete playbook for testing

    - hosts: localhost
    
      vars:
    
        input_file: data.json
    
        users:
          - name: admin
            password: updatedpassword
    
        update: "{{ [data.users, users] | community.general.lists_mergeby('name')
                                        | community.general.dict_kv('users') }}"
        data_update: "{{ [data, update] | combine }}"
    
      tasks:
    
        - include_vars:
            file: "{{ input_file }}"
            name: data
    
        - debug:
            var: data
        - debug:
            var: update
        - debug:
            var: data_update
    
        - copy:
            dest: "{{ output_file }}"
            content: |
              {{ data_update | to_nice_json }}
          vars:
            arr: "{{ input_file | splitext | list }}"
            output_file: "{{ arr.0 }}_updated{{ arr.1 }}"
    

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search