22
33set -euo pipefail
44
5+ log () {
6+ echo " [$( date +' %H:%M:%S' ) ] $* "
7+ }
8+
9+ # --- Configuration ---
510NAMESPACE=" monitoring"
11+ GRAFANA_SECRET_NAME=" grafana-admin"
12+ SECRET_NAME=" grafana-webhook-credentials"
13+ PARAM_NAME=" /unicornstore/prometheus/internal-dns"
14+
15+ # Temporary files to clean up
16+ VALUES_FILE=" prometheus-values.yaml"
17+ EXTRA_SCRAPE_FILE=" extra-scrape-configs.yaml"
18+ DATASOURCE_FILE=" grafana-datasource.yaml"
19+ DASHBOARD_JSON_FILE=" jvm-dashboard.json"
20+ DASHBOARD_PROVISIONING_FILE=" dashboard-provisioning.yaml"
21+ ALERT_RULE_FILE=" grafana-alert-rules.yaml"
22+ GRAFANA_VALUES_FILE=" grafana-values.yaml"
23+ LAMBDA_ALERT_RULE_FILE=" lambda-alert-rule.json"
24+ NOTIFICATION_POLICY_CONFIGMAP_FILE=" notification-policy.yaml"
25+
26+ cleanup_temp_files () {
27+ log " 🧹 Cleaning up temporary files..."
28+ rm -f " $VALUES_FILE " " $EXTRA_SCRAPE_FILE " " $DATASOURCE_FILE " " $NOTIFICATION_POLICY_CONFIGMAP_FILE " \
29+ " $DASHBOARD_JSON_FILE " " $DASHBOARD_PROVISIONING_FILE " \
30+ " $ALERT_RULE_FILE " " $GRAFANA_VALUES_FILE " " $LAMBDA_ALERT_RULE_FILE " \
31+ " grafana-credentials.txt"
32+ }
33+ trap cleanup_temp_files EXIT
34+
35+ log " 🚨 Starting monitoring stack cleanup..."
36+
37+ # --- Get Grafana credentials before cleanup ---
38+ GRAFANA_USER=" admin"
39+ GRAFANA_PASSWORD=" "
40+
41+ if kubectl get secret " $GRAFANA_SECRET_NAME " -n " $NAMESPACE " > /dev/null 2>&1 ; then
42+ GRAFANA_PASSWORD=$( kubectl get secret " $GRAFANA_SECRET_NAME " -n " $NAMESPACE " -o jsonpath=" {.data.password}" | base64 --decode)
43+ log " 📋 Retrieved Grafana password from existing secret"
44+ fi
45+
46+ # Get Grafana LoadBalancer hostname before cleanup
47+ GRAFANA_LB=$( kubectl get svc grafana -n " $NAMESPACE " -o jsonpath=" {.status.loadBalancer.ingress[0].hostname}" 2> /dev/null || true)
48+ if [[ -n " $GRAFANA_LB " && " $GRAFANA_LB " != " <no value>" ]]; then
49+ GRAFANA_URL=" http://$GRAFANA_LB "
50+ log " 📋 Found Grafana URL: $GRAFANA_URL "
51+ fi
52+
53+ # Get Prometheus LoadBalancer hostname before cleanup
54+ PROM_LB_HOSTNAME=$( kubectl get svc prometheus-server -n " $NAMESPACE " -o jsonpath=" {.status.loadBalancer.ingress[0].hostname}" 2> /dev/null || true)
55+ if [[ -n " $PROM_LB_HOSTNAME " && " $PROM_LB_HOSTNAME " != " <no value>" ]]; then
56+ log " 📋 Found Prometheus hostname: $PROM_LB_HOSTNAME "
57+ fi
58+
59+ # --- Clean up Grafana alert rules (if Grafana is accessible) ---
60+ if [[ -n " $GRAFANA_LB " && -n " $GRAFANA_PASSWORD " ]]; then
61+ log " 🔧 Cleaning up Grafana alert rules..."
62+
63+ # Wait briefly for Grafana to be accessible
64+ for i in {1..5}; do
65+ if curl -s -o /dev/null -w " %{http_code}" -u " $GRAFANA_USER :$GRAFANA_PASSWORD " " $GRAFANA_URL /api/health" | grep -q " 200" ; then
66+ log " ✅ Grafana is accessible for cleanup"
67+ break
68+ fi
69+ log " ⏳ Waiting for Grafana access... ($i /5)"
70+ sleep 2
71+ done
72+
73+ # Delete alert rules
74+ ALERT_RULES=$( curl -s -u " $GRAFANA_USER :$GRAFANA_PASSWORD " " $GRAFANA_URL /api/v1/provisioning/alert-rules" 2> /dev/null || echo " []" )
75+ if [[ " $ALERT_RULES " != " []" ]]; then
76+ echo " $ALERT_RULES " | jq -r ' .[].uid' | while read -r rule_uid; do
77+ if [[ -n " $rule_uid " && " $rule_uid " != " null" ]]; then
78+ log " 🗑️ Deleting alert rule: $rule_uid "
79+ curl -s -X DELETE -u " $GRAFANA_USER :$GRAFANA_PASSWORD " \
80+ " $GRAFANA_URL /api/v1/provisioning/alert-rules/$rule_uid " > /dev/null || true
81+ fi
82+ done
83+ fi
84+
85+ # Delete contact points
86+ CONTACT_POINTS=$( curl -s -u " $GRAFANA_USER :$GRAFANA_PASSWORD " " $GRAFANA_URL /api/v1/provisioning/contact-points" 2> /dev/null || echo " []" )
87+ if [[ " $CONTACT_POINTS " != " []" ]]; then
88+ echo " $CONTACT_POINTS " | jq -r ' .[] | select(.name=="lambda-webhook") | .uid' | while read -r cp_uid; do
89+ if [[ -n " $cp_uid " && " $cp_uid " != " null" ]]; then
90+ log " 🗑️ Deleting contact point: $cp_uid "
91+ curl -s -X DELETE -u " $GRAFANA_USER :$GRAFANA_PASSWORD " \
92+ " $GRAFANA_URL /api/v1/provisioning/contact-points/$cp_uid " > /dev/null || true
93+ fi
94+ done
95+ fi
96+
97+ # Delete folders
98+ FOLDERS=$( curl -s -u " $GRAFANA_USER :$GRAFANA_PASSWORD " " $GRAFANA_URL /api/folders" 2> /dev/null || echo " []" )
99+ if [[ " $FOLDERS " != " []" ]]; then
100+ echo " $FOLDERS " | jq -r ' .[] | select(.title=="Unicorn Store Dashboards") | .uid' | while read -r folder_uid; do
101+ if [[ -n " $folder_uid " && " $folder_uid " != " null" ]]; then
102+ log " 🗑️ Deleting folder: $folder_uid "
103+ curl -s -X DELETE -u " $GRAFANA_USER :$GRAFANA_PASSWORD " \
104+ " $GRAFANA_URL /api/folders/$folder_uid " > /dev/null || true
105+ fi
106+ done
107+ fi
108+ fi
109+
110+ # --- Clean up Prometheus LoadBalancer Security Group rules ---
111+ if [[ -n " $PROM_LB_HOSTNAME " ]]; then
112+ log " 🔐 Cleaning up Prometheus LoadBalancer Security Group rules..."
113+
114+ VPC_ID=$( aws ec2 describe-vpcs --filters " Name=tag:Name,Values=unicornstore-vpc" --query " Vpcs[0].VpcId" --output text 2> /dev/null || true)
115+ if [[ -n " $VPC_ID " && " $VPC_ID " != " None" ]]; then
116+ VPC_CIDR=$( aws ec2 describe-vpcs --vpc-ids " $VPC_ID " --query " Vpcs[0].CidrBlock" --output text 2> /dev/null || true)
117+
118+ LB_ARN=$( aws elbv2 describe-load-balancers --output json 2> /dev/null | jq -r \
119+ --arg dns " $PROM_LB_HOSTNAME " '
120+ .LoadBalancers[] | select(.DNSName == $dns) | .LoadBalancerArn' || true)
121+
122+ if [[ -n " $LB_ARN " ]]; then
123+ ILB_SG_ID=$( aws elbv2 describe-load-balancers \
124+ --load-balancer-arns " $LB_ARN " \
125+ --query " LoadBalancers[0].SecurityGroups[0]" \
126+ --output text 2> /dev/null || true)
127+
128+ if [[ -n " $ILB_SG_ID " && " $ILB_SG_ID " != " None" ]]; then
129+ log " 🗑️ Removing security group rule from $ILB_SG_ID "
130+ aws ec2 revoke-security-group-ingress \
131+ --group-id " $ILB_SG_ID " \
132+ --protocol tcp \
133+ --port 9090 \
134+ --cidr " $VPC_CIDR " \
135+ --output text 2> /dev/null || log " ℹ️ Security group rule may not exist"
136+ fi
137+ fi
138+ fi
139+ fi
140+
141+ # --- Uninstall Helm releases ---
142+ log " 🗑️ Uninstalling Helm releases..."
143+
144+ if helm list -n " $NAMESPACE " | grep -q " grafana" ; then
145+ log " 🗑️ Uninstalling Grafana..."
146+ helm uninstall grafana --namespace " $NAMESPACE " || log " ⚠️ Failed to uninstall Grafana"
147+ fi
148+
149+ if helm list -n " $NAMESPACE " | grep -q " prometheus" ; then
150+ log " 🗑️ Uninstalling Prometheus..."
151+ helm uninstall prometheus --namespace " $NAMESPACE " || log " ⚠️ Failed to uninstall Prometheus"
152+ fi
153+
154+ # --- Clean up Kubernetes resources ---
155+ log " 🗑️ Cleaning up Kubernetes resources..."
156+
157+ # Delete ConfigMaps
158+ kubectl delete configmap unicornstore-datasource -n " $NAMESPACE " 2> /dev/null || log " ℹ️ ConfigMap unicornstore-datasource not found"
159+ kubectl delete configmap unicornstore-dashboard -n " $NAMESPACE " 2> /dev/null || log " ℹ️ ConfigMap unicornstore-dashboard not found"
160+ kubectl delete configmap prometheus-extra-scrape -n " $NAMESPACE " 2> /dev/null || log " ℹ️ ConfigMap prometheus-extra-scrape not found"
161+ kubectl delete configmap unicornstore-notification-policy -n " $NAMESPACE " 2> /dev/null || log " ℹ️ ConfigMap unicornstore-notification-policy not found"
162+
163+ # Delete Secrets
164+ kubectl delete secret " $GRAFANA_SECRET_NAME " -n " $NAMESPACE " 2> /dev/null || log " ℹ️ Secret $GRAFANA_SECRET_NAME not found"
165+
166+ # Delete PVCs (Persistent Volume Claims)
167+ log " 🗑️ Cleaning up Persistent Volume Claims..."
168+ kubectl get pvc -n " $NAMESPACE " -o name 2> /dev/null | while read -r pvc; do
169+ if [[ -n " $pvc " ]]; then
170+ log " 🗑️ Deleting $pvc "
171+ kubectl delete " $pvc " -n " $NAMESPACE " || log " ⚠️ Failed to delete $pvc "
172+ fi
173+ done
174+
175+ # Wait for PVCs to be deleted
176+ log " ⏳ Waiting for PVCs to be fully deleted..."
177+ for i in {1..30}; do
178+ PVC_COUNT=$( kubectl get pvc -n " $NAMESPACE " --no-headers 2> /dev/null | wc -l || echo " 0" )
179+ if [[ " $PVC_COUNT " -eq 0 ]]; then
180+ log " ✅ All PVCs deleted"
181+ break
182+ fi
183+ log " ⏳ Waiting for $PVC_COUNT PVCs to be deleted... ($i /30)"
184+ sleep 5
185+ done
186+
187+ # --- Delete namespace ---
188+ log " 🗑️ Deleting namespace $NAMESPACE ..."
189+ kubectl delete namespace " $NAMESPACE " --timeout=60s 2> /dev/null || log " ⚠️ Failed to delete namespace or namespace not found"
190+
191+ # Wait for namespace deletion
192+ log " ⏳ Waiting for namespace deletion..."
193+ for i in {1..30}; do
194+ if ! kubectl get namespace " $NAMESPACE " > /dev/null 2>&1 ; then
195+ log " ✅ Namespace $NAMESPACE deleted"
196+ break
197+ fi
198+ log " ⏳ Waiting for namespace deletion... ($i /30)"
199+ sleep 5
200+ done
201+
202+ # --- Clean up AWS resources ---
203+ log " 🗑️ Cleaning up AWS resources..."
204+
205+ # Delete SSM Parameter
206+ if aws ssm get-parameter --name " $PARAM_NAME " > /dev/null 2>&1 ; then
207+ log " 🗑️ Deleting SSM parameter $PARAM_NAME "
208+ aws ssm delete-parameter --name " $PARAM_NAME " || log " ⚠️ Failed to delete SSM parameter"
209+ else
210+ log " ℹ️ SSM parameter $PARAM_NAME not found"
211+ fi
212+
213+ # Delete Secrets Manager secret
214+ if aws secretsmanager describe-secret --secret-id " $SECRET_NAME " > /dev/null 2>&1 ; then
215+ log " 🗑️ Deleting Secrets Manager secret $SECRET_NAME "
216+ aws secretsmanager delete-secret --secret-id " $SECRET_NAME " --force-delete-without-recovery || log " ⚠️ Failed to delete secret"
217+ else
218+ log " ℹ️ Secrets Manager secret $SECRET_NAME not found"
219+ fi
220+
221+ # --- Clean up Lambda Function URL (optional) ---
222+ log " 🔧 Checking Lambda Function URL..."
223+ LAMBDA_FUNCTION_NAME=" unicornstore-thread-dump-lambda"
224+
225+ if aws lambda get-function --function-name " $LAMBDA_FUNCTION_NAME " > /dev/null 2>&1 ; then
226+ # Check if Function URL exists
227+ if aws lambda get-function-url-config --function-name " $LAMBDA_FUNCTION_NAME " > /dev/null 2>&1 ; then
228+ log " 🗑️ Removing Lambda Function URL..."
229+ aws lambda delete-function-url-config --function-name " $LAMBDA_FUNCTION_NAME " || log " ⚠️ Failed to delete Function URL"
230+
231+ # Remove the permission
232+ aws lambda remove-permission \
233+ --function-name " $LAMBDA_FUNCTION_NAME " \
234+ --statement-id AllowPublicAccess 2> /dev/null || log " ℹ️ Permission may not exist"
235+ else
236+ log " ℹ️ Lambda Function URL not found"
237+ fi
238+ else
239+ log " ℹ️ Lambda function $LAMBDA_FUNCTION_NAME not found"
240+ fi
241+
242+ # --- Remove Helm repositories (optional) ---
243+ log " 🗑️ Cleaning up Helm repositories..."
244+ helm repo remove prometheus-community 2> /dev/null || log " ℹ️ prometheus-community repo not found"
245+ helm repo remove grafana 2> /dev/null || log " ℹ️ grafana repo not found"
6246
7- # ConfigMap-Namen
8- ALERT_RULE_CONFIGMAP_NAME=" unicornstore-alert-rule"
9- CONTACT_POINT_CONFIGMAP_NAME=" unicornstore-contact-point"
10- DATASOURCE_CONFIGMAP_NAME=" unicornstore-datasource"
11- DASHBOARD_CONFIGMAP_NAME=" unicornstore-dashboard"
12- SCRAPE_CONFIGMAP_NAME=" prometheus-extra-scrape"
247+ # --- Final validation ---
248+ log " 🔍 Validating cleanup..."
13249
14- # Helm Releases
15- GRAFANA_HELM_RELEASE=" grafana"
16- PROMETHEUS_HELM_RELEASE=" prometheus"
250+ # Check if namespace still exists
251+ if kubectl get namespace " $NAMESPACE " > /dev/null 2>&1 ; then
252+ log " ⚠️ Warning: Namespace $NAMESPACE still exists"
253+ else
254+ log " ✅ Namespace $NAMESPACE successfully deleted"
255+ fi
17256
18- echo " 🧹 Starting cleanup of Kubernetes-based monitoring stack..."
257+ # Check if Helm releases still exist
258+ REMAINING_RELEASES=$( helm list -A | grep -E " (prometheus|grafana)" || true)
259+ if [[ -n " $REMAINING_RELEASES " ]]; then
260+ log " ⚠️ Warning: Some Helm releases may still exist:"
261+ echo " $REMAINING_RELEASES "
262+ else
263+ log " ✅ All monitoring Helm releases cleaned up"
264+ fi
19265
20- # Delete alert rule configmap
21- echo " 🔸 Deleting Alert Rule ConfigMap: $ALERT_RULE_CONFIGMAP_NAME "
22- kubectl delete configmap " $ALERT_RULE_CONFIGMAP_NAME " -n " $NAMESPACE " --ignore-not-found
266+ # Check AWS resources
267+ if aws secretsmanager describe-secret --secret-id " $SECRET_NAME " > /dev/null 2>&1 ; then
268+ log " ⚠️ Warning: Secrets Manager secret $SECRET_NAME still exists"
269+ else
270+ log " ✅ Secrets Manager secret cleaned up"
271+ fi
23272
24- # Delete contact point configmap
25- echo " 🔸 Deleting Contact Point ConfigMap: $CONTACT_POINT_CONFIGMAP_NAME "
26- kubectl delete configmap " $CONTACT_POINT_CONFIGMAP_NAME " -n " $NAMESPACE " --ignore-not-found
273+ if aws ssm get-parameter --name " $PARAM_NAME " > /dev/null 2>&1 ; then
274+ log " ⚠️ Warning: SSM parameter $PARAM_NAME still exists"
275+ else
276+ log " ✅ SSM parameter cleaned up"
277+ fi
27278
28- # Delete datasource configmap
29- echo " 🔸 Deleting Datasource ConfigMap: $DATASOURCE_CONFIGMAP_NAME "
30- kubectl delete configmap " $DATASOURCE_CONFIGMAP_NAME " -n " $NAMESPACE " --ignore- not-found
279+ log " ✅ Monitoring stack cleanup completed! "
280+ log " ℹ️ Note: Some AWS resources (like Load Balancers) may take additional time to fully terminate "
281+ log " ℹ️ Note: Persistent Volumes may need manual cleanup if they were not automatically deleted "
31282
32- # Delete dashboard configmap
33- echo " 🔸 Deleting Dashboard ConfigMap: $DASHBOARD_CONFIGMAP_NAME "
34- kubectl delete configmap " $DASHBOARD_CONFIGMAP_NAME " -n " $NAMESPACE " --ignore-not-found
283+ # --- Optional: List remaining resources for manual cleanup ---
284+ log " 📋 Checking for any remaining resources that may need manual cleanup..."
35285
36- # Delete extra scrape config
37- echo " 🔸 Deleting Extra Scrape ConfigMap: $SCRAPE_CONFIGMAP_NAME "
38- kubectl delete configmap " $SCRAPE_CONFIGMAP_NAME " -n " $NAMESPACE " --ignore-not-found
286+ # Check for remaining PVs
287+ REMAINING_PVS=$( kubectl get pv | grep " $NAMESPACE " || true)
288+ if [[ -n " $REMAINING_PVS " ]]; then
289+ log " ⚠️ Warning: Found Persistent Volumes that may need manual cleanup:"
290+ echo " $REMAINING_PVS "
291+ fi
39292
40- # Uninstall Helm releases
41- echo " 🔸 Uninstalling Helm release: $GRAFANA_HELM_RELEASE "
42- helm uninstall " $GRAFANA_HELM_RELEASE " -n " $NAMESPACE " || echo " ⚠️ Grafana release not found or already uninstalled."
293+ # Check for remaining Load Balancers
294+ REMAINING_LBS=$( aws elbv2 describe-load-balancers --output table | grep -E " (prometheus|grafana)" || true)
295+ if [[ -n " $REMAINING_LBS " ]]; then
296+ log " ⚠️ Warning: Found Load Balancers that may need manual cleanup:"
297+ echo " $REMAINING_LBS "
298+ fi
43299
44- echo " 🔸 Uninstalling Helm release: $PROMETHEUS_HELM_RELEASE "
45- helm uninstall " $PROMETHEUS_HELM_RELEASE " -n " $NAMESPACE "
300+ log " 🎉 Cleanup script execution completed!"
0 commit comments