Skip to content

Commit 46008ef

Browse files
committed
Introducing restore code for backupdr
1 parent 9e59fc8 commit 46008ef

File tree

2 files changed

+205
-0
lines changed

2 files changed

+205
-0
lines changed

backupdr/restore/main.tf

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
terraform {
2+
required_providers {
3+
http = {
4+
source = "hashicorp/http"
5+
version = "~> 3.4"
6+
}
7+
# ADDED: Provider for the null_resource used for polling
8+
null = {
9+
source = "hashicorp/null"
10+
version = "~> 3.2"
11+
}
12+
}
13+
}
14+
15+
variable "trigger_dr_restore" {
16+
type = bool
17+
description = "Set to true to trigger the DR restore API call."
18+
default = false
19+
}
20+
21+
variable "gcp_access_token" {
22+
type = string
23+
description = "A valid GCP access token."
24+
default = "" # Provide a default to avoid errors when trigger_dr_restore is false
25+
}
26+
27+
variable "consumer_project_id" {
28+
type = string
29+
description = "Consumer project ID"
30+
default = "kavishgupta-consumer-18"
31+
}
32+
33+
variable "location" {
34+
type = string
35+
description = "GCP region for the BackupDR service"
36+
default = "asia-northeast1"
37+
}
38+
39+
variable "target_zone" {
40+
type = string
41+
description = "Target zone for the restored instance"
42+
default = "asia-northeast1-c"
43+
}
44+
45+
variable "restored_vm_name" {
46+
type = string
47+
description = "Name for the restored VM"
48+
default = "instance-11-restrd"
49+
}
50+
51+
variable "backup_vault" {
52+
type = string
53+
default = "bv1"
54+
}
55+
56+
variable "data_source" {
57+
type = string
58+
default = "ds1"
59+
}
60+
61+
variable "backup_id" {
62+
type = string
63+
default = "b1"
64+
}
65+
66+
variable "restore_network" {
67+
type = string
68+
default = "projects/kavishgupta-consumer-18/global/networks/test-restore"
69+
}
70+
71+
variable "restore_subnetwork" {
72+
type = string
73+
default = "projects/kavishgupta-consumer-18/regions/asia-northeast1/subnetworks/test-subnet"
74+
}
75+
76+
variable "service_account_email" {
77+
type = string
78+
default = "<REDACTED_EMAIL>"
79+
}
80+
81+
locals {
82+
api_endpoint = "https://backupdr.googleapis.com" # Base endpoint without version
83+
restore_url = "${local.api_endpoint}/v1/projects/${var.consumer_project_id}/locations/${var.location}/backupVaults/${var.backup_vault}/dataSources/${var.data_source}/backups/${var.backup_id}:restore"
84+
85+
request_body = jsonencode({
86+
compute_instance_target_environment = {
87+
project = "nkuravi-cons-1"
88+
zone = var.target_zone
89+
}
90+
compute_instance_restore_properties = {
91+
name = var.restored_vm_name
92+
network_interfaces = [
93+
{
94+
network = var.restore_network
95+
subnetwork = var.restore_subnetwork
96+
}
97+
]
98+
service_accounts = [
99+
{
100+
email = var.service_account_email
101+
}
102+
]
103+
}
104+
})
105+
}
106+
107+
# Step 1: Trigger the initial restore operation
108+
data "http" "gcbdr_restore" {
109+
count = var.trigger_dr_restore ? 1 : 0
110+
111+
url = local.restore_url
112+
method = "POST"
113+
114+
request_headers = {
115+
"Authorization" = "Bearer ${var.gcp_access_token}"
116+
"Content-Type" = "application/json"
117+
"X-Goog-User-Project" = var.consumer_project_id
118+
}
119+
120+
request_body = local.request_body
121+
}
122+
123+
# --------------------------------------------------------------------------
124+
# --- APPENDED SCRIPT TO POLL THE OPERATION ---
125+
# --------------------------------------------------------------------------
126+
127+
# Step 2: Poll the operation until it is 'done' using a local-exec provisioner
128+
# Step 2: Poll the operation until it is 'done' using a local-exec provisioner
129+
resource "null_resource" "poll_restore_operation" {
130+
count = var.trigger_dr_restore ? 1 : 0
131+
132+
# This trigger ensures the provisioner runs only when a new operation is created
133+
triggers = {
134+
operation_body = data.http.gcbdr_restore[0].response_body
135+
}
136+
137+
provisioner "local-exec" {
138+
interpreter = ["/bin/bash", "-c"]
139+
140+
command = <<-EOT
141+
set -e
142+
OPERATION_NAME=$(echo '${self.triggers.operation_body}' | jq -r '.name')
143+
if [ -z "$OPERATION_NAME" ] || [ "$OPERATION_NAME" == "null" ]; then
144+
echo "Error: Could not parse operation name from response."
145+
echo '${self.triggers.operation_body}'
146+
exit 1
147+
fi
148+
149+
OPERATION_URL="https://backupdr.googleapis.com/v1/$OPERATION_NAME"
150+
echo "Polling operation at: $OPERATION_URL"
151+
152+
for i in {1..40}; do
153+
RESPONSE=$$(curl --fail -s -H "Authorization: Bearer '${var.gcp_access_token}'" "$${OPERATION_URL}")
154+
DONE_STATUS=$$(echo "$${RESPONSE}" | jq -r '.done')
155+
echo "Attempt $$i: Polling... Operation done status is '$${DONE_STATUS}'."
156+
157+
if [ "$${DONE_STATUS}" == "true" ]; then
158+
echo "Operation has completed."
159+
if echo "$${RESPONSE}" | jq -e '.error' > /dev/null; then
160+
echo "Final Status: FAILED"
161+
echo "$${RESPONSE}" | jq '.error'
162+
exit 1
163+
else
164+
echo "Final Status: SUCCESS"
165+
echo "$${RESPONSE}" > operation_result.json
166+
exit 0
167+
fi
168+
fi
169+
sleep 15
170+
done
171+
172+
echo "Error: Operation polling timed out after 10 minutes."
173+
exit 1
174+
EOT
175+
}
176+
}
177+
# Step 3 (Optional but recommended): Read the result from the file created by the poller
178+
data "local_file" "operation_result" {
179+
count = var.trigger_dr_restore ? 1 : 0
180+
181+
filename = "${path.module}/operation_result.json"
182+
183+
# Ensures this data source reads the file only after the polling script has finished
184+
depends_on = [null_resource.poll_restore_operation]
185+
}
186+
187+
# --- UPDATED AND NEW OUTPUTS ---
188+
189+
output "final_operation_details" {
190+
description = "The full JSON body of the completed operation after polling."
191+
value = jsondecode(data.local_file.operation_result[0].content)
192+
sensitive = true
193+
}

backupdr/restore/terraform.tfvars

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# File: dr-orchestrator/terraform.tfvars
2+
trigger_dr_restore = true
3+
consumer_project_id = "nkuravi-consumer-100"
4+
location = "us-central1"
5+
target_zone = "us-central1-c"
6+
restored_vm_name = "instance-11-restrd-tf-triggered" # Maybe a new name to avoid conflicts
7+
backup_vault = "vault-rest"
8+
data_source = "7308242de123e6299ebb85a41a1738f6567aa08e"
9+
backup_id = "da676d02-484d-4bd8-8730-46182bc2ad77"
10+
restore_network = "projects/nkuravi-cons-1/global/networks/test-restore"
11+
restore_subnetwork = "projects/nkuravi-cons-1/regions/us-central1/subnetworks/test-rest"
12+
service_account_email = "sample@nkuravi-cons-1.iam.gserviceaccount.com" # Make sure this is a valid SA email with permissions

0 commit comments

Comments
 (0)