diff --git a/aws/internal/service/route53resolver/finder/finder.go b/aws/internal/service/route53resolver/finder/finder.go index 3ede34d4771..892ad88eea6 100644 --- a/aws/internal/service/route53resolver/finder/finder.go +++ b/aws/internal/service/route53resolver/finder/finder.go @@ -94,3 +94,23 @@ func FirewallRuleGroupByID(conn *route53resolver.Route53Resolver, firewallGroupI return output.FirewallRuleGroup, nil } + +// FirewallDomainListByID returns the DNS Firewall rule group corresponding to the specified ID. +// Returns nil if no DNS Firewall rule group is found. +func FirewallDomainListByID(conn *route53resolver.Route53Resolver, firewallDomainListId string) (*route53resolver.FirewallDomainList, error) { + input := &route53resolver.GetFirewallDomainListInput{ + FirewallDomainListId: aws.String(firewallDomainListId), + } + + output, err := conn.GetFirewallDomainList(input) + + if err != nil { + return nil, err + } + + if output == nil { + return nil, nil + } + + return output.FirewallDomainList, nil +} diff --git a/aws/internal/service/route53resolver/waiter/status.go b/aws/internal/service/route53resolver/waiter/status.go index b0086ebc332..4abeba22ed4 100644 --- a/aws/internal/service/route53resolver/waiter/status.go +++ b/aws/internal/service/route53resolver/waiter/status.go @@ -17,6 +17,9 @@ const ( resolverDnssecConfigStatusNotFound = "NotFound" resolverDnssecConfigStatusUnknown = "Unknown" + + firewallDomainListStatusNotFound = "NotFound" + firewallDomainListStatusUnknown = "Unknown" ) // QueryLogConfigAssociationStatus fetches the QueryLogConfigAssociation and its Status @@ -81,3 +84,24 @@ func DnssecConfigStatus(conn *route53resolver.Route53Resolver, dnssecConfigID st return dnssecConfig, aws.StringValue(dnssecConfig.ValidationStatus), nil } } + +// FirewallDomainListStatus fetches the FirewallDomainList and its Status +func FirewallDomainListStatus(conn *route53resolver.Route53Resolver, firewallDomainListId string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + firewallDomainList, err := finder.FirewallDomainListByID(conn, firewallDomainListId) + + if tfawserr.ErrCodeEquals(err, route53resolver.ErrCodeResourceNotFoundException) { + return nil, firewallDomainListStatusNotFound, nil + } + + if err != nil { + return nil, firewallDomainListStatusUnknown, err + } + + if firewallDomainList == nil { + return nil, firewallDomainListStatusNotFound, nil + } + + return firewallDomainList, aws.StringValue(firewallDomainList.Status), nil + } +} diff --git a/aws/internal/service/route53resolver/waiter/waiter.go b/aws/internal/service/route53resolver/waiter/waiter.go index a414e334b03..08f12bdd7b4 100644 --- a/aws/internal/service/route53resolver/waiter/waiter.go +++ b/aws/internal/service/route53resolver/waiter/waiter.go @@ -1,8 +1,10 @@ package waiter import ( + "fmt" "time" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/route53resolver" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) @@ -25,6 +27,12 @@ const ( // Maximum amount of time to wait for a DnssecConfig to return DISABLED DnssecConfigDeletedTimeout = 5 * time.Minute + + // Maximum amount of time to wait for a FirewallDomainList to be updated + FirewallDomainListUpdatedTimeout = 5 * time.Minute + + // Maximum amount of time to wait for a FirewallDomainList to be deleted + FirewallDomainListDeletedTimeout = 5 * time.Minute ) // QueryLogConfigAssociationCreated waits for a QueryLogConfig to return ACTIVE @@ -134,3 +142,48 @@ func DnssecConfigDisabled(conn *route53resolver.Route53Resolver, dnssecConfigID return nil, err } + +// FirewallDomainListUpdated waits for a FirewallDomainList to be updated +func FirewallDomainListUpdated(conn *route53resolver.Route53Resolver, firewallDomainListId string) (*route53resolver.FirewallDomainList, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{ + route53resolver.FirewallDomainListStatusUpdating, + route53resolver.FirewallDomainListStatusImporting, + }, + Target: []string{ + route53resolver.FirewallDomainListStatusComplete, + route53resolver.FirewallDomainListStatusCompleteImportFailed, + }, + Refresh: FirewallDomainListStatus(conn, firewallDomainListId), + Timeout: FirewallDomainListUpdatedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*route53resolver.FirewallDomainList); ok { + if aws.StringValue(v.Status) != route53resolver.FirewallDomainListStatusComplete { + err = fmt.Errorf("error updating Route 53 Resolver DNS Firewall domain list (%s): %s", firewallDomainListId, aws.StringValue(v.StatusMessage)) + } + return v, err + } + + return nil, err +} + +// FirewallDomainListDeleted waits for a FirewallDomainList to be deleted +func FirewallDomainListDeleted(conn *route53resolver.Route53Resolver, firewallDomainListId string) (*route53resolver.FirewallDomainList, error) { + stateConf := &resource.StateChangeConf{ + Pending: []string{route53resolver.FirewallDomainListStatusDeleting}, + Target: []string{}, + Refresh: FirewallDomainListStatus(conn, firewallDomainListId), + Timeout: FirewallDomainListDeletedTimeout, + } + + outputRaw, err := stateConf.WaitForState() + + if v, ok := outputRaw.(*route53resolver.FirewallDomainList); ok { + return v, err + } + + return nil, err +} diff --git a/aws/provider.go b/aws/provider.go index 8aef6bb2896..5f309de76bc 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -918,6 +918,7 @@ func Provider() *schema.Provider { "aws_route53_health_check": resourceAwsRoute53HealthCheck(), "aws_route53_resolver_dnssec_config": resourceAwsRoute53ResolverDnssecConfig(), "aws_route53_resolver_endpoint": resourceAwsRoute53ResolverEndpoint(), + "aws_route53_resolver_firewall_domain_list": resourceAwsRoute53ResolverFirewallDomainList(), "aws_route53_resolver_firewall_rule_group": resourceAwsRoute53ResolverFirewallRuleGroup(), "aws_route53_resolver_query_log_config": resourceAwsRoute53ResolverQueryLogConfig(), "aws_route53_resolver_query_log_config_association": resourceAwsRoute53ResolverQueryLogConfigAssociation(), diff --git a/aws/resource_aws_route53_resolver_firewall_domain_list.go b/aws/resource_aws_route53_resolver_firewall_domain_list.go new file mode 100644 index 00000000000..1a0944042d3 --- /dev/null +++ b/aws/resource_aws_route53_resolver_firewall_domain_list.go @@ -0,0 +1,201 @@ +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 resourceAwsRoute53ResolverFirewallDomainList() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsRoute53ResolverFirewallDomainListCreate, + Read: resourceAwsRoute53ResolverFirewallDomainListRead, + Update: resourceAwsRoute53ResolverFirewallDomainListUpdate, + Delete: resourceAwsRoute53ResolverFirewallDomainListDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "arn": { + Type: schema.TypeString, + Computed: true, + }, + + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validateRoute53ResolverName, + }, + + "domains": { + Type: schema.TypeSet, + Optional: true, + MinItems: 0, + MaxItems: 255, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + + "tags": tagsSchema(), + }, + } +} + +func resourceAwsRoute53ResolverFirewallDomainListCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).route53resolverconn + + input := &route53resolver.CreateFirewallDomainListInput{ + CreatorRequestId: aws.String(resource.PrefixedUniqueId("tf-r53-resolver-firewall-domain-list-")), + 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 Route 53 Resolver DNS Firewall domain list: %#v", input) + output, err := conn.CreateFirewallDomainList(input) + if err != nil { + return fmt.Errorf("error creating Route 53 Resolver DNS Firewall domain list: %w", err) + } + + d.SetId(aws.StringValue(output.FirewallDomainList.Id)) + d.Set("arn", output.FirewallDomainList.Arn) + + return resourceAwsRoute53ResolverFirewallDomainListUpdate(d, meta) +} + +func resourceAwsRoute53ResolverFirewallDomainListRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).route53resolverconn + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + firewallDomainList, err := finder.FirewallDomainListByID(conn, d.Id()) + + if isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") { + log.Printf("[WARN] Route53 Resolver DNS Firewall domain list (%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 domain list (%s): %w", d.Id(), err) + } + + if firewallDomainList == nil { + log.Printf("[WARN] Route 53 Resolver DNS Firewall domain list (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + arn := aws.StringValue(firewallDomainList.Arn) + d.Set("arn", arn) + d.Set("name", firewallDomainList.Name) + + input := &route53resolver.ListFirewallDomainsInput{ + FirewallDomainListId: aws.String(d.Id()), + } + + domains := []*string{} + + err = conn.ListFirewallDomainsPages(input, func(output *route53resolver.ListFirewallDomainsOutput, lastPage bool) bool { + domains = append(domains, output.Domains...) + return !lastPage + }) + + if err != nil { + return fmt.Errorf("error listing Route 53 Resolver DNS Firewall domain list (%s) domains: %w", d.Id(), err) + } + + d.Set("domains", flattenStringSet(domains)) + + tags, err := keyvaluetags.Route53resolverListTags(conn, arn) + if err != nil { + return fmt.Errorf("error listing tags for Route53 Resolver DNS Firewall domain list (%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 resourceAwsRoute53ResolverFirewallDomainListUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).route53resolverconn + + if d.HasChange("domains") { + o, n := d.GetChange("domains") + if o == nil { + o = new(schema.Set) + } + if n == nil { + n = new(schema.Set) + } + os := o.(*schema.Set) + ns := n.(*schema.Set) + + domains := ns + operation := route53resolver.FirewallDomainUpdateOperationReplace + + if domains.Len() == 0 { + domains = os + operation = route53resolver.FirewallDomainUpdateOperationRemove + } + + _, err := conn.UpdateFirewallDomains(&route53resolver.UpdateFirewallDomainsInput{ + FirewallDomainListId: aws.String(d.Id()), + Domains: expandStringSet(domains), + Operation: aws.String(operation), + }) + + if err != nil { + return fmt.Errorf("error updating Route 53 Resolver DNS Firewall domain list (%s) domains: %w", d.Id(), err) + } + + _, err = waiter.FirewallDomainListUpdated(conn, d.Id()) + + if err != nil { + return fmt.Errorf("error waiting for Route 53 Resolver DNS Firewall domain list (%s) domains 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 domain list (%s) tags: %w", d.Get("arn").(string), err) + } + } + + return resourceAwsRoute53ResolverFirewallDomainListRead(d, meta) +} + +func resourceAwsRoute53ResolverFirewallDomainListDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).route53resolverconn + + _, err := conn.DeleteFirewallDomainList(&route53resolver.DeleteFirewallDomainListInput{ + FirewallDomainListId: aws.String(d.Id()), + }) + + if isAWSErr(err, route53resolver.ErrCodeResourceNotFoundException, "") { + return nil + } + + if err != nil { + return fmt.Errorf("error deleting Route 53 Resolver DNS Firewall domain list (%s): %w", d.Id(), err) + } + + _, err = waiter.FirewallDomainListDeleted(conn, d.Id()) + + if err != nil { + return fmt.Errorf("error waiting for Route 53 Resolver DNS Firewall domain list (%s) to be deleted: %w", d.Id(), err) + } + + return nil +} diff --git a/aws/resource_aws_route53_resolver_firewall_domain_list_test.go b/aws/resource_aws_route53_resolver_firewall_domain_list_test.go new file mode 100644 index 00000000000..e24da89d3a6 --- /dev/null +++ b/aws/resource_aws_route53_resolver_firewall_domain_list_test.go @@ -0,0 +1,295 @@ +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_domain_list", &resource.Sweeper{ + Name: "aws_route53_resolver_firewall_domain_list", + F: testSweepRoute53ResolverFirewallDomainLists, + }) +} + +func testSweepRoute53ResolverFirewallDomainLists(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.ListFirewallDomainListsPages(&route53resolver.ListFirewallDomainListsInput{}, func(page *route53resolver.ListFirewallDomainListsOutput, isLast bool) bool { + if page == nil { + return !isLast + } + + for _, queryLogConfig := range page.FirewallDomainLists { + id := aws.StringValue(queryLogConfig.Id) + + log.Printf("[INFO] Deleting Route53 Resolver DNS Firewall domain list: %s", id) + r := resourceAwsRoute53ResolverFirewallDomainList() + 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 domain lists 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 domain lists: %w", err)) + } + + return sweeperErrs.ErrorOrNil() +} + +func TestAccAWSRoute53ResolverFirewallDomainList_basic(t *testing.T) { + var v route53resolver.FirewallDomainList + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_route53_resolver_firewall_domain_list.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallDomainListDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallDomainListConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallDomainListExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "0"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAWSRoute53ResolverFirewallDomainList_domains(t *testing.T) { + var v route53resolver.FirewallDomainList + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_route53_resolver_firewall_domain_list.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallDomainListDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallDomainListConfigDomains(rName, "foo.com."), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallDomainListExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "domains.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "domains.*", "foo.com."), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccRoute53ResolverFirewallDomainListConfigDomains(rName, "bar.com."), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallDomainListExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "domains.#", "1"), + resource.TestCheckTypeSetElemAttr(resourceName, "domains.*", "bar.com."), + ), + }, + { + Config: testAccRoute53ResolverFirewallDomainListConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallDomainListExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "domains.#", "0"), + ), + }, + }, + }) +} + +func TestAccAWSRoute53ResolverFirewallDomainList_disappears(t *testing.T) { + var v route53resolver.FirewallDomainList + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_route53_resolver_firewall_domain_list.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallDomainListDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallDomainListConfig(rName), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallDomainListExists(resourceName, &v), + testAccCheckResourceDisappears(testAccProvider, resourceAwsRoute53ResolverFirewallDomainList(), resourceName), + ), + ExpectNonEmptyPlan: true, + }, + }, + }) +} + +func TestAccAWSRoute53ResolverFirewallDomainList_tags(t *testing.T) { + var v route53resolver.FirewallDomainList + rName := acctest.RandomWithPrefix("tf-acc-test") + resourceName := "aws_route53_resolver_firewall_domain_list.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSRoute53Resolver(t) }, + ErrorCheck: testAccErrorCheck(t, route53resolver.EndpointsID), + Providers: testAccProviders, + CheckDestroy: testAccCheckRoute53ResolverFirewallDomainListDestroy, + Steps: []resource.TestStep{ + { + Config: testAccRoute53ResolverFirewallDomainListConfigTags1(rName, "key1", "value1"), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallDomainListExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccRoute53ResolverFirewallDomainListConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallDomainListExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), + resource.TestCheckResourceAttr(resourceName, "tags.key1", "value1updated"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + { + Config: testAccRoute53ResolverFirewallDomainListConfigTags1(rName, "key2", "value2"), + Check: resource.ComposeTestCheckFunc( + testAccCheckRoute53ResolverFirewallDomainListExists(resourceName, &v), + resource.TestCheckResourceAttr(resourceName, "name", rName), + resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(resourceName, "tags.key2", "value2"), + ), + }, + }, + }) +} + +func testAccCheckRoute53ResolverFirewallDomainListDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*AWSClient).route53resolverconn + + for _, rs := range s.RootModule().Resources { + if rs.Type != "aws_route53_resolver_firewall_domain_list" { + continue + } + + // Try to find the resource + _, err := finder.FirewallDomainListByID(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 domain list still exists: %s", rs.Primary.ID) + } + + return nil +} + +func testAccCheckRoute53ResolverFirewallDomainListExists(n string, v *route53resolver.FirewallDomainList) 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 domain list ID is set") + } + + conn := testAccProvider.Meta().(*AWSClient).route53resolverconn + out, err := finder.FirewallDomainListByID(conn, rs.Primary.ID) + if err != nil { + return err + } + + *v = *out + + return nil + } +} + +func testAccRoute53ResolverFirewallDomainListConfig(rName string) string { + return fmt.Sprintf(` +resource "aws_route53_resolver_firewall_domain_list" "test" { + name = %[1]q +} +`, rName) +} + +func testAccRoute53ResolverFirewallDomainListConfigDomains(rName, domain string) string { + return fmt.Sprintf(` +resource "aws_route53_resolver_firewall_domain_list" "test" { + name = %[1]q + domains = [%[2]q] +} +`, rName, domain) +} + +func testAccRoute53ResolverFirewallDomainListConfigTags1(rName, tagKey1, tagValue1 string) string { + return fmt.Sprintf(` +resource "aws_route53_resolver_firewall_domain_list" "test" { + name = %[1]q + tags = { + %[2]q = %[3]q + } +} +`, rName, tagKey1, tagValue1) +} + +func testAccRoute53ResolverFirewallDomainListConfigTags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string { + return fmt.Sprintf(` +resource "aws_route53_resolver_firewall_domain_list" "test" { + name = %[1]q + tags = { + %[2]q = %[3]q + %[4]q = %[5]q + } +} +`, rName, tagKey1, tagValue1, tagKey2, tagValue2) +} diff --git a/website/docs/r/route53_resolver_firewall_domain_list.markdown b/website/docs/r/route53_resolver_firewall_domain_list.markdown new file mode 100644 index 00000000000..8bc13101428 --- /dev/null +++ b/website/docs/r/route53_resolver_firewall_domain_list.markdown @@ -0,0 +1,42 @@ +--- +subcategory: "Route53 Resolver" +layout: "aws" +page_title: "AWS: aws_route53_resolver_firewall_domain_list" +description: |- + Provides a Route 53 Resolver DNS Firewall domain list resource. +--- + +# Resource: aws_route53_resolver_firewall_domain_list + +Provides a Route 53 Resolver DNS Firewall domain list resource. + +## Example Usage + +```terraform +resource "aws_route53_resolver_firewall_domain_list" "example" { + name = "example" +} +``` + +## Argument Reference + +The following argument is supported: + +* `name` - (Required) A name that lets you identify the domain list, to manage and use it. +* `domains` - (Optional) A array of domains for the firewall domain list. +* `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 domain list. +* `id` - The ID of the domain list. + +## Import + + Route 53 Resolver DNS Firewall domain lists can be imported using the Route 53 Resolver DNS Firewall domain list ID, e.g. + +``` +$ terraform import aws_route53_resolver_firewall_domain_list.example rslvr-fdl-0123456789abcdef +```