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

r/aws_route53_resolver_query_log_config_association: New resource #14901

Merged
Show file tree
Hide file tree
Changes from 3 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
44 changes: 44 additions & 0 deletions aws/internal/service/route53resolver/finder/finder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package finder

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53resolver"
)

// ResolverQueryLogConfigAssociationByID returns the query logging configuration association corresponding to the specified ID.
// Returns nil if no configuration is found.
func ResolverQueryLogConfigAssociationByID(conn *route53resolver.Route53Resolver, queryLogConfigAssociationID string) (*route53resolver.ResolverQueryLogConfigAssociation, error) {
input := &route53resolver.GetResolverQueryLogConfigAssociationInput{
ResolverQueryLogConfigAssociationId: aws.String(queryLogConfigAssociationID),
}

output, err := conn.GetResolverQueryLogConfigAssociation(input)
if err != nil {
return nil, err
}

if output == nil {
return nil, nil
}

return output.ResolverQueryLogConfigAssociation, nil
}

// ResolverQueryLogConfigByID returns the query logging configuration corresponding to the specified ID.
// Returns nil if no configuration is found.
func ResolverQueryLogConfigByID(conn *route53resolver.Route53Resolver, queryLogConfigID string) (*route53resolver.ResolverQueryLogConfig, error) {
input := &route53resolver.GetResolverQueryLogConfigInput{
ResolverQueryLogConfigId: aws.String(queryLogConfigID),
}

output, err := conn.GetResolverQueryLogConfig(input)
if err != nil {
return nil, err
}

if output == nil {
return nil, nil
}

return output.ResolverQueryLogConfig, nil
}
59 changes: 59 additions & 0 deletions aws/internal/service/route53resolver/waiter/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package waiter

import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53resolver"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/service/route53resolver/finder"
)

const (
resolverQueryLogConfigAssociationStatusNotFound = "NotFound"
resolverQueryLogConfigAssociationStatusUnknown = "Unknown"

resolverQueryLogConfigStatusNotFound = "NotFound"
resolverQueryLogConfigStatusUnknown = "Unknown"
)

// QueryLogConfigAssociationStatus fetches the QueryLogConfigAssociation and its Status
func QueryLogConfigAssociationStatus(conn *route53resolver.Route53Resolver, queryLogConfigAssociationID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
queryLogConfigAssociation, err := finder.ResolverQueryLogConfigAssociationByID(conn, queryLogConfigAssociationID)

if tfawserr.ErrCodeEquals(err, route53resolver.ErrCodeResourceNotFoundException) {
return nil, resolverQueryLogConfigAssociationStatusNotFound, nil
}

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

if queryLogConfigAssociation == nil {
return nil, resolverQueryLogConfigAssociationStatusNotFound, nil
}

return queryLogConfigAssociation, aws.StringValue(queryLogConfigAssociation.Status), nil
}
}

// QueryLogConfigStatus fetches the QueryLogConfig and its Status
func QueryLogConfigStatus(conn *route53resolver.Route53Resolver, queryLogConfigID string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
queryLogConfig, err := finder.ResolverQueryLogConfigByID(conn, queryLogConfigID)

if tfawserr.ErrCodeEquals(err, route53resolver.ErrCodeResourceNotFoundException) {
return nil, resolverQueryLogConfigStatusNotFound, nil
}

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

if queryLogConfig == nil {
return nil, resolverQueryLogConfigStatusNotFound, nil
}

return queryLogConfig, aws.StringValue(queryLogConfig.Status), nil
}
}
94 changes: 94 additions & 0 deletions aws/internal/service/route53resolver/waiter/waiter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package waiter

import (
"time"

"github.com/aws/aws-sdk-go/service/route53resolver"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

const (
// Maximum amount of time to wait for a QueryLogConfigAssociation to return ACTIVE
QueryLogConfigAssociationCreatedTimeout = 5 * time.Minute

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

// Maximum amount of time to wait for a QueryLogConfig to return CREATED
QueryLogConfigCreatedTimeout = 5 * time.Minute

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

// QueryLogConfigAssociationCreated waits for a QueryLogConfig to return ACTIVE
func QueryLogConfigAssociationCreated(conn *route53resolver.Route53Resolver, queryLogConfigAssociationID string) (*route53resolver.ResolverQueryLogConfigAssociation, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{route53resolver.ResolverQueryLogConfigAssociationStatusCreating},
Target: []string{route53resolver.ResolverQueryLogConfigAssociationStatusActive},
Refresh: QueryLogConfigAssociationStatus(conn, queryLogConfigAssociationID),
Timeout: QueryLogConfigAssociationCreatedTimeout,
}

outputRaw, err := stateConf.WaitForState()

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

return nil, err
}

// QueryLogConfigAssociationCreated waits for a QueryLogConfig to be deleted
func QueryLogConfigAssociationDeleted(conn *route53resolver.Route53Resolver, queryLogConfigAssociationID string) (*route53resolver.ResolverQueryLogConfigAssociation, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{route53resolver.ResolverQueryLogConfigAssociationStatusDeleting},
Target: []string{},
Refresh: QueryLogConfigAssociationStatus(conn, queryLogConfigAssociationID),
Timeout: QueryLogConfigAssociationDeletedTimeout,
}

outputRaw, err := stateConf.WaitForState()

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

return nil, err
}

// QueryLogConfigCreated waits for a QueryLogConfig to return CREATED
func QueryLogConfigCreated(conn *route53resolver.Route53Resolver, queryLogConfigID string) (*route53resolver.ResolverQueryLogConfig, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{route53resolver.ResolverQueryLogConfigStatusCreating},
Target: []string{route53resolver.ResolverQueryLogConfigStatusCreated},
Refresh: QueryLogConfigStatus(conn, queryLogConfigID),
Timeout: QueryLogConfigCreatedTimeout,
}

outputRaw, err := stateConf.WaitForState()

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

return nil, err
}

// QueryLogConfigCreated waits for a QueryLogConfig to be deleted
func QueryLogConfigDeleted(conn *route53resolver.Route53Resolver, queryLogConfigID string) (*route53resolver.ResolverQueryLogConfig, error) {
stateConf := &resource.StateChangeConf{
Pending: []string{route53resolver.ResolverQueryLogConfigStatusDeleting},
Target: []string{},
Refresh: QueryLogConfigStatus(conn, queryLogConfigID),
Timeout: QueryLogConfigDeletedTimeout,
}

outputRaw, err := stateConf.WaitForState()

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

return nil, err
}
2 changes: 2 additions & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,8 @@ func Provider() *schema.Provider {
"aws_route53_zone": resourceAwsRoute53Zone(),
"aws_route53_health_check": resourceAwsRoute53HealthCheck(),
"aws_route53_resolver_endpoint": resourceAwsRoute53ResolverEndpoint(),
"aws_route53_resolver_query_log_config": resourceAwsRoute53ResolverQueryLogConfig(),
"aws_route53_resolver_query_log_config_association": resourceAwsRoute53ResolverQueryLogConfigAssociation(),
"aws_route53_resolver_rule_association": resourceAwsRoute53ResolverRuleAssociation(),
"aws_route53_resolver_rule": resourceAwsRoute53ResolverRule(),
"aws_route": resourceAwsRoute(),
Expand Down
166 changes: 166 additions & 0 deletions aws/resource_aws_route53_resolver_query_log_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package aws

import (
"fmt"
"log"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53resolver"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
"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 resourceAwsRoute53ResolverQueryLogConfig() *schema.Resource {
return &schema.Resource{
Create: resourceAwsRoute53ResolverQueryLogConfigCreate,
Read: resourceAwsRoute53ResolverQueryLogConfigRead,
Update: resourceAwsRoute53ResolverQueryLogConfigUpdate,
Delete: resourceAwsRoute53ResolverQueryLogConfigDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

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

"destination_arn": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateArn,
},

"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateRoute53ResolverName,
},

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

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

"tags": tagsSchema(),
},
}
}

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

input := &route53resolver.CreateResolverQueryLogConfigInput{
CreatorRequestId: aws.String(resource.PrefixedUniqueId("tf-r53-resolver-query-log-config-")),
DestinationArn: aws.String(d.Get("destination_arn").(string)),
Name: aws.String(d.Get("name").(string)),
}
if v, ok := d.GetOk("tags"); ok && len(v.(map[string]interface{})) > 0 {
input.Tags = keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().Route53resolverTags()
}

log.Printf("[DEBUG] Creating Route53 Resolver Query Log Config: %s", input)
output, err := conn.CreateResolverQueryLogConfig(input)

if err != nil {
return fmt.Errorf("error creating Route53 Resolver Query Log Config: %w", err)
}

d.SetId(aws.StringValue(output.ResolverQueryLogConfig.Id))

_, err = waiter.QueryLogConfigCreated(conn, d.Id())

if err != nil {
return fmt.Errorf("error waiting for Route53 Resolver Query Log Config (%s) to become available: %w", d.Id(), err)
}

return resourceAwsRoute53ResolverQueryLogConfigRead(d, meta)
}

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

queryLogConfig, err := finder.ResolverQueryLogConfigByID(conn, d.Id())

if isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") {
log.Printf("[WARN] Route53 Resolver Query Log Config (%s), removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error reading Route53 Resolver Query Log Config (%s): %w", d.Id(), err)
}

if queryLogConfig == nil {
log.Printf("[WARN] Route53 Resolver Query Log Config (%s), removing from state", d.Id())
d.SetId("")
return nil
}

arn := aws.StringValue(queryLogConfig.Arn)
d.Set("arn", arn)
d.Set("destination_arn", queryLogConfig.DestinationArn)
d.Set("name", queryLogConfig.Name)
d.Set("owner_id", queryLogConfig.OwnerId)
d.Set("share_status", queryLogConfig.ShareStatus)

tags, err := keyvaluetags.Route53resolverListTags(conn, arn)
if err != nil {
return fmt.Errorf("error listing tags for Route53 Resolver Query Log Config (%s): %w", arn, err)
}

if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %w", err)
}

return nil
}

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

if d.HasChange("tags") {
o, n := d.GetChange("tags")
if err := keyvaluetags.Route53resolverUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return fmt.Errorf("error updating Route53 Resolver Query Log Config (%s) tags: %s", d.Get("arn").(string), err)
}
}

return resourceAwsRoute53ResolverQueryLogConfigRead(d, meta)
}

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

log.Printf("[DEBUG] Deleting Route53 Resolver Query Log Config (%s)", d.Id())
_, err := conn.DeleteResolverQueryLogConfig(&route53resolver.DeleteResolverQueryLogConfigInput{
ResolverQueryLogConfigId: aws.String(d.Id()),
})
if isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") {
return nil
}
if err != nil {
return fmt.Errorf("error deleting Route53 Resolver Query Log Config (%s): %w", d.Id(), err)
}

_, err = waiter.QueryLogConfigDeleted(conn, d.Id())

if err != nil {
return fmt.Errorf("error waiting for Route53 Resolver Query Log Config (%s) to be deleted: %w", d.Id(), err)
}

return nil
}
Loading