best way to modify json in ansible

前端 未结 2 1691
野的像风
野的像风 2020-12-10 17:24

I have a variable (via set_fact) containing a json string:

{
  \"PolicyVersion\": {
    \"CreateDate\": \"2017-08-07T02:48:05Z\",
    \"Document\": {
      \         


        
相关标签:
2条回答
  • 2020-12-10 17:26

    I don't know about the best way, but one option is to write a simple library module to handle the mechanics of the update for you. You could use the jsonpointer module as a way of locating the data you wish to modify, and then return the modified object to ansible. A starting point might look like:

    #!/usr/bin/python
    
    from ansible.module_utils.basic import AnsibleModule
    
    import json
    
    try:
        import jsonpointer
    except ImportError:
        jsonpointer = None
    
    
    def main():
        module = AnsibleModule(
            argument_spec=dict(
                data=dict(required=True, type='dict'),
                pointer=dict(required=True),
                action=dict(required=True,
                            choices=['append', 'extend', 'update']),
                update=dict(type='dict'),
                extend=dict(type='list'),
                append=dict(),
            ),
            supports_check_mode=True,
        )
    
        if jsonpointer is None:
            module.fail_json(msg='jsonpointer module is not available')
    
        action = module.params['action']
        data = module.params['data']
        pointer = module.params['pointer']
    
        if isinstance(data, str):
            data = json.loads(str)
    
        try:
            res = jsonpointer.resolve_pointer(data, pointer)
        except jsonpointer.JsonPointerException as err:
            module.fail_json(msg=str(err))
    
        if action == 'append':
            res.append(module.params['append'])
        if action == 'extend':
            res.extend(module.params['extend'])
        elif action == 'update':
            res.update(module.params['update'])
    
        module.exit_json(changed=True,
                         result=data)
    
    
    if __name__ == '__main__':
        main()
    

    If you drop this into, e.g., library/json_modify.py, you can use it in a playbook like this:

    - hosts: localhost
      gather_facts: false
      vars:
        myvar: {
            "PolicyVersion": {
              "CreateDate": "2017-08-07T02:48:05Z",
              "Document": {
                "Statement": [
                  {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Resource": [
                      "arn:aws:iam::123456789123:role/Root_Update_svcacct",
                      "arn:aws:iam::123456789123:role/Root_Delete_svcacct",
                      "arn:aws:iam::123456789123:role/Root_Create_svcacct",
                      "arn:aws:iam::123456789123:role/Root_Full_svcacct",
                      "arn:aws:iam::987654321987:role/Member1_Create_svcacct",
                      "arn:aws:iam::987654321987:role/Member1_Update_svcacct",
                      "arn:aws:iam::987654321987:role/Member1_Delete_svcacct",
                      "arn:aws:iam::987654321987:role/Member1_Full_svcacct"
                    ]
                  }
                ],
                "Version": "2012-10-17"
              },
              "IsDefaultVersion": true,
              "VersionId": "v2"
            }
          }
      tasks:
        - json_modify:
            data: "{{ myvar }}"
            pointer: "/PolicyVersion/Document/Statement/0/Resource"
            action: extend
            extend:
              - "arn:aws:iam::001122334455:role/Member1_Create_svcacct"
              - "arn:aws:iam::001122334455:role/Member1_Update_svcacct"
              - "arn:aws:iam::001122334455:role/Member1_Delete_svcacct"
              - "arn:aws:iam::001122334455:role/Member1_Full_svcacct"
          register: result
    
        - debug:
            var: result.result
    

    The result of running this playbook and the proposed module is:

    TASK [debug] *******************************************************************
    ok: [localhost] => {
        "result.result": {
            "PolicyVersion": {
                "CreateDate": "2017-08-07T02:48:05Z", 
                "Document": {
                    "Statement": [
                        {
                            "Action": "sts:AssumeRole", 
                            "Effect": "Allow", 
                            "Resource": [
                                "arn:aws:iam::123456789123:role/Root_Update_svcacct", 
                                "arn:aws:iam::123456789123:role/Root_Delete_svcacct", 
                                "arn:aws:iam::123456789123:role/Root_Create_svcacct", 
                                "arn:aws:iam::123456789123:role/Root_Full_svcacct", 
                                "arn:aws:iam::987654321987:role/Member1_Create_svcacct", 
                                "arn:aws:iam::987654321987:role/Member1_Update_svcacct", 
                                "arn:aws:iam::987654321987:role/Member1_Delete_svcacct", 
                                "arn:aws:iam::987654321987:role/Member1_Full_svcacct", 
                                "arn:aws:iam::001122334455:role/Member1_Create_svcacct", 
                                "arn:aws:iam::001122334455:role/Member1_Update_svcacct", 
                                "arn:aws:iam::001122334455:role/Member1_Delete_svcacct", 
                                "arn:aws:iam::001122334455:role/Member1_Full_svcacct"
                            ]
                        }
                    ], 
                    "Version": "2012-10-17"
                }, 
                "IsDefaultVersion": true, 
                "VersionId": "v2"
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-10 17:45

    Actually Ansible is natively able to read JSON files.

    see this question:

    add-a-new-key-value-to-a-json-file-using-ansible

    0 讨论(0)
提交回复
热议问题