Skip to content

Commit 4531efa

Browse files
authored
Merge pull request #44473 from stefanfreitag/f-aws_route53recoverycontrolconfig_cluster-add-tag-support
feat: add tagging support for multiple Route53RecoveryControl resources
2 parents 9300c25 + b1bff45 commit 4531efa

14 files changed

+578
-59
lines changed

.changelog/44473.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
```release-note:enhancement
2+
resource/aws_route53recoverycontrolconfig_cluster: Add tagging support
3+
```
4+
5+
```release-note:enhancement
6+
resource/aws_route53recoverycontrolconfig_control_panel: Add tagging support
7+
```
8+
9+
```release-note:enhancement
10+
resource/aws_route53recoverycontrolconfig_safety_rule: Add tagging support
11+
```

internal/service/route53recoverycontrolconfig/cluster.go

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@ import (
1818
"github.com/hashicorp/terraform-provider-aws/internal/enum"
1919
"github.com/hashicorp/terraform-provider-aws/internal/errs"
2020
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
21+
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
2122
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
2223
"github.com/hashicorp/terraform-provider-aws/names"
2324
)
2425

2526
// @SDKResource("aws_route53recoverycontrolconfig_cluster", name="Cluster")
27+
// @Tags(identifierAttribute="arn")
2628
func resourceCluster() *schema.Resource {
2729
return &schema.Resource{
2830
CreateWithoutTimeout: resourceClusterCreate,
@@ -69,6 +71,8 @@ func resourceCluster() *schema.Resource {
6971
Type: schema.TypeString,
7072
Computed: true,
7173
},
74+
names.AttrTags: tftags.TagsSchema(),
75+
names.AttrTagsAll: tftags.TagsSchemaComputed(),
7276
},
7377
}
7478
}
@@ -103,6 +107,10 @@ func resourceClusterCreate(ctx context.Context, d *schema.ResourceData, meta any
103107
return sdkdiag.AppendErrorf(diags, "waiting for Route53 Recovery Control Config Cluster (%s) to be Deployed: %s", d.Id(), err)
104108
}
105109

110+
if err := createTags(ctx, conn, d.Id(), getTagsIn(ctx)); err != nil {
111+
return sdkdiag.AppendErrorf(diags, "setting Route53 Recovery Control Config Cluster (%s) tags: %s", d.Id(), err)
112+
}
113+
106114
return append(diags, resourceClusterRead(ctx, d, meta)...)
107115
}
108116

@@ -138,26 +146,28 @@ func resourceClusterUpdate(ctx context.Context, d *schema.ResourceData, meta any
138146
var diags diag.Diagnostics
139147
conn := meta.(*conns.AWSClient).Route53RecoveryControlConfigClient(ctx)
140148

141-
input := &r53rcc.UpdateClusterInput{
142-
ClusterArn: aws.String(d.Id()),
143-
}
149+
if d.HasChangesExcept(names.AttrTags, names.AttrTagsAll) {
150+
input := &r53rcc.UpdateClusterInput{
151+
ClusterArn: aws.String(d.Id()),
152+
}
144153

145-
if d.HasChanges("network_type") {
146-
input.NetworkType = awstypes.NetworkType(d.Get("network_type").(string))
147-
}
154+
if d.HasChanges("network_type") {
155+
input.NetworkType = awstypes.NetworkType(d.Get("network_type").(string))
156+
}
148157

149-
output, err := conn.UpdateCluster(ctx, input)
158+
output, err := conn.UpdateCluster(ctx, input)
150159

151-
if err != nil {
152-
return sdkdiag.AppendErrorf(diags, "updating Route53 Recovery Control Config Cluster: %s", err)
153-
}
160+
if err != nil {
161+
return sdkdiag.AppendErrorf(diags, "updating Route53 Recovery Control Config Cluster: %s", err)
162+
}
154163

155-
if output == nil || output.Cluster == nil {
156-
return sdkdiag.AppendErrorf(diags, "updating Route53 Recovery Control Config Cluster: empty response")
157-
}
164+
if output == nil || output.Cluster == nil {
165+
return sdkdiag.AppendErrorf(diags, "updating Route53 Recovery Control Config Cluster: empty response")
166+
}
158167

159-
if _, err := waitClusterUpdated(ctx, conn, d.Id()); err != nil {
160-
return sdkdiag.AppendErrorf(diags, "waiting for Route53 Recovery Control Config Cluster (%s) to be Updated: %s", d.Id(), err)
168+
if _, err := waitClusterUpdated(ctx, conn, d.Id()); err != nil {
169+
return sdkdiag.AppendErrorf(diags, "waiting for Route53 Recovery Control Config Cluster (%s) to be Updated: %s", d.Id(), err)
170+
}
161171
}
162172

163173
return append(diags, resourceClusterRead(ctx, d, meta)...)

internal/service/route53recoverycontrolconfig/cluster_test.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ func testAccCluster_basic(t *testing.T) {
4242
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "DEPLOYED"),
4343
resource.TestCheckResourceAttr(resourceName, "cluster_endpoints.#", "5"),
4444
resource.TestCheckResourceAttr(resourceName, "network_type", string(awstypes.NetworkTypeIpv4)),
45+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "0"),
46+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsAllPercent, "0"),
4547
),
4648
},
4749
{
@@ -114,6 +116,65 @@ func testAccCluster_networkType(t *testing.T) {
114116
})
115117
}
116118

