Skip to content

Commit 5551edd

Browse files
authored
Improve teardown and support purge mode
* Improve fetching of env_crn in Runtime role to not rely on Platform role * Have DF teardown only execute when an Environment is found * Introduce 'purge' keyword for Definitions to signal that an AWS VPC and all child objects, and all unattached EBS volumes in the name_prefix, should be removed from the given infra_region * Add network, compute, and storage discovery to AWS Initialization * Add teardown of discovered network, compute and storage when purge is used * Enforce check that a CDP Environment has no listed descendants before allowing teardown * Add new Runtime purge discovery and execution controlled by new purge key * Move Datahub purge to after Experiences that lean on Datahubs for execution to allow controlled removal to be tried first * Improve async wait for Runtime removal to complete * Add force delete, and force data removal options to Runtimes where appropriate * Standardise usage of json_query to correctly use FQCN of community.general.json_query * Add warning to Create AWS Buckets function for common error where user attempts to create a bucket that is already owned elsewhere * Remove unused Runtime service info registrations * Make EKS Teardown async in case of multiple orphaned clusters * Handle edge case for network teardown where the entry exists but has no objects to remove * Reorder AWS Network teardown so that NGW and RTB are removed before cleaning ENI that may be using them * Improve setting CDP Environment CRN during Runtime role Discovery when an Environment matching the name is found. Do not default to an empty string. * Add task to discover list of DF Service Deployments matching target Environment during Runtime role execution. * Improve logic around when to run DF and DW teardown tasks. * Add option to loop over DF Service teardown for situations where multiple Disabled services may need purging besides the single Active service. * Source force_teardown from globals rather than from top level key Signed-off-by: Daniel Chaffelson <chaffelson@gmail.com>
1 parent cbe3e20 commit 5551edd

19 files changed

+552
-145
lines changed

roles/common/defaults/main.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,4 +138,7 @@ common__include_dw: "{{ dw is defined | bool }}"
138138
common__include_de: "{{ de is defined | bool }}"
139139
common__include_df: "{{ df is defined | bool }}"
140140
common__include_datahub: "{{ datahub is defined | bool }}"
141-
common__include_opdb: "{{ opdb is defined | bool }}"
141+
common__include_opdb: "{{ opdb is defined | bool }}"
142+
143+
# Teardown
144+
common__force_teardown: "{{ globals.force_teardown | default(False) }}" # WARNING: This will purge your namespace and anything related to it, use with extreme caution

roles/infrastructure/defaults/main.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,7 @@ infra__cdp_control_plane_cidr: "{{ env.cdp.control_plane.cidr | default(inf
133133
# Utility Service for Download Mirror
134134
infra__create_utility_service: "{{ globals.create_utility_service | default('no') | bool }}"
135135
infra__utlity_bucket_name: "{{ globals.utility_bucket_name | default('') }}"
136+
137+
# Teardown
138+
infra__force_teardown: "{{ common__force_teardown }}"
139+
infra__env_name: "{{ common__env_name }}" # Used for purge lookups

roles/infrastructure/tasks/initialize_aws.yml

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,133 @@
8888
- name: Set Download Mirror output artefacts
8989
ansible.builtin.set_fact:
9090
infra__type: "{{ infra__type }}"
91-
infra__region: "{{ infra__region }}"
91+
infra__region: "{{ infra__region }}"
92+
93+
- name: Discover VPC Dependencies during Purge cleanup
94+
when:
95+
- infra__force_teardown | bool
96+
- infra__aws_vpc_id | length > 1
97+
block:
98+
- name: Fetch Network Interfaces in VPC
99+
register: __infra_vpc_enis
100+
amazon.aws.ec2_eni_info:
101+
region: "{{ infra__region }}"
102+
filters: "{{ __filters | items2dict }}"
103+
vars:
104+
__filters:
105+
- key: "vpc-id"
106+
value: "{{ infra__aws_vpc_id }}"
107+
108+
- name: List all EC2 instances in VPC
109+
register: __infra_vpc_ec2_instances
110+
community.aws.ec2_instance_info:
111+
region: "{{ infra__region }}"
112+
filters: "{{ __filters | items2dict }}"
113+
vars:
114+
__filters:
115+
- key: "vpc-id"
116+
value: "{{ infra__aws_vpc_id }}"
117+
118+
- name: Update discovered compute inventory for later action
119+
ansible.builtin.set_fact:
120+
infra__discovered_compute_inventory: "{{ infra__discovered_compute_inventory + __infra_vpc_ec2_instances.instances }}"
121+
122+
- name: List EKS Clusters
123+
register: __infra_eks_cluster_list
124+
command: "aws eks list-clusters"
125+
126+
- name: Describe all EKS Clusters
127+
register: __infra_eks_cluster_details
128+
ansible.builtin.command: "aws eks describe-cluster --name {{ __infra_eks_cluster_item }}"
129+
loop_control:
130+
loop_var: __infra_eks_cluster_item
131+
loop: "{{ __infra_eks_cluster_list.stdout | from_json | community.general.json_query('clusters') }} "
132+
133+
- name: Filter EKS by this VPC
134+
ansible.builtin.set_fact:
135+
__infra_vpc_eks_cluster_names: "{{ __infra_vpc_eks_cluster_names | d([]) + [__infra_lookup_name] }}"
136+
when: __infra_lookup_vpc == infra__aws_vpc_id
137+
vars:
138+
__infra_lookup_vpc: "{{ __infra_eks_cluster_detail_item.stdout | from_json | community.general.json_query('cluster.resourcesVpcConfig.vpcId') }}"
139+
__infra_lookup_name: "{{ __infra_eks_cluster_detail_item.stdout | from_json | community.general.json_query('cluster.name') }}"
140+
loop: "{{ __infra_eks_cluster_details.results }}"
141+
loop_control:
142+
loop_var: __infra_eks_cluster_detail_item
143+
144+
- name: List all ASGs in region
145+
register: __infra_ec2_asg_list
146+
community.aws.ec2_asg_info:
147+
region: "{{ infra__region }}"
148+
149+
- name: Fetch list of all Subnets in VPC
150+
register: __infra_disc_subnets
151+
amazon.aws.ec2_vpc_subnet_info:
152+
filters:
153+
vpc-id: "{{ infra__aws_vpc_id }}"
154+
155+
- name: Filter ASGs by Subnets in this VPC
156+
when:
157+
- __infra_ec2_asg_list.results | length > 0
158+
- __infra_asg_filter_item.vpc_zone_identifier in __infra_vpc_subnet_ids
159+
ansible.builtin.set_fact:
160+
__infra_aws_asg_names: "{{ __infra_aws_asg_names | default([]) + [__infra_asg_filter_item.auto_scaling_group_name] }}"
161+
vars:
162+
__infra_vpc_subnet_ids: "{{ __infra_disc_subnets.subnets | community.general.json_query('[*].id') | list | unique }}"
163+
__infra_vpc_sg_ids: "{{ __infra_disc_sgs.security_groups | community.general.json_query('[*].group_id') | list | unique }}"
164+
loop: "{{ __infra_ec2_asg_list.results }}"
165+
loop_control:
166+
loop_var: __infra_asg_filter_item
167+
168+
- name: List all AWS ELBs in region
169+
community.aws.ec2_elb_info:
170+
region: "{{ infra__region }}"
171+
register: __infra_ec2_elbs
172+
173+
- name: Filter list of ELBS to match our VPC
174+
when:
175+
- __infra_ec2_elbs.elbs | length > 0
176+
- __infra_ec2_elb_item.vpc_id == infra__aws_vpc_id
177+
ansible.builtin.set_fact:
178+
__infra_ec2_elb_names: "{{ __infra_ec2_elb_names | default([]) + [__infra_ec2_elb_item.name] }}"
179+
loop: "{{ __infra_ec2_elbs.elbs }}"
180+
loop_control:
181+
loop_var: __infra_ec2_elb_item
182+
183+
- name: List NAT gatways in VPC
184+
community.aws.ec2_vpc_nat_gateway_info:
185+
region: "{{ infra__region }}"
186+
filters:
187+
vpc-id: "{{ infra__aws_vpc_id }}"
188+
register: __infra_aws_nat_gateways
189+
190+
- name: List all Security Groups in VPC
191+
register: __infra_aws_sgs
192+
amazon.aws.ec2_group_info:
193+
region: "{{ infra__region }}"
194+
filters:
195+
vpc-id: "{{ infra__aws_vpc_id }}"
196+
197+
- name: List all Route tables in VPC
198+
register: __infra_aws_rtbs
199+
community.aws.ec2_vpc_route_table_info:
200+
region: "{{ infra__region }}"
201+
filters:
202+
vpc-id: "{{ infra__aws_vpc_id }}"
203+
204+
- name: Discover Storage during Purge cleanup
205+
when:
206+
- infra__force_teardown | bool
207+
block:
208+
- name: List AWS EBS Volumes
209+
register: __infra_aws_ebs_vols
210+
amazon.aws.ec2_vol_info:
211+
region: "{{ infra__region }}"
212+
filters:
213+
status: available
214+
215+
- name: Check for Orphaned EFS matching Namespace
216+
register: __infra_efs_fs
217+
community.aws.efs_info:
218+
region: "{{ infra__region }}"
219+
tags:
220+
Environment: "{{ infra__env_name }}"

roles/infrastructure/tasks/initialize_azure.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@
5151

5252
- name: Set Azure Caller Information
5353
ansible.builtin.set_fact:
54-
infra__azure_subscription_id: "{{ __azure_account_info.stdout | from_json | json_query('id') }}"
55-
infra__azure_subscription_name: "{{ __azure_account_info.stdout | from_json | json_query('name') }}"
56-
infra__azure_tenant_id: "{{ __azure_account_info.stdout | from_json | json_query('tenantId') }}"
57-
infra__azure_calling_user: "{{ __azure_account_info.stdout | from_json | json_query('user.name') }}"
54+
infra__azure_subscription_id: "{{ __azure_account_info.stdout | from_json | community.general.json_query('id') }}"
55+
infra__azure_subscription_name: "{{ __azure_account_info.stdout | from_json | community.general.json_query('name') }}"
56+
infra__azure_tenant_id: "{{ __azure_account_info.stdout | from_json | community.general.json_query('tenantId') }}"
57+
infra__azure_calling_user: "{{ __azure_account_info.stdout | from_json | community.general.json_query('user.name') }}"
5858

5959
- name: Print Azure Account Info
6060
ansible.builtin.debug:

roles/infrastructure/tasks/setup_aws_storage.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
- name: Warn user about HeadBucket Forbidden errors
18+
debug:
19+
msg:
20+
- "If the 'Create AWS Buckets' task below fails. "
21+
- "If you see HeadBucket Forbidden errors. "
22+
- "Your bucket name is probably use in another AWS account and you should use a different name_prefix"
23+
1724
- name: Create AWS Buckets
1825
amazon.aws.aws_s3:
1926
region: "{{ infra__region }}"

roles/infrastructure/tasks/setup_azure_network.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848

4949
- name: Set fact for Azure Security Group IDs
5050
ansible.builtin.set_fact:
51-
infra__azure_security_group_knox_uri: "{{ __azure_security_group_info | json_query(knox) | first }}"
52-
infra__azure_security_group_default_uri: "{{ __azure_security_group_info | json_query(default) | first }}"
51+
infra__azure_security_group_knox_uri: "{{ __azure_security_group_info | community.general.json_query(knox) | first }}"
52+
infra__azure_security_group_default_uri: "{{ __azure_security_group_info | community.general.json_query(default) | first }}"
5353
vars:
5454
knox: "results[?__azure_network_security_group_name_item=='{{ infra__security_group_knox_name }}'].state.id"
5555
default: "results[?__azure_network_security_group_name_item=='{{ infra__security_group_default_name }}'].state.id"

roles/infrastructure/tasks/teardown_aws_compute.yml

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,53 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17+
- name: Handle EC2 Autoscaling Groups removal if discovered
18+
when:
19+
- infra__force_teardown | bool
20+
- __infra_aws_asg_names is defined
21+
- __infra_aws_asg_names | length > 0
22+
community.aws.ec2_asg:
23+
name: "{{ __infra_asg_remove_item }}"
24+
state: absent
25+
loop: "{{ __infra_aws_asg_names }}"
26+
loop_control:
27+
loop_var: __infra_asg_remove_item
28+
29+
- name: Handle EKS Cluster removal if discovered
30+
when:
31+
- infra__force_teardown | bool
32+
- __infra_vpc_eks_cluster_names is defined
33+
- __infra_vpc_eks_cluster_names | length > 0
34+
community.aws.aws_eks_cluster:
35+
name: "{{ __infra_eks_remove_item }}"
36+
wait: yes
37+
state: absent
38+
loop: "{{ __infra_vpc_eks_cluster_names }}"
39+
loop_control:
40+
loop_var: __infra_eks_remove_item
41+
async: 3600 # 1 hour timeout
42+
poll: 0
43+
register: __eks_teardowns_info
44+
45+
- name: Wait for EKS teardowns to complete
46+
when:
47+
- __eks_teardowns_info is defined
48+
- __eks_teardowns_info.results is defined
49+
- __eks_teardowns_info.results | length > 0
50+
ansible.builtin.async_status:
51+
jid: "{{ __eks_teardown.ansible_job_id }}"
52+
loop_control:
53+
loop_var: __eks_teardown
54+
loop: "{{ __eks_teardowns_info.results }}"
55+
register: __eks_teardowns_async
56+
until: __eks_teardowns_async.finished
57+
retries: 120
58+
delay: 10
59+
1760
- name: Handle Compute Removal if Discovered
1861
when: infra__discovered_compute_inventory | count > 0
1962
amazon.aws.ec2:
2063
region: "{{ infra__region }}"
2164
wait: yes
2265
state: absent
23-
instance_ids: "{{ infra__discovered_compute_inventory | community.general.json_query('[*].instance_id') | list }}"
66+
instance_ids: "{{ infra__discovered_compute_inventory | community.general.json_query('[*].instance_id') | list | unique }}"

0 commit comments

Comments
 (0)