@@ -8,18 +8,14 @@ include Makefile-common
88# NetApp DR Starter Kit - Infrastructure Targets
99# =============================================================================
1010#
11- # These targets manage the DR infrastructure:
12- # - Terraform state backend (S3 bucket + DynamoDB from values-trident.yaml)
11+ # These targets manage the DR infrastructure via Crossplane (GitOps):
1312# - Cluster discovery (auto-detect VPC, CIDR, region from kubeconfigs)
14- # - VPC peering between prod and DR clusters
15- # - FSx for NetApp ONTAP filesystems in each region
13+ # - Crossplane values written to Helm values files
14+ # - ArgoCD syncs Crossplane managed resources (FSx, S3, VPC Peering, Route53)
1615#
1716# Required:
1817# PROD_KUBECONFIG - path to production cluster kubeconfig
1918# DR_KUBECONFIG - path to DR cluster kubeconfig
20- #
21- # The terraform state bucket name is read from values-trident.yaml
22- # (.terraform.state.bucket) automatically by the playbook.
2319# =============================================================================
2420
2521# Expand ~ in kubeconfig paths
@@ -82,130 +78,64 @@ endef
8278
8379# #@ NetApp DR Infrastructure
8480
85- .PHONY : build-dr
86- build-dr : # # Build complete DR infrastructure (state backend, VPC peering, FSx filesystems)
87- $(call _validate_kubeconfigs,build-dr)
88- @echo " =========================================="
89- @echo " Building DR Infrastructure"
90- @echo " Prod kubeconfig: $( _PROD_KUBECONFIG) "
91- @echo " DR kubeconfig: $( _DR_KUBECONFIG) "
92- @echo " State bucket: from values-trident.yaml"
93- @echo " =========================================="
94- ansible-playbook $(EXTRA_PLAYBOOK_OPTS ) ansible/dr-setup.yaml \
95- -e @ansible/dr-vars.yml \
96- $(_DR_EXTRA_VARS )
81+ # #@ Crossplane Infrastructure
9782
98- .PHONY : destroy-dr
99- destroy-dr : # # Destroy DR infrastructure (FSx filesystems and VPC peering; preserves state bucket )
100- $(call _validate_kubeconfigs,destroy-dr )
83+ .PHONY : crossplane-setup
84+ crossplane-setup : # # Discover clusters and write Crossplane values (then commit+push for ArgoCD )
85+ $(call _validate_kubeconfigs,crossplane-setup )
10186 @echo " =========================================="
102- @echo " Destroying DR Infrastructure"
87+ @echo " Crossplane Infrastructure Setup "
10388 @echo " Prod kubeconfig: $( _PROD_KUBECONFIG) "
10489 @echo " DR kubeconfig: $( _DR_KUBECONFIG) "
105- @echo " Note: State bucket is preserved "
90+ @echo " (Route53: configure AWS credentials for hosted-zone discovery — no zone ID in Git) "
10691 @echo " =========================================="
107- ansible-playbook $(EXTRA_PLAYBOOK_OPTS ) ansible/dr-setup.yaml \
108- -e @ansible/dr-vars.yml \
109- $(_DR_EXTRA_VARS ) \
110- -e destroy_resources=true
111-
112- # Trident Protect AppVault S3 bucket from values-global.yaml
113- _APPVAULT_BUCKET := $(shell yq '.global.tridentProtect.appVault.s3.bucketName // ""' values-global.yaml 2>/dev/null)
114- _APPVAULT_REGION := $(shell yq '.global.tridentProtect.appVault.s3.region // ""' values-global.yaml 2>/dev/null)
115-
116- .PHONY : create-appvault-bucket
117- create-appvault-bucket : # # Create the S3 bucket for Trident Protect AppVault
118- @if [ -z " $( _APPVAULT_BUCKET) " ]; then \
119- echo " Error: Could not read .global.tridentProtect.appVault.s3.bucketName from values-global.yaml" ; \
120- exit 1; \
121- fi
122- @if [ -z " $( _APPVAULT_REGION) " ]; then \
123- echo " Error: Could not read .global.tridentProtect.appVault.s3.region from values-global.yaml" ; \
124- exit 1; \
125- fi
126- @echo " =========================================="
127- @echo " Trident Protect AppVault S3 Bucket"
92+ ansible-playbook $(EXTRA_PLAYBOOK_OPTS ) ansible/crossplane-setup.yaml \
93+ -e @ansible/crossplane-vars.yml \
94+ $(_DR_EXTRA_VARS )
95+ @echo " "
12896 @echo " =========================================="
129- @echo " Bucket: $( _APPVAULT_BUCKET) "
130- @echo " Region: $( _APPVAULT_REGION) "
97+ @echo " Values files updated. Next steps:"
98+ @echo " 1. git diff (review changes)"
99+ @echo " 2. git add -A && git commit"
100+ @echo " 3. git push (triggers ArgoCD sync)"
101+ @echo " 4. kubectl get managed (monitor)"
131102 @echo " =========================================="
132- @if aws s3api head-bucket --bucket $(_APPVAULT_BUCKET ) --region $(_APPVAULT_REGION ) 2> /dev/null; then \
133- echo " Bucket '$( _APPVAULT_BUCKET) ' already exists - nothing to do." ; \
134- else \
135- echo " Creating S3 bucket '$( _APPVAULT_BUCKET) ' in $( _APPVAULT_REGION) ..." ; \
136- if [ " $( _APPVAULT_REGION) " = " us-east-1" ]; then \
137- aws s3api create-bucket \
138- --bucket $(_APPVAULT_BUCKET ) \
139- --region $(_APPVAULT_REGION ) ; \
140- else \
141- aws s3api create-bucket \
142- --bucket $(_APPVAULT_BUCKET ) \
143- --region $(_APPVAULT_REGION ) \
144- --create-bucket-configuration LocationConstraint=$(_APPVAULT_REGION ) ; \
145- fi ; \
146- echo " Bucket '$( _APPVAULT_BUCKET) ' created." ; \
147- fi
148103
149- # State bucket name, DynamoDB table, and region from values-trident.yaml
150- _STATE_BUCKET := $(shell yq '.terraform.state.bucket // ""' values-trident.yaml 2>/dev/null)
151- _DYNAMODB_TABLE := $(shell yq '.terraform.state.dynamodb_table // "terraform-state-lock"' values-trident.yaml 2>/dev/null)
152- _STATE_REGION := $(shell yq '.terraform.state.region // "us-east-1"' values-trident.yaml 2>/dev/null)
104+ # #@ Crossplane DR Teardown
153105
154- .PHONY : destroy-terraform-state
155- destroy-terraform-state : # # Destroy the Terraform state backend (S3 bucket + DynamoDB table) - DESTRUCTIVE
156- @if [ -z " $( _STATE_BUCKET) " ]; then \
157- echo " Error: Could not read .terraform.state.bucket from values-trident.yaml" ; \
158- exit 1; \
159- fi
106+ .PHONY : destroy-dr dr-destroy
107+ # dr-destroy is an alias (same recipe as destroy-dr)
108+ destroy-dr dr-destroy : # # Destroy DR infrastructure (pauses ArgoCD, cleans ONTAP, deletes Crossplane resources)
109+ $(call _validate_kubeconfigs,destroy-dr)
160110 @echo " =========================================="
161- @echo " WARNING: Destroying Terraform State Backend "
111+ @echo " WARNING: Destroying DR Infrastructure "
162112 @echo " =========================================="
163- @echo " S3 Bucket: $( _STATE_BUCKET) "
164- @echo " DynamoDB Table: $( _DYNAMODB_TABLE) "
165- @echo " Region: $( _STATE_REGION) "
113+ @echo " Prod kubeconfig: $( _PROD_KUBECONFIG) "
114+ @echo " DR kubeconfig: $( _DR_KUBECONFIG) "
166115 @echo " "
167- @echo " This will permanently delete all Terraform state!"
168- @echo " Make sure you have destroyed all DR resources first"
169- @echo " (make destroy-dr) or they will become orphaned."
116+ @echo " This will:"
117+ @echo " 1. Pause ArgoCD auto-sync on both clusters"
118+ @echo " 2. Clean up ONTAP (SnapMirror, volumes, peers)"
119+ @echo " 3. Scrub AppVault S3 bucket"
120+ @echo " 4. Delete Crossplane-managed AWS resources (hub oc delete)"
121+ @echo " 5. AWS CLI fallback: remove any remaining FSx + VPC peering by tag/VPC pair"
122+ @echo " (playbook fails if they still exist — needs aws configure / env creds)"
170123 @echo " =========================================="
171124 @echo " "
172125 @read -p " Type 'yes' to confirm: " confirm && [ " $$ confirm" = " yes" ] || (echo " Aborted." ; exit 1)
173- @echo " "
174- @echo " --- Emptying S3 bucket (all object versions) ---"
175- @aws s3api list-object-versions \
176- --bucket $(_STATE_BUCKET ) \
177- --region $(_STATE_REGION ) \
178- --query ' {Objects: Versions[].{Key:Key,VersionId:VersionId}}' \
179- --output json 2> /dev/null | \
180- python3 -c " \
181- import sys, json, subprocess; \
182- data = json.load(sys.stdin); \
183- objects = data.get(' Objects' ) or []; \
184- [subprocess.run([' aws' , ' s3api' , ' delete-objects' , ' --bucket' , ' $(_STATE_BUCKET)' , ' --region' , ' $(_STATE_REGION)' , ' --delete' , json.dumps({' Objects' : objects[i:i+1000], ' Quiet' : True})], check=True) for i in range(0, len(objects), 1000)] if objects else None; \
185- print(f' Deleted {len(objects)} object versions' ) if objects else print(' No object versions to delete' )" || true
186- @echo " --- Removing delete markers ---"
187- @aws s3api list-object-versions \
188- --bucket $(_STATE_BUCKET ) \
189- --region $(_STATE_REGION ) \
190- --query ' {Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}' \
191- --output json 2> /dev/null | \
192- python3 -c " \
193- import sys, json, subprocess; \
194- data = json.load(sys.stdin); \
195- objects = data.get(' Objects' ) or []; \
196- [subprocess.run([' aws' , ' s3api' , ' delete-objects' , ' --bucket' , ' $(_STATE_BUCKET)' , ' --region' , ' $(_STATE_REGION)' , ' --delete' , json.dumps({' Objects' : objects[i:i+1000], ' Quiet' : True})], check=True) for i in range(0, len(objects), 1000)] if objects else None; \
197- print(f' Removed {len(objects)} delete markers' ) if objects else print(' No delete markers to remove' )" || true
198- @echo " --- Deleting S3 bucket ---"
199- @aws s3api delete-bucket --bucket $(_STATE_BUCKET ) --region $(_STATE_REGION ) \
200- && echo " S3 bucket '$( _STATE_BUCKET) ' deleted" \
201- || echo " S3 bucket '$( _STATE_BUCKET) ' not found (already deleted?)"
202- @echo " --- Deleting DynamoDB table ---"
203- @aws dynamodb delete-table --table-name $(_DYNAMODB_TABLE ) --region $(_STATE_REGION ) > /dev/null 2>&1 \
204- && echo " DynamoDB table '$( _DYNAMODB_TABLE) ' deleted" \
205- || echo " DynamoDB table '$( _DYNAMODB_TABLE) ' not found (already deleted?)"
206- @echo " --- Cleaning local working directory ---"
207- @rm -rf /tmp/netapp-dr-terraform/terraform-state
208- @echo " "
209- @echo " =========================================="
210- @echo " Terraform State Backend Destroyed"
211- @echo " =========================================="
126+ ansible-playbook $(EXTRA_PLAYBOOK_OPTS ) ansible/crossplane-destroy.yaml \
127+ -e @ansible/crossplane-vars.yml \
128+ $(_DR_EXTRA_VARS )
129+
130+ # #@ Code quality (Biome — JSON formatter parity with GitHub super-linter v8)
131+
132+ .PHONY : deps-js lint-biome format-biome
133+
134+ deps-js : # # Install Node devDependencies (Biome); uses package-lock.json
135+ npm ci
136+
137+ lint-biome : deps-js # # Run Biome check (format + lint) on the repo
138+ npm run lint:biome
139+
140+ format-biome : deps-js # # Write Biome formatting (e.g. Grafana dashboard JSON)
141+ npm run format:biome
0 commit comments