|
1 | | -echo "--- Step 1: Define Hosted Zone ---" |
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +set -e |
| 4 | +set -o pipefail |
| 5 | + |
| 6 | +# Colors for logging |
| 7 | +GREEN='\033[0;32m' |
| 8 | +BLUE='\033[0;34m' |
| 9 | +RED='\033[0;31m' |
| 10 | +NC='\033[0m' |
| 11 | + |
| 12 | +# Logging functions |
| 13 | +log() { |
| 14 | + echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1" >&2 |
| 15 | +} |
| 16 | + |
| 17 | +error_log() { |
| 18 | + echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" >&2 |
| 19 | +} |
| 20 | + |
| 21 | +trap 'error_log "An error occurred. Exiting..."; exit 1' ERR |
| 22 | + |
| 23 | +# Step 1: Define Hosted Zone |
| 24 | +log "Defining hosted zone..." |
2 | 25 | HOSTED_ZONE_NAME="hello-localstack.com" |
3 | 26 | RAW_HOSTED_ZONE_ID=$(awslocal route53 create-hosted-zone \ |
4 | 27 | --name "$HOSTED_ZONE_NAME" \ |
5 | 28 | --caller-reference "zone-$(date +%s)" | jq -r .HostedZone.Id) |
6 | 29 | CLEANED_HOSTED_ZONE_ID="${RAW_HOSTED_ZONE_ID#/hostedzone/}" |
7 | | -echo "Hosted Zone Name: $HOSTED_ZONE_NAME" |
8 | | -echo "Raw Hosted Zone ID: $RAW_HOSTED_ZONE_ID" |
9 | | -echo |
10 | 30 |
|
11 | | -export HOSTED_ZONE_NAME |
12 | | -export RAW_HOSTED_ZONE_ID |
| 31 | +log "Hosted Zone Name: $HOSTED_ZONE_NAME" |
| 32 | +log "Raw Hosted Zone ID: $RAW_HOSTED_ZONE_ID" |
| 33 | +export HOSTED_ZONE_NAME RAW_HOSTED_ZONE_ID |
13 | 34 |
|
14 | | -echo "--- Step 2: Define API Gateway and Health Check Parameters ---" |
| 35 | +# Step 2: Define API Gateway and Health Check Parameters |
| 36 | +log "Defining API Gateway and health check parameters..." |
15 | 37 | PRIMARY_API_ID="12345" |
16 | 38 | SECONDARY_API_ID="67890" |
17 | | -PRIMARY_API_REGION="us-east-1" # Define the region of your primary API Gateway |
18 | | - |
| 39 | +PRIMARY_API_REGION="us-east-1" |
19 | 40 | HEALTH_CHECK_RESOURCE_PATH="/dev/healthcheck" |
20 | 41 | PRIMARY_API_GATEWAY_FQDN="${PRIMARY_API_ID}.execute-api.localhost.localstack.cloud" |
21 | 42 | HEALTH_CHECK_PORT=4566 |
22 | 43 |
|
23 | | -echo "Primary API ID: $PRIMARY_API_ID in region $PRIMARY_API_REGION" |
24 | | -echo "Primary API FQDN for Health Check: $PRIMARY_API_GATEWAY_FQDN" |
25 | | -echo "Health Check Port: $HEALTH_CHECK_PORT" |
26 | | -echo "Health Check Path: $HEALTH_CHECK_RESOURCE_PATH" |
27 | | -echo |
| 44 | +log "Primary API ID: $PRIMARY_API_ID" |
| 45 | +log "Primary API FQDN: $PRIMARY_API_GATEWAY_FQDN" |
| 46 | +log "Health Check Port: $HEALTH_CHECK_PORT" |
| 47 | +log "Health Check Path: $HEALTH_CHECK_RESOURCE_PATH" |
28 | 48 |
|
29 | | -echo "--- Step 3: Create Health Check for the Primary API Gateway ---" |
30 | | -# Health check can be created in any region, let's use us-west-1 as an example for the HC resource |
| 49 | +# Step 3: Create Health Check for the Primary API Gateway |
| 50 | +log "Creating Route 53 health check..." |
31 | 51 | HEALTH_CHECK_RESOURCE_REGION="us-west-1" |
32 | 52 | HEALTH_CHECK_ID=$(awslocal route53 create-health-check \ |
33 | 53 | --caller-reference "hc-app-${PRIMARY_API_ID}-$(date +%s)" \ |
34 | 54 | --region "$HEALTH_CHECK_RESOURCE_REGION" \ |
35 | | - --health-check-config "{ |
36 | | - \"FullyQualifiedDomainName\": \"${PRIMARY_API_GATEWAY_FQDN}\", |
37 | | - \"Port\": ${HEALTH_CHECK_PORT}, |
38 | | - \"ResourcePath\": \"${HEALTH_CHECK_RESOURCE_PATH}\", |
39 | | - \"Type\": \"HTTP\", |
40 | | - \"RequestInterval\": 10, |
41 | | - \"FailureThreshold\": 2 |
42 | | - }" | jq -r .HealthCheck.Id) |
43 | | -echo "Health Check ID created ($HEALTH_CHECK_ID) in region $HEALTH_CHECK_RESOURCE_REGION" |
| 55 | + --health-check-config "{\"FullyQualifiedDomainName\": \"${PRIMARY_API_GATEWAY_FQDN}\", \"Port\": ${HEALTH_CHECK_PORT}, \"ResourcePath\": \"${HEALTH_CHECK_RESOURCE_PATH}\", \"Type\": \"HTTP\", \"RequestInterval\": 10, \"FailureThreshold\": 2}" | jq -r .HealthCheck.Id) |
| 56 | + |
| 57 | +log "Health check created with ID: $HEALTH_CHECK_ID in region $HEALTH_CHECK_RESOURCE_REGION" |
44 | 58 | export HEALTH_CHECK_ID |
45 | | -echo |
46 | 59 | sleep 5 |
47 | 60 |
|
48 | | -echo "--- Step 4: Verify Initial Health of Primary API Gateway (No Chaos) ---" |
49 | | -echo "Attempting to curl the primary health check endpoint directly (should be 200 OK):" |
50 | | -curl --connect-timeout 5 -v "http://${PRIMARY_API_GATEWAY_FQDN}:${HEALTH_CHECK_PORT}${HEALTH_CHECK_RESOURCE_PATH}" |
51 | | -echo |
52 | | -echo |
53 | | -echo "Fetching initial health check status from Route 53 (may take a few checks to show Success):" |
54 | | -sleep 25 # (RequestInterval * FailureThreshold + buffer) |
55 | | -# Query the health check status from the region it was created in |
56 | | -awslocal route53 get-health-check-status --health-check-id "$HEALTH_CHECK_ID" --region "$HEALTH_CHECK_RESOURCE_REGION" |
57 | | -echo |
58 | | -echo |
| 61 | +# Step 4: Verify Initial Health |
| 62 | +log "Verifying primary health check endpoint (expect HTTP 200)..." |
| 63 | +curl --connect-timeout 5 -v "http://${PRIMARY_API_GATEWAY_FQDN}:${HEALTH_CHECK_PORT}${HEALTH_CHECK_RESOURCE_PATH}" || true |
59 | 64 |
|
60 | | -echo "--- Step 5: Create CNAME Records for Regional API Endpoints ---" |
| 65 | +log "Fetching health check status from Route 53 (may take a few seconds)..." |
| 66 | +sleep 25 |
| 67 | +awslocal route53 get-health-check-status \ |
| 68 | + --health-check-id "$HEALTH_CHECK_ID" \ |
| 69 | + --region "$HEALTH_CHECK_RESOURCE_REGION" >/dev/null |
| 70 | + |
| 71 | +# Step 5: Create CNAME Records |
| 72 | +log "Creating CNAME records for regional endpoints..." |
61 | 73 | PRIMARY_REGIONAL_DNS_NAME="${PRIMARY_API_ID}.${HOSTED_ZONE_NAME}" |
62 | 74 | SECONDARY_REGIONAL_DNS_NAME="${SECONDARY_API_ID}.${HOSTED_ZONE_NAME}" |
63 | 75 | PRIMARY_API_TARGET_FQDN="${PRIMARY_API_ID}.execute-api.localhost.localstack.cloud" |
64 | 76 | SECONDARY_API_TARGET_FQDN="${SECONDARY_API_ID}.execute-api.localhost.localstack.cloud" |
65 | 77 |
|
66 | | -CHANGE_BATCH_REGIONAL_CNAMES_JSON=$(printf '{ |
67 | | - "Comment": "Creating CNAMEs for regional API endpoints", |
68 | | - "Changes": [ |
69 | | - {"Action": "UPSERT", "ResourceRecordSet": {"Name": "%s", "Type": "CNAME", "TTL": 60, "ResourceRecords": [{"Value": "%s"}]}}, |
70 | | - {"Action": "UPSERT", "ResourceRecordSet": {"Name": "%s", "Type": "CNAME", "TTL": 60, "ResourceRecords": [{"Value": "%s"}]}} |
71 | | - ] |
72 | | -}' "$PRIMARY_REGIONAL_DNS_NAME" "$PRIMARY_API_TARGET_FQDN" "$SECONDARY_REGIONAL_DNS_NAME" "$SECONDARY_API_TARGET_FQDN") |
| 78 | +CHANGE_BATCH_REGIONAL_CNAMES_JSON=$(cat <<EOF |
| 79 | +{ |
| 80 | + "Comment": "Creating CNAMEs for regional API endpoints", |
| 81 | + "Changes": [ |
| 82 | + { |
| 83 | + "Action": "UPSERT", |
| 84 | + "ResourceRecordSet": { |
| 85 | + "Name": "$PRIMARY_REGIONAL_DNS_NAME", |
| 86 | + "Type": "CNAME", |
| 87 | + "TTL": 60, |
| 88 | + "ResourceRecords": [{ "Value": "$PRIMARY_API_TARGET_FQDN" }] |
| 89 | + } |
| 90 | + }, |
| 91 | + { |
| 92 | + "Action": "UPSERT", |
| 93 | + "ResourceRecordSet": { |
| 94 | + "Name": "$SECONDARY_REGIONAL_DNS_NAME", |
| 95 | + "Type": "CNAME", |
| 96 | + "TTL": 60, |
| 97 | + "ResourceRecords": [{ "Value": "$SECONDARY_API_TARGET_FQDN" }] |
| 98 | + } |
| 99 | + } |
| 100 | + ] |
| 101 | +} |
| 102 | +EOF |
| 103 | +) |
73 | 104 |
|
74 | | -echo "Creating/Updating CNAMEs for regional API Gateways..." |
75 | | -awslocal route53 change-resource-record-sets --hosted-zone-id "$RAW_HOSTED_ZONE_ID" --change-batch "$CHANGE_BATCH_REGIONAL_CNAMES_JSON" |
76 | | -echo |
| 105 | +awslocal route53 change-resource-record-sets \ |
| 106 | + --hosted-zone-id "$RAW_HOSTED_ZONE_ID" \ |
| 107 | + --change-batch "$CHANGE_BATCH_REGIONAL_CNAMES_JSON" >/dev/null |
| 108 | +log "CNAME records created." |
77 | 109 |
|
78 | | -echo "--- Step 6: Create Failover Alias Records ---" |
| 110 | +# Step 6: Create Failover Alias Records |
| 111 | +log "Creating failover alias records..." |
79 | 112 | FAILOVER_RECORD_NAME="test.${HOSTED_ZONE_NAME}" |
80 | 113 | PRIMARY_FAILOVER_SET_ID="primary-app-${PRIMARY_API_ID}" |
81 | 114 | SECONDARY_FAILOVER_SET_ID="secondary-app-${SECONDARY_API_ID}" |
82 | 115 |
|
83 | | -CHANGE_BATCH_FAILOVER_ALIASES_JSON=$(printf '{ |
84 | | - "Comment": "Creating failover alias records for %s", |
85 | | - "Changes": [ |
86 | | - { |
87 | | - "Action": "UPSERT", |
88 | | - "ResourceRecordSet": { |
89 | | - "Name": "%s", "Type": "CNAME", "SetIdentifier": "%s", "Failover": "PRIMARY", "HealthCheckId": "%s", |
90 | | - "AliasTarget": {"HostedZoneId": "%s", "DNSName": "%s", "EvaluateTargetHealth": true} |
91 | | - } |
92 | | - }, |
93 | | - { |
94 | | - "Action": "UPSERT", |
95 | | - "ResourceRecordSet": { |
96 | | - "Name": "%s", "Type": "CNAME", "SetIdentifier": "%s", "Failover": "SECONDARY", |
97 | | - "AliasTarget": {"HostedZoneId": "%s", "DNSName": "%s", "EvaluateTargetHealth": false} |
98 | | - } |
| 116 | +CHANGE_BATCH_FAILOVER_ALIASES_JSON=$(cat <<EOF |
| 117 | +{ |
| 118 | + "Comment": "Creating failover alias records for $FAILOVER_RECORD_NAME", |
| 119 | + "Changes": [ |
| 120 | + { |
| 121 | + "Action": "UPSERT", |
| 122 | + "ResourceRecordSet": { |
| 123 | + "Name": "$FAILOVER_RECORD_NAME", |
| 124 | + "Type": "CNAME", |
| 125 | + "SetIdentifier": "$PRIMARY_FAILOVER_SET_ID", |
| 126 | + "Failover": "PRIMARY", |
| 127 | + "HealthCheckId": "$HEALTH_CHECK_ID", |
| 128 | + "AliasTarget": { |
| 129 | + "HostedZoneId": "$RAW_HOSTED_ZONE_ID", |
| 130 | + "DNSName": "$PRIMARY_REGIONAL_DNS_NAME", |
| 131 | + "EvaluateTargetHealth": true |
99 | 132 | } |
100 | | - ] |
101 | | -}' "$FAILOVER_RECORD_NAME" \ |
102 | | - "$FAILOVER_RECORD_NAME" "$PRIMARY_FAILOVER_SET_ID" "$HEALTH_CHECK_ID" "$RAW_HOSTED_ZONE_ID" "$PRIMARY_REGIONAL_DNS_NAME" \ |
103 | | - "$FAILOVER_RECORD_NAME" "$SECONDARY_FAILOVER_SET_ID" "$RAW_HOSTED_ZONE_ID" "$SECONDARY_REGIONAL_DNS_NAME") |
| 133 | + } |
| 134 | + }, |
| 135 | + { |
| 136 | + "Action": "UPSERT", |
| 137 | + "ResourceRecordSet": { |
| 138 | + "Name": "$FAILOVER_RECORD_NAME", |
| 139 | + "Type": "CNAME", |
| 140 | + "SetIdentifier": "$SECONDARY_FAILOVER_SET_ID", |
| 141 | + "Failover": "SECONDARY", |
| 142 | + "AliasTarget": { |
| 143 | + "HostedZoneId": "$RAW_HOSTED_ZONE_ID", |
| 144 | + "DNSName": "$SECONDARY_REGIONAL_DNS_NAME", |
| 145 | + "EvaluateTargetHealth": false |
| 146 | + } |
| 147 | + } |
| 148 | + } |
| 149 | + ] |
| 150 | +} |
| 151 | +EOF |
| 152 | +) |
| 153 | + |
| 154 | +awslocal route53 change-resource-record-sets \ |
| 155 | + --hosted-zone-id "$RAW_HOSTED_ZONE_ID" \ |
| 156 | + --change-batch "$CHANGE_BATCH_FAILOVER_ALIASES_JSON" >/dev/null |
| 157 | +log "Failover alias records created." |
104 | 158 |
|
105 | | -echo "Creating/Updating failover alias records for $FAILOVER_RECORD_NAME..." |
106 | | -awslocal route53 change-resource-record-sets --hosted-zone-id "$RAW_HOSTED_ZONE_ID" --change-batch "$CHANGE_BATCH_FAILOVER_ALIASES_JSON" |
| 159 | +# Final Output |
107 | 160 | echo |
| 161 | +echo -e "${BLUE}Route 53 and failover setup completed successfully.${NC}" |
| 162 | +echo -e "${BLUE}Hosted Zone:${NC} $HOSTED_ZONE_NAME" |
| 163 | +echo -e "${BLUE}Primary API FQDN:${NC} $PRIMARY_API_GATEWAY_FQDN" |
| 164 | +echo -e "${BLUE}Health Check ID:${NC} $HEALTH_CHECK_ID" |
| 165 | +echo -e "${BLUE}Failover Domain:${NC} $FAILOVER_RECORD_NAME" |
0 commit comments