How to Write a Json File Using Ansible

How to Write a Json File Using Ansible

I need to write a json file using ansible

So I used ansible shell module.

But it gives this error:

TASK [Generate certs] ********************************************************** fatal: [xxx.xxx.xx.xxx]: FAILED! => {"changed": true, "cmd": "cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager \n", "delta": "0:00:00.015363", "end": "2020-08-14 16:26:35.643003", "msg": "non-zero return code", "rc": 1, "start": "2020-08-14 16:26:35.627640", "stderr": "Failed to load config file: {"code":5200,"message":"could not read configuration file"}Failed to parse input: unexpected end of JSON input", "stderr_lines": ["Failed to load config file: {"code":5200,"message":"could not read configuration file"}Failed to parse input: unexpected end of JSON input"], "stdout": "", "stdout_lines": []} PLAY RECAP ********************************************************************* 35.246.9.221 : ok=2 changed=1 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

And this is the playbook for this:

---
- hosts: kube_master
  tasks:
    - name: Create kube-controller-manager.pem &kube-controller-manager-key.pem
      # become: true      
      shell: |
        cat > kube-controller-manager-csr.json << EOF
        {
          "CN": "system:kube-controller-manager",
          "key": {
            "algo": "rsa",
            "size": 2048
          },
          "names": [
            {
              "C": "US",
              "L": "Portland",
              "O": "system:kube-controller-manager",
              "OU": "Kubernetes The Hard Way",
              "ST": "Oregon"
            }
          ]
        }
        EOF        
                 

    - name: Generate certs
      shell: |
        cfssl gencert \
        -ca=ca.pem \
        -ca-key=ca-key.pem \
        -config=ca-config.json \
        -profile=kubernetes \
        kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager                               

Can someone tell me what is this error and why it is happening?

4

1 Answer

So what you can do, if you really want to keep your data in the playbook itself is to translate your JSON data in a dictionary in YAML.

An equivalent representation of your actual JSON would be:

certificate: 
  CN: system:kube-controller-manager
  key: 
    algo: rsa
    size: 2048
  names:
    - C: US
      L: Portland
      O: system:kube-controller-manager
      OU: Kubernetes The Hard Way
      ST: Oregon

Then, based on this, you could simply apply a to_json filter on top of it, before using the copy module with the content parameter.

So given this playbook:

- hosts: all
  gather_facts: no
  vars: 
    certificate: 
      CN: system:kube-controller-manager
      key: 
        algo: rsa
        size: 2048
      names:
        - C: US
          L: Portland
          O: system:kube-controller-manager
          OU: Kubernetes The Hard Way
          ST: Oregon
      
  tasks:
    - copy:
        dest: kube-controller-manager-csr.json
        content: "{{ certificate | to_json }}" 

We end up with this recap:

PLAY [all] **********************************************************************************************************

TASK [copy] *********************************************************************************************************
changed: [localhost]

PLAY RECAP **********************************************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

And this kube-controller-manager-csr.json file

{"CN": "system:kube-controller-manager", "key": {"algo": "rsa", "size": 2048}, "names": [{"C": "US", "L": "Portland", "O": "system:kube-controller-manager", "OU": "Kubernetes The Hard Way", "ST": "Oregon"}]}

Some extra notes:

  • Here, the JSON is not really human readable (all is in one line). If this is causing you an issue, you can switch from using to_json filter to using to_nice_json filter
  • YAML is a natural superset of JSON, this means that you can actually use a JSON structure as a valid YAML variable.
    I wouldn't do it, though, because I find it odd to mix two languages in YAML files, but if you personnaly see no objection to it, this playbook, that doesn't even use the to_json filter, is also a working one:
    - hosts: all
      gather_facts: no
      vars: 
        certificate: {
          "CN": "system:kube-controller-manager",
          "key": {
            "algo": "rsa",
            "size": 2048
          },
          "names": [
            {
              "C": "US",
              "L": "Portland",
              "O": "system:kube-controller-manager",
              "OU": "Kubernetes The Hard Way",
              "ST": "Oregon"
            }
          ]
        }
    
      tasks:
        - copy:
            dest: kube-controller-manager-csr.json
            content: "{{ certificate }}" 
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Robert Thorne
Author

Robert Thorne

Robert Thorne covers electric vehicle innovations, autonomous driving systems, global mobility trends, and automotive engineering developments.