Skip to content

fix: add plan level validation for ttl on route53 record #43001

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

quixoticmonk
Copy link
Contributor

@quixoticmonk quixoticmonk commented Jun 13, 2025

Rollback Plan

If a change needs to be reverted, we will publish an updated version of the library.

Changes to Security Controls

Are there any changes to security controls (access controls, encryption, logging) in this pull request? If so, explain.
None

Description

Fixed the aws_route53_record resource to validate TTL requirements at plan time instead of apply time, preventing runtime errors when users forget to specify TTL with records.

1. Schema Modification (/internal/service/route53/record.go)

Before:

"ttl": {
    Type:          schema.TypeInt,
    Optional:      true,
    ConflictsWith: []string{names.AttrAlias},
    RequiredWith:  []string{"records", "ttl"}, // Circular dependency!
},

After:

"ttl": {
    Type:          schema.TypeInt,
    Optional:      true,
    ConflictsWith: []string{names.AttrAlias},
    Description:   "The TTL of the record. Required when records are provided and alias is not used.",
},

2. Added CustomizeDiff Validation

func validateRoute53RecordTTLRequirement(ctx context.Context, diff *schema.ResourceDiff, meta interface{}) error {
    records, hasRecords := diff.GetOk("records")
    alias, hasAlias := diff.GetOk(names.AttrAlias)
    ttl, hasTTL := diff.GetOk("ttl")

    // If records are provided
    if hasRecords && records.(*schema.Set).Len() > 0 {
        // And no alias is provided
        if !hasAlias || len(alias.([]interface{})) == 0 {
            // Then TTL must be provided and greater than 0
            if !hasTTL || ttl.(int) <= 0 {
                return fmt.Errorf("TTL is required when records are provided and alias is not used. " +
                    "Route 53 requires exactly one of: alias target, [TTL and resource records], or traffic policy instance ID")
            }
        }
    }
    return nil
}

3. Updated Resource Definition

return &schema.Resource{
    CreateWithoutTimeout: resourceRecordCreate,
    ReadWithoutTimeout:   resourceRecordRead,
    UpdateWithoutTimeout: resourceRecordUpdate,
    DeleteWithoutTimeout: resourceRecordDelete,
    
    SchemaVersion: 2,
    MigrateState:  recordMigrateState,
    CustomizeDiff: validateRoute53RecordTTLRequirement, // Added this line
    
    Schema: map[string]*schema.Schema{
        // ... rest of schema
    },
}

Test Coverage Added

Unit Tests (/internal/service/route53/record_validation_test.go)

  • ✅ Records with TTL - should pass
  • ✅ Records without TTL - should fail
  • ✅ Records with zero TTL - should fail
  • ✅ Alias without TTL - should pass
  • ✅ Empty records set - should pass
  • ✅ Schema validation tests

Acceptance Tests (/internal/service/route53/record_test.go)

  • ✅ TTL validation with records (failure case)
  • ✅ TTL validation with records (success case)
  • ✅ Alias validation without TTL (success case)
  • ✅ Zero TTL with records (failure case)

Relations

Closes #0000

References

Output from Acceptance Testing

% make testacc TESTS=TestAccXXX PKG=ec2

...
go test -parallel 4 ./internal/service/route53 -v
2025/06/13 09:12:25 Initializing Terraform AWS Provider...
=== RUN   TestNormalizeAliasDomainName
=== PAUSE TestNormalizeAliasDomainName
=== RUN   TestCleanZoneID

....
--- PASS: TestParseRecordID (0.00s)
    --- PASS: TestParseRecordID/ABCDEF (0.00s)
    --- PASS: TestParseRecordID/ABCDEF__underscore.example.com_A_set_with1 (0.00s)
    --- PASS: TestParseRecordID/ABCDEF__A (0.00s)
    --- PASS: TestParseRecordID/ABCDEF_prefix._underscore.example.com_A (0.00s)
    --- PASS: TestParseRecordID/ABCDEF_prefix._underscore.example.com_A_set_underscore (0.00s)
    --- PASS: TestParseRecordID/ABCDEF__underscore.example.com_A_set_with_1 (0.00s)
    --- PASS: TestParseRecordID/ABCDEF_prefix._underscore.example.com_A_set (0.00s)
    --- PASS: TestParseRecordID/ABCDEF__underscore.example.com_A_set1 (0.00s)
    --- PASS: TestParseRecordID/ABCDEF_test.example.com_A_set1 (0.00s)
    --- PASS: TestParseRecordID/ABCDEF_test.example.com._A (0.00s)
    --- PASS: TestParseRecordID/ABCDEF__underscore.example.com_A (0.00s)
    --- PASS: TestParseRecordID/ABCDEF_test.example.com (0.00s)
    --- PASS: TestParseRecordID/ABCDEF_test.example.com_A (0.00s)
PASS
ok  	github.com/hashicorp/terraform-provider-aws/internal/service/route53	4.708s

Copy link
Contributor

Community Guidelines

This comment is added to every new Pull Request to provide quick reference to how the Terraform AWS Provider is maintained. Please review the information below, and thank you for contributing to the community that keeps the provider thriving! 🚀

Voting for Prioritization

  • Please vote on this Pull Request by adding a 👍 reaction to the original post to help the community and maintainers prioritize it.
  • Please see our prioritization guide for additional information on how the maintainers handle prioritization.
  • Please do not leave +1 or other comments that do not add relevant new information or questions; they generate extra noise for others following the Pull Request and do not help prioritize the request.

Pull Request Authors

  • Review the contribution guide relating to the type of change you are making to ensure all of the necessary steps have been taken.
  • Whether or not the branch has been rebased will not impact prioritization, but doing so is always a welcome surprise.

@github-actions github-actions bot added needs-triage Waiting for first response or review from a maintainer. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure. service/route53 Issues and PRs that pertain to the route53 service. size/XL Managed by automation to categorize the size of a PR. partner Contribution from a partner. labels Jun 13, 2025
@justinretzolk justinretzolk added enhancement Requests to existing resources that expand the functionality or scope. and removed needs-triage Waiting for first response or review from a maintainer. labels Jun 17, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Requests to existing resources that expand the functionality or scope. partner Contribution from a partner. service/route53 Issues and PRs that pertain to the route53 service. size/XL Managed by automation to categorize the size of a PR. tests PRs: expanded test coverage. Issues: expanded coverage, enhancements to test infrastructure.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants