diff --git a/docs/tutorials/aws.md b/docs/tutorials/aws.md index e708cafe2..36705b9b4 100644 --- a/docs/tutorials/aws.md +++ b/docs/tutorials/aws.md @@ -407,6 +407,13 @@ For any given DNS name, only **one** of the following routing policies can be us * `external-dns.alpha.kubernetes.io/aws-geolocation-subdivision-code` * Multi-value answer:`external-dns.alpha.kubernetes.io/aws-multi-value-answer` +## Associating DNS records with healthchecks + +You can configure Route53 to associate DNS records with healthchecks for automated DNS failover using +`external-dns.alpha.kubernetes.io/health-check-id: ` annotation. + +Note: ExternalDNS does not support creating healthchecks, and assumes that `` already exists. + ## Clean up Make sure to delete all Service objects before terminating the cluster so all load balancers get cleaned up correctly. diff --git a/provider/aws/aws.go b/provider/aws/aws.go index 22d6f2a6f..16db34c12 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -50,6 +50,7 @@ const ( providerSpecificGeolocationCountryCode = "aws/geolocation-country-code" providerSpecificGeolocationSubdivisionCode = "aws/geolocation-subdivision-code" providerSpecificMultiValueAnswer = "aws/multi-value-answer" + providerSpecificHealthCheckID = "aws/health-check-id" ) var ( @@ -349,6 +350,11 @@ func (p *AWSProvider) records(ctx context.Context, zones map[string]*route53.Hos // one of the above needs to be set, otherwise SetIdentifier doesn't make sense } } + + if r.HealthCheckId != nil { + ep.WithProviderSpecific(providerSpecificHealthCheckID, aws.StringValue(r.HealthCheckId)) + } + endpoints = append(endpoints, ep) } } @@ -595,6 +601,10 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint, recordsCac } } + if prop, ok := ep.GetProviderSpecificProperty(providerSpecificHealthCheckID); ok { + change.ResourceRecordSet.HealthCheckId = aws.String(prop.Value) + } + return change, dualstack } diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index 3de6cff1e..b56057e8f 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -326,6 +326,8 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificMultiValueAnswer, ""), endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationContinentCode, "EU"), endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificGeolocationCountryCode, "DE"), + endpoint.NewEndpoint("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.example.com").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"), + endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20").WithProviderSpecific(providerSpecificHealthCheckID, "abc-def-healthcheck-id"), }) records, err := provider.Records(context.Background()) @@ -347,6 +349,8 @@ func TestAWSRecords(t *testing.T) { endpoint.NewEndpointWithTTL("multi-value-answer-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set").WithProviderSpecific(providerSpecificMultiValueAnswer, ""), endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "1.2.3.4").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeolocationContinentCode, "EU"), endpoint.NewEndpointWithTTL("geolocation-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificGeolocationCountryCode, "DE"), + endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, endpoint.TTL(recordTTL), "foo.example.com").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificWeight, "10").WithProviderSpecific(providerSpecificHealthCheckID, "foo-bar-healthcheck-id"), + endpoint.NewEndpointWithTTL("healthcheck-test.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, endpoint.TTL(recordTTL), "4.3.2.1").WithSetIdentifier("test-set-2").WithProviderSpecific(providerSpecificWeight, "20").WithProviderSpecific(providerSpecificHealthCheckID, "abc-def-healthcheck-id"), }) }