我正在尝试在一个块中执行以下几个任务:
- name: site.yml --> Handle existing' user's public SSH keys
block:
- name: site.yml --> Get client's existing public SSH key
shell: "aws iam list-ssh-public-keys --user-name {{ client_name }}"
register: rv_keylist
- name: site.yml --> Conditionally delete client's public SSH key
shell: "aws iam delete-ssh-public-key --user-name {{ client_name }} --ssh-public-key-id {{ item.SSHPublicKeyId }}"
loop: "{{ (rv_keylist.stdout | from_json).SSHPublicKeys }}"
when: rv_client_exists.rc == 0 and renew_client_key == 'True'
尽管when
子句的计算结果为false(如下面的输出所示),但是该任务失败了,因为ansible
试图对不存在的变量进行插值,当然失败了
TASK [site.yml --> Get client's existing public SSH key] **********************************************************************************************************************************************************
Friday 05 April 2019 22:23:41 +0300 (0:00:01.800) 0:00:08.818 **********
skipping: [127.0.0.0] => changed=false
skip_reason: Conditional result was False
TASK [site.yml --> Conditionally delete client's public SSH key] **************************************************************************************************************************************************
Friday 05 April 2019 22:23:41 +0300 (0:00:00.063) 0:00:08.882 **********
fatal: [127.0.0.0]: FAILED! =>
msg: 'Unexpected templating type error occurred on ({{ (rv_keylist.stdout | from_json).SSHPublicKeys }}): expected string or buffer'
谁能解决这个问题?
答案 0 :(得分:1)
问题是由两件事引起的:
block
的操作方式是将when
条件分别应用于该块中的每个任务(不会导致整个block
被跳过)。
when
的行为因您的任务是否有循环而有所不同。
对于非循环任务,例如您的“获取客户端现有的公共SSH密钥”任务,when
条件确定Ansible是否应跳过任务。
对于循环任务,when
确定Ansible是否应跳过任务的特定迭代。换句话说,loop
命令仍在评估中,这就是为什么您遇到此特定错误的原因。
您可以这样解决:
- name: site.yml --> Handle existing' user's public SSH keys
when: rv_client_exists.rc == 0 and renew_client_key == 'True'
block:
- name: site.yml --> Get client's existing public SSH key
shell: "aws iam list-ssh-public-keys --user-name {{ client_name }}"
register: rv_keylist
- name: site.yml --> Conditionally delete client's public SSH key
shell: "aws iam delete-ssh-public-key --user-name {{ client_name }} --ssh-public-key-id {{ item.SSHPublicKeyId }}"
loop: "{{ ((rv_keylist.stdout|default('{}'))|from_json).SSHPublicKeys|default([]) }}"
这在几个地方使用了default
过滤器,以确保loop
语句始终具有有效数据。如果rv_keylist.stdout
不可用,则整个表达式将计算为空列表。