如何在 Ansible uri 模块中的 json 字符串中使用变量?

u12*_*123 2 ansible

在 ubuntu 16.10 上使用 ansible 2.5.3。

我需要在 JSON 字符串中为 Ansible uri 模块的 body 标记包含一个变量。我尝试了各种各样的事情。我最近的尝试在下面的任务中看起来像这样:

- name: REST POST Example
  uri:
    url: "{{ webapp_url }}/api/orgs"
    method: POST
    return_content: yes
    body: "{ \"name\": \"{{ project_name }}\" }"
    validate_certs: no
    user: "{{ user }}"
    password: "{{ password }}"
    force_basic_auth: yes
    headers:
      Content-Type: "application/json"
Run Code Online (Sandbox Code Playgroud)

在我的剧本中,我定义了project_name变量:

---

- hosts: all
  gather_facts: no
  vars:
      project_name: "SAMPLE_PROJECT"
Run Code Online (Sandbox Code Playgroud)

但是当我运行剧本时,project_name变量似乎没有正确扩展:

任务执行过程中发生异常。要查看完整的回溯,请使用 -vvv。错误是:TypeError: unhashable type
fatal: [localhost]: FAILED! => {"changed": false, "content": "", "msg": "状态代码是 -1 而不是 [200]: 发生未知错误:unhashable type", "redirected": false, "status" : -1, "url": " https://webapp/api/orgs "}

在上述角色/任务中。如果我对身体进行硬编码,例如:

body: "{\"name\": \"SAMPLE_PROJECT\"}"
Run Code Online (Sandbox Code Playgroud)

它工作正常。但我不能这样做,我需要那里的变量。关于如何修复的任何建议:

body: "{ \"name\": \"{{ project_name }}\" }"
Run Code Online (Sandbox Code Playgroud)

?

小智 6

Ansible ca 自动将 YAML 解释为 json,我推荐以下方法:

- name: REST POST Example
  uri:
    url: "{{ webapp_url }}/api/orgs"
    method: POST
    return_content: yes
    body:
      name: "{{ projectname }}"
    body_format: json
    validate_certs: no
    user: "{{ user }}"
    password: "{{ password }}"
    force_basic_auth: yes
Run Code Online (Sandbox Code Playgroud)


tec*_*raf 5

设置json为内部body_format参数的主体类型:

- name: REST POST Example
  uri:
    url: "{{ webapp_url }}/api/orgs"
    method: POST
    return_content: yes
    body: "{ \"name\": \"{{ project_name }}\" }"
    body_format: json
    validate_certs: no
    user: "{{ user }}"
    password: "{{ password }}"
    force_basic_auth: yes
Run Code Online (Sandbox Code Playgroud)

使用时body: "{\"name\": \"SAMPLE_PROJECT\"}",该值在内部表示为字符串 ( AnsibleUnicode)。

当您使用 时body: "{ \"name\": \"{{ project_name }}\" }",该值将变成一个字典 ( dict),因为它通过模板引擎,之后输出被映射到一个 Python 对象(它不会发生在纯字符串中)。

小知识:你仍然可以通过在 first 之前添加一个空格来欺骗 Ansible 认为它是一个字符串{。请参阅此处的答案

uri模块body_format: raw默认使用并且它需要一个字符串,如果它找到一个失败的对象;参考这个问题