Ansible ec2_instance模块幂等性及返回值获取问题咨询
问题描述
首次运行Ansible Playbook时,ec2_instance模块可成功创建EC2实例,注册变量会包含完整实例信息(如实例ID),可用于后续操作。但无修改地重复运行同一Playbook时,模块返回"无变更"状态,注册变量中不再包含任何实例相关数据,仅提示1 instances already running, nothing to do.。
示例Playbook:
- name: Create EC2 Instance ec2_instance: image_id: ami-02b9b693377a07477 wait: true name: "{{ ec2_tag }}" exact_count: 1 register: ec2 - name: Print instance ansible.builtin.debug: var: ec2
首次运行输出:
TASK [aws : Create EC2 Instance] ************************************************************************************************************** changed: [localhost] TASK [aws : Print instance] ******************************************************************************************************************* ok: [localhost] => { "ec2": { "changed": true, "failed": false, "instance_ids": [ "i-0390a772d4a60fb83" ], "instances": [ { "ami_launch_index": 0, "architecture": "x86_64", ......
重复运行输出:
TASK [aws : Create EC2 Instance] ************************************************************************************************************** ok: [localhost] TASK [aws : Print instance] ******************************************************************************************************************* ok: [localhost] => { "ec2": { "changed": false, "failed": false, "msg": "1 instances already running, nothing to do." } }
尝试过的无效方案:
- 使用
state: restarted触发变更,但会导致实例重启,不符合无影响重复运行的需求 - 配置
purge_tags: true和动态标签date: "{{ ansible_date_time.iso8601 }}",模块未更新标签,也无法获取实例信息
疑问:
- Ansible的
ec2_instance模块是否具备正确的幂等性? - 如何在保证幂等性的同时,重复运行Playbook时仍能获取实例返回值?
解答
关于ec2_instance的幂等性
ec2_instance模块具备正确的幂等性:当指定exact_count: 1时,模块会检查是否存在符合条件的运行中实例,若数量匹配则不会执行任何变更操作,完全符合幂等性定义(重复执行同一操作不会产生额外影响)。该问题并非幂等性失效,而是模块在无变更时的返回值设计导致的。
解决重复运行时获取实例信息的方案
方案1:结合ec2_instance_info模块查询实例
这是最可靠的方式,在ec2_instance任务之后,通过标签、名称等唯一标识查询实例信息,无论ec2_instance是否执行变更,都能获取到实例数据:
- name: Create EC2 Instance ec2_instance: image_id: ami-02b9b693377a07477 wait: true name: "{{ ec2_tag }}" exact_count: 1 register: ec2 - name: Get EC2 instance info ec2_instance_info: filters: "tag:Name": "{{ ec2_tag }}" instance-state-name: running register: ec2_instance_details - name: Print instance ID ansible.builtin.debug: var: ec2_instance_details.instances[0].instance_id
方案2:强制模块返回实例信息(触发微小无影响变更)
若不想额外添加查询任务,可通过让模块每次执行一个无业务影响的变更来触发返回实例数据。比如使用tags配合purge_tags: false,添加一个用于刷新的时间标签:
- name: Create/Update EC2 Instance with refresh tag ec2_instance: image_id: ami-02b9b693377a07477 wait: true name: "{{ ec2_tag }}" exact_count: 1 purge_tags: false tags: Name: "{{ ec2_tag }}" last_checked: "{{ ansible_date_time.iso8601 }}" register: ec2 - name: Print instance ID ansible.builtin.debug: var: ec2.instances[0].instance_id
注意purge_tags设为false,避免删除实例上已有的其他标签。每次运行时last_checked标签会被更新,模块会返回完整实例信息,同时保证实例本身不会被重建,仅更新标签,符合幂等性要求。
关于之前尝试方案的问题说明
state: restarted:该参数会重启实例,虽能触发变更返回实例信息,但会导致实例重启,不符合无影响重复运行的需求。purge_tags: true+ 动态标签:当purge_tags设为true时,模块会删除所有未在tags参数中定义的标签,首次运行时实例的Name标签是通过name参数设置的,后续运行时如果tags中未包含Name,会导致原有Name标签被删除,同时模块的标签更新判断逻辑未触发变更,因此没有返回实例数据。
内容的提问来源于stack exchange,提问作者Max Allan
相关产品推荐
相关产品推荐