119+
func testAccCluster_tags(t *testing.T) {
120+
ctx := acctest.Context(t)
121+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
122+
resourceName := "aws_route53recoverycontrolconfig_cluster.test"
123+
124+
resource.Test(t, resource.TestCase{
125+
PreCheck: func() {
126+
acctest.PreCheck(ctx, t)
127+
acctest.PreCheckPartitionHasService(t, names.Route53RecoveryControlConfigEndpointID)
128+
},
129+
ErrorCheck: acctest.ErrorCheck(t, names.Route53RecoveryControlConfigServiceID),
130+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
131+
CheckDestroy: testAccCheckClusterDestroy(ctx),
132+
Steps: []resource.TestStep{
133+
{
134+
Config: testAccClusterConfig_tags1(rName, acctest.CtKey1, acctest.CtValue1),
135+
Check: resource.ComposeTestCheckFunc(
136+
testAccCheckClusterExists(ctx, resourceName),
137+
resource.TestCheckResourceAttr(resourceName, names.AttrName, rName),
138+
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "DEPLOYED"),
139+
resource.TestCheckResourceAttr(resourceName, "cluster_endpoints.#", "5"),
140+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"),
141+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1),
142+
),
143+
},
144+
{
145+
ResourceName: resourceName,
146+
ImportState: true,
147+
ImportStateVerify: true,
148+
ImportStateVerifyIgnore: []string{"cluster_endpoints"},
149+
},
150+
151+
{
152+
Config: testAccClusterConfig_tags2(rName, acctest.CtKey1, acctest.CtValue1Updated, acctest.CtKey2, acctest.CtValue2),
153+
Check: resource.ComposeTestCheckFunc(
154+
testAccCheckClusterExists(ctx, resourceName),
155+
resource.TestCheckResourceAttr(resourceName, names.AttrName, rName),
156+
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "DEPLOYED"),
157+
resource.TestCheckResourceAttr(resourceName, "cluster_endpoints.#", "5"),
158+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "2"),
159+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1Updated),
160+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2),
161+
),
162+
},
163+
{
164+
Config: testAccClusterConfig_tags1(rName, acctest.CtKey2, acctest.CtValue2),
165+
Check: resource.ComposeTestCheckFunc(
166+
testAccCheckClusterExists(ctx, resourceName),
167+
resource.TestCheckResourceAttr(resourceName, names.AttrName, rName),
168+
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "DEPLOYED"),
169+
resource.TestCheckResourceAttr(resourceName, "cluster_endpoints.#", "5"),
170+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"),
171+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2),
172+
),
173+
},
174+
},
175+
})
176+
}
177+
117178
func testAccCluster_disappears(t *testing.T) {
118179
ctx := acctest.Context(t)
119180
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
@@ -197,3 +258,26 @@ resource "aws_route53recoverycontrolconfig_cluster" "test" {
197258
}
198259
`, rName, networkType)
199260
}
261+
262+
func testAccClusterConfig_tags1(rName, tagKey1, tagValue1 string) string {
263+
return fmt.Sprintf(`
264+
resource "aws_route53recoverycontrolconfig_cluster" "test" {
265+
name = %[1]q
266+
tags = {
267+
%[2]q = %[3]q
268+
}
269+
}
270+
`, rName, tagKey1, tagValue1)
271+
}
272+
273+
func testAccClusterConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
274+
return fmt.Sprintf(`
275+
resource "aws_route53recoverycontrolconfig_cluster" "test" {
276+
name = %[1]q
277+
tags = {
278+
%[2]q = %[3]q
279+
%[4]q = %[5]q
280+
}
281+
}
282+
`, rName, tagKey1, tagValue1, tagKey2, tagValue2)
283+
}

internal/service/route53recoverycontrolconfig/control_panel.go

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ import (
1717
"github.com/hashicorp/terraform-provider-aws/internal/conns"
1818
"github.com/hashicorp/terraform-provider-aws/internal/errs"
1919
"github.com/hashicorp/terraform-provider-aws/internal/errs/sdkdiag"
20+
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
2021
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
2122
"github.com/hashicorp/terraform-provider-aws/names"
2223
)
2324

2425
// @SDKResource("aws_route53recoverycontrolconfig_control_panel", name="Control Panel")
26+
// @Tags(identifierAttribute="arn")
2527
func resourceControlPanel() *schema.Resource {
2628
return &schema.Resource{
2729
CreateWithoutTimeout: resourceControlPanelCreate,
@@ -57,6 +59,8 @@ func resourceControlPanel() *schema.Resource {
5759
Type: schema.TypeString,
5860
Computed: true,
5961
},
62+
names.AttrTags: tftags.TagsSchema(),
63+
names.AttrTagsAll: tftags.TagsSchemaComputed(),
6064
},
6165
}
6266
}
@@ -88,6 +92,10 @@ func resourceControlPanelCreate(ctx context.Context, d *schema.ResourceData, met
8892
return sdkdiag.AppendErrorf(diags, "waiting for Route53 Recovery Control Config Control Panel (%s) to be Deployed: %s", d.Id(), err)
8993
}
9094

95+
if err := createTags(ctx, conn, d.Id(), getTagsIn(ctx)); err != nil {
96+
return sdkdiag.AppendErrorf(diags, "setting Route53 Recovery Control Config Control Panel (%s) tags: %s", d.Id(), err)
97+
}
98+
9199
return append(diags, resourceControlPanelRead(ctx, d, meta)...)
92100
}
93101

@@ -121,15 +129,17 @@ func resourceControlPanelUpdate(ctx context.Context, d *schema.ResourceData, met
121129
var diags diag.Diagnostics
122130
conn := meta.(*conns.AWSClient).Route53RecoveryControlConfigClient(ctx)
123131

124-
input := &r53rcc.UpdateControlPanelInput{
125-
ControlPanelName: aws.String(d.Get(names.AttrName).(string)),
126-
ControlPanelArn: aws.String(d.Get(names.AttrARN).(string)),
127-
}
132+
if d.HasChangesExcept(names.AttrTags, names.AttrTagsAll) {
133+
input := &r53rcc.UpdateControlPanelInput{
134+
ControlPanelName: aws.String(d.Get(names.AttrName).(string)),
135+
ControlPanelArn: aws.String(d.Get(names.AttrARN).(string)),
136+
}
128137

129-
_, err := conn.UpdateControlPanel(ctx, input)
138+
_, err := conn.UpdateControlPanel(ctx, input)
130139

131-
if err != nil {
132-
return sdkdiag.AppendErrorf(diags, "updating Route53 Recovery Control Config Control Panel: %s", err)
140+
if err != nil {
141+
return sdkdiag.AppendErrorf(diags, "updating Route53 Recovery Control Config Control Panel: %s", err)
142+
}
133143
}
134144

135145
return append(diags, resourceControlPanelRead(ctx, d, meta)...)

internal/service/route53recoverycontrolconfig/control_panel_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ func testAccControlPanel_basic(t *testing.T) {
4040
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "DEPLOYED"),
4141
resource.TestCheckResourceAttr(resourceName, "default_control_panel", acctest.CtFalse),
4242
resource.TestCheckResourceAttr(resourceName, "routing_control_count", "0"),
43+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "0"),
44+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsAllPercent, "0"),
4345
),
4446
},
4547
{
@@ -51,6 +53,65 @@ func testAccControlPanel_basic(t *testing.T) {
5153
})
5254
}
5355

56+
func testAccControlPanel_tags(t *testing.T) {
57+
ctx := acctest.Context(t)
58+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
59+
resourceName := "aws_route53recoverycontrolconfig_control_panel.test"
60+
61+
resource.Test(t, resource.TestCase{
62+
PreCheck: func() {
63+
acctest.PreCheck(ctx, t)
64+
acctest.PreCheckPartitionHasService(t, names.Route53RecoveryControlConfigEndpointID)
65+
},
66+
ErrorCheck: acctest.ErrorCheck(t, names.Route53RecoveryControlConfigServiceID),
67+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
68+
CheckDestroy: testAccCheckControlPanelDestroy(ctx),
69+
Steps: []resource.TestStep{
70+
{
71+
Config: testAccControlPanelConfig_tags1(rName, acctest.CtKey1, acctest.CtValue1),
72+
Check: resource.ComposeTestCheckFunc(
73+
testAccCheckControlPanelExists(ctx, resourceName),
74+
resource.TestCheckResourceAttr(resourceName, names.AttrName, rName),
75+
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "DEPLOYED"),
76+
resource.TestCheckResourceAttr(resourceName, "default_control_panel", acctest.CtFalse),
77+
resource.TestCheckResourceAttr(resourceName, "routing_control_count", "0"),
78+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"),
79+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1),
80+
),
81+
},
82+
{
83+
ResourceName: resourceName,
84+
ImportState: true,
85+
ImportStateVerify: true,
86+
},
87+
{
88+
Config: testAccControlPanelConfig_tags2(rName, acctest.CtKey1, acctest.CtValue1Updated, acctest.CtKey2, acctest.CtValue2),
89+
Check: resource.ComposeTestCheckFunc(
90+
testAccCheckControlPanelExists(ctx, resourceName),
91+
resource.TestCheckResourceAttr(resourceName, names.AttrName, rName),
92+
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "DEPLOYED"),
93+
resource.TestCheckResourceAttr(resourceName, "default_control_panel", acctest.CtFalse),
94+
resource.TestCheckResourceAttr(resourceName, "routing_control_count", "0"),
95+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "2"),
96+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey1, acctest.CtValue1Updated),
97+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2),
98+
),
99+
},
100+
{
101+
Config: testAccControlPanelConfig_tags1(rName, acctest.CtKey2, acctest.CtValue2),
102+
Check: resource.ComposeTestCheckFunc(
103+
testAccCheckControlPanelExists(ctx, resourceName),
104+
resource.TestCheckResourceAttr(resourceName, names.AttrName, rName),
105+
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "DEPLOYED"),
106+
resource.TestCheckResourceAttr(resourceName, "default_control_panel", acctest.CtFalse),
107+
resource.TestCheckResourceAttr(resourceName, "routing_control_count", "0"),
108+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsPercent, "1"),
109+
resource.TestCheckResourceAttr(resourceName, acctest.CtTagsKey2, acctest.CtValue2),
110+
),
111+
},
112+
},
113+
})
114+
}
54115
func testAccControlPanel_disappears(t *testing.T) {
55116
ctx := acctest.Context(t)
56117
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
@@ -134,3 +195,28 @@ resource "aws_route53recoverycontrolconfig_control_panel" "test" {
134195
}
135196
`, rName))
136197
}
198+
199+
func testAccControlPanelConfig_tags1(rName, tagKey1, tagValue1 string) string {
200+
return acctest.ConfigCompose(testAccClusterSetUp(rName), fmt.Sprintf(`
201+
resource "aws_route53recoverycontrolconfig_control_panel" "test" {
202+
name = %[1]q
203+
cluster_arn = aws_route53recoverycontrolconfig_cluster.test.arn
204+
tags = {
205+
%[2]q = %[3]q
206+
}
207+
}
208+
`, rName, tagKey1, tagValue1))
209+
}
210+
211+
func testAccControlPanelConfig_tags2(rName, tagKey1, tagValue1, tagKey2, tagValue2 string) string {
212+
return acctest.ConfigCompose(testAccClusterSetUp(rName), fmt.Sprintf(`
213+
resource "aws_route53recoverycontrolconfig_control_panel" "test" {
214+
name = %[1]q
215+
cluster_arn = aws_route53recoverycontrolconfig_cluster.test.arn
216+
tags = {
217+
%[2]q = %[3]q
218+
%[4]q = %[5]q
219+
}
220+
}
221+
`, rName, tagKey1, tagValue1, tagKey2, tagValue2))
222+
}

internal/service/route53recoverycontrolconfig/generate.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) HashiCorp, Inc.
22
// SPDX-License-Identifier: MPL-2.0
33

4+
//go:generate go run ../../generate/tags/main.go -ServiceTagsMap -CreateTags -ListTags -UpdateTags -KVTValues
45
//go:generate go run ../../generate/servicepackage/main.go
56
// ONLY generate directives and package declaration! Do not add anything else to this file.
67

internal/service/route53recoverycontrolconfig/route53recoverycontrolconfig_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ func TestAccRoute53RecoveryControlConfig_serial(t *testing.T) {
1919
acctest.CtBasic: testAccCluster_basic,
2020
acctest.CtDisappears: testAccCluster_disappears,
2121
"networkType": testAccCluster_networkType,
22+
"tags": testAccCluster_tags,
2223
},
2324
"ControlPanel": {
2425
acctest.CtBasic: testAccControlPanel_basic,
2526
acctest.CtDisappears: testAccControlPanel_disappears,
27+
"tags": testAccControlPanel_tags,
2628
},
2729
"RoutingControl": {
2830
acctest.CtBasic: testAccRoutingControl_basic,
@@ -33,6 +35,7 @@ func TestAccRoute53RecoveryControlConfig_serial(t *testing.T) {
3335
"assertionRule": testAccSafetyRule_assertionRule,
3436
"gatingRule": testAccSafetyRule_gatingRule,
3537
acctest.CtDisappears: testAccSafetyRule_disappears,
38+
"tags": testAccSafetyRule_tags,
3639
},
3740
}
3841

0 commit comments

Comments
 (0)