Skip to content

Commit bda755c

Browse files
authored
Merge pull request #43520 from asungur/b-aws_ec_user_group-skip-removed-user
aws_elasticache_user_group: Skip deleted users during user group update
2 parents 3f19059 + f68d2fa commit bda755c

File tree

3 files changed

+144
-1
lines changed

3 files changed

+144
-1
lines changed

.changelog/43520.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
resource/aws_elasticache_user_group: Ignore `InvalidParameterValue: User xxx is not a member of user group xxx` errors during group modification
3+
```

internal/service/elasticache/user_group.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ func resourceUserGroupUpdate(ctx context.Context, d *schema.ResourceData, meta a
173173

174174
_, err := conn.ModifyUserGroup(ctx, input)
175175

176-
if err != nil {
176+
if err != nil && !errs.IsAErrorMessageContains[*awstypes.InvalidParameterValueException](err, "is not a member of user group") {
177177
return sdkdiag.AppendErrorf(diags, "updating ElastiCache User Group (%q): %s", d.Id(), err)
178178
}
179179

internal/service/elasticache/user_group_test.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
awstypes "github.com/aws/aws-sdk-go-v2/service/elasticache/types"
1212
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
13+
"github.com/hashicorp/terraform-plugin-testing/plancheck"
1314
"github.com/hashicorp/terraform-plugin-testing/terraform"
1415
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
1516
"github.com/hashicorp/terraform-provider-aws/internal/retry"
@@ -52,6 +53,8 @@ func TestAccElastiCacheUserGroup_update(t *testing.T) {
5253
var userGroup awstypes.UserGroup
5354
rName := acctest.RandomWithPrefix(t, "tf-acc")
5455
resourceName := "aws_elasticache_user_group.test"
56+
user1ResourceName := "aws_elasticache_user.test1"
57+
user2ResourceName := "aws_elasticache_user.test2"
5558

5659
acctest.ParallelTest(ctx, t, resource.TestCase{
5760
PreCheck: func() { acctest.PreCheck(ctx, t) },
@@ -76,7 +79,105 @@ func TestAccElastiCacheUserGroup_update(t *testing.T) {
7679
resource.TestCheckResourceAttr(resourceName, "user_group_id", rName),
7780
resource.TestCheckResourceAttr(resourceName, names.AttrEngine, "redis"),
7881
),
82+
ConfigPlanChecks: resource.ConfigPlanChecks{
83+
PreApply: []plancheck.PlanCheck{
84+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
85+
plancheck.ExpectResourceAction(user1ResourceName, plancheck.ResourceActionNoop),
86+
plancheck.ExpectResourceAction(user2ResourceName, plancheck.ResourceActionNoop),
87+
},
88+
},
7989
},
90+
{
91+
Config: testAccUserGroupConfig_basic(rName),
92+
Check: resource.ComposeTestCheckFunc(
93+
testAccCheckUserGroupExists(ctx, t, resourceName, &userGroup),
94+
resource.TestCheckResourceAttr(resourceName, "user_ids.#", "1"),
95+
resource.TestCheckResourceAttr(resourceName, "user_group_id", rName),
96+
resource.TestCheckResourceAttr(resourceName, names.AttrEngine, "redis"),
97+
),
98+
ConfigPlanChecks: resource.ConfigPlanChecks{
99+
PreApply: []plancheck.PlanCheck{
100+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
101+
plancheck.ExpectResourceAction(user1ResourceName, plancheck.ResourceActionNoop),
102+
plancheck.ExpectResourceAction(user2ResourceName, plancheck.ResourceActionNoop),
103+
},
104+
},
105+
},
106+
},
107+
})
108+
}
109+
110+
func TestAccElastiCacheUserGroup_rotate(t *testing.T) {
111+
ctx := acctest.Context(t)
112+
var userGroup awstypes.UserGroup
113+
rName := acctest.RandomWithPrefix(t, "tf-acc")
114+
resourceName := "aws_elasticache_user_group.test"
115+
user1ResourceName := "aws_elasticache_user.test1"
116+
user2ResourceName := "aws_elasticache_user.test2"
117+
118+
acctest.ParallelTest(ctx, t, resource.TestCase{
119+
PreCheck: func() { acctest.PreCheck(ctx, t) },
120+
ErrorCheck: acctest.ErrorCheck(t, names.ElastiCacheServiceID),
121+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
122+
CheckDestroy: testAccCheckUserGroupDestroy(ctx, t),
123+
Steps: []resource.TestStep{
124+
{
125+
Config: testAccUserGroupConfig_basic(rName),
126+
Check: resource.ComposeTestCheckFunc(
127+
testAccCheckUserGroupExists(ctx, t, resourceName, &userGroup),
128+
resource.TestCheckResourceAttr(resourceName, "user_ids.#", "1"),
129+
resource.TestCheckResourceAttr(resourceName, "user_group_id", rName),
130+
resource.TestCheckResourceAttr(resourceName, names.AttrEngine, "redis"),
131+
),
132+
},
133+
{
134+
Config: testAccUserGroupConfig_rotate(rName),
135+
Check: resource.ComposeTestCheckFunc(
136+
testAccCheckUserGroupExists(ctx, t, resourceName, &userGroup),
137+
resource.TestCheckResourceAttr(resourceName, "user_ids.#", "2"),
138+
resource.TestCheckResourceAttr(resourceName, "user_group_id", rName),
139+
resource.TestCheckResourceAttr(resourceName, names.AttrEngine, "redis"),
140+
),
141+
ConfigPlanChecks: resource.ConfigPlanChecks{
142+
PreApply: []plancheck.PlanCheck{
143+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
144+
plancheck.ExpectResourceAction(user1ResourceName, plancheck.ResourceActionNoop),
145+
plancheck.ExpectResourceAction(user2ResourceName, plancheck.ResourceActionReplace),
146+
},
147+
},
148+
},
149+
{
150+
Config: testAccUserGroupConfig_basic(rName),
151+
Check: resource.ComposeTestCheckFunc(
152+
testAccCheckUserGroupExists(ctx, t, resourceName, &userGroup),
153+
resource.TestCheckResourceAttr(resourceName, "user_ids.#", "1"),
154+
resource.TestCheckResourceAttr(resourceName, "user_group_id", rName),
155+
resource.TestCheckResourceAttr(resourceName, names.AttrEngine, "redis"),
156+
),
157+
ConfigPlanChecks: resource.ConfigPlanChecks{
158+
PreApply: []plancheck.PlanCheck{
159+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
160+
plancheck.ExpectResourceAction(user1ResourceName, plancheck.ResourceActionNoop),
161+
plancheck.ExpectResourceAction(user2ResourceName, plancheck.ResourceActionReplace),
162+
},
163+
},
164+
},
165+
},
166+
})
167+
}
168+
169+
func TestAccElastiCacheUserGroup_engineValkey(t *testing.T) {
170+
ctx := acctest.Context(t)
171+
var userGroup awstypes.UserGroup
172+
rName := acctest.RandomWithPrefix(t, "tf-acc")
173+
resourceName := "aws_elasticache_user_group.test"
174+
175+
acctest.ParallelTest(ctx, t, resource.TestCase{
176+
PreCheck: func() { acctest.PreCheck(ctx, t) },
177+
ErrorCheck: acctest.ErrorCheck(t, names.ElastiCacheServiceID),
178+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
179+
CheckDestroy: testAccCheckUserGroupDestroy(ctx, t),
180+
Steps: []resource.TestStep{
80181
{
81182
Config: testAccUserGroupConfig_basic(rName),
82183
Check: resource.ComposeTestCheckFunc(
@@ -168,6 +269,11 @@ func TestAccElastiCacheUserGroup_disappears(t *testing.T) {
168269
acctest.CheckResourceDisappears(ctx, acctest.Provider, tfelasticache.ResourceUserGroup(), resourceName),
169270
),
170271
ExpectNonEmptyPlan: true,
272+
ConfigPlanChecks: resource.ConfigPlanChecks{
273+
PostApplyPostRefresh: []plancheck.PlanCheck{
274+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
275+
},
276+
},
171277
},
172278
},
173279
})
@@ -246,6 +352,32 @@ resource "aws_elasticache_user_group" "test" {
246352
`, rName))
247353
}
248354

