Skip to content
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

resource/aws_route53_resolver_dnssec_config - new resource #17012

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions aws/internal/service/route53resolver/finder/finder.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,36 @@ func ResolverQueryLogConfigByID(conn *route53resolver.Route53Resolver, queryLogC

return output.ResolverQueryLogConfig, nil
}

// ResolverDnssecConfigByID returns the dnssec configuration corresponding to the specified ID.
// Returns nil if no configuration is found.
func ResolverDnssecConfigByID(conn *route53resolver.Route53Resolver, dnssecConfigID string) (*route53resolver.ResolverDnssecConfig, error) {
input := &route53resolver.ListResolverDnssecConfigsInput{}

var config *route53resolver.ResolverDnssecConfig
// GetResolverDnssecConfigs does not support query with id
err := conn.ListResolverDnssecConfigsPages(input, func(page *route53resolver.ListResolverDnssecConfigsOutput, lastPage bool) bool {
if page == nil {
return !lastPage
}

for _, c := range page.ResolverDnssecConfigs {
if aws.StringValue(c.Id) == dnssecConfigID {
config = c
return false
}
}

return !lastPage
})

if err != nil {
return nil, err
}

if config == nil {
return nil, nil
}

return config, nil
}
20 changes: 20 additions & 0 deletions aws/internal/service/route53resolver/waiter/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const (

resolverQueryLogConfigStatusNotFound = "NotFound"
resolverQueryLogConfigStatusUnknown = "Unknown"

resolverDnssecConfigStatusNotFound = "NotFound"
resolverDnssecConfigStatusUnknown = "Unknown"
)

// QueryLogConfigAssociationStatus fetches the QueryLogConfigAssociation and its Status
Expand Down Expand Up @@ -57,3 +60,20 @@ func QueryLogConfigStatus(conn *route53resolver.Route53Resolver, queryLogConfigI
return queryLogConfig, aws.StringValue(queryLogConfig.Status), nil
}
}

// DnssecConfigStatus fetches the DnssecConfig and its Status
func DnssecConfigStatus(conn *route53resolver.Route53Resolver, dnssecConfigID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
dnssecConfig, err := finder.ResolverDnssecConfigByID(conn, dnssecConfigID)

if err != nil {
return nil, resolverDnssecConfigStatusUnknown, err
}

if dnssecConfig == nil {
return nil, resolverDnssecConfigStatusNotFound, nil
}

return dnssecConfig, aws.StringValue(dnssecConfig.ValidationStatus), nil
}
}
42 changes: 42 additions & 0 deletions aws/internal/service/route53resolver/waiter/waiter.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ const (

// Maximum amount of time to wait for a QueryLogConfig to be deleted
QueryLogConfigDeletedTimeout = 5 * time.Minute

// Maximum amount of time to wait for a DnssecConfig to return ENABLED
DnssecConfigCreatedTimeout = 5 * time.Minute

// Maximum amount of time to wait for a DnssecConfig to return DISABLED
DnssecConfigDeletedTimeout = 5 * time.Minute
)

// QueryLogConfigAssociationCreated waits for a QueryLogConfig to return ACTIVE
Expand Down Expand Up @@ -92,3 +98,39 @@ func QueryLogConfigDeleted(conn *route53resolver.Route53Resolver, queryLogConfig

return nil, err
}

// DnssecConfigCreated waits for a DnssecConfig to return ENABLED
func DnssecConfigCreated(conn *route53resolver.Route53Resolver, dnssecConfigID string) (*route53resolver.ResolverDnssecConfig, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{route53resolver.ResolverDNSSECValidationStatusEnabling},
Target: []string{route53resolver.ResolverDNSSECValidationStatusEnabled},
Refresh: DnssecConfigStatus(conn, dnssecConfigID),
Timeout: DnssecConfigCreatedTimeout,
}

outputRaw, err := stateConf.WaitForState()

if v, ok := outputRaw.(*route53resolver.ResolverDnssecConfig); ok {
return v, err
}

return nil, err
}

// DnssecConfigCreated waits for a DnssecConfig to return DELETED
func DnssecConfigDeleted(conn *route53resolver.Route53Resolver, dnssecConfigID string) (*route53resolver.ResolverDnssecConfig, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{route53resolver.ResolverDNSSECValidationStatusDisabling},
Target: []string{route53resolver.ResolverDNSSECValidationStatusDisabled},
Refresh: DnssecConfigStatus(conn, dnssecConfigID),
Timeout: DnssecConfigDeletedTimeout,
}

outputRaw, err := stateConf.WaitForState()

if v, ok := outputRaw.(*route53resolver.ResolverDnssecConfig); ok {
return v, err
}

return nil, err
}
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,7 @@ func Provider() *schema.Provider {
"aws_route53_vpc_association_authorization": resourceAwsRoute53VPCAssociationAuthorization(),
"aws_route53_zone": resourceAwsRoute53Zone(),
"aws_route53_health_check": resourceAwsRoute53HealthCheck(),
"aws_route53_resolver_dnssec_config": resourceAwsRoute53ResolverDnssecConfig(),
"aws_route53_resolver_endpoint": resourceAwsRoute53ResolverEndpoint(),
"aws_route53_resolver_query_log_config": resourceAwsRoute53ResolverQueryLogConfig(),
"aws_route53_resolver_query_log_config_association": resourceAwsRoute53ResolverQueryLogConfigAssociation(),
Expand Down
131 changes: 131 additions & 0 deletions aws/resource_aws_route53_resolver_dnssec_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/route53resolver"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/route53resolver/finder"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/route53resolver/waiter"
)

func resourceAwsRoute53ResolverDnssecConfig() *schema.Resource {
return &schema.Resource{
Create: resourceAwsRoute53ResolverDnssecConfigCreate,
Read: resourceAwsRoute53ResolverDnssecConfigRead,
Delete: resourceAwsRoute53ResolverDnssecConfigDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},

"id": {
Type: schema.TypeString,
Computed: true,
},

"owner_id": {
Type: schema.TypeString,
Computed: true,
},

"resource_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"validation_status": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func resourceAwsRoute53ResolverDnssecConfigCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).route53resolverconn

req := &route53resolver.UpdateResolverDnssecConfigInput{
ResourceId: aws.String(d.Get("resource_id").(string)),
Validation: aws.String(route53resolver.ValidationEnable),
}

log.Printf("[DEBUG] Creating Route53 Resolver DNSSEC config: %#v", req)
resp, err := conn.UpdateResolverDnssecConfig(req)
if err != nil {
return fmt.Errorf("error creating Route53 Resolver DNSSEC config: %w", err)
}

d.SetId(aws.StringValue(resp.ResolverDNSSECConfig.Id))

_, err = waiter.DnssecConfigCreated(conn, d.Id())
if err != nil {
return err
}

return resourceAwsRoute53ResolverDnssecConfigRead(d, meta)
}

func resourceAwsRoute53ResolverDnssecConfigRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).route53resolverconn

config, err := finder.ResolverDnssecConfigByID(conn, d.Id())

if err != nil {
return fmt.Errorf("error getting Route53 Resolver DNSSEC config (%s): %w", d.Id(), err)
}

if config == nil || aws.StringValue(config.ValidationStatus) == route53resolver.ResolverDNSSECValidationStatusDisabled {
log.Printf("[WARN] Route53 Resolver DNSSEC config (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

d.Set("id", config.Id)
d.Set("owner_id", config.OwnerId)
d.Set("resource_id", config.ResourceId)
d.Set("validation_status", config.ValidationStatus)

configArn := arn.ARN{
Partition: meta.(*AWSClient).partition,
Service: "route53resolver",
Region: meta.(*AWSClient).region,
AccountID: aws.StringValue(config.OwnerId),
Resource: fmt.Sprintf("resolver-dnssec-config/%s", aws.StringValue(config.ResourceId)),
}.String()
d.Set("arn", configArn)

return nil
}

func resourceAwsRoute53ResolverDnssecConfigDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).route53resolverconn

log.Printf("[DEBUG] Deleting Route53 Resolver DNSSEC config: %s", d.Id())
_, err := conn.UpdateResolverDnssecConfig(&route53resolver.UpdateResolverDnssecConfigInput{
ResourceId: aws.String(d.Get("resource_id").(string)),
Validation: aws.String(route53resolver.ValidationDisable),
})
if isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") {
return nil
}
if err != nil {
return fmt.Errorf("error deleting Route53 Resolver DNSSEC config (%s): %w", d.Id(), err)
}

_, err = waiter.DnssecConfigDeleted(conn, d.Id())
if err != nil {
return err
}

return nil
}
Loading