skip to Main Content

I have a simple json that looks like this:

{
   "aaa": "true",
   "bbb": "false",
   "ccc": "true"
}

I would like enable ‘bbb’ value using ansible. Here is my playbook:

---
- hosts: "{{hosts}}"
  remote_user: 'centos'
  gather_facts: yes
  become: yes

  tasks:
  - name: Load current facts
    slurp:
      path: "/tmp/file.json"
    register: facts

  - name: Enable fact
    set_fact:
      facts: "{{ facts | combine({ 'bbb': 'true' }) }}"

Nothing happen when i run this playbook, and the json file stays the same. What could be the issue?

2

Answers


  1. You’ve got a few problems. First, you’ll want to inspect the content of the facts variable after your Load current facts task has completed:

      - name: Load current facts
        slurp:
          path: "/tmp/file.json"
        register: facts
    
      - debug:
          var: facts
    

    This will show you that the contents of your facts variable is not what you think:

    TASK [debug] *********************************************************************************************************************************************************************************
    ok: [localhost] => {
        "facts": {
            "changed": false,
            "content": "ewogICAiYWFhIjogInRydWUiLAogICAiYmJiIjogImZhbHNlIiwKICAgImNjYyI6ICJ0cnVlIgp9Cgo=",
            "encoding": "base64",
            "failed": false,
            "source": "file.json"
        }
    }
    

    To actual get the data from your JSON file, you would need to base64-decode the content key:

    - debug:
        var: facts.content|b64decode
    

    Which gets you:

    TASK [debug] *********************************************************************************************************************************************************************************
    ok: [localhost] => {
        "facts.content|b64decode": {
            "aaa": "true",
            "bbb": "false",
            "ccc": "true"
        }
    }
    

    Putting that together gives us a playbook that looks something like this:

    ---
    - hosts: localhost
      gather_facts: false
      tasks:
      - name: Load current facts
        slurp:
          path: "file.json"
        register: facts_raw
    
      - name: Enable fact
        set_fact:
          facts: "{{ facts | combine({ 'bbb': 'true' }) }}"
        vars:
          facts: "{{ facts_raw.content|b64decode }}"
    
      - debug:
          var: facts
    

    Which will output:

    TASK [Load current facts] ********************************************************************************************************************************************************************
    ok: [localhost]
    
    TASK [Enable fact] ***************************************************************************************************************************************************************************
    ok: [localhost]
    
    TASK [debug] *********************************************************************************************************************************************************************************
    ok: [localhost] => {
        "facts": {
            "aaa": "true",
            "bbb": "true",
            "ccc": "true"
        }
    }
    
    

    Nothing happen when i run this playbook, and the json file stays the same. What could be the issue?

    The set_fact simply creates an Ansible variable. If your goal is to actually modify /tmp/file.json, you will need to add a task to write out the modified data to that file. Something like:

    - name: write modified data to file
      copy:
        content: "{{ facts | to_nice_json }}"
        dest: /tmp/file.json
    
    Login or Signup to reply.
  2. Q: "I would like to enable ‘bbb’ value … the JSON file stays the same."

    shell> cat /tmp/file.json 
    {
        "aaa": "true",
        "bbb": "false",
        "ccc": "true"
    }
    

    A: Use replace to modify the file. For example

        - replace:
            path: /tmp/file.json
            regexp: '"bbb": "false"'
            replace: '"bbb": "true"'
    

    gives

    shell> cat /tmp/file.json 
    {
        "aaa": "true",
        "bbb": "true",
        "ccc": "true"
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search