355+
func testAccUserGroupConfig_rotate(rName string) string {
356+
return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(`
357+
resource "aws_elasticache_user" "test1" {
358+
user_id = "%[1]s-1"
359+
user_name = "default"
360+
access_string = "on ~app::* -@all +@read +@hash +@bitmap +@geo -setbit -bitfield -hset -hsetnx -hmset -hincrby -hincrbyfloat -hdel -bitop -geoadd -georadius -georadiusbymember"
361+
engine = "REDIS"
362+
passwords = ["password123456789"]
363+
}
364+
365+
resource "aws_elasticache_user" "test2" {
366+
user_id = "%[1]s-3"
367+
user_name = "username1"
368+
access_string = "on ~app::* -@all +@read +@hash +@bitmap +@geo -setbit -bitfield -hset -hsetnx -hmset -hincrby -hincrbyfloat -hdel -bitop -geoadd -georadius -georadiusbymember"
369+
engine = "REDIS"
370+
passwords = ["password123456789"]
371+
}
372+
373+
resource "aws_elasticache_user_group" "test" {
374+
user_group_id = %[1]q
375+
engine = "REDIS"
376+
user_ids = [aws_elasticache_user.test1.user_id, aws_elasticache_user.test2.user_id]
377+
}
378+
`, rName))
379+
}
380+
249381
func testAccUserGroupConfig_multiple(rName string) string {
250382
return acctest.ConfigCompose(acctest.ConfigAvailableAZsNoOptIn(), fmt.Sprintf(`
251383
resource "aws_elasticache_user" "test1" {
@@ -282,6 +414,14 @@ resource "aws_elasticache_user" "test1" {
282414
passwords = ["password123456789"]
283415
}
284416
417+
resource "aws_elasticache_user" "test2" {
418+
user_id = "%[1]s-2"
419+
user_name = "username1"
420+
access_string = "on ~app::* -@all +@read +@hash +@bitmap +@geo -setbit -bitfield -hset -hsetnx -hmset -hincrby -hincrbyfloat -hdel -bitop -geoadd -georadius -georadiusbymember"
421+
engine = "REDIS"
422+
passwords = ["password123456789"]
423+
}
424+
285425
resource "aws_elasticache_user_group" "test" {
286426
user_group_id = %[1]q
287427
engine = "VALKEY"

0 commit comments

Comments
 (0)