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

Robert Thorne

Automotive & Future Transportation Editor

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

Share this article
Twitter Facebook Pinterest