diff --git a/provider/aws/aws.go b/provider/aws/aws.go index a5d964b67f..aa6a34d199 100644 --- a/provider/aws/aws.go +++ b/provider/aws/aws.go @@ -66,6 +66,8 @@ const ( providerSpecificGeoProximityLocationLocalZoneGroup = "aws/geoproximity-local-zone-group" providerSpecificMultiValueAnswer = "aws/multi-value-answer" providerSpecificHealthCheckID = "aws/health-check-id" + providerSpecificAliasDisableA = "aws/alias-disable-a" + providerSpecificAliasDisableAAAA = "aws/alias-disable-aaaa" sameZoneAlias = "same-zone" // Currently supported up to 10 health checks or hosted zones. // https://docs.aws.amazon.com/Route53/latest/APIReference/API_ListTagsForResources.html#API_ListTagsForResources_RequestSyntax @@ -863,19 +865,32 @@ func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoi ep.SetProviderSpecificProperty(providerSpecificEvaluateTargetHealth, strconv.FormatBool(p.evaluateTargetHealth)) } - if ep.RecordType == endpoint.RecordTypeCNAME { - // This needs to match two records from Route53, one alias for 'A' (IPv4) - // and one alias for 'AAAA' (IPv6). - aliasCnameAaaaEndpoints = append(aliasCnameAaaaEndpoints, &endpoint.Endpoint{ - DNSName: ep.DNSName, - Targets: ep.Targets, - RecordType: endpoint.RecordTypeAAAA, - RecordTTL: ep.RecordTTL, - Labels: ep.Labels, - ProviderSpecific: ep.ProviderSpecific, - SetIdentifier: ep.SetIdentifier, - }) - ep.RecordType = endpoint.RecordTypeA + disableA := aliasDisableARecord(ep) + disableAaaa := aliasDisableAaaaRecord(ep) + disableAlias := disableA && disableAaaa + enableAandAAAA := !disableA && !disableAaaa + + if ep.RecordType == endpoint.RecordTypeCNAME && !disableAlias { + if disableA { + ep.RecordType = endpoint.RecordTypeAAAA + } + if disableAaaa { + ep.RecordType = endpoint.RecordTypeA + } + if enableAandAAAA { + // Add a new endpoint for the AAAA record + aliasCnameAaaaEndpoints = append(aliasCnameAaaaEndpoints, &endpoint.Endpoint{ + DNSName: ep.DNSName, + Targets: ep.Targets, + RecordType: endpoint.RecordTypeAAAA, + RecordTTL: ep.RecordTTL, + Labels: ep.Labels, + ProviderSpecific: ep.ProviderSpecific, + SetIdentifier: ep.SetIdentifier, + }) + // Modify the original endpoint to be the A record + ep.RecordType = endpoint.RecordTypeA + } } } else { ep.DeleteProviderSpecificProperty(providerSpecificEvaluateTargetHealth) @@ -888,6 +903,16 @@ func (p *AWSProvider) AdjustEndpoints(endpoints []*endpoint.Endpoint) ([]*endpoi return endpoints, nil } +func aliasDisableARecord(ep *endpoint.Endpoint) bool { + disable, ok := ep.GetProviderSpecificProperty(providerSpecificAliasDisableA) + return ok && disable == "true" +} + +func aliasDisableAaaaRecord(ep *endpoint.Endpoint) bool { + disable, ok := ep.GetProviderSpecificProperty(providerSpecificAliasDisableAAAA) + return ok && disable == "true" +} + // if the endpoint is using geoproximity, set the bias to 0 if not set // this is needed to avoid unnecessary Upserts if the desired endpoint doesn't specify a bias func adjustGeoProximityLocationEndpoint(ep *endpoint.Endpoint) { diff --git a/provider/aws/aws_test.go b/provider/aws/aws_test.go index a269c3ede8..23c4585cf8 100644 --- a/provider/aws/aws_test.go +++ b/provider/aws/aws_test.go @@ -710,6 +710,9 @@ func TestAWSAdjustEndpoints(t *testing.T) { endpoint.NewEndpoint("cname-test-elb-no-eth.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "false"), // eth = evaluate target health endpoint.NewEndpoint("cname-test-elb-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeCNAME, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("a-test-geoproximity-no-bias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeoProximityLocationAWSRegion, "us-west-2"), + endpoint.NewEndpoint("same-zone-alias-test.teapot.zalan.do", endpoint.RecordTypeCNAME, "same-zone-alias-target.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificAliasDisableA, "true"), + endpoint.NewEndpoint("same-zone-alias-test2.teapot.zalan.do", endpoint.RecordTypeCNAME, "same-zone-alias-target2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificAliasDisableAAAA, "true"), + endpoint.NewEndpoint("same-zone-alias-test3.teapot.zalan.do", endpoint.RecordTypeCNAME, "same-zone-alias-target3.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificAliasDisableA, "true").WithProviderSpecific(providerSpecificAliasDisableAAAA, "true"), } records, err := provider.AdjustEndpoints(records) @@ -728,6 +731,9 @@ func TestAWSAdjustEndpoints(t *testing.T) { endpoint.NewEndpoint("cname-test-elb-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("cname-test-elb-alias.zone-2.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeAAAA, "foo.eu-central-1.elb.amazonaws.com").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), endpoint.NewEndpoint("a-test-geoproximity-no-bias.zone-1.ext-dns-test-2.teapot.zalan.do", endpoint.RecordTypeA, "8.8.8.8").WithSetIdentifier("test-set-1").WithProviderSpecific(providerSpecificGeoProximityLocationAWSRegion, "us-west-2").WithProviderSpecific(providerSpecificGeoProximityLocationBias, "0"), + endpoint.NewEndpoint("same-zone-alias-test.teapot.zalan.do", endpoint.RecordTypeAAAA, "same-zone-alias-target.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificAliasDisableA, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), + endpoint.NewEndpoint("same-zone-alias-test2.teapot.zalan.do", endpoint.RecordTypeA, "same-zone-alias-target2.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificAliasDisableAAAA, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), + endpoint.NewEndpoint("same-zone-alias-test3.teapot.zalan.do", endpoint.RecordTypeCNAME, "same-zone-alias-target3.teapot.zalan.do").WithProviderSpecific(providerSpecificAlias, "true").WithProviderSpecific(providerSpecificAliasDisableA, "true").WithProviderSpecific(providerSpecificAliasDisableAAAA, "true").WithProviderSpecific(providerSpecificEvaluateTargetHealth, "true"), }) }