diff --git a/providers/route53/route53Provider.go b/providers/route53/route53Provider.go index ae4fa392c..6993cef04 100644 --- a/providers/route53/route53Provider.go +++ b/providers/route53/route53Provider.go @@ -478,9 +478,37 @@ func nativeToRecords(set r53Types.ResourceRecordSet, origin string) ([]*models.R rtype = "TXT" fallthrough default: + ty := string(rtype) + val := *rec.Value + + // AWS Route53 has a bug. Sometimes it returns a target + // without a trailing dot. In this case we add the dot. It is + // not risky to "just add the dot" because this field never + // includes shortnames. That said, we only do it for certain + // record types where we can show the problem exists. + // 2022-02-23: NS records do NOT have this bug. + // + // NOTE: The dot is missing when the record is added via the + // AWS web console manually. + // + // The next "dnscontrol push" will update the record, even + // though it doesn't seem to be broken. This only happens once + // per record. Sadly the updates only fix the first record. + // So, if n records are affected by this bug, the next n + // pushes will be required to clean up all the records. + // Someone converting a new zone will see this issue for the + // first n pushes. It will seem odd but this is AWS's bug. + // The UPSERT command only fixes the first record, even if + // the UPSET received a list of corrections. + if ty == "CNAME" || ty == "MX" { + if !strings.HasSuffix(val, ".") { + val = val + "." + } + } + rc := &models.RecordConfig{TTL: uint32(aws.ToInt64(set.TTL))} rc.SetLabelFromFQDN(unescape(set.Name), origin) - if err := rc.PopulateFromString(string(rtype), *rec.Value, origin); err != nil { + if err := rc.PopulateFromString(string(rtype), val, origin); err != nil { return nil, fmt.Errorf("unparsable record received from R53: %w", err) } results = append(results, rc)