Open matt-horwood-mayden opened 2 months ago
@matt-horwood-mayden Can you clarify what the problem is that you are having with the amazon.aws collection? You are passing a list of instance-ids to the ec2_instance module. Are you saying this task is deleting more than those instance ids? Can you provide the logs with verbose output enabled?
Hi @gravesm
We have been using molecule testing to re-write all our roles with Ansible 9, that all works great and looks to work as we want.
But we had an instance created outside of Ansible and had no tags or name that would clash with Ansible molecule testing, but after someone had run molecule test
that random instance was gone.
So I did a test and made an instance from the webUI, then ran molecule test
and after the destroy task of molecule testing my instance was gone too.
It seems that if you hand the ec2_instance
module an empty instance_ids
it will destroy all instance in that account
OK, thanks, that clarifies things. The module does delete everything if the only filter you give it is an empty list of instance ids. In this case, the module isn't clear exactly what the intended behavior should be, but I think this is a bug as it shouldn't be so easy to do so.
great, will work on some code to stop the list being empty or skip it
Here is the updated playbook, this will skip the Destroy ephemeral EC2 instances
task if the list is empty
---
- name: Destroy
hosts: localhost
connection: local
gather_facts: false
no_log: "{{ molecule_no_log }}"
collections:
- community.aws
vars:
# Run config handling
default_run_id: "{{ lookup('password', '/dev/null chars=ascii_lowercase length=5') }}"
default_run_config:
run_id: "{{ default_run_id }}"
run_config_path: "{{ lookup('env', 'MOLECULE_EPHEMERAL_DIRECTORY') }}/run-config.yml"
run_config_from_file: "{{ (lookup('file', run_config_path, errors='ignore') or '{}') | from_yaml }}"
run_config: '{{ default_run_config | combine(run_config_from_file) }}'
# Platform settings handling
default_aws_profile: "{{ lookup('env', 'AWS_PROFILE') }}"
default_key_inject_method: cloud-init # valid values: [cloud-init, ec2]
default_key_name: "molecule-{{ run_config.run_id }}"
default_security_group_name: "molecule-{{ run_config.run_id }}"
platform_defaults:
aws_profile: "{{ default_aws_profile }}"
key_inject_method: "{{ default_key_inject_method }}"
key_name: "{{ default_key_name }}"
region: ""
security_group_name: "{{ default_security_group_name }}"
security_groups: []
vpc_id: ""
vpc_subnet_id: ""
# Merging defaults into a list of dicts is, it turns out, not straightforward
platforms: >-
{{ [platform_defaults | dict2items]
| product(molecule_yml.platforms | map('dict2items') | list)
| map('flatten', levels=1)
| list
| map('items2dict')
| list }}
# Stored instance config
instance_config: "{{ (lookup('file', molecule_instance_config, errors='ignore') or '[]') | from_yaml }}"
pre_tasks:
- name: Validate platform configurations
assert:
that:
- platforms | length > 0
- platform.name is string and platform.name | length > 0
- platform.aws_profile is string
- platform.key_inject_method is in ["cloud-init", "ec2"]
- platform.key_name is string and platform.key_name | length > 0
- platform.region is string
- platform.security_group_name is string and platform.security_group_name | length > 0
- platform.security_groups is sequence
- platform.vpc_id is string
- platform.vpc_subnet_id is string and platform.vpc_subnet_id | length > 0
quiet: true
loop: '{{ platforms }}'
loop_control:
loop_var: platform
label: "{{ platform.name }}"
tasks:
- name: Look up subnets to determine VPCs (if needed)
ec2_vpc_subnet_info:
subnet_ids: "{{ item.vpc_subnet_id }}"
loop: "{{ platforms }}"
loop_control:
label: "{{ item.name }}"
when: not item.vpc_id
register: subnet_info
- name: Validate discovered information
assert:
that: platform.vpc_id or (subnet_info.results[index].subnets | length > 0)
quiet: true
loop: "{{ platforms }}"
loop_control:
loop_var: platform
index_var: index
label: "{{ platform.name }}"
- name: Destroy ephemeral EC2 instances
ec2_instance:
profile: "{{ item.aws_profile | default(omit) }}"
region: "{{ item.region | default(omit) }}"
instance_ids: "{{ item.instance_ids }}"
state: absent
when: item is defined
loop: "{{ instance_config }}"
loop_control:
label: "{{ item.instance }}"
register: ec2_instances_async
- name: you dead yet
ec2_instance_info:
instance_ids: "{{ instance.instance_id }}"
vars:
instance: "{{ ec2_instances_async.results[index].instances[0] }}"
loop: "{{ ec2_instances_async.results }}"
loop_control:
index_var: index
label: "{{ platforms[index].name }}"
until: instance.state.name == "terminated"
when: ec2_instances_async is changed
retries: 300
- name: Write Molecule instance configs
copy:
dest: "{{ molecule_instance_config }}"
content: "{{ [] | to_yaml }}"
- name: Destroy ephemeral security groups (if needed)
ec2_group:
profile: "{{ item.aws_profile | default(omit) }}"
region: "{{ item.region | default(omit) }}"
vpc_id: "{{ item.vpc_id or vpc_subnet.vpc_id }}"
name: "{{ item.security_group_name }}"
state: absent
vars:
vpc_subnet: "{{ subnet_info.results[index].subnets[0] }}"
loop: "{{ platforms }}"
loop_control:
index_var: index
label: "{{ item.name }}"
when: item.security_groups | length == 0
- name: Destroy ephemeral keys (if needed)
ec2_key:
profile: "{{ item.aws_profile | default(omit) }}"
region: "{{ item.region | default(omit) }}"
name: "{{ item.key_name }}"
state: absent
loop: "{{ platforms }}"
loop_control:
index_var: index
label: "{{ item.name }}"
when: item.key_inject_method == "ec2"
Summary
when running molecule a molecule test, any instance not made with molecule is destroyed
Issue Type
Bug Report
Component Name
ec2_instance
Ansible Version
Collection Versions
AWS SDK versions
Configuration
OS / Environment
AWS CLI
Steps to Reproduce
Expected Results
when I run a destroy either nothing happens or
Actual Results
Code of Conduct