Skip to content

Commit d90a76e

Browse files
authored
Merge pull request #43138 from acwwat/f-aws_accessanalyzer_analyzer-add_internal_access_analyzer_support
feat: Add internal access analyzer support to aws_accessanalyzer_analyzer
2 parents fa497c9 + 16e3d6f commit d90a76e

File tree

6 files changed

+577
-32
lines changed

6 files changed

+577
-32
lines changed

.changelog/43138.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
resource/aws_accessanalyzer_analyzer: Add `configuration.internal_access` argument
3+
```

.ci/.tflint.hcl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ rule "terraform_required_version" {
2525
rule "aws_acm_certificate_lifecycle" {
2626
enabled = false
2727
}
28+
29+
rule "aws_accessanalyzer_analyzer_invalid_type" {
30+
enabled = false
31+
}

internal/service/accessanalyzer/accessanalyzer_test.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ func TestAccAccessAnalyzer_serial(t *testing.T) {
1818

1919
testCases := map[string]map[string]func(t *testing.T){
2020
"Analyzer": {
21-
acctest.CtBasic: testAccAnalyzer_basic,
22-
"configuration": testAccAnalyzer_configuration,
23-
"organizationUnusedAccess": testAccAnalyzer_organizationUnusedAccess,
24-
acctest.CtDisappears: testAccAnalyzer_disappears,
25-
"tags": testAccAccessAnalyzerAnalyzer_tagsSerial,
26-
"type_Organization": testAccAnalyzer_typeOrganization,
27-
"upgradeV5_95_0": testAccAnalyzer_upgradeV5_95_0,
21+
acctest.CtBasic: testAccAnalyzer_basic,
22+
"accountInternalAccess": testAccAnalyzer_accountInternalAccess,
23+
"accountUnusedAccess": testAccAnalyzer_accountUnusedAccess,
24+
"organizationInternalAccess": testAccAnalyzer_organizationInternalAccess,
25+
"organizationUnusedAccess": testAccAnalyzer_organizationUnusedAccess,
26+
acctest.CtDisappears: testAccAnalyzer_disappears,
27+
"tags": testAccAccessAnalyzerAnalyzer_tagsSerial,
28+
"type_Organization": testAccAnalyzer_typeOrganization,
29+
"upgradeV5_95_0": testAccAnalyzer_upgradeV5_95_0,
2830
},
2931
"ArchiveRule": {
3032
acctest.CtBasic: testAccAnalyzerArchiveRule_basic,

internal/service/accessanalyzer/analyzer.go

Lines changed: 219 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/hashicorp/terraform-provider-aws/internal/flex"
2525
tftags "github.com/hashicorp/terraform-provider-aws/internal/tags"
2626
"github.com/hashicorp/terraform-provider-aws/internal/tfresource"
27+
"github.com/hashicorp/terraform-provider-aws/internal/verify"
2728
"github.com/hashicorp/terraform-provider-aws/names"
2829
)
2930

@@ -71,11 +72,69 @@ func resourceAnalyzer() *schema.Resource {
7172
MaxItems: 1,
7273
Elem: &schema.Resource{
7374
Schema: map[string]*schema.Schema{
75+
"internal_access": {
76+
Type: schema.TypeList,
77+
Optional: true,
78+
ForceNew: true,
79+
MaxItems: 1,
80+
ConflictsWith: []string{"configuration.0.unused_access"},
81+
Elem: &schema.Resource{
82+
Schema: map[string]*schema.Schema{
83+
"analysis_rule": {
84+
Type: schema.TypeList,
85+
Optional: true,
86+
ForceNew: true,
87+
MaxItems: 1,
88+
Elem: &schema.Resource{
89+
Schema: map[string]*schema.Schema{
90+
"inclusion": {
91+
Type: schema.TypeList,
92+
Optional: true,
93+
ForceNew: true,
94+
Elem: &schema.Resource{
95+
Schema: map[string]*schema.Schema{
96+
"account_ids": {
97+
Type: schema.TypeList,
98+
Optional: true,
99+
ForceNew: true,
100+
Elem: &schema.Schema{
101+
Type: schema.TypeString,
102+
ValidateFunc: verify.ValidAccountID,
103+
},
104+
},
105+
"resource_arns": {
106+
Type: schema.TypeList,
107+
Optional: true,
108+
ForceNew: true,
109+
Elem: &schema.Schema{
110+
Type: schema.TypeString,
111+
ValidateFunc: verify.ValidARN,
112+
},
113+
},
114+
"resource_types": {
115+
Type: schema.TypeList,
116+
Optional: true,
117+
ForceNew: true,
118+
Elem: &schema.Schema{
119+
Type: schema.TypeString,
120+
ValidateDiagFunc: enum.Validate[types.ResourceType](),
121+
},
122+
},
123+
},
124+
},
125+
},
126+
},
127+
},
128+
},
129+
},
130+
},
131+
},
74132
"unused_access": {
75-
Type: schema.TypeList,
76-
Optional: true,
77-
ForceNew: true,
78-
MaxItems: 1,
133+
Type: schema.TypeList,
134+
Optional: true,
135+
ForceNew: true,
136+
MaxItems: 1,
137+
ConflictsWith: []string{"configuration.0.internal_access"},
79138
Elem: &schema.Resource{
80139
Schema: map[string]*schema.Schema{
81140
"analysis_rule": {
@@ -98,7 +157,7 @@ func resourceAnalyzer() *schema.Resource {
98157
MaxItems: 2000,
99158
Elem: &schema.Schema{
100159
Type: schema.TypeString,
101-
ValidateFunc: validation.StringMatch(regexache.MustCompile(`^\d{12}$`), "Must be a 12-digit account ID"),
160+
ValidateFunc: verify.ValidAccountID,
102161
},
103162
},
104163
names.AttrResourceTags: {
@@ -268,10 +327,94 @@ func expandAnalyzerConfiguration(tfMap map[string]any) types.AnalyzerConfigurati
268327
return nil
269328
}
270329

271-
apiObject := &types.AnalyzerConfigurationMemberUnusedAccess{}
330+
var apiObject types.AnalyzerConfiguration
272331

332+
if v, ok := tfMap["internal_access"].([]any); ok && len(v) > 0 && v[0] != nil {
333+
internalAccess := &types.AnalyzerConfigurationMemberInternalAccess{}
334+
internalAccess.Value = expandInternalAccessConfiguration(v[0].(map[string]any))
335+
apiObject = internalAccess
336+
}
273337
if v, ok := tfMap["unused_access"].([]any); ok && len(v) > 0 && v[0] != nil {
274-
apiObject.Value = expandUnusedAccessConfiguration(v[0].(map[string]any))
338+
unusedAccess := &types.AnalyzerConfigurationMemberUnusedAccess{}
339+
unusedAccess.Value = expandUnusedAccessConfiguration(v[0].(map[string]any))
340+
apiObject = unusedAccess
341+
}
342+
343+
return apiObject
344+
}
345+
346+
func expandInternalAccessConfiguration(tfMap map[string]any) types.InternalAccessConfiguration {
347+
apiObject := types.InternalAccessConfiguration{}
348+
349+
if v, ok := tfMap["analysis_rule"].([]any); ok && len(v) > 0 && v[0] != nil {
350+
apiObject.AnalysisRule = expandInternalAccessAnalysisRule(v[0].(map[string]any))
351+
}
352+
353+
return apiObject
354+
}
355+
356+
func expandInternalAccessAnalysisRule(tfMap map[string]any) *types.InternalAccessAnalysisRule {
357+
apiObject := &types.InternalAccessAnalysisRule{}
358+
359+
if v, ok := tfMap["inclusion"].([]any); ok && len(v) > 0 {
360+
apiObject.Inclusions = expandInternalAccessAnalysisRuleCriterias(v)
361+
}
362+
363+
return apiObject
364+
}
365+
366+
func expandInternalAccessAnalysisRuleCriterias(tfList []any) []types.InternalAccessAnalysisRuleCriteria {
367+
if len(tfList) == 0 {
368+
return nil
369+
}
370+
371+
var apiObjects []types.InternalAccessAnalysisRuleCriteria
372+
373+
for _, tfMapRaw := range tfList {
374+
tfMap, ok := tfMapRaw.(map[string]any)
375+
if !ok {
376+
continue
377+
}
378+
379+
apiObject := expandInternalAccessAnalysisRuleCriteria(tfMap)
380+
381+
if apiObject == nil {
382+
continue
383+
}
384+
385+
apiObjects = append(apiObjects, *apiObject)
386+
}
387+
388+
return apiObjects
389+
}
390+
391+
func expandInternalAccessAnalysisRuleCriteria(tfMap map[string]any) *types.InternalAccessAnalysisRuleCriteria {
392+
if tfMap == nil {
393+
return nil
394+
}
395+
396+
apiObject := &types.InternalAccessAnalysisRuleCriteria{}
397+
398+
if tfList, ok := tfMap["account_ids"].([]any); ok && len(tfList) > 0 {
399+
for _, v := range tfList {
400+
accountID, ok := v.(string)
401+
if !ok {
402+
continue
403+
}
404+
apiObject.AccountIds = append(apiObject.AccountIds, accountID)
405+
}
406+
}
407+
408+
if tfList, ok := tfMap["resource_arns"].([]any); ok && len(tfList) > 0 {
409+
for _, v := range tfList {
410+
apiObject.ResourceArns = append(apiObject.ResourceArns, v.(string))
411+
}
412+
}
413+
414+
if tfList, ok := tfMap["resource_types"].([]any); ok && len(tfList) > 0 {
415+
for _, v := range tfList {
416+
apiObject.ResourceTypes = append(apiObject.ResourceTypes, types.ResourceType(v.(string)))
417+
}
275418
}
276419

277420
return apiObject
@@ -360,13 +503,82 @@ func flattenAnalyzerConfiguration(apiObject types.AnalyzerConfiguration) map[str
360503
tfMap := map[string]any{}
361504

362505
switch v := apiObject.(type) {
506+
case *types.AnalyzerConfigurationMemberInternalAccess:
507+
tfMap["internal_access"] = []any{flattenInternalAccessConfiguration(&v.Value)}
363508
case *types.AnalyzerConfigurationMemberUnusedAccess:
364509
tfMap["unused_access"] = []any{flattenUnusedAccessConfiguration(&v.Value)}
365510
}
366511

367512
return tfMap
368513
}
369514

515+
func flattenInternalAccessConfiguration(apiObject *types.InternalAccessConfiguration) map[string]any {
516+
if apiObject == nil {
517+
return nil
518+
}
519+
520+
tfMap := map[string]any{}
521+
522+
if v := apiObject.AnalysisRule; v != nil {
523+
tfMap["analysis_rule"] = []any{flattenInternalAccessAnalysisRule(v)}
524+
}
525+
526+
return tfMap
527+
}
528+
529+
func flattenInternalAccessAnalysisRule(apiObject *types.InternalAccessAnalysisRule) map[string]any {
530+
if apiObject == nil {
531+
return nil
532+
}
533+
534+
tfMap := map[string]any{}
535+
536+
if v := apiObject.Inclusions; v != nil {
537+
tfMap["inclusion"] = flattenInternalAccessAnalysisRuleCriterias(v)
538+
}
539+
540+
return tfMap
541+
}
542+
543+
func flattenInternalAccessAnalysisRuleCriterias(apiObjects []types.InternalAccessAnalysisRuleCriteria) []any {
544+
if len(apiObjects) == 0 {
545+
return nil
546+
}
547+
548+
var tfList []any
549+
550+
for _, apiObject := range apiObjects {
551+
tfMap := flattenInternalAccessAnalysisRuleCriteria(&apiObject)
552+
if tfMap != nil {
553+
tfList = append(tfList, tfMap)
554+
}
555+
}
556+
557+
return tfList
558+
}
559+
560+
func flattenInternalAccessAnalysisRuleCriteria(apiObject *types.InternalAccessAnalysisRuleCriteria) map[string]any {
561+
if apiObject == nil {
562+
return nil
563+
}
564+
565+
tfMap := map[string]any{}
566+
567+
if v := apiObject.AccountIds; len(v) > 0 {
568+
tfMap["account_ids"] = v
569+
}
570+
571+
if v := apiObject.ResourceArns; len(v) > 0 {
572+
tfMap["resource_arns"] = v
573+
}
574+
575+
if v := apiObject.ResourceTypes; len(v) > 0 {
576+
tfMap["resource_types"] = v
577+
}
578+
579+
return tfMap
580+
}
581+
370582
func flattenUnusedAccessConfiguration(apiObject *types.UnusedAccessConfiguration) map[string]any {
371583
if apiObject == nil {
372584
return nil

0 commit comments

Comments
 (0)