Skip to content

Commit

Permalink
Merge pull request #17012 from shuheiktgw/add_route53_resolver_dnssec…
Browse files Browse the repository at this point in the history
…_config

resource/aws_route53_resolver_dnssec_config - new resource
  • Loading branch information
breathingdust authored Jan 14, 2021
2 parents 95f94ad + e22f485 commit 60dac14
Show file tree
Hide file tree
Showing 7 changed files with 510 additions and 0 deletions.
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 @@ -863,6 +863,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

0 comments on commit 60dac14

Please sign in to comment.