Ansible RAW Module - Curl and JSON file (Kubernetes)

5/25/2018

I need to parse a JSON attribute named keys_base64 with curl. I only have the option to accomplish this with raw module of Ansible. This is because of a network related issue. I tried many different approaches, but am lost. How can I get this to work?

Update: Found the answer

Original Post

** JSON Keys example object **

{"keys":["tony_01","tony_02","tony_03"],"keys_base64": 
["dG9ueV8wMQ==","dG9ueV8wMg==","dG9ueV8wMw=="],"root_token":"6c03bbce-eb8a-0af0-4e37-77e3a647d41d"}

** unseal.json **

{ "key": {{ item }} }

** Playbook **

- name: "Unseal Vault OCS"
  remote_user: Tony
  raw: curl -k -d@"{{ lookup('template','templates/unseal.json') }} https://{{ vault_ocs_pod_ip }}:8200/v1/sys/unseal"
  delegate_to: 10.x.x.10
  with_items: "{{ (vault_ocs_unseal_keys.stdout | from_json)['keys_base64'] }}"
  register: vault_ocs_unseal_result

The playbook variable "vault_ocs_unseal_keys" contains the JSON object.

** Playbook Output **

<10.x.x.10> ESTABLISH SSH CONNECTION FOR USER: quattro
<10.x.x.10> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=tony -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/%h-%r -tt 10.x.x.10 'curl -k -d - "{
  "key": gB2ZTK2V9Ch/9rOTenpz06u+p7t9qp5uKXEjqeCREEAZ
}
 https://10.x.x.98:8200/v1/sys/unseal"'
<10.x.x.10> (3, 'curl: (3) Illegal characters found in URL\r\n', 'Shared 
connection to 10.x.x.10 closed.\r\n')
failed: [localhost -> 10.x.x.10] 
(item=gB2ZTK2V9Ch/9rOTenpz06u+p7t9qp5uKXEjqeCREEAZ) => {
"changed": true,
"item": "gB2ZTK2V9Ch/9rOTenpz06u+p7t9qp5uKXEjqeCREEAZ",
"rc": 3

}

STDOUT:

curl: (3) Illegal characters found in URL

STDERR:

Shared connection to 10.x.x.10 closed.

MSG:

non-zero return code
-- wintersa
ansible
ansible-vault
hashicorp-vault
json
kubernetes

2 Answers

5/25/2018

This is working for me. Used the curl command without the @, as mentioned it is used for reading files. And I used the run_once. The lookup plugin does the looping. And it needs the keys found in the keys_base64 attribute to apply for every key a API call. Great!

**** Working code ****

- name: "Unseal Vault OCS"
  remote_user: tony
  raw: "curl -k -d '{{ lookup('template','unseal.json') | to_json }}' https://10.x.x.1:8200/v1/sys/unseal"
  with_items: "{{ (vault_ocs_unseal_keys.stdout | from_json)['keys_base64'] | list }}"
  delegate_to: 10.x.x.2
  run_once: true
  register: vault_ocs_unseal_keys_result
-- wintersa
Source: StackOverflow

5/25/2018

I found two problems in that task:

  1. In curl, @ is for reading files. As you are using lookup function in Ansible, you are inserting the content in that command, there is no need to read a file.

  2. The double-quotes should be limiting the JSON data, without including the URL

Here is the code that worked for me. Maybe it is not the same for you as I've hard-coded the JSON data:

- name: "Unseal Vault OCS"
  raw: curl -k -d "{{ lookup('template','unseal.json') }}" https://10.x.x.10/v1/sys/unseal
  with_items:
    - {"keys":["tony_01","tony_02","tony_03"],"keys_base64": ["dG9ueV8wMQ==","dG9ueV8wMg==","dG9ueV8wMw=="],"root_token":"6c03bbce-eb8a-0af0-4e37-77e3a647d41d"}
  register: vault_ocs_unseal_result
-- Ignacio Millán
Source: StackOverflow