Skip to content

Commit 2e46ce0

Browse files
authored
Merge pull request #43516 from hashicorp/upgrade-to-v6-refresh=false-region
Prevent planned `forces replacement` on `region` when upgrading from a pre-v6.0.0 provider version and `-refresh=false` is in effect
2 parents 4284cf1 + 9fd9b14 commit 2e46ce0

File tree

5 files changed

+539
-11
lines changed

5 files changed

+539
-11
lines changed

.changelog/43516.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
provider: Prevent planned `forces replacement` on `region` when upgrading from a pre-v6.0.0 provider version and `-refresh=false` is in effect
3+
```

internal/provider/framework/region.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,12 @@ func (r resourceForceNewIfRegionChangesInterceptor) modifyPlan(ctx context.Conte
280280
return diags
281281
}
282282

283+
var configRegion types.String
284+
diags.Append(request.Config.GetAttribute(ctx, path.Root(names.AttrRegion), &configRegion)...)
285+
if diags.HasError() {
286+
return diags
287+
}
288+
283289
var planRegion types.String
284290
diags.Append(request.Plan.GetAttribute(ctx, path.Root(names.AttrRegion), &planRegion)...)
285291
if diags.HasError() {
@@ -292,9 +298,15 @@ func (r resourceForceNewIfRegionChangesInterceptor) modifyPlan(ctx context.Conte
292298
return diags
293299
}
294300

295-
providerRegion := c.AwsConfig(ctx).Region
296-
if stateRegion.IsNull() && planRegion.ValueString() == providerRegion {
297-
return diags
301+
if stateRegion.IsNull() {
302+
// Upgrade from pre-v6.0.0 provider and '-refresh=false' in effect.
303+
if configRegion.IsNull() {
304+
return diags
305+
}
306+
307+
if providerRegion := c.AwsConfig(ctx).Region; planRegion.ValueString() == providerRegion {
308+
return diags
309+
}
298310
}
299311

300312
if !planRegion.Equal(stateRegion) {

internal/service/appfabric/app_bundle_test.go

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,256 @@ func testAccAppBundle_upgradeFromV5(t *testing.T) {
189189
})
190190
}
191191

192+
func testAccAppBundle_upgradeFromV5PlanRefreshFalse(t *testing.T) {
193+
ctx := acctest.Context(t)
194+
var appbundle awstypes.AppBundle
195+
resourceName := "aws_appfabric_app_bundle.test"
196+
197+
resource.Test(t, resource.TestCase{
198+
PreCheck: func() {
199+
acctest.PreCheck(ctx, t)
200+
acctest.PreCheckRegion(t, endpoints.UsEast1RegionID, endpoints.ApNortheast1RegionID, endpoints.EuWest1RegionID)
201+
testAccPreCheck(ctx, t)
202+
},
203+
ErrorCheck: acctest.ErrorCheck(t, names.AppFabricServiceID),
204+
CheckDestroy: testAccCheckAppBundleDestroy(ctx),
205+
AdditionalCLIOptions: &resource.AdditionalCLIOptions{
206+
Plan: resource.PlanOptions{
207+
NoRefresh: true,
208+
},
209+
},
210+
Steps: []resource.TestStep{
211+
{
212+
ExternalProviders: map[string]resource.ExternalProvider{
213+
"aws": {
214+
Source: "hashicorp/aws",
215+
VersionConstraint: "5.100.0",
216+
},
217+
},
218+
Config: testAccAppBundleConfig_basic,
219+
Check: resource.ComposeAggregateTestCheckFunc(
220+
testAccCheckAppBundleExists(ctx, resourceName, &appbundle),
221+
),
222+
ConfigPlanChecks: resource.ConfigPlanChecks{
223+
PreApply: []plancheck.PlanCheck{
224+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
225+
},
226+
},
227+
ConfigStateChecks: []statecheck.StateCheck{
228+
tfstatecheck.ExpectNoValue(resourceName, tfjsonpath.New(names.AttrRegion)),
229+
},
230+
},
231+
{
232+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
233+
Config: testAccAppBundleConfig_basic,
234+
Check: resource.ComposeAggregateTestCheckFunc(
235+
testAccCheckAppBundleExists(ctx, resourceName, &appbundle),
236+
),
237+
ConfigPlanChecks: resource.ConfigPlanChecks{
238+
PreApply: []plancheck.PlanCheck{
239+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
240+
},
241+
PostApplyPostRefresh: []plancheck.PlanCheck{
242+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
243+
},
244+
},
245+
ConfigStateChecks: []statecheck.StateCheck{
246+
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.Region())),
247+
},
248+
},
249+
},
250+
})
251+
}
252+
253+
func testAccAppBundle_upgradeFromV5WithUpdatePlanRefreshFalse(t *testing.T) {
254+
ctx := acctest.Context(t)
255+
var appbundle awstypes.AppBundle
256+
resourceName := "aws_appfabric_app_bundle.test"
257+
258+
resource.Test(t, resource.TestCase{
259+
PreCheck: func() {
260+
acctest.PreCheck(ctx, t)
261+
acctest.PreCheckRegion(t, endpoints.UsEast1RegionID, endpoints.ApNortheast1RegionID, endpoints.EuWest1RegionID)
262+
testAccPreCheck(ctx, t)
263+
},
264+
ErrorCheck: acctest.ErrorCheck(t, names.AppFabricServiceID),
265+
CheckDestroy: testAccCheckAppBundleDestroy(ctx),
266+
AdditionalCLIOptions: &resource.AdditionalCLIOptions{
267+
Plan: resource.PlanOptions{
268+
NoRefresh: true,
269+
},
270+
},
271+
Steps: []resource.TestStep{
272+
{
273+
ExternalProviders: map[string]resource.ExternalProvider{
274+
"aws": {
275+
Source: "hashicorp/aws",
276+
VersionConstraint: "5.100.0",
277+
},
278+
},
279+
Config: testAccAppBundleConfig_tags1(acctest.CtKey1, acctest.CtValue1),
280+
Check: resource.ComposeAggregateTestCheckFunc(
281+
testAccCheckAppBundleExists(ctx, resourceName, &appbundle),
282+
),
283+
ConfigPlanChecks: resource.ConfigPlanChecks{
284+
PreApply: []plancheck.PlanCheck{
285+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
286+
},
287+
},
288+
ConfigStateChecks: []statecheck.StateCheck{
289+
tfstatecheck.ExpectNoValue(resourceName, tfjsonpath.New(names.AttrRegion)),
290+
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{
291+
acctest.CtKey1: knownvalue.StringExact(acctest.CtValue1),
292+
})),
293+
},
294+
},
295+
{
296+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
297+
Config: testAccAppBundleConfig_tags1(acctest.CtKey1, acctest.CtValue1Updated),
298+
Check: resource.ComposeAggregateTestCheckFunc(
299+
testAccCheckAppBundleExists(ctx, resourceName, &appbundle),
300+
),
301+
ConfigPlanChecks: resource.ConfigPlanChecks{
302+
PreApply: []plancheck.PlanCheck{
303+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
304+
},
305+
PostApplyPostRefresh: []plancheck.PlanCheck{
306+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
307+
},
308+
},
309+
ConfigStateChecks: []statecheck.StateCheck{
310+
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.Region())),
311+
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrTags), knownvalue.MapExact(map[string]knownvalue.Check{
312+
acctest.CtKey1: knownvalue.StringExact(acctest.CtValue1Updated),
313+
})),
314+
},
315+
},
316+
},
317+
})
318+
}
319+
320+
func testAccAppBundle_upgradeFromV5WithDefaultRegionRefreshFalse(t *testing.T) {
321+
ctx := acctest.Context(t)
322+
var appbundle awstypes.AppBundle
323+
resourceName := "aws_appfabric_app_bundle.test"
324+
325+
resource.Test(t, resource.TestCase{
326+
PreCheck: func() {
327+
acctest.PreCheck(ctx, t)
328+
acctest.PreCheckRegion(t, endpoints.UsEast1RegionID, endpoints.ApNortheast1RegionID, endpoints.EuWest1RegionID)
329+
testAccPreCheck(ctx, t)
330+
},
331+
ErrorCheck: acctest.ErrorCheck(t, names.AppFabricServiceID),
332+
CheckDestroy: testAccCheckAppBundleDestroy(ctx),
333+
AdditionalCLIOptions: &resource.AdditionalCLIOptions{
334+
Plan: resource.PlanOptions{
335+
NoRefresh: true,
336+
},
337+
},
338+
Steps: []resource.TestStep{
339+
{
340+
ExternalProviders: map[string]resource.ExternalProvider{
341+
"aws": {
342+
Source: "hashicorp/aws",
343+
VersionConstraint: "5.100.0",
344+
},
345+
},
346+
Config: testAccAppBundleConfig_basic,
347+
Check: resource.ComposeAggregateTestCheckFunc(
348+
testAccCheckAppBundleExists(ctx, resourceName, &appbundle),
349+
),
350+
ConfigPlanChecks: resource.ConfigPlanChecks{
351+
PreApply: []plancheck.PlanCheck{
352+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
353+
},
354+
},
355+
ConfigStateChecks: []statecheck.StateCheck{
356+
tfstatecheck.ExpectNoValue(resourceName, tfjsonpath.New(names.AttrRegion)),
357+
},
358+
},
359+
{
360+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
361+
Config: testAccAppBundleConfig_region(acctest.Region()),
362+
Check: resource.ComposeAggregateTestCheckFunc(
363+
testAccCheckAppBundleExists(ctx, resourceName, &appbundle),
364+
),
365+
ConfigPlanChecks: resource.ConfigPlanChecks{
366+
PreApply: []plancheck.PlanCheck{
367+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionUpdate),
368+
},
369+
PostApplyPostRefresh: []plancheck.PlanCheck{
370+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
371+
},
372+
},
373+
ConfigStateChecks: []statecheck.StateCheck{
374+
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(acctest.Region())),
375+
},
376+
},
377+
},
378+
})
379+
}
380+
381+
func testAccAppBundle_upgradeFromV5WithNewRegionRefreshFalse(t *testing.T) {
382+
ctx := acctest.Context(t)
383+
var appbundle awstypes.AppBundle
384+
resourceName := "aws_appfabric_app_bundle.test"
385+
386+
resource.Test(t, resource.TestCase{
387+
PreCheck: func() {
388+
acctest.PreCheck(ctx, t)
389+
acctest.PreCheckRegion(t, endpoints.UsEast1RegionID)
390+
testAccPreCheck(ctx, t)
391+
},
392+
ErrorCheck: acctest.ErrorCheck(t, names.AppFabricServiceID),
393+
CheckDestroy: testAccCheckAppBundleDestroy(ctx),
394+
AdditionalCLIOptions: &resource.AdditionalCLIOptions{
395+
Plan: resource.PlanOptions{
396+
NoRefresh: true,
397+
},
398+
},
399+
Steps: []resource.TestStep{
400+
{
401+
ExternalProviders: map[string]resource.ExternalProvider{
402+
"aws": {
403+
Source: "hashicorp/aws",
404+
VersionConstraint: "5.100.0",
405+
},
406+
},
407+
Config: testAccAppBundleConfig_basic,
408+
Check: resource.ComposeAggregateTestCheckFunc(
409+
testAccCheckAppBundleExists(ctx, resourceName, &appbundle),
410+
),
411+
ConfigPlanChecks: resource.ConfigPlanChecks{
412+
PreApply: []plancheck.PlanCheck{
413+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionCreate),
414+
},
415+
},
416+
ConfigStateChecks: []statecheck.StateCheck{
417+
tfstatecheck.ExpectNoValue(resourceName, tfjsonpath.New(names.AttrRegion)),
418+
},
419+
},
420+
{
421+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
422+
Config: testAccAppBundleConfig_region(endpoints.EuWest1RegionID),
423+
Check: resource.ComposeAggregateTestCheckFunc(
424+
testAccCheckAppBundleExistsInRegion(ctx, resourceName, &appbundle, endpoints.EuWest1RegionID),
425+
),
426+
ConfigPlanChecks: resource.ConfigPlanChecks{
427+
PreApply: []plancheck.PlanCheck{
428+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionReplace),
429+
},
430+
PostApplyPostRefresh: []plancheck.PlanCheck{
431+
plancheck.ExpectResourceAction(resourceName, plancheck.ResourceActionNoop),
432+
},
433+
},
434+
ConfigStateChecks: []statecheck.StateCheck{
435+
statecheck.ExpectKnownValue(resourceName, tfjsonpath.New(names.AttrRegion), knownvalue.StringExact(endpoints.EuWest1RegionID)),
436+
},
437+
},
438+
},
439+
})
440+
}
441+
192442
func testAccAppBundle_regionCreateNull(t *testing.T) {
193443
ctx := acctest.Context(t)
194444
var appbundle awstypes.AppBundle
@@ -427,6 +677,16 @@ resource "aws_appfabric_app_bundle" "test" {
427677
`, rName)
428678
}
429679

680+
func testAccAppBundleConfig_tags1(tagKey1, tagValue1 string) string {
681+
return fmt.Sprintf(`
682+
resource "aws_appfabric_app_bundle" "test" {
683+
tags = {
684+
%[1]q = %[2]q
685+
}
686+
}
687+
`, tagKey1, tagValue1)
688+
}
689+
430690
func testAccAppBundleConfig_region(region string) string {
431691
if region != "null" {
432692
region = strconv.Quote(region)

internal/service/appfabric/appfabric_test.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,18 @@ func TestAccAppFabric_serial(t *testing.T) {
2121

2222
testCases := map[string]map[string]func(t *testing.T){
2323
"AppBundle": {
24-
acctest.CtBasic: testAccAppBundle_basic,
25-
acctest.CtDisappears: testAccAppBundle_disappears,
26-
"cmk": testAccAppBundle_cmk,
27-
"tags": testAccAppFabricAppBundle_tagsSerial,
28-
"regionCreateNull": testAccAppBundle_regionCreateNull,
29-
"regionCreateNonNull": testAccAppBundle_regionCreateNonNull,
30-
"upgradeFromV5": testAccAppBundle_upgradeFromV5,
31-
"Identity": testAccAppFabricAppBundle_IdentitySerial,
24+
acctest.CtBasic: testAccAppBundle_basic,
25+
acctest.CtDisappears: testAccAppBundle_disappears,
26+
"cmk": testAccAppBundle_cmk,
27+
"tags": testAccAppFabricAppBundle_tagsSerial,
28+
"regionCreateNull": testAccAppBundle_regionCreateNull,
29+
"regionCreateNonNull": testAccAppBundle_regionCreateNonNull,
30+
"upgradeFromV5": testAccAppBundle_upgradeFromV5,
31+
"upgradeFromV5PlanRefreshFalse": testAccAppBundle_upgradeFromV5PlanRefreshFalse,
32+
"upgradeFromV5WithUpdatePlanRefreshFalse": testAccAppBundle_upgradeFromV5WithUpdatePlanRefreshFalse,
33+
"upgradeFromV5WithDefaultRegionRefreshFalse": testAccAppBundle_upgradeFromV5WithDefaultRegionRefreshFalse,
34+
"upgradeFromV5WithNewRegionRefreshFalse": testAccAppBundle_upgradeFromV5WithNewRegionRefreshFalse,
35+
"Identity": testAccAppFabricAppBundle_IdentitySerial,
3236
},
3337
"AppAuthorization": {
3438
acctest.CtBasic: testAccAppAuthorization_basic,

0 commit comments

Comments
 (0)