From 426623e9495bb8961795396aa8d8716010a26877 Mon Sep 17 00:00:00 2001 From: Gareth Oakley Date: Fri, 9 Apr 2021 22:43:09 +0100 Subject: [PATCH 1/8] resource/aws_route53_resolver_firewall_rule_group_association: Add new resource --- .../service/route53resolver/finder/finder.go | 19 + .../service/route53resolver/waiter/status.go | 24 ++ .../service/route53resolver/waiter/waiter.go | 64 +++ aws/provider.go | 1 + ...esolver_firewall_rule_group_association.go | 213 ++++++++++ ...er_firewall_rule_group_association_test.go | 401 ++++++++++++++++++ ...r_firewall_rule_group_association.markdown | 52 +++ 7 files changed, 774 insertions(+) create mode 100644 aws/resource_aws_route53_resolver_firewall_rule_group_association.go create mode 100644 aws/resource_aws_route53_resolver_firewall_rule_group_association_test.go create mode 100644 website/docs/r/route53_resolver_firewall_rule_group_association.markdown diff --git a/aws/internal/service/route53resolver/finder/finder.go b/aws/internal/service/route53resolver/finder/finder.go index 82a94981889..59286ec207d 100644 --- a/aws/internal/service/route53resolver/finder/finder.go +++ b/aws/internal/service/route53resolver/finder/finder.go @@ -156,3 +156,22 @@ func FirewallRuleByID(conn *route53resolver.Route53Resolver, firewallRuleId stri return rule, nil } + +// FirewallRuleGroupAssociationByID returns the DNS Firewall rule group association corresponding to the specified ID. +// Returns nil if no DNS Firewall rule group association is found. +func FirewallRuleGroupAssociationByID(conn *route53resolver.Route53Resolver, firewallRuleGroupAssociationId string) (*route53resolver.FirewallRuleGroupAssociation, error) { + input := &route53resolver.GetFirewallRuleGroupAssociationInput{ + FirewallRuleGroupAssociationId: aws.String(firewallRuleGroupAssociationId), + } + + output, err := conn.GetFirewallRuleGroupAssociation(input) + if err != nil { + return nil, err + } + + if output == nil { + return nil, nil + } + + return output.FirewallRuleGroupAssociation, nil +} diff --git a/aws/internal/service/route53resolver/waiter/status.go b/aws/internal/service/route53resolver/waiter/status.go index 4abeba22ed4..72d24206b4c 100644 --- a/aws/internal/service/route53resolver/waiter/status.go +++ b/aws/internal/service/route53resolver/waiter/status.go @@ -20,6 +20,9 @@ const ( firewallDomainListStatusNotFound = "NotFound" firewallDomainListStatusUnknown = "Unknown" + + resolverFirewallRuleGroupAssociationStatusNotFound = "NotFound" + resolverFirewallRuleGroupAssociationStatusUnknown = "Unknown" ) // QueryLogConfigAssociationStatus fetches the QueryLogConfigAssociation and its Status @@ -105,3 +108,24 @@ func FirewallDomainListStatus(conn *route53resolver.Route53Resolver, firewallDom return firewallDomainList, aws.StringValue(firewallDomainList.Status), nil } } + +// FirewallRuleGroupAssociationStatus fetches the FirewallRuleGroupAssociation and its Status +func FirewallRuleGroupAssociationStatus(conn *route53resolver.Route53Resolver, firewallRuleGroupAssociationId string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + firewallRuleGroupAssociation, err := finder.FirewallRuleGroupAssociationByID(conn, firewallRuleGroupAssociationId) + + if tfawserr.ErrCodeEquals(err, route53resolver.ErrCodeResourceNotFoundException) { + return nil, resolverFirewallRuleGroupAssociationStatusNotFound, nil + } + + if err != nil { + return nil, resolverFirewallRuleGroupAssociationStatusUnknown, err + } + + if firewallRuleGroupAssociation == nil { + return nil, resolverFirewallRuleGroupAssociationStatusNotFound, nil + } + + return firewallRuleGroupAssociation, aws.StringValue(firewallRuleGroupAssociation.Status), nil + } +} diff --git a/aws/internal/service/route53resolver/waiter/waiter.go b/aws/internal/service/route53resolver/waiter/waiter.go index 08f12bdd7b4..ea43d9abe51 100644 --- a/aws/internal/service/route53resolver/waiter/waiter.go +++ b/aws/internal/service/route53resolver/waiter/waiter.go @@ -33,6 +33,15 @@ const ( // Maximum amount of time to wait for a FirewallDomainList to be deleted FirewallDomainListDeletedTimeout = 5 * time.Minute + + // Maximum amount of time to wait for a FirewallRuleGroupAssociation to be created + FirewallRuleGroupAssociationCreatedTimeout = 5 * time.Minute + + // Maximum amount of time to wait for a FirewallRuleGroupAssociation to be updated + FirewallRuleGroupAssociationUpdatedTimeout = 5 * time.Minute + + // Maximum amount of time to wait for a FirewallRuleGroupAssociation to be deleted + FirewallRuleGroupAssociationDeletedTimeout = 5 * time.Minute ) // QueryLogConfigAssociationCreated waits for a QueryLogConfig to return ACTIVE @@ -187,3 +196,58 @@ func FirewallDomainListDeleted(conn *route53resolver.Route53Resolver, firewallDo return nil, err } + +// FirewallRuleGroupAssociationCreated waits for a FirewallRuleGroupAssociation to return COMPLETE +func FirewallRuleGroupAssociationCreated(conn *route53resolver.Route53Resolver, firewallRuleGroupAssociationId string) (*route53resolver.FirewallRuleGroupAssociation, error) { + stateConf := &resource.StateChangeConf{ + // TODO: What should this be? + Pending: []string{route53resolver.FirewallRuleGroupAssociationStatusUpdating}, + Target: []string{route53resolver.FirewallRuleGroupAssociationStatusComplete}, + Refresh: FirewallRuleGroupAssociationStatus(conn, firewallRuleGroupAssociationId), + Timeout: FirewallRuleGroupAssociationCreatedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*route53resolver.FirewallRuleGroupAssociation); ok { + return v, err + } + + return nil, err +} + +// FirewallRuleGroupAssociationUpdated waits for a FirewallRuleGroupAssociation to return COMPLETE +func FirewallRuleGroupAssociationUpdated(conn *route53resolver.Route53Resolver, firewallRuleGroupAssociationId string) (*route53resolver.FirewallRuleGroupAssociation, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{route53resolver.FirewallRuleGroupAssociationStatusUpdating}, + Target: []string{route53resolver.FirewallRuleGroupAssociationStatusComplete}, + Refresh: FirewallRuleGroupAssociationStatus(conn, firewallRuleGroupAssociationId), + Timeout: FirewallRuleGroupAssociationUpdatedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*route53resolver.FirewallRuleGroupAssociation); ok { + return v, err + } + + return nil, err +} + +// FirewallRuleGroupAssociationDeleted waits for a FirewallRuleGroupAssociation to be deleted +func FirewallRuleGroupAssociationDeleted(conn *route53resolver.Route53Resolver, firewallRuleGroupAssociationId string) (*route53resolver.FirewallRuleGroupAssociation, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{route53resolver.FirewallRuleGroupAssociationStatusDeleting}, + Target: []string{}, + Refresh: FirewallRuleGroupAssociationStatus(conn, firewallRuleGroupAssociationId), + Timeout: FirewallRuleGroupAssociationDeletedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*route53resolver.FirewallRuleGroupAssociation); ok { + return v, err + } + + return nil, err +} diff --git a/aws/provider.go b/aws/provider.go index 96b7993a55c..d199d5bb7ea 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -930,6 +930,7 @@ func Provider() *schema.Provider { "aws_route53_resolver_firewall_domain_list": resourceAwsRoute53ResolverFirewallDomainList(), "aws_route53_resolver_firewall_rule": resourceAwsRoute53ResolverFirewallRule(), "aws_route53_resolver_firewall_rule_group": resourceAwsRoute53ResolverFirewallRuleGroup(), + "aws_route53_resolver_firewall_rule_group_association": resourceAwsRoute53ResolverFirewallRuleGroupAssociation(), "aws_route53_resolver_query_log_config": resourceAwsRoute53ResolverQueryLogConfig(), "aws_route53_resolver_query_log_config_association": resourceAwsRoute53ResolverQueryLogConfigAssociation(), "aws_route53_resolver_rule_association": resourceAwsRoute53ResolverRuleAssociation(), diff --git a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go new file mode 100644 index 00000000000..aff7dcb4b8c --- /dev/null +++ b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go @@ -0,0 +1,213 @@ +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/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "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 resourceAwsRoute53ResolverFirewallRuleGroupAssociation() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsRoute53ResolverFirewallRuleGroupAssociationCreate, + Read: resourceAwsRoute53ResolverFirewallRuleGroupAssociationRead, + Update: resourceAwsRoute53ResolverFirewallRuleGroupAssociationUpdate, + Delete: resourceAwsRoute53ResolverFirewallRuleGroupAssociationDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + + "id": { + Type: schema.TypeString, + Computed: true, + }, + + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateRoute53ResolverName, + }, + + "firewall_rule_group_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateRoute53ResolverName, + }, + + "mutation_protection": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(route53resolver.MutationProtectionStatus_Values(), false), + }, + + "priority": { + Type: schema.TypeInt, + Required: true, + }, + + "vpc_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateRoute53ResolverName, + }, + + "tags": tagsSchema(), + }, + } +} + +func resourceAwsRoute53ResolverFirewallRuleGroupAssociationCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).route53resolverconn + + input := &route53resolver.AssociateFirewallRuleGroupInput{ + CreatorRequestId: aws.String(resource.PrefixedUniqueId("tf-r53-rslvr-frgassoc-")), + Name: aws.String(d.Get("name").(string)), + FirewallRuleGroupId: aws.String(d.Get("firewall_rule_group_id").(string)), + Priority: aws.Int64(int64(d.Get("priority").(int))), + VpcId: aws.String(d.Get("vpc_id").(string)), + } + + if v, ok := d.GetOk("mutation_protection"); ok { + input.MutationProtection = aws.String(v.(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 Route 53 Resolver DNS Firewall rule group association: %#v", input) + output, err := conn.AssociateFirewallRuleGroup(input) + if err != nil { + return fmt.Errorf("error creating Route 53 Resolver DNS Firewall rule group association: %w", err) + } + + d.SetId(aws.StringValue(output.FirewallRuleGroupAssociation.Id)) + + _, err = waiter.FirewallRuleGroupAssociationCreated(conn, d.Id()) + + if err != nil { + return fmt.Errorf("error waiting for Route53 Resolver DNS Firewall rule group association (%s) to become available: %w", d.Id(), err) + } + + return resourceAwsRoute53ResolverFirewallRuleGroupAssociationRead(d, meta) +} + +func resourceAwsRoute53ResolverFirewallRuleGroupAssociationRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).route53resolverconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + ruleGroupAssociation, err := finder.FirewallRuleGroupAssociationByID(conn, d.Id()) + + if isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] Route53 Resolver DNS Firewall rule group association (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error getting Route 53 Resolver DNS Firewall rule group association (%s): %w", d.Id(), err) + } + + if ruleGroupAssociation == nil { + log.Printf("[WARN] Route 53 Resolver DNS Firewall rule group association (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + arn := aws.StringValue(ruleGroupAssociation.Arn) + d.Set("arn", arn) + d.Set("id", ruleGroupAssociation.Id) + d.Set("name", ruleGroupAssociation.Name) + d.Set("firewall_rule_group_id", ruleGroupAssociation.FirewallRuleGroupId) + d.Set("mutation_protection", ruleGroupAssociation.MutationProtection) + d.Set("priority", ruleGroupAssociation.Priority) + d.Set("vpc_id", ruleGroupAssociation.VpcId) + + tags, err := keyvaluetags.Route53resolverListTags(conn, arn) + if err != nil { + return fmt.Errorf("error listing tags for Route53 Resolver DNS Firewall rule group association (%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 resourceAwsRoute53ResolverFirewallRuleGroupAssociationUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).route53resolverconn + + if d.HasChanges("name", "mutation_protection", "priority") { + input := &route53resolver.UpdateFirewallRuleGroupAssociationInput{ + FirewallRuleGroupAssociationId: aws.String(d.Id()), + Name: aws.String(d.Get("name").(string)), + Priority: aws.Int64(int64(d.Get("priority").(int))), + } + + if v, ok := d.GetOk("mutation_protection"); ok { + input.MutationProtection = aws.String(v.(string)) + } + + log.Printf("[DEBUG] Updating Route 53 Resolver DNS Firewall rule group association: %#v", input) + _, err := conn.UpdateFirewallRuleGroupAssociation(input) + if err != nil { + return fmt.Errorf("error creating Route 53 Resolver DNS Firewall rule group association: %w", err) + } + + _, err = waiter.FirewallRuleGroupAssociationUpdated(conn, d.Id()) + + if err != nil { + return fmt.Errorf("error waiting for Route53 Resolver DNS Firewall rule group association (%s) to be updated: %w", d.Id(), err) + } + } + + 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 DNS Firewall rule group association (%s) tags: %w", d.Get("arn").(string), err) + } + } + + return resourceAwsRoute53ResolverFirewallRuleGroupAssociationRead(d, meta) +} + +func resourceAwsRoute53ResolverFirewallRuleGroupAssociationDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).route53resolverconn + + _, err := conn.DisassociateFirewallRuleGroup(&route53resolver.DisassociateFirewallRuleGroupInput{ + FirewallRuleGroupAssociationId: aws.String(d.Id()), + }) + + if isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Route 53 Resolver DNS Firewall rule group association (%s): %w", d.Id(), err) + } + + _, err = waiter.FirewallRuleGroupAssociationDeleted(conn, d.Id()) + + if err != nil { + return fmt.Errorf("error waiting for Route53 Resolver DNS Firewall rule group association (%s) to be deleted: %w", d.Id(), err) + } + + return nil +} diff --git a/aws/resource_aws_route53_resolver_firewall_rule_group_association_test.go b/aws/resource_aws_route53_resolver_firewall_rule_group_association_test.go new file mode 100644 index 00000000000..0780d9539ad --- /dev/null +++ b/aws/resource_aws_route53_resolver_firewall_rule_group_association_test.go @@ -0,0 +1,401 @@ +package aws + +import ( + "fmt" + "log" + "testing" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/route53resolver" + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/route53resolver/finder" +) + +func init() { + resource.AddTestSweepers("aws_route53_resolver_firewall_rule_group_association", &resource.Sweeper{ + Name: "aws_route53_resolver_firewall_rule_group_association", + F: testSweepRoute53ResolverFirewallRuleGroupAssociations, + }) +} + +func testSweepRoute53ResolverFirewallRuleGroupAssociations(region string) error { + client, err := sharedClientForRegion(region) + if err != nil { + return fmt.Errorf("error getting client: %s", err) + } + conn := client.(*AWSClient).route53resolverconn + var sweeperErrs *multierror.Error + + err = conn.ListFirewallRuleGroupAssociationsPages(&route53resolver.ListFirewallRuleGroupAssociationsInput{}, func(page *route53resolver.ListFirewallRuleGroupAssociationsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, firewallRuleGroupAssociation := range page.FirewallRuleGroupAssociations { + id := aws.StringValue(firewallRuleGroupAssociation.Id) + + log.Printf("[INFO] Deleting Route53 Resolver DNS Firewall rule group association: %s", id) + r := resourceAwsRoute53ResolverFirewallRuleGroupAssociation() + d := r.Data(nil) + d.SetId(id) + err := r.Delete(d, client) + + if err != nil { + log.Printf("[ERROR] %s", err) + sweeperErrs = multierror.Append(sweeperErrs, err) + continue + } + } + + return !isLast + }) + if testSweepSkipSweepError(err) { + log.Printf("[WARN] Skipping Route53 Resolver DNS Firewall rule group associations sweep for %s: %s", region, err) + return sweeperErrs.ErrorOrNil() // In case we have completed some pages, but had errors + } + if err != nil { + sweeperErrs = multierror.Append(sweeperErrs, fmt.Errorf("error retrieving Route53 Resolver DNS Firewall rule group associations: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + +func TestAccAWSRoute53ResolverFirewallRuleGroupAssociation_basic(t *testing.T) { + var v route53resolver.FirewallRuleGroupAssociation + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_route53_resolver_firewall_rule_group_association.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallRuleGroupAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttrPair(resourceName, "firewall_rule_group_id", "aws_route53_resolver_firewall_rule_group.test", "id"), + resource.TestCheckResourceAttr(resourceName, "mutation_protection", "DISABLED"), + resource.TestCheckResourceAttr(resourceName, "priority", "101"), + resource.TestCheckResourceAttrPair(resourceName, "vpc_id", "aws_vpc.test", "id"), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSRoute53ResolverFirewallRuleGroupAssociation_name(t *testing.T) { + var v route53resolver.FirewallRuleGroupAssociation + rName := acctest.RandomWithPrefix("tf-acc-test") + rNewName := acctest.RandomWithPrefix("tf-acc-test2") + resourceName := "aws_route53_resolver_firewall_rule_group_association.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallRuleGroupAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfig(rNewName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rNewName), + ), + }, + }, + }) +} + +func TestAccAWSRoute53ResolverFirewallRuleGroupAssociation_mutationProtection(t *testing.T) { + var v route53resolver.FirewallRuleGroupAssociation + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_route53_resolver_firewall_rule_group_association.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallRuleGroupAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfig_mutationProtection(rName, "ENABLED"), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "mutation_protection", "ENABLED"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfig_mutationProtection(rName, "DISABLED"), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "mutation_protection", "DISABLED"), + ), + }, + }, + }) +} + +func TestAccAWSRoute53ResolverFirewallRuleGroupAssociation_priority(t *testing.T) { + var v route53resolver.FirewallRuleGroupAssociation + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_route53_resolver_firewall_rule_group_association.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallRuleGroupAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfig_priority(rName, 101), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "priority", "101"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfig_priority(rName, 200), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "priority", "200"), + ), + }, + }, + }) +} + +func TestAccAWSRoute53ResolverFirewallRuleGroupAssociation_disappears(t *testing.T) { + var v route53resolver.FirewallRuleGroupAssociation + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_route53_resolver_firewall_rule_group_association.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallRuleGroupAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + testAccCheckResourceDisappears(testAccProvider, resourceAwsRoute53ResolverFirewallRuleGroupAssociation(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAWSRoute53ResolverFirewallRuleGroupAssociation_tags(t *testing.T) { + var v route53resolver.FirewallRuleGroupAssociation + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_route53_resolver_firewall_rule_group_association.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallRuleGroupAssociationDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccRoute53ResolverFirewallRuleGroupAssociationConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func testAccCheckRoute53ResolverFirewallRuleGroupAssociationDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).route53resolverconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_route53_resolver_firewall_rule_group_association" { + continue + } + + // Try to find the resource + _, err := finder.FirewallRuleGroupAssociationByID(conn, rs.Primary.ID) + // Verify the error is what we want + if isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") { + continue + } + if err != nil { + return err + } + return fmt.Errorf("Route 53 Resolver DNS Firewall rule group association still exists: %s", rs.Primary.ID) + } + + return nil +} + +func testAccCheckRoute53ResolverFirewallRuleGroupAssociationExists(n string, v *route53resolver.FirewallRuleGroupAssociation) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Route 53 Resolver DNS Firewall rule group association ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).route53resolverconn + out, err := finder.FirewallRuleGroupAssociationByID(conn, rs.Primary.ID) + if err != nil { + return err + } + + *v = *out + + return nil + } +} + +func testAccRoute53ResolverFirewallRuleGroupAssociationConfig_base(rName string) string { + return fmt.Sprintf(` +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" +} + +resource "aws_route53_resolver_firewall_rule_group" "test" { + name = %[1]q +} +`, rName) +} + +func testAccRoute53ResolverFirewallRuleGroupAssociationConfig(rName string) string { + return fmt.Sprintf(` +%[1]s + +resource "aws_route53_resolver_firewall_rule_group_association" "test" { + name = %[2]q + firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.test.id + mutation_protection = "DISABLED" + priority = 101 + vpc_id = aws_vpc.test.id +} +`, testAccRoute53ResolverFirewallRuleGroupAssociationConfig_base(rName), rName) +} + +func testAccRoute53ResolverFirewallRuleGroupAssociationConfig_mutationProtection(rName, mutationProtection string) string { + return fmt.Sprintf(` +%[1]s + +resource "aws_route53_resolver_firewall_rule_group_association" "test" { + name = %[2]q + firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.test.id + mutation_protection = %[3]q + priority = 101 + vpc_id = aws_vpc.test.id +} +`, testAccRoute53ResolverFirewallRuleGroupAssociationConfig_base(rName), rName, mutationProtection) +} + +func testAccRoute53ResolverFirewallRuleGroupAssociationConfig_priority(rName string, priority int) string { + return fmt.Sprintf(` +%[1]s + +resource "aws_route53_resolver_firewall_rule_group_association" "test" { + name = %[2]q + firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.test.id + priority = %[3]d + vpc_id = aws_vpc.test.id +} +`, testAccRoute53ResolverFirewallRuleGroupAssociationConfig_base(rName), rName, priority) +} + +func testAccRoute53ResolverFirewallRuleGroupAssociationConfigTags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +%[1]s + +resource "aws_route53_resolver_firewall_rule_group_association" "test" { + name = %[2]q + firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.test.id + priority = 101 + vpc_id = aws_vpc.test.id + + tags = { + %[3]q = %[4]q + } +} +`, testAccRoute53ResolverFirewallRuleGroupAssociationConfig_base(rName), rName, tagKey1, tagValue1) +} + +func testAccRoute53ResolverFirewallRuleGroupAssociationConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +%[1]s + +resource "aws_route53_resolver_firewall_rule_group_association" "test" { + name = %[2]q + firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.test.id + priority = 101 + vpc_id = aws_vpc.test.id + + tags = { + %[3]q = %[4]q + %[5]q = %[6]q + } +} +`, testAccRoute53ResolverFirewallRuleGroupAssociationConfig_base(rName), rName, tagKey1, tagValue1, tagKey2, tagValue2) +} diff --git a/website/docs/r/route53_resolver_firewall_rule_group_association.markdown b/website/docs/r/route53_resolver_firewall_rule_group_association.markdown new file mode 100644 index 00000000000..936dbe582a5 --- /dev/null +++ b/website/docs/r/route53_resolver_firewall_rule_group_association.markdown @@ -0,0 +1,52 @@ +--- +subcategory: "Route53 Resolver" +layout: "aws" +page_title: "AWS: aws_route53_resolver_firewall_rule_group_association" +description: |- + Provides a Route 53 Resolver DNS Firewall rule group association resource. +--- + +# Resource: aws_route53_resolver_firewall_rule_group_association + +Provides a Route 53 Resolver DNS Firewall rule group association resource. + +## Example Usage + +```terraform +resource "aws_route53_resolver_firewall_rule_group" "example" { + name = "example" +} + +resource "aws_route53_resolver_firewall_rule_group_association" "example" { + name = "example" + firewall_rule_group_id = aws_route53_resolver_firewall_rule_group.example.id + priority = 100 + vpc_id = aws_vpc.example.id +} +``` + +## Argument Reference + +The following argument is supported: + +* `name` - (Required) A name that lets you identify the rule group association, to manage and use it. +* `firewall_rule_group_id` - (Required) The unique identifier of the firewall rule group. +* `mutation_protection` - (Optional) If enabled, this setting disallows modification or removal of the association, to help prevent against accidentally altering DNS firewall protections. Valid values: `ENABLED`, `DISABLED`. +* `priority` - (Required) The setting that determines the processing order of the rule group among the rule groups that you associate with the specified VPC. DNS Firewall filters VPC traffic starting from the rule group with the lowest numeric priority setting. +* `vpc_id` - (Required) The unique identifier of the VPC that you want to associate with the rule group. +* `tags` - (Optional) A map of tags to assign to the resource. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `arn` - The ARN (Amazon Resource Name) of the firewall rule group association. +* `id` - The identifier for the association. + +## Import + + Route 53 Resolver DNS Firewall rule group associations can be imported using the Route 53 Resolver DNS Firewall rule group association ID, e.g. + +``` +$ terraform import aws_route53_resolver_firewall_rule_group_association.example rslvr-frgassoc-0123456789abcdef +``` From 616b71cbeebac5bbea3f5e9f24d616efa7d31325 Mon Sep 17 00:00:00 2001 From: Gareth Oakley Date: Wed, 21 Apr 2021 19:19:44 +0100 Subject: [PATCH 2/8] resource/aws_route53_resolver_firewall_rule_group_association: Address review comments --- .changelog/18731.txt | 3 +++ ..._aws_route53_resolver_firewall_rule_group_association.go | 6 ------ ...route53_resolver_firewall_rule_group_association_test.go | 6 +++--- 3 files changed, 6 insertions(+), 9 deletions(-) create mode 100644 .changelog/18731.txt diff --git a/.changelog/18731.txt b/.changelog/18731.txt new file mode 100644 index 00000000000..e0fa66fb0a6 --- /dev/null +++ b/.changelog/18731.txt @@ -0,0 +1,3 @@ +```release-note:new-resource +aws_route53_resolver_firewall_rule_group_association +``` \ No newline at end of file diff --git a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go index aff7dcb4b8c..282594e9110 100644 --- a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go +++ b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go @@ -30,11 +30,6 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociation() *schema.Resource { Computed: true, }, - "id": { - Type: schema.TypeString, - Computed: true, - }, - "name": { Type: schema.TypeString, Required: true, @@ -132,7 +127,6 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociationRead(d *schema.Resour arn := aws.StringValue(ruleGroupAssociation.Arn) d.Set("arn", arn) - d.Set("id", ruleGroupAssociation.Id) d.Set("name", ruleGroupAssociation.Name) d.Set("firewall_rule_group_id", ruleGroupAssociation.FirewallRuleGroupId) d.Set("mutation_protection", ruleGroupAssociation.MutationProtection) diff --git a/aws/resource_aws_route53_resolver_firewall_rule_group_association_test.go b/aws/resource_aws_route53_resolver_firewall_rule_group_association_test.go index 0780d9539ad..e6f1debc0a5 100644 --- a/aws/resource_aws_route53_resolver_firewall_rule_group_association_test.go +++ b/aws/resource_aws_route53_resolver_firewall_rule_group_association_test.go @@ -29,9 +29,9 @@ func testSweepRoute53ResolverFirewallRuleGroupAssociations(region string) error conn := client.(*AWSClient).route53resolverconn var sweeperErrs *multierror.Error - err = conn.ListFirewallRuleGroupAssociationsPages(&route53resolver.ListFirewallRuleGroupAssociationsInput{}, func(page *route53resolver.ListFirewallRuleGroupAssociationsOutput, isLast bool) bool { + err = conn.ListFirewallRuleGroupAssociationsPages(&route53resolver.ListFirewallRuleGroupAssociationsInput{}, func(page *route53resolver.ListFirewallRuleGroupAssociationsOutput, lastPage bool) bool { if page == nil { - return !isLast + return !lastPage } for _, firewallRuleGroupAssociation := range page.FirewallRuleGroupAssociations { @@ -50,7 +50,7 @@ func testSweepRoute53ResolverFirewallRuleGroupAssociations(region string) error } } - return !isLast + return !lastPage }) if testSweepSkipSweepError(err) { log.Printf("[WARN] Skipping Route53 Resolver DNS Firewall rule group associations sweep for %s: %s", region, err) From 035d9a27a4917073c3fd2e59e749adabe8beb248 Mon Sep 17 00:00:00 2001 From: Gareth Oakley Date: Tue, 27 Apr 2021 20:35:06 +0100 Subject: [PATCH 3/8] resource/aws_route53_resolver_firewall_rule_group_association: Add support for `tags_all` --- ...esolver_firewall_rule_group_association.go | 26 +++++++++++++------ ...r_firewall_rule_group_association.markdown | 5 ++-- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go index 282594e9110..e8e931ee048 100644 --- a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go +++ b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go @@ -62,13 +62,18 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociation() *schema.Resource { ValidateFunc: validateRoute53ResolverName, }, - "tags": tagsSchema(), + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), }, + + CustomizeDiff: SetTagsDiff, } } func resourceAwsRoute53ResolverFirewallRuleGroupAssociationCreate(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).route53resolverconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) input := &route53resolver.AssociateFirewallRuleGroupInput{ CreatorRequestId: aws.String(resource.PrefixedUniqueId("tf-r53-rslvr-frgassoc-")), @@ -76,16 +81,13 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociationCreate(d *schema.Reso FirewallRuleGroupId: aws.String(d.Get("firewall_rule_group_id").(string)), Priority: aws.Int64(int64(d.Get("priority").(int))), VpcId: aws.String(d.Get("vpc_id").(string)), + Tags: tags.IgnoreAws().Route53resolverTags(), } if v, ok := d.GetOk("mutation_protection"); ok { input.MutationProtection = aws.String(v.(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 Route 53 Resolver DNS Firewall rule group association: %#v", input) output, err := conn.AssociateFirewallRuleGroup(input) if err != nil { @@ -105,6 +107,7 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociationCreate(d *schema.Reso func resourceAwsRoute53ResolverFirewallRuleGroupAssociationRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).route53resolverconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig ruleGroupAssociation, err := finder.FirewallRuleGroupAssociationByID(conn, d.Id()) @@ -138,10 +141,17 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociationRead(d *schema.Resour return fmt.Errorf("error listing tags for Route53 Resolver DNS Firewall rule group association (%s): %w", arn, err) } - if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil { + tags = tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { return fmt.Errorf("error setting tags: %w", err) } + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + return nil } @@ -172,8 +182,8 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociationUpdate(d *schema.Reso } } - if d.HasChange("tags") { - o, n := d.GetChange("tags") + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") if err := keyvaluetags.Route53resolverUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { return fmt.Errorf("error updating Route53 Resolver DNS Firewall rule group association (%s) tags: %w", d.Get("arn").(string), err) } diff --git a/website/docs/r/route53_resolver_firewall_rule_group_association.markdown b/website/docs/r/route53_resolver_firewall_rule_group_association.markdown index 936dbe582a5..5afddd9b84b 100644 --- a/website/docs/r/route53_resolver_firewall_rule_group_association.markdown +++ b/website/docs/r/route53_resolver_firewall_rule_group_association.markdown @@ -34,7 +34,7 @@ The following argument is supported: * `mutation_protection` - (Optional) If enabled, this setting disallows modification or removal of the association, to help prevent against accidentally altering DNS firewall protections. Valid values: `ENABLED`, `DISABLED`. * `priority` - (Required) The setting that determines the processing order of the rule group among the rule groups that you associate with the specified VPC. DNS Firewall filters VPC traffic starting from the rule group with the lowest numeric priority setting. * `vpc_id` - (Required) The unique identifier of the VPC that you want to associate with the rule group. -* `tags` - (Optional) A map of tags to assign to the resource. +* `tags` - (Optional) Key-value map of resource tags. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level. ## Attributes Reference @@ -42,10 +42,11 @@ In addition to all arguments above, the following attributes are exported: * `arn` - The ARN (Amazon Resource Name) of the firewall rule group association. * `id` - The identifier for the association. +* `tags_all` - A map of tags assigned to the resource, including those inherited from the provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block). ## Import - Route 53 Resolver DNS Firewall rule group associations can be imported using the Route 53 Resolver DNS Firewall rule group association ID, e.g. +Route 53 Resolver DNS Firewall rule group associations can be imported using the Route 53 Resolver DNS Firewall rule group association ID, e.g. ``` $ terraform import aws_route53_resolver_firewall_rule_group_association.example rslvr-frgassoc-0123456789abcdef From 82252d1f47208e903171765e6e436e940c18b6a9 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 29 Apr 2021 15:39:18 -0400 Subject: [PATCH 4/8] Rename CHANGELOG entry file due to git snafu. --- .changelog/{18731.txt => 19164.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .changelog/{18731.txt => 19164.txt} (100%) diff --git a/.changelog/18731.txt b/.changelog/19164.txt similarity index 100% rename from .changelog/18731.txt rename to .changelog/19164.txt From 105c6c86ceb467e1c86ca9827fedb134f21cfc31 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 29 Apr 2021 16:31:07 -0400 Subject: [PATCH 5/8] Update aws/internal/service/route53resolver/waiter/waiter.go Co-authored-by: Brian Flad --- aws/internal/service/route53resolver/waiter/waiter.go | 1 - 1 file changed, 1 deletion(-) diff --git a/aws/internal/service/route53resolver/waiter/waiter.go b/aws/internal/service/route53resolver/waiter/waiter.go index ea43d9abe51..ea18d0b32e6 100644 --- a/aws/internal/service/route53resolver/waiter/waiter.go +++ b/aws/internal/service/route53resolver/waiter/waiter.go @@ -200,7 +200,6 @@ func FirewallDomainListDeleted(conn *route53resolver.Route53Resolver, firewallDo // FirewallRuleGroupAssociationCreated waits for a FirewallRuleGroupAssociation to return COMPLETE func FirewallRuleGroupAssociationCreated(conn *route53resolver.Route53Resolver, firewallRuleGroupAssociationId string) (*route53resolver.FirewallRuleGroupAssociation, error) { stateConf := &resource.StateChangeConf{ - // TODO: What should this be? Pending: []string{route53resolver.FirewallRuleGroupAssociationStatusUpdating}, Target: []string{route53resolver.FirewallRuleGroupAssociationStatusComplete}, Refresh: FirewallRuleGroupAssociationStatus(conn, firewallRuleGroupAssociationId), From fa2dbd159e6fd5db458b03389e16d4d145d4f184 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 29 Apr 2021 16:31:54 -0400 Subject: [PATCH 6/8] Update aws/resource_aws_route53_resolver_firewall_rule_group_association.go Co-authored-by: Brian Flad --- ...urce_aws_route53_resolver_firewall_rule_group_association.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go index e8e931ee048..af1233bcbcf 100644 --- a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go +++ b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go @@ -112,7 +112,7 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociationRead(d *schema.Resour ruleGroupAssociation, err := finder.FirewallRuleGroupAssociationByID(conn, d.Id()) - if isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") { + if !d.IsNewResource() && isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") { log.Printf("[WARN] Route53 Resolver DNS Firewall rule group association (%s) not found, removing from state", d.Id()) d.SetId("") return nil From 30ef041b54c1e076e41fe14b4e8047c3117dbe3f Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 29 Apr 2021 16:32:01 -0400 Subject: [PATCH 7/8] Update aws/resource_aws_route53_resolver_firewall_rule_group_association.go Co-authored-by: Brian Flad --- ...ce_aws_route53_resolver_firewall_rule_group_association.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go index af1233bcbcf..3f56c15432d 100644 --- a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go +++ b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go @@ -123,6 +123,10 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociationRead(d *schema.Resour } if ruleGroupAssociation == nil { + if d.IsNewResource() { + return fmt.Errorf("error getting Route 53 Resolver DNS Firewall rule group association (%s): not found after creation", d.Id()) + } + log.Printf("[WARN] Route 53 Resolver DNS Firewall rule group association (%s) not found, removing from state", d.Id()) d.SetId("") return nil From 3a2fd11b424979f1a5f5710d27d0015418bcbc85 Mon Sep 17 00:00:00 2001 From: Kit Ewbank Date: Thu, 29 Apr 2021 16:34:27 -0400 Subject: [PATCH 8/8] r/aws_route53_resolver_firewall_rule_group_association: Remove resource ID validations. --- ...e53_resolver_firewall_rule_group_association.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go index 3f56c15432d..f21c99e288f 100644 --- a/aws/resource_aws_route53_resolver_firewall_rule_group_association.go +++ b/aws/resource_aws_route53_resolver_firewall_rule_group_association.go @@ -37,10 +37,9 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociation() *schema.Resource { }, "firewall_rule_group_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validateRoute53ResolverName, + Type: schema.TypeString, + Required: true, + ForceNew: true, }, "mutation_protection": { @@ -56,10 +55,9 @@ func resourceAwsRoute53ResolverFirewallRuleGroupAssociation() *schema.Resource { }, "vpc_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validateRoute53ResolverName, + Type: schema.TypeString, + Required: true, + ForceNew: true, }, "tags": tagsSchema(),