Ansible json_query 正在向字典值添加额外的字符

Ansible json_query is adding extra characters to dictionary values

我在使用 ansible 时遇到了一个奇怪的问题,我确信这只是因为我缺乏经验,因为我对 ansible 还比较陌生(我只用了几个星期)

所以,简而言之,我想做的是使用命令模块 运行 AWS CLI 命令列出用户的 AWS 访问密钥,然后从该用户中删除它们。我使用 CLI 而不是 iam 模块的原因是因为我相信 IAM 模块在删除访问密钥方面存在错误。即使我指定状态更新和访问密钥删除和访问密钥状态删除它仍然不会删除访问密钥,或者当我将访问密钥状态设置为非活动时使它们不活动。

第一个任务列出给定用户的访问密钥并注册输出:

- name: List the access keys (if any) of the user(s) we just created
  vars:
    use_key: "{{ enable_access_keys }}"
  command: "aws iam list-access-keys --user-name {{ item }}"
  with_items:
    - "{{ iam_user_name_list }}"
  when: not use_key
  register: list_key_output

^请记住,iam_user_name_list 目前仅包含 1 个用户,这就是为什么我按我的方式访问结果。我知道这需要在未来改变。

因为来自 list_key_output 的标准输出看起来像这样

    "stdout": "{\n    \"AccessKeyMetadata\": [\n        {\n            \"UserName\": \"other-guy\", \n            \"Status\": \"Active\", \n            \"CreateDate\": \"2017-06-29T18:45:04Z\", \n            \"AccessKeyId\": \"removed\"\n        }\n    ]\n}",

我调试 msg stdout 并将其注册到变量 test 以提供正确的 json 格式,没有斜杠和换行符,因此我可以使用 json_query 从 stdout 获取密钥。我正在使用 json 查询,因为无论出于何种原因,AccessKeyId 都未被识别为 AccessKeyMetadata 字典的键。

- name: list keys stdout
  debug:
    msg: "{{ list_key_output.results[0].stdout }}"
  register: test

- name: test variable output
  debug:
    msg: "{{ test.msg.AccessKeyMetadata | json_query('[].AccessKeyId') }}"

至此,我成功从标准输出中获取了访问密钥

ok: [127.0.0.1] => {
    "changed": false,
    "msg": [
        "correct access key here"
    ]
}

现在,我像这样将访问密钥提供给 delete CLI 命令

- name: Remove any access keys our new console user might have
  vars:
    use_key: "{{ enable_access_keys }}"
  command: "aws iam delete-access-key --access-key {{ test.msg.AccessKeyMetadata | json_query('[].AccessKeyId') }} --user-name other-guy"
  when: not use_key
  register: delete_key_output

由于提供的访问密钥无效,此任务失败。

fatal: [127.0.0.1]: FAILED! => {"changed": true, "cmd": ["aws", "iam", "delete-access-key", "--access-key", "[u********************]", "--user-name", "other-guy"], "delta": "0:00:00.388902", "end": "2017-06-29 18:59:13.308230", "failed": true, "rc": 255, "start": "2017-06-29 18:59:12.919328", "stderr": "\nAn error occurred (ValidationError) when calling the DeleteAccessKey operation: The specified value for accessKeyId is invalid. It must contain only alphanumeric characters.", "stderr_lines": ["", "An error occurred (ValidationError) when calling the DeleteAccessKey operation: The specified value for accessKeyId is invalid. It must contain only alphanumeric characters."], "stdout": "", "stdout_lines": []}

如您所见,当我将访问密钥传递给命令时,[u 被添加到访问密钥的前面,] 被附加到它的后面。

为什么会这样?如何在不将 3 个字符添加到访问密钥使其无效的情况下实现我的目标?我不明白为什么会发生这种情况,因为当我以与将它提供给命令的方式相同的方式调试 msg 访问密钥时,它只显示访问密钥,前面没有 [u,后面没有 ]。

抱歉这么久 post 但我觉得我真的必须描述情况才能在这里获得帮助。在此先感谢您的回答!

回答您的确切问题:

ok: [127.0.0.1] => {
    "changed": false,
    "msg": [
        "correct access key here"
    ]
}

注意 msg 中的 [] – 这意味着您打印一个列表,其中包含一个元素 – correct access key here 字符串。

当您尝试将列表转换为字符串时,您会得到它的 Python 解释 [u'correct access key here']

您需要获取列表的第一个元素:

{{ test.msg.AccessKeyMetadata | json_query('[].AccessKeyId') | first }}

P.S。但从我的角度来看,你走错了路。尝试使用 iam 模块解决您的问题。