|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +# This is a demo script that showcases Route53 DNS failover in LocalStack |
| 4 | +# Make sure the Docker Compose setup is running before executing this script |
| 5 | + |
| 6 | +set -eux |
| 7 | + |
| 8 | +HOSTED_ZONE_NAME=hello-localstack.com |
| 9 | + |
| 10 | +# Create a hosted zone |
| 11 | +HOSTED_ZONE_ID=$(awslocal route53 create-hosted-zone --name $HOSTED_ZONE_NAME --caller-reference foo | jq -r .HostedZone.Id) |
| 12 | + |
| 13 | +# Create a health check that runs against the `http_echo` container |
| 14 | +HEALTH_CHECK_ID=$(awslocal route53 create-health-check --caller-reference foobar --health-check-config '{ |
| 15 | + "FullyQualifiedDomainName": "http_echo", |
| 16 | + "Port": 80, |
| 17 | + "ResourcePath": "/", |
| 18 | + "Type": "HTTP", |
| 19 | + "RequestInterval": 10 |
| 20 | +}' | jq -r .HealthCheck.Id) |
| 21 | + |
| 22 | +# Create RRSets |
| 23 | +awslocal route53 change-resource-record-sets --hosted-zone ${HOSTED_ZONE_ID#/hostedzone/} --change-batch '{ |
| 24 | +"Changes": [ |
| 25 | + { |
| 26 | + "Action": "CREATE", |
| 27 | + "ResourceRecordSet": { |
| 28 | + "Name": "target1.'$HOSTED_ZONE_NAME'", |
| 29 | + "Type": "CNAME", |
| 30 | + "TTL": 60, |
| 31 | + "ResourceRecords": [{"Value": "target1.example.com"}] |
| 32 | + } |
| 33 | + }, |
| 34 | + { |
| 35 | + "Action": "CREATE", |
| 36 | + "ResourceRecordSet": { |
| 37 | + "Name": "target2.'$HOSTED_ZONE_NAME'", |
| 38 | + "Type": "CNAME", |
| 39 | + "TTL": 60, |
| 40 | + "ResourceRecords": [{"Value": "target2.example.com"}] |
| 41 | + } |
| 42 | + } |
| 43 | +]}' |
| 44 | +awslocal route53 change-resource-record-sets --hosted-zone-id ${HOSTED_ZONE_ID#/hostedzone/} --change-batch '{ |
| 45 | +"Changes": [ |
| 46 | + { |
| 47 | + "Action": "CREATE", |
| 48 | + "ResourceRecordSet": { |
| 49 | + "Name": "test.'$HOSTED_ZONE_NAME'", |
| 50 | + "Type": "CNAME", |
| 51 | + "SetIdentifier": "target1", |
| 52 | + "AliasTarget": { |
| 53 | + "HostedZoneId": "'${HOSTED_ZONE_ID#/hostedzone/}'", |
| 54 | + "DNSName": "target1.'$HOSTED_ZONE_NAME'", |
| 55 | + "EvaluateTargetHealth": true |
| 56 | + }, |
| 57 | + "HealthCheckId": "'${HEALTH_CHECK_ID}'", |
| 58 | + "Failover": "PRIMARY" |
| 59 | + } |
| 60 | + }, |
| 61 | + { |
| 62 | + "Action": "CREATE", |
| 63 | + "ResourceRecordSet": { |
| 64 | + "Name": "test.'$HOSTED_ZONE_NAME'", |
| 65 | + "Type": "CNAME", |
| 66 | + "SetIdentifier": "target2", |
| 67 | + "AliasTarget": { |
| 68 | + "HostedZoneId": "'${HOSTED_ZONE_ID#/hostedzone/}'", |
| 69 | + "DNSName": "target2.'$HOSTED_ZONE_NAME'", |
| 70 | + "EvaluateTargetHealth": true |
| 71 | + }, |
| 72 | + "Failover": "SECONDARY" |
| 73 | + } |
| 74 | + } |
| 75 | +]}' |
| 76 | + |
| 77 | +# Get the IP address of the LocalStack container on the Docker bridge |
| 78 | +LOCALSTACK_DNS_SERVER=$(docker inspect localstack_main | jq -r '.[0].NetworkSettings.Networks."route53-dns-failover_sweet_mahavira".IPAddress') |
| 79 | +LOCALSTACK_DNS_SERVER=localhost |
| 80 | + |
| 81 | +# This IP address is used to query the LocalStack DNS server |
| 82 | +# This should return `target1.example.com` as the healthcheck is currently passing |
| 83 | +dig @$LOCALSTACK_DNS_SERVER +noall +answer test.hello-localstack.com CNAME |
| 84 | + |
| 85 | +# Make the healthcheck fail by pointing it to a nonexistent host |
| 86 | +awslocal route53 update-health-check --health-check-id ${HEALTH_CHECK_ID} --fully-qualified-domain-name bad-host-p45e8eG94rK.com |
| 87 | + |
| 88 | +# Wait for the healthcheck to refresh |
| 89 | +sleep 12 |
| 90 | + |
| 91 | +# This should return the failover `target2.example.com` |
| 92 | +dig @$LOCALSTACK_DNS_SERVER +noall +answer test.hello-localstack.com CNAME |
0 commit comments