Skip to content

Commit 83fb37e

Browse files
authored
Merge pull request #45202 from hashicorp/b-aws_accessanalyzer_analyzer.resource_tags-crash
r/aws_accessanalyzer_analyzer Fix crash when `resource_tags` are `null`
2 parents 5e59bb9 + 18e4ce2 commit 83fb37e

File tree

4 files changed

+62
-20
lines changed

4 files changed

+62
-20
lines changed

.changelog/45202.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_accessanalyzer_analyzer: Fix `interface conversion: interface {} is nil, not map[string]interface {}` panics when `configuration.unused_access.analysis_rule.exclusion.resource_tags` contains `null` values
3+
```

internal/service/accessanalyzer/accessanalyzer_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ func TestAccAccessAnalyzer_serial(t *testing.T) {
2626
"tags": testAccAccessAnalyzerAnalyzer_tagsSerial,
2727
"type_Organization": testAccAnalyzer_typeOrganization,
2828
"upgradeV5_95_0": testAccAnalyzer_upgradeV5_95_0,
29+
"nullInResourceTags": testAccAnalyzer_nullInResourceTags,
2930
},
3031
"ArchiveRule": {
3132
acctest.CtBasic: testAccAnalyzerArchiveRule_basic,

internal/service/accessanalyzer/analyzer.go

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -397,25 +397,15 @@ func expandInternalAccessAnalysisRuleCriteria(tfMap map[string]any) *types.Inter
397397
apiObject := &types.InternalAccessAnalysisRuleCriteria{}
398398

399399
if tfList, ok := tfMap["account_ids"].([]any); ok && len(tfList) > 0 {
400-
for _, v := range tfList {
401-
accountID, ok := v.(string)
402-
if !ok {
403-
continue
404-
}
405-
apiObject.AccountIds = append(apiObject.AccountIds, accountID)
406-
}
400+
apiObject.AccountIds = flex.ExpandStringValueList(tfList)
407401
}
408402

409403
if tfList, ok := tfMap["resource_arns"].([]any); ok && len(tfList) > 0 {
410-
for _, v := range tfList {
411-
apiObject.ResourceArns = append(apiObject.ResourceArns, v.(string))
412-
}
404+
apiObject.ResourceArns = flex.ExpandStringValueList(tfList)
413405
}
414406

415407
if tfList, ok := tfMap["resource_types"].([]any); ok && len(tfList) > 0 {
416-
for _, v := range tfList {
417-
apiObject.ResourceTypes = append(apiObject.ResourceTypes, types.ResourceType(v.(string)))
418-
}
408+
apiObject.ResourceTypes = flex.ExpandStringyValueList[types.ResourceType](tfList)
419409
}
420410

421411
return apiObject
@@ -478,17 +468,14 @@ func expandAnalysisRuleCriteria(tfMap map[string]any) *types.AnalysisRuleCriteri
478468
apiObject := &types.AnalysisRuleCriteria{}
479469

480470
if tfList, ok := tfMap["account_ids"].([]any); ok && len(tfList) > 0 {
481-
for _, v := range tfList {
482-
accountID, ok := v.(string)
483-
if !ok {
484-
continue
485-
}
486-
apiObject.AccountIds = append(apiObject.AccountIds, accountID)
487-
}
471+
apiObject.AccountIds = flex.ExpandStringValueList(tfList)
488472
}
489473

490474
if tfList, ok := tfMap[names.AttrResourceTags].([]any); ok && len(tfList) > 0 {
491475
for _, v := range tfList {
476+
if v == nil {
477+
continue
478+
}
492479
apiObject.ResourceTags = append(apiObject.ResourceTags, flex.ExpandStringValueMap(v.(map[string]any)))
493480
}
494481
}

internal/service/accessanalyzer/analyzer_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"testing"
1010

11+
"github.com/YakDriver/regexache"
1112
"github.com/aws/aws-sdk-go-v2/service/accessanalyzer/types"
1213
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
1314
"github.com/hashicorp/terraform-plugin-testing/plancheck"
@@ -358,6 +359,29 @@ func testAccAnalyzer_upgradeV5_95_0(t *testing.T) {
358359
})
359360
}
360361

362+
// https://github.com/hashicorp/terraform-provider-aws/issues/45136.
363+
func testAccAnalyzer_nullInResourceTags(t *testing.T) {
364+
ctx := acctest.Context(t)
365+
rName := acctest.RandomWithPrefix(t, acctest.ResourcePrefix)
366+
367+
acctest.Test(ctx, t, resource.TestCase{
368+
PreCheck: func() {
369+
acctest.PreCheck(ctx, t)
370+
testAccPreCheck(ctx, t)
371+
},
372+
ErrorCheck: acctest.ErrorCheck(t, names.AccessAnalyzerServiceID),
373+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
374+
CheckDestroy: testAccCheckAnalyzerDestroy(ctx, t),
375+
Steps: []resource.TestStep{
376+
{
377+
Config: testAccAnalyzerConfig_nullInResourceTags(rName),
378+
// Error, but no crash.
379+
ExpectError: regexache.MustCompile(`External Access analyzers cannot be created with the configuration`),
380+
},
381+
},
382+
})
383+
}
384+
361385
func testAccCheckAnalyzerDestroy(ctx context.Context, t *testing.T) resource.TestCheckFunc {
362386
return func(s *terraform.State) error {
363387
conn := acctest.ProviderMeta(ctx, t).AccessAnalyzerClient(ctx)
@@ -603,3 +627,30 @@ resource "aws_accessanalyzer_analyzer" "test" {
603627
}
604628
`, rName)
605629
}
630+
631+
func testAccAnalyzerConfig_nullInResourceTags(rName string) string {
632+
return fmt.Sprintf(`
633+
resource "aws_accessanalyzer_analyzer" "test" {
634+
analyzer_name = %[1]q
635+
636+
configuration {
637+
unused_access {
638+
unused_access_age = 180
639+
analysis_rule {
640+
exclusion {
641+
account_ids = [
642+
"123456789012",
643+
"234567890123",
644+
]
645+
}
646+
exclusion {
647+
resource_tags = [
648+
{ key1 = null },
649+
]
650+
}
651+
}
652+
}
653+
}
654+
}
655+
`, rName)
656+
}

0 commit comments

Comments
 (0)