- name: Integration testing for ec2_eip
  module_defaults:
    group/aws:
      aws_access_key: '{{ aws_access_key }}'
      aws_secret_key: '{{ aws_secret_key }}'
      security_token: '{{ security_token | default(omit) }}'
      region: '{{ aws_region }}'
    ec2_eip:
      in_vpc: true
  collections:
    - amazon.aws
  block:
  # =====================================================
  - name: Get the current caller identity facts
    aws_caller_info: null
    register: caller_info
  - name: list available AZs
    aws_az_info: null
    register: region_azs
  - name: pick an AZ for testing
    set_fact:
      subnet_az: '{{ region_azs.availability_zones[0].zone_name }}'
  - name: create a VPC
    ec2_vpc_net:
      name: '{{ resource_prefix }}-vpc'
      state: present
      cidr_block: '{{ vpc_cidr }}'
      tags:
        AnsibleEIPTest: Pending
        AnsibleEIPTestPrefix: '{{ resource_prefix }}'
    register: vpc_result
  - name: create subnet
    ec2_vpc_subnet:
      cidr: '{{ subnet_cidr }}'
      az: '{{ subnet_az }}'
      vpc_id: '{{ vpc_result.vpc.id }}'
      state: present
    register: vpc_subnet_create
  - ec2_vpc_igw:
      state: present
      vpc_id: '{{ vpc_result.vpc.id }}'
    register: vpc_igw
  - name: "Find AMI to use"
    ec2_ami_info:
      owners: 'amazon'
      filters:
        name: 'amzn2-ami-hvm-2.0.20190612-x86_64-gp2'
    register: ec2_amis
  - name: "create a security group"
    ec2_group:
      state: present
      name: '{{ resource_prefix }}-sg'
      description: a security group for ansible tests
      vpc_id: '{{ vpc_result.vpc.id }}'
      rules:
        - proto: tcp
          from_port: 22
          to_port: 22
          cidr_ip: 0.0.0.0/0
    register: security_group
  - name: Create instance for attaching
    ec2_instance:
      name: '{{ resource_prefix }}-instance'
      image_id: '{{ ec2_amis.images[0].image_id }}'
      security_group: '{{ security_group.group_id }}'
      vpc_subnet_id: '{{ vpc_subnet_create.subnet.id }}'
      wait: no  ## Don't delay the tests, we'll check again before we need it
    register: create_ec2_instance_result

  # =====================================================
  - name: Look for signs of concurrent EIP tests.  Pause if they are running or their prefix comes before ours.
    vars:
      running_query: vpcs[?tags.AnsibleEIPTest=='Running']
      pending_query: vpcs[?tags.AnsibleEIPTest=='Pending'].tags.AnsibleEIPTestPrefix
    ec2_vpc_net_info:
      filters:
        tag:AnsibleEIPTest:
        - Pending
        - Running
    register: vpc_info
    retries: 120
    delay: 5
    until:
    - ( vpc_info | community.general.json_query(running_query) | length == 0 )
    - ( vpc_info | community.general.json_query(pending_query) | sort | first == resource_prefix )
  - name: Make a crude lock
    ec2_vpc_net:
      name: '{{ resource_prefix }}-vpc'
      state: present
      cidr_block: '{{ vpc_cidr }}'
      tags:
        AnsibleEIPTest: Running
        AnsibleEIPTestPrefix: '{{ resource_prefix }}'
  # =====================================================
  - name: Get current state of EIPs
    ec2_eip_info: null
    register: eip_info_start
  - name: Require that there are no free IPs when we start, otherwise we can't test things properly
    assert:
      that:
      - eip_info_start is defined
      - '"addresses" in eip_info_start'
      - ( eip_info_start.addresses | length ) == ( eip_info_start | community.general.json_query("addresses[].association_id") | length )
  - name: Allocate a new eip (no conditions)
    ec2_eip:
      state: present
    register: eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip is defined
      - eip is changed
      - eip.public_ip is defined and ( eip.public_ip | ansible.netcommon.ipaddr )
      - eip.allocation_id is defined and eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 1 == ( eip_info.addresses | length )
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
  - assert:
      that:
      - '"addresses" in eip_info'
      - eip_info.addresses | length == 1
      - eip_info.addresses[0].allocation_id == eip.allocation_id
      - eip_info.addresses[0].domain == "vpc"
      - eip_info.addresses[0].public_ip == eip.public_ip
  - ec2_eip_info:
      filters:
        allocation-id: '{{ eip.allocation_id }}'
  - assert:
      that:
      - '"addresses" in eip_info'
      - eip_info.addresses | length == 1
      - eip_info.addresses[0].allocation_id == eip.allocation_id
      - eip_info.addresses[0].domain == "vpc"
      - eip_info.addresses[0].public_ip == eip.public_ip
  - name: Release eip
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
    register: eip_release
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip_release is defined
      - eip_release is changed
      - ( eip_info_start.addresses | length ) == ( eip_info.addresses | length )
  - name: Allocate a new eip - attempt reusing unallocated ones (none available)
    ec2_eip:
      state: present
      reuse_existing_ip_allowed: true
    register: eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip is defined
      - eip is changed
      - eip.public_ip is defined and ( eip.public_ip | ansible.netcommon.ipaddr )
      - eip.allocation_id is defined and eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 1  == ( eip_info.addresses | length )
  - name: Re-Allocate a new eip - attempt reusing unallocated ones (one available)
    ec2_eip:
      state: present
      reuse_existing_ip_allowed: true
    register: reallocate_eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - reallocate_eip is defined
      - reallocate_eip is not changed
      - reallocate_eip.public_ip is defined and ( reallocate_eip.public_ip | ansible.netcommon.ipaddr )
      - reallocate_eip.allocation_id is defined and reallocate_eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 1  == ( eip_info.addresses | length )
  - name: Release eip
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
    register: eip_release
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - ( eip_info_start.addresses | length ) == ( eip_info.addresses | length )
      - eip_release is defined
      - eip_release is changed
  - name: Allocate a new eip
    ec2_eip:
      state: present
    register: eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip is defined
      - eip is changed
      - eip.public_ip is defined and ( eip.public_ip | ansible.netcommon.ipaddr )
      - eip.allocation_id is defined and eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 1  == ( eip_info.addresses | length )
  - name: Match an existing eip (changed == false)
    ec2_eip:
      state: present
      public_ip: '{{ eip.public_ip }}'
    register: reallocate_eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - reallocate_eip is defined
      - reallocate_eip is not changed
      - reallocate_eip.public_ip is defined and ( reallocate_eip.public_ip | ansible.netcommon.ipaddr )
      - reallocate_eip.allocation_id is defined and reallocate_eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 1  == ( eip_info.addresses | length )
  - name: Release eip
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
    register: eip_release
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip_release is defined
      - eip_release is changed
      - ( eip_info_start.addresses | length )  == ( eip_info.addresses | length )
  - name: Allocate a new eip (no tags)
    ec2_eip:
      state: present
    register: eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip is defined
      - eip is changed
      - eip.public_ip is defined and ( eip.public_ip | ansible.netcommon.ipaddr )
      - eip.allocation_id is defined and eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 1  == ( eip_info.addresses | length )
  - name: attempt reusing an existing eip with a tag (No match available)
    ec2_eip:
      state: present
      reuse_existing_ip_allowed: true
      tag_name: Team
    register: no_tagged_eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - no_tagged_eip is defined
      - no_tagged_eip is changed
      - no_tagged_eip.public_ip is defined and ( no_tagged_eip.public_ip | ansible.netcommon.ipaddr )
      - no_tagged_eip.allocation_id is defined and no_tagged_eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 2  == ( eip_info.addresses | length )
  - name: tag eip so we can try matching it
    ec2_tag:
      state: present
      resource: '{{ eip.allocation_id }}'
      tags:
        Team: Frontend
  - name: attempt reusing an existing eip with a tag (Match available)
    ec2_eip:
      state: present
      reuse_existing_ip_allowed: true
      tag_name: Team
    register: reallocate_eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - reallocate_eip is defined
      - reallocate_eip is not changed
      - reallocate_eip.public_ip is defined and ( reallocate_eip.public_ip | ansible.netcommon.ipaddr )
      - reallocate_eip.allocation_id is defined and reallocate_eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 2  == ( eip_info.addresses | length )
  - name: attempt reusing an existing eip with a tag and it's value (no match available)
    ec2_eip:
      state: present
      reuse_existing_ip_allowed: true
      tag_name: Team
      tag_value: Backend
    register: backend_eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - backend_eip is defined
      - backend_eip is changed
      - backend_eip.public_ip is defined and ( backend_eip.public_ip | ansible.netcommon.ipaddr )
      - backend_eip.allocation_id is defined and backend_eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 3  == ( eip_info.addresses | length )
  - name: tag eip so we can try matching it
    ec2_tag:
      state: present
      resource: '{{ eip.allocation_id }}'
      tags:
        Team: Backend
  - name: attempt reusing an existing eip with a tag and it's value (match available)
    ec2_eip:
      state: present
      reuse_existing_ip_allowed: true
      tag_name: Team
      tag_value: Backend
    register: reallocate_eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - reallocate_eip is defined
      - reallocate_eip is not changed
      - reallocate_eip.public_ip is defined and reallocate_eip.public_ip != ""
      - reallocate_eip.allocation_id is defined and reallocate_eip.allocation_id != ""
      - ( eip_info_start.addresses | length ) + 3  == ( eip_info.addresses | length )
  - name: Release backend_eip
    ec2_eip:
      state: absent
      public_ip: '{{ backend_eip.public_ip }}'
    register: eip_release
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip_release is defined
      - eip_release is changed
      - ( eip_info_start.addresses | length ) + 2  == ( eip_info.addresses | length )
  - name: Release no_tagged_eip
    ec2_eip:
      state: absent
      public_ip: '{{ no_tagged_eip.public_ip }}'
    register: eip_release
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip_release is defined
      - eip_release is changed
      - ( eip_info_start.addresses | length ) + 1  == ( eip_info.addresses | length )
  - name: Release eip
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
    register: eip_release
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip_release is defined
      - eip_release is changed
      - ( eip_info_start.addresses | length ) == ( eip_info.addresses | length )
  - name: allocate a new eip from a pool
    ec2_eip:
      state: present
      public_ipv4_pool: amazon
    register: eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip is defined
      - eip is changed
      - eip.public_ip is defined and ( eip.public_ip | ansible.netcommon.ipaddr )
      - eip.allocation_id is defined and eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 1  == ( eip_info.addresses | length )
  - name: create ENI A
    ec2_eni:
      subnet_id: '{{ vpc_subnet_create.subnet.id }}'
    register: eni_create_a
  - name: create ENI B
    ec2_eni:
      subnet_id: '{{ vpc_subnet_create.subnet.id }}'
    register: eni_create_b
  - name: Attach EIP to ENI A
    ec2_eip:
      public_ip: '{{ eip.public_ip }}'
      device_id: '{{ eni_create_a.interface.id }}'
    register: associate_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
    register: eip_info
  - assert:
      that:
      - associate_eip is defined
      - associate_eip is changed
      - eip_info.addresses | length == 1
      - associate_eip.public_ip is defined and eip.public_ip == associate_eip.public_ip
      - associate_eip.allocation_id is defined and eip.allocation_id == associate_eip.allocation_id
      - eip_info.addresses[0].allocation_id == eip.allocation_id
      - eip_info.addresses[0].domain == "vpc"
      - eip_info.addresses[0].public_ip == eip.public_ip
      - eip_info.addresses[0].association_id is defined and eip_info.addresses[0].association_id.startswith("eipassoc-")
      - eip_info.addresses[0].network_interface_id == eni_create_a.interface.id
      - eip_info.addresses[0].private_ip_address is defined and ( eip_info.addresses[0].private_ip_address | ansible.netcommon.ipaddr )
      - eip_info.addresses[0].network_interface_owner_id == caller_info.account
  - name: Re-Attach EIP to ENI A (no change)
    ec2_eip:
      public_ip: '{{ eip.public_ip }}'
      device_id: '{{ eni_create_a.interface.id }}'
    register: associate_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
    register: eip_info
  - assert:
      that:
      - associate_eip is defined
      - associate_eip is not changed
      - associate_eip.public_ip is defined and eip.public_ip == associate_eip.public_ip
      - associate_eip.allocation_id is defined and eip.allocation_id == associate_eip.allocation_id
      - eip_info.addresses | length == 1
      - eip_info.addresses[0].allocation_id == eip.allocation_id
      - eip_info.addresses[0].domain == "vpc"
      - eip_info.addresses[0].public_ip == eip.public_ip
      - eip_info.addresses[0].association_id is defined and eip_info.addresses[0].association_id.startswith("eipassoc-")
      - eip_info.addresses[0].network_interface_id == eni_create_a.interface.id
      - eip_info.addresses[0].private_ip_address is defined and ( eip_info.addresses[0].private_ip_address | ansible.netcommon.ipaddr )
  - name: Attach EIP to ENI B (should fail, already associated)
    ec2_eip:
      public_ip: '{{ eip.public_ip }}'
      device_id: '{{ eni_create_b.interface.id }}'
    register: associate_eip
    ignore_errors: true
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
    register: eip_info
  - assert:
      that:
      - associate_eip is defined
      - associate_eip is failed
      - eip_info.addresses | length == 1
      - eip_info.addresses[0].allocation_id == eip.allocation_id
      - eip_info.addresses[0].domain == "vpc"
      - eip_info.addresses[0].public_ip == eip.public_ip
      - eip_info.addresses[0].association_id is defined and eip_info.addresses[0].association_id.startswith("eipassoc-")
      - eip_info.addresses[0].network_interface_id == eni_create_a.interface.id
      - eip_info.addresses[0].private_ip_address is defined and ( eip_info.addresses[0].private_ip_address | ansible.netcommon.ipaddr )
  - name: Attach EIP to ENI B
    ec2_eip:
      public_ip: '{{ eip.public_ip }}'
      device_id: '{{ eni_create_b.interface.id }}'
      allow_reassociation: true
    register: associate_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
    register: eip_info
  - assert:
      that:
      - associate_eip is defined
      - associate_eip is changed
      - associate_eip.public_ip is defined and eip.public_ip == associate_eip.public_ip
      - associate_eip.allocation_id is defined and eip.allocation_id == associate_eip.allocation_id
      - eip_info.addresses | length == 1
      - eip_info.addresses[0].allocation_id == eip.allocation_id
      - eip_info.addresses[0].domain == "vpc"
      - eip_info.addresses[0].public_ip == eip.public_ip
      - eip_info.addresses[0].association_id is defined and eip_info.addresses[0].association_id.startswith("eipassoc-")
      - eip_info.addresses[0].network_interface_id == eni_create_b.interface.id
      - eip_info.addresses[0].private_ip_address is defined and ( eip_info.addresses[0].private_ip_address | ansible.netcommon.ipaddr )
  - name: Detach EIP from ENI B, without enabling release on disassociation
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
      device_id: '{{ eni_create_b.interface.id }}'
    register: disassociate_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
    register: eip_info
  - assert:
      that:
      - associate_eip is defined
      - associate_eip is changed
      - eip_info.addresses | length == 1
  - name: Re-detach EIP from ENI B, without enabling release on disassociation
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
      device_id: '{{ eni_create_b.interface.id }}'
    register: associate_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
    register: eip_info
  - assert:
      that:
      - associate_eip is defined
      - associate_eip is not changed
      - eip_info.addresses | length == 1
  - name: Attach EIP to ENI A
    ec2_eip:
      public_ip: '{{ eip.public_ip }}'
      device_id: '{{ eni_create_a.interface.id }}'
    register: associate_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
    register: eip_info
  - assert:
      that:
      - associate_eip is defined
      - associate_eip is changed
      - associate_eip.public_ip is defined and eip.public_ip == associate_eip.public_ip
      - associate_eip.allocation_id is defined and eip.allocation_id == associate_eip.allocation_id
      - eip_info.addresses[0].network_interface_id == eni_create_a.interface.id
  - name: Detach EIP from ENI A, enabling release on disassociation
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
      device_id: '{{ eni_create_a.interface.id }}'
      release_on_disassociation: true
    register: disassociate_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
    register: eip_info
  - assert:
      that:
      - associate_eip is defined
      - associate_eip is changed
      - eip_info.addresses | length == 0
  - name: Re-detach EIP from ENI A, enabling release on disassociation
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
      device_id: '{{ eni_create_a.interface.id }}'
      release_on_disassociation: true
    register: associate_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ eip.public_ip }}'
    register: eip_info
  - assert:
      that:
      - associate_eip is defined
      - associate_eip is not changed
      - eip_info.addresses | length == 0
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - ( eip_info_start.addresses | length ) == ( eip_info.addresses | length )
  - name: Cleanup ENI B
    ec2_eni:
      state: absent
      eni_id: '{{ eni_create_b.interface.id }}'
  - name: Cleanup ENI A
    ec2_eni:
      state: absent
      eni_id: '{{ eni_create_a.interface.id }}'
  - name: Make sure the instance is ready
    ec2_instance_info:
      filters:
        "tag:Name": '{{ resource_prefix }}-instance'
    register: instance_info
    until: instance_info.instances[0].state.name == 'running'
  - name: Attach eip to an EC2 instance
    ec2_eip:
      device_id: '{{ instance_info.instances[0].instance_id }}'
      state: present
      release_on_disassociation: yes
    register: instance_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ instance_eip.public_ip }}'
    register: eip_info
  - assert:
      that:
        - instance_eip is success
        - eip_info.addresses[0].allocation_id is defined
        - eip_info.addresses[0].instance_id == '{{ instance_info.instances[0].instance_id }}'
  - name: Attach eip to an EC2 instance with private Ip specified
    ec2_eip:
      device_id: '{{ instance_info.instances[0].instance_id }}'
      private_ip_address: '{{ instance_info.instances[0].private_ip_address }}'
      state: present
      release_on_disassociation: yes
    register: instance_eip
  - ec2_eip_info:
      filters:
        public-ip: '{{ instance_eip.public_ip }}'
    register: eip_info
  - assert:
      that:
        - instance_eip is success
        - eip_info.addresses[0].allocation_id is defined
        - eip_info.addresses[0].instance_id == '{{ instance_info.instances[0].instance_id }}'
  # =====================================================
  - name: Cleanup instance
    ec2_instance:
      instance_ids: '{{ create_ec2_instance_result.instance_ids }}'
      state: absent
  - name: Cleanup instance eip
    ec2_eip:
      state: absent
      public_ip: '{{ instance_eip.public_ip }}'
    register: eip_cleanup
    retries: 5
    delay: 5
    until: eip_cleanup is successful
  - name: Cleanup IGW
    ec2_vpc_igw:
      state: absent
      vpc_id: '{{ vpc_result.vpc.id }}'
    register: vpc_igw
  - name: Cleanup security group
    ec2_group:
      state: absent
      name: '{{ resource_prefix }}-sg'
  - name: Cleanup Subnet
    ec2_vpc_subnet:
      state: absent
      cidr: '{{ subnet_cidr }}'
      vpc_id: '{{ vpc_result.vpc.id }}'
  - name: Release eip
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
    register: eip_release
    ignore_errors: true
  - name: allocate a new eip
    ec2_eip:
      state: present
    register: eip
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip is defined
      - eip is changed
      - eip.public_ip is defined and ( eip.public_ip | ansible.netcommon.ipaddr )
      - eip.allocation_id is defined and eip.allocation_id.startswith("eipalloc-")
      - ( eip_info_start.addresses | length ) + 1 == ( eip_info.addresses | length )
  - name: Release eip
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
    register: eip_release
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip_release is defined
      - eip_release is changed
      - ( eip_info_start.addresses | length ) == ( eip_info.addresses | length )
  - name: Rerelease eip (no change)
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
    register: eip_release
  - ec2_eip_info: null
    register: eip_info
  - assert:
      that:
      - eip_release is defined
      - eip_release is not changed
      - ( eip_info_start.addresses | length ) == ( eip_info.addresses | length )
  - name: Cleanup VPC
    ec2_vpc_net:
      state: absent
      name: '{{ resource_prefix }}-vpc'
      cidr_block: '{{ vpc_cidr }}'
  # =====================================================
  always:
  - name: Cleanup instance (by id)
    ec2_instance:
      instance_ids: '{{ create_ec2_instance_result.instance_ids }}'
      state: absent
      wait: true
    ignore_errors: true
  - name: Cleanup instance (by name)
    ec2_instance:
      name: '{{ resource_prefix }}-instance'
      state: absent
      wait: true
    ignore_errors: true
  - name: Cleanup ENI A
    ec2_eni:
      state: absent
      eni_id: '{{ eni_create_a.interface.id }}'
    ignore_errors: true
  - name: Cleanup ENI B
    ec2_eni:
      state: absent
      eni_id: '{{ eni_create_b.interface.id }}'
    ignore_errors: true
  - name: Cleanup instance eip
    ec2_eip:
      state: absent
      public_ip: '{{ instance_eip.public_ip }}'
    retries: 5
    delay: 5
    until: eip_cleanup is successful
    ignore_errors: true
  - name: Cleanup IGW
    ec2_vpc_igw:
      state: absent
      vpc_id: '{{ vpc_result.vpc.id }}'
    register: vpc_igw
    ignore_errors: true
  - name: Cleanup security group
    ec2_group:
      state: absent
      name: '{{ resource_prefix }}-sg'
    ignore_errors: true
  - name: Cleanup Subnet
    ec2_vpc_subnet:
      state: absent
      cidr: '{{ subnet_cidr }}'
      vpc_id: '{{ vpc_result.vpc.id }}'
    ignore_errors: true
  - name: Cleanup eip
    ec2_eip:
      state: absent
      public_ip: '{{ eip.public_ip }}'
    when: eip is changed
    ignore_errors: true
  - name: Cleanup reallocate_eip
    ec2_eip:
      state: absent
      public_ip: '{{ reallocate_eip.public_ip }}'
    when: reallocate_eip is changed
    ignore_errors: true
  - name: Cleanup backend_eip
    ec2_eip:
      state: absent
      public_ip: '{{ backend_eip.public_ip }}'
    when: backend_eip is changed
    ignore_errors: true
  - name: Cleanup no_tagged_eip
    ec2_eip:
      state: absent
      public_ip: '{{ no_tagged_eip.public_ip }}'
    when: no_tagged_eip is changed
    ignore_errors: true
  - name: Cleanup VPC
    ec2_vpc_net:
      state: absent
      name: '{{ resource_prefix }}-vpc'
      cidr_block: '{{ vpc_cidr }}'
    ignore_errors: true
