forked from PinSpace-Org/GistPin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmigrate-state.sh
More file actions
153 lines (136 loc) 路 3.83 KB
/
Copy pathmigrate-state.sh
File metadata and controls
153 lines (136 loc) 路 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "${REPO_ROOT}"
TERRAFORM_DIR="${TERRAFORM_DIR:-infrastructure/terraform}"
BACKEND_CONFIG="${BACKEND_CONFIG:-}"
ACTION="${1:-}"
STATE_FILE="${2:-}"
EXIT_CODE=0
log() { echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] $*"; }
error() { log "ERROR: $*"; EXIT_CODE=1; }
check_prerequisites() {
if ! command -v terraform >/dev/null 2>&1; then
error "terraform not found."
fi
if [[ ! -d "${TERRAFORM_DIR}" ]]; then
error "Terraform directory not found: ${TERRAFORM_DIR}"
fi
}
backup_state() {
log "Creating state backup..."
local backup_dir="${TERRAFORM_DIR}/backups"
mkdir -p "${backup_dir}"
if terraform -chdir="${TERRAFORM_DIR}" state pull > "${backup_dir}/state-backup-$(date -u +%Y%m%d-%H%M%S).json" 2>&1; then
log "State backup created in ${backup_dir}"
else
error "Failed to backup state."
fi
}
validate_state() {
log "Validating current state..."
if terraform -chdir="${TERRAFORM_DIR}" validate 2>&1; then
log "Terraform configuration is valid."
else
error "Terraform configuration is invalid."
fi
}
migrate_state() {
log "Starting state migration..."
if [[ -n "${BACKEND_CONFIG}" && -f "${BACKEND_CONFIG}" ]]; then
terraform -chdir="${TERRAFORM_DIR}" init -migrate-state -backend-config="${BACKEND_CONFIG}" 2>&1
else
terraform -chdir="${TERRAFORM_DIR}" init -migrate-state 2>&1
fi
if [[ $? -eq 0 ]]; then
log "State migration completed successfully."
else
error "State migration failed."
fi
}
rollback_state() {
log "Rolling back to previous state..."
local backup_dir="${TERRAFORM_DIR}/backups"
local latest_backup
latest_backup=$(ls -t "${backup_dir}"/state-backup-*.json 2>/dev/null | head -1)
if [[ -z "${latest_backup}" ]]; then
error "No backup found for rollback."
fi
log "Using backup: ${latest_backup}"
terraform -chdir="${TERRAFORM_DIR}" state push "${latest_backup}" 2>&1
log "Rollback completed."
}
import_resource() {
if [[ $# -lt 2 ]]; then
error "Usage: $0 import <address> <id>"
fi
local address="${2:-}"
local id="${3:-}"
if [[ -z "${address}" || -z "${id}" ]]; then
error "Resource address and ID required."
fi
terraform -chdir="${TERRAFORM_DIR}" import "${address}" "${id}" 2>&1
}
mv_resource() {
if [[ $# -lt 2 ]]; then
error "Usage: $0 mv <source> <destination>"
fi
local source="${2:-}"
local dest="${3:-}"
if [[ -z "${source}" || -z "${dest}" ]]; then
error "Source and destination addresses required."
fi
terraform -chdir="${TERRAFORM_DIR}" state mv "${source}" "${dest}" 2>&1
}
rm_resource() {
local address="${2:-}"
if [[ -z "${address}" ]]; then
error "Usage: $0 rm <address>"
fi
terraform -chdir="${TERRAFORM_DIR}" state rm "${address}" 2>&1
}
main() {
check_prerequisites
case "${ACTION}" in
backup)
backup_state
;;
validate)
validate_state
;;
migrate)
backup_state
validate_state
if [[ "${EXIT_CODE}" -eq 0 ]]; then
migrate_state
fi
;;
rollback)
rollback_state
;;
import)
import_resource "$@"
;;
mv)
mv_resource "$@"
;;
rm)
rm_resource "$@"
;;
*)
echo "Usage: $0 {backup|validate|migrate|rollback|import|mv|rm} [args...]"
echo ""
echo "Actions:"
echo " backup Create a state backup"
echo " validate Validate current state"
echo " migrate [backend-config] Migrate state to new backend"
echo " rollback Rollback to latest backup"
echo " import <address> <id> Import a resource"
echo " mv <src> <dst> Move a resource in state"
echo " rm <address> Remove a resource from state"
exit 1
;;
esac
exit "${EXIT_CODE}"
}
main "$@"