diff --git a/.changelog/45492.txt b/.changelog/45492.txt new file mode 100644 index 000000000000..72f460823449 --- /dev/null +++ b/.changelog/45492.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +data-source/aws_route53_resolver_rule: Add `target_ips` attribute +``` diff --git a/internal/service/route53resolver/rule_data_source.go b/internal/service/route53resolver/rule_data_source.go index dc6d53e097b6..6af0e3e46500 100644 --- a/internal/service/route53resolver/rule_data_source.go +++ b/internal/service/route53resolver/rule_data_source.go @@ -70,6 +70,30 @@ func dataSourceRule() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "target_ips": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "ipv6": { + Type: schema.TypeString, + Computed: true, + }, + names.AttrPort: { + Type: schema.TypeInt, + Computed: true, + }, + names.AttrProtocol: { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, names.AttrTags: tftags.TagsSchemaComputed(), }, } @@ -134,6 +158,9 @@ func dataSourceRuleRead(ctx context.Context, d *schema.ResourceData, meta any) d d.Set("rule_type", rule.RuleType) shareStatus := rule.ShareStatus d.Set("share_status", shareStatus) + if err := d.Set("target_ips", flattenRuleTargetIPs(rule.TargetIps)); err != nil { + return sdkdiag.AppendErrorf(diags, "setting target_ips: %s", err) + } // https://github.com/hashicorp/terraform-provider-aws/issues/10211 if shareStatus != awstypes.ShareStatusSharedWithMe { tags, err := listTags(ctx, conn, arn) diff --git a/internal/service/route53resolver/rule_data_source_test.go b/internal/service/route53resolver/rule_data_source_test.go index 3ef69b635263..fd4eb253c942 100644 --- a/internal/service/route53resolver/rule_data_source_test.go +++ b/internal/service/route53resolver/rule_data_source_test.go @@ -106,6 +106,39 @@ func TestAccRoute53ResolverRuleDataSource_resolverEndpointIdWithTags(t *testing. }) } +func TestAccRoute53ResolverRuleDataSource_targetIPs(t *testing.T) { + ctx := acctest.Context(t) + domainName := acctest.RandomDomainName() + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_route53_resolver_rule.test" + dsResourceName := "data.aws_route53_resolver_rule.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) }, + ErrorCheck: acctest.ErrorCheck(t, names.Route53ResolverServiceID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccRuleDataSourceConfig_targetIPs(rName, domainName), + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttrPair(dsResourceName, names.AttrID, resourceName, names.AttrID), + resource.TestCheckResourceAttr(dsResourceName, "target_ips.#", "2"), + resource.TestCheckTypeSetElemNestedAttrs(dsResourceName, "target_ips.*", map[string]string{ + "ip": "192.0.2.7", + names.AttrPort: "53", + names.AttrProtocol: "Do53", + }), + resource.TestCheckTypeSetElemNestedAttrs(dsResourceName, "target_ips.*", map[string]string{ + "ip": "192.0.2.8", + names.AttrPort: "53", + names.AttrProtocol: "Do53", + }), + ), + }, + }, + }) +} + func TestAccRoute53ResolverRuleDataSource_sharedByMe(t *testing.T) { ctx := acctest.Context(t) domainName := acctest.RandomDomainName() @@ -318,6 +351,30 @@ data "aws_route53_resolver_rule" "by_resolver_endpoint_id" { `, rName, domainName)) } +func testAccRuleDataSourceConfig_targetIPs(rName, domainName string) string { + return acctest.ConfigCompose(testAccRuleConfig_resolverEndpointBase(rName), fmt.Sprintf(` +resource "aws_route53_resolver_rule" "test" { + domain_name = %[2]q + rule_type = "FORWARD" + name = %[1]q + + resolver_endpoint_id = aws_route53_resolver_endpoint.test[1].id + + target_ip { + ip = "192.0.2.7" + } + + target_ip { + ip = "192.0.2.8" + } +} + +data "aws_route53_resolver_rule" "test" { + resolver_rule_id = aws_route53_resolver_rule.test.id +} +`, rName, domainName)) +} + // testAccErrorCheckSkipRoute53 skips Route53 tests that have error messages indicating unsupported features func testAccErrorCheckSkipRoute53(t *testing.T) resource.ErrorCheckFunc { return acctest.ErrorCheckSkipMessagesContaining(t, diff --git a/website/docs/d/route53_resolver_rule.html.markdown b/website/docs/d/route53_resolver_rule.html.markdown index 0ebf14efaff7..6f57cb39225c 100644 --- a/website/docs/d/route53_resolver_rule.html.markdown +++ b/website/docs/d/route53_resolver_rule.html.markdown @@ -42,3 +42,11 @@ This data source exports the following attributes in addition to the arguments a * `share_status` - Whether the rules is shared and, if so, whether the current account is sharing the rule with another account, or another account is sharing the rule with the current account. Values are `NOT_SHARED`, `SHARED_BY_ME` or `SHARED_WITH_ME` * `tags` - Map of tags assigned to the resolver rule. +* `target_ips` - List of configurations for target IP addresses. Only applicable for `FORWARD` rules. See [`target_ips`](#target_ips) below for details. + +### target_ips + +* `ip` - IPv4 address that you want to forward DNS queries to. +* `ipv6` - IPv6 address that you want to forward DNS queries to. +* `port` - Port at the IP address that you want to forward DNS queries to. +* `protocol` - Protocol for the target IP address. Valid values are `Do53` (DNS over port 53), `DoH` (DNS over HTTPS), and `DoH-FIPS` (DNS over HTTPS with FIPS).