Ansible等待异步任务报错:'dict object'无'ansible_job_id'属性
解决Ansible多异步任务等待报错问题
错误原因
当deployment_type不是'x'或'y'时,你的异步任务会被跳过,此时注册的变量(比如ec2_item)里没有ansible_job_id字段,只有skipped: true标记。等待任务遍历这些变量时,试图访问不存在的ansible_job_id就会触发报错。另外,直接逐个维护9个任务的注册变量,后续修改和扩展也会很麻烦。
解决方案
方案1:过滤跳过的任务,精准等待已执行任务
修改等待任务,给每个注册变量设置默认值,再通过条件跳过未执行的任务:
- name: Wait on EC2 Async Tasks async_status: jid: "{{ item.ansible_job_id }}" with_items: - "{{ ec2_item | default({'skipped': True}) }}" - "{{ ec2_item_again | default({'skipped': True}) }}" # 把剩下7个异步任务的注册变量依次添加到这里 register: job_result until: job_result.finished retries: 60 delay: 15 when: not item.skipped
这样,只要原异步任务被跳过,对应的等待步骤也会自动跳过,不会出现变量未定义的错误。
方案2:统一收集任务ID(推荐,适配多任务场景)
先把所有执行过的异步任务ID收集到一个列表,再统一等待,避免逐个维护变量:
# 1. 执行所有异步任务并注册结果 - name: EC2 spin up async: 6000 poll: 0 shell: # spin up an instance with a playbook register: ec2_item when: deployment_type == 'x' or deployment_type == 'y' - name: EC2 spin up another async: 6000 poll: 0 shell: # spin up another instance with a playbook register: ec2_item_again when: deployment_type == 'x' or deployment_type == 'y' # 剩下7个异步任务按同样格式依次编写 # 2. 收集已执行任务的job ID - name: Collect EC2 async job IDs set_fact: async_job_ids: "{{ async_job_ids | default([]) + [item.ansible_job_id] }}" with_items: - "{{ ec2_item }}" - "{{ ec2_item_again }}" # 把剩下7个任务的注册变量依次添加到这里 when: not item.skipped # 3. 统一等待所有异步任务完成 - name: Wait for all EC2 async tasks to finish async_status: jid: "{{ item }}" with_items: "{{ async_job_ids | default([]) }}" register: job_result until: job_result.finished retries: 60 delay: 15
这个方案更适合你有9个任务的场景,后续新增或删除异步任务时,只需要修改收集列表即可,维护成本更低。
额外提示
- 如果异步任务有可能失败,建议在
async_status任务中保留默认的错误检测(不要加ignore_errors: yes),确保任务失败时能及时终止流程。 - 可以根据EC2实例的实际创建耗时,调整
retries和delay参数,避免重试次数不足或间隔过长导致的等待失效。
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

