Skip to content

Commit fce53c2

Browse files
committed
feat(cloud/aws/rds): add create-instance, delete-instance, snapshot-create, snapshot-restore, modify-instance, and rds-healthcheck with docs
1 parent a8ae545 commit fce53c2

13 files changed

Lines changed: 2257 additions & 0 deletions

cloud/aws/rds/create-instance.sh

Lines changed: 420 additions & 0 deletions
Large diffs are not rendered by default.

cloud/aws/rds/delete-instance.sh

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
usage() {
5+
cat << 'USAGE'
6+
Usage: delete-instance.sh [OPTIONS]
7+
8+
Delete an AWS RDS DB instance with controlled snapshot behavior.
9+
10+
Options:
11+
--identifier ID DB instance identifier (required)
12+
--skip-final-snapshot Skip final snapshot (dangerous)
13+
--final-snapshot-id ID Final snapshot identifier (auto-generated when omitted)
14+
--delete-automated-backups Delete retained automated backups (default)
15+
--retain-automated-backups Keep retained automated backups
16+
--wait Wait until DB instance is fully deleted
17+
--timeout SEC Wait timeout in seconds (default: 7200)
18+
--poll-interval SEC Poll interval in seconds (default: 20)
19+
--region REGION AWS region
20+
--profile PROFILE AWS CLI profile
21+
--dry-run Print AWS command without executing
22+
-h, --help Show help
23+
USAGE
24+
}
25+
26+
die() {
27+
printf 'ERROR: %s\n' "$*" >&2
28+
exit 2
29+
}
30+
31+
log() {
32+
printf '%s [delete-instance] %s\n' "$(date +"%Y-%m-%dT%H:%M:%S%z")" "$*" >&2
33+
}
34+
35+
command_exists() {
36+
command -v "$1" > /dev/null 2>&1
37+
}
38+
39+
validate_identifier() {
40+
[[ "$1" =~ ^[a-z][a-z0-9-]{0,62}$ && ! "$1" =~ -- && ! "$1" =~ -$ ]]
41+
}
42+
43+
validate_snapshot_identifier() {
44+
[[ "$1" =~ ^[a-z][a-z0-9-]{0,254}$ && ! "$1" =~ -- && ! "$1" =~ -$ ]]
45+
}
46+
47+
timestamp_utc() {
48+
date -u +"%Y%m%d%H%M%S"
49+
}
50+
51+
wait_for_deleted() {
52+
local start_time elapsed out rc
53+
start_time="$(date +%s)"
54+
55+
while true; do
56+
set +e
57+
out="$(aws "${aws_options[@]}" rds describe-db-instances \
58+
--db-instance-identifier "$identifier" \
59+
--query 'DBInstances[0].DBInstanceStatus' \
60+
--output text 2>&1)"
61+
rc=$?
62+
set -e
63+
64+
if ((rc != 0)); then
65+
if grep -q "DBInstanceNotFound" <<< "$out"; then
66+
return 0
67+
fi
68+
die "failed while checking deletion status: $out"
69+
fi
70+
71+
elapsed=$(($(date +%s) - start_time))
72+
if ((elapsed >= timeout_seconds)); then
73+
die "timeout waiting for DB instance deletion: $identifier"
74+
fi
75+
76+
sleep "$poll_interval"
77+
done
78+
}
79+
80+
aws_options=()
81+
identifier=""
82+
skip_final_snapshot=false
83+
final_snapshot_id=""
84+
delete_automated_backups=true
85+
wait_enabled=false
86+
timeout_seconds=7200
87+
poll_interval=20
88+
dry_run=false
89+
90+
while (($#)); do
91+
case "$1" in
92+
--identifier)
93+
shift
94+
(($#)) || die "--identifier requires a value"
95+
validate_identifier "$1" || die "invalid --identifier value"
96+
identifier="$1"
97+
;;
98+
--skip-final-snapshot)
99+
skip_final_snapshot=true
100+
;;
101+
--final-snapshot-id)
102+
shift
103+
(($#)) || die "--final-snapshot-id requires a value"
104+
validate_snapshot_identifier "$1" || die "invalid --final-snapshot-id value"
105+
final_snapshot_id="$1"
106+
;;
107+
--delete-automated-backups)
108+
delete_automated_backups=true
109+
;;
110+
--retain-automated-backups)
111+
delete_automated_backups=false
112+
;;
113+
--wait)
114+
wait_enabled=true
115+
;;
116+
--timeout)
117+
shift
118+
(($#)) || die "--timeout requires a value"
119+
[[ "$1" =~ ^[1-9][0-9]*$ ]] || die "--timeout must be a positive integer"
120+
timeout_seconds="$1"
121+
;;
122+
--poll-interval)
123+
shift
124+
(($#)) || die "--poll-interval requires a value"
125+
[[ "$1" =~ ^[1-9][0-9]*$ ]] || die "--poll-interval must be a positive integer"
126+
poll_interval="$1"
127+
;;
128+
--region)
129+
shift
130+
(($#)) || die "--region requires a value"
131+
aws_options+=(--region "$1")
132+
;;
133+
--profile)
134+
shift
135+
(($#)) || die "--profile requires a value"
136+
aws_options+=(--profile "$1")
137+
;;
138+
--dry-run)
139+
dry_run=true
140+
;;
141+
-h | --help)
142+
usage
143+
exit 0
144+
;;
145+
*)
146+
die "unknown option: $1"
147+
;;
148+
esac
149+
shift
150+
done
151+
152+
command_exists aws || die "aws CLI is required but not found"
153+
[[ -n "$identifier" ]] || die "--identifier is required"
154+
155+
instance_state="$(aws "${aws_options[@]}" rds describe-db-instances \
156+
--db-instance-identifier "$identifier" \
157+
--query 'DBInstances[0].DBInstanceStatus' \
158+
--output text 2> /dev/null || true)"
159+
160+
if [[ -z "$instance_state" || "$instance_state" == "None" ]]; then
161+
die "DB instance not found: $identifier"
162+
fi
163+
164+
if [[ "$instance_state" == "deleting" ]]; then
165+
log "instance is already deleting: $identifier"
166+
if $wait_enabled; then
167+
wait_for_deleted
168+
log "instance deleted: $identifier"
169+
fi
170+
exit 0
171+
fi
172+
173+
if $skip_final_snapshot && [[ -n "$final_snapshot_id" ]]; then
174+
die "--final-snapshot-id cannot be used with --skip-final-snapshot"
175+
fi
176+
177+
if ! $skip_final_snapshot && [[ -z "$final_snapshot_id" ]]; then
178+
final_snapshot_id="${identifier}-final-$(timestamp_utc)"
179+
fi
180+
181+
delete_cmd=(aws "${aws_options[@]}" rds delete-db-instance --db-instance-identifier "$identifier")
182+
183+
if $skip_final_snapshot; then
184+
delete_cmd+=(--skip-final-snapshot)
185+
else
186+
validate_snapshot_identifier "$final_snapshot_id" || die "generated final snapshot ID is invalid: $final_snapshot_id"
187+
delete_cmd+=(--final-db-snapshot-identifier "$final_snapshot_id")
188+
fi
189+
190+
if $delete_automated_backups; then
191+
delete_cmd+=(--delete-automated-backups)
192+
else
193+
delete_cmd+=(--no-delete-automated-backups)
194+
fi
195+
196+
if $dry_run; then
197+
printf 'DRY-RUN:' >&2
198+
printf ' %q' "${delete_cmd[@]}" >&2
199+
printf '\n' >&2
200+
log "dry-run mode: instance not deleted"
201+
exit 0
202+
fi
203+
204+
"${delete_cmd[@]}" > /dev/null
205+
log "delete requested for DB instance: $identifier"
206+
if ! $skip_final_snapshot; then
207+
log "final snapshot: $final_snapshot_id"
208+
fi
209+
210+
if $wait_enabled; then
211+
wait_for_deleted
212+
log "instance deleted: $identifier"
213+
fi
214+
215+
exit 0

0 commit comments

Comments
 (0)