Skip to content

Commit 300d57c

Browse files
committed
resource/aws_accessanalyzer_analyzer: Support ORGANIZATION value in type argument
Reference: #12593 Output from acceptance testing in Organizations testing account: ``` --- PASS: TestAccAWSAccessAnalyzer_serial (344.90s) --- PASS: TestAccAWSAccessAnalyzer_serial/Analyzer (344.90s) --- PASS: TestAccAWSAccessAnalyzer_serial/Analyzer/basic (10.64s) --- PASS: TestAccAWSAccessAnalyzer_serial/Analyzer/disappears (7.41s) --- PASS: TestAccAWSAccessAnalyzer_serial/Analyzer/Tags (22.00s) --- PASS: TestAccAWSAccessAnalyzer_serial/Analyzer/Type_Organization (304.86s) ```
1 parent 05e5313 commit 300d57c

4 files changed

Lines changed: 100 additions & 5 deletions

aws/resource_aws_accessanalyzer_analyzer.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package aws
33
import (
44
"fmt"
55
"log"
6+
"time"
67

78
"github.com/aws/aws-sdk-go/aws"
89
"github.com/aws/aws-sdk-go/service/accessanalyzer"
@@ -12,6 +13,14 @@ import (
1213
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
1314
)
1415

16+
const (
17+
// Maximum amount of time to wait for Organizations eventual consistency on creation
18+
// This timeout value is much higher than usual since the cross-service validation
19+
// appears to be consistently caching for 5 minutes:
20+
// --- PASS: TestAccAWSAccessAnalyzer_serial/Analyzer/Type_Organization (315.86s)
21+
accessAnalyzerOrganizationCreationTimeout = 10 * time.Minute
22+
)
23+
1524
func resourceAwsAccessAnalyzerAnalyzer() *schema.Resource {
1625
return &schema.Resource{
1726
Create: resourceAwsAccessAnalyzerAnalyzerCreate,
@@ -37,9 +46,11 @@ func resourceAwsAccessAnalyzerAnalyzer() *schema.Resource {
3746
"type": {
3847
Type: schema.TypeString,
3948
Optional: true,
49+
ForceNew: true,
4050
Default: accessanalyzer.TypeAccount,
4151
ValidateFunc: validation.StringInSlice([]string{
4252
accessanalyzer.TypeAccount,
53+
accessanalyzer.TypeOrganization,
4354
}, false),
4455
},
4556
},
@@ -57,7 +68,24 @@ func resourceAwsAccessAnalyzerAnalyzerCreate(d *schema.ResourceData, meta interf
5768
Type: aws.String(d.Get("type").(string)),
5869
}
5970

60-
_, err := conn.CreateAnalyzer(input)
71+
// Handle Organizations eventual consistency
72+
err := resource.Retry(accessAnalyzerOrganizationCreationTimeout, func() *resource.RetryError {
73+
_, err := conn.CreateAnalyzer(input)
74+
75+
if isAWSErr(err, accessanalyzer.ErrCodeValidationException, "You must create an organization") {
76+
return resource.RetryableError(err)
77+
}
78+
79+
if err != nil {
80+
return resource.NonRetryableError(err)
81+
}
82+
83+
return nil
84+
})
85+
86+
if isResourceTimeoutError(err) {
87+
_, err = conn.CreateAnalyzer(input)
88+
}
6189

6290
if err != nil {
6391
return fmt.Errorf("error creating Access Analyzer Analyzer (%s): %s", analyzerName, err)

aws/resource_aws_accessanalyzer_analyzer_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,38 @@ func testAccAWSAccessAnalyzerAnalyzer_Tags(t *testing.T) {
112112
})
113113
}
114114

115+
// This test can be run via the pattern: TestAccAWSAccessAnalyzer
116+
func testAccAWSAccessAnalyzerAnalyzer_Type_Organization(t *testing.T) {
117+
var analyzer accessanalyzer.AnalyzerSummary
118+
119+
rName := acctest.RandomWithPrefix("tf-acc-test")
120+
resourceName := "aws_accessanalyzer_analyzer.test"
121+
122+
resource.Test(t, resource.TestCase{
123+
PreCheck: func() {
124+
testAccPreCheck(t)
125+
testAccPreCheckAWSAccessAnalyzer(t)
126+
// testAccOrganizationsAccountPreCheck(t)
127+
},
128+
Providers: testAccProviders,
129+
CheckDestroy: testAccCheckAccessAnalyzerAnalyzerDestroy,
130+
Steps: []resource.TestStep{
131+
{
132+
Config: testAccAWSAccessAnalyzerAnalyzerConfigTypeOrganization(rName),
133+
Check: resource.ComposeTestCheckFunc(
134+
testAccCheckAwsAccessAnalyzerAnalyzerExists(resourceName, &analyzer),
135+
resource.TestCheckResourceAttr(resourceName, "type", accessanalyzer.TypeOrganization),
136+
),
137+
},
138+
{
139+
ResourceName: resourceName,
140+
ImportState: true,
141+
ImportStateVerify: true,
142+
},
143+
},
144+
})
145+
}
146+
115147
func testAccCheckAccessAnalyzerAnalyzerDestroy(s *terraform.State) error {
116148
conn := testAccProvider.Meta().(*AWSClient).accessanalyzerconn
117149

@@ -218,3 +250,20 @@ resource "aws_accessanalyzer_analyzer" "test" {
218250
}
219251
`, rName, tagKey1, tagValue1, tagKey2, tagValue2)
220252
}
253+
254+
func testAccAWSAccessAnalyzerAnalyzerConfigTypeOrganization(rName string) string {
255+
return fmt.Sprintf(`
256+
data "aws_partition" "current" {}
257+
258+
resource "aws_organizations_organization" "test" {
259+
aws_service_access_principals = ["access-analyzer.${data.aws_partition.current.dns_suffix}"]
260+
}
261+
262+
resource "aws_accessanalyzer_analyzer" "test" {
263+
depends_on = [aws_organizations_organization.test]
264+
265+
analyzer_name = %[1]q
266+
type = "ORGANIZATION"
267+
}
268+
`, rName)
269+
}

aws/resource_aws_accessanalyzer_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import (
1111
func TestAccAWSAccessAnalyzer_serial(t *testing.T) {
1212
testCases := map[string]map[string]func(t *testing.T){
1313
"Analyzer": {
14-
"basic": testAccAWSAccessAnalyzerAnalyzer_basic,
15-
"disappears": testAccAWSAccessAnalyzerAnalyzer_disappears,
16-
"Tags": testAccAWSAccessAnalyzerAnalyzer_Tags,
14+
"basic": testAccAWSAccessAnalyzerAnalyzer_basic,
15+
"disappears": testAccAWSAccessAnalyzerAnalyzer_disappears,
16+
"Tags": testAccAWSAccessAnalyzerAnalyzer_Tags,
17+
"Type_Organization": testAccAWSAccessAnalyzerAnalyzer_Type_Organization,
1718
},
1819
}
1920

website/docs/r/accessanalyzer_analyzer.html.markdown

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,29 @@ Manages an Access Analyzer Analyzer. More information can be found in the [Acces
1212

1313
## Example Usage
1414

15+
### Account Analyzer
16+
1517
```hcl
1618
resource "aws_accessanalyzer_analyzer" "example" {
1719
analyzer_name = "example"
1820
}
1921
```
2022

23+
### Organization Analyzer
24+
25+
```hcl
26+
resource "aws_organizations_organization" "example" {
27+
aws_service_access_principals = ["access-analyzer.amazonaws.com"]
28+
}
29+
30+
resource "aws_accessanalyzer_analyzer" "example" {
31+
depends_on = [aws_organizations_organization.example]
32+
33+
analyzer_name = "example"
34+
type = "ORGANIZATION"
35+
}
36+
```
37+
2138
## Argument Reference
2239

2340
The following arguments are required:
@@ -27,7 +44,7 @@ The following arguments are required:
2744
The following arguments are optional:
2845

2946
* `tags` - (Optional) Key-value map of resource tags.
30-
* `type` - (Optional) Type of Analyzer. Valid value is currently only `ACCOUNT`. Defaults to `ACCOUNT`.
47+
* `type` - (Optional) Type of Analyzer. Valid values are `ACCOUNT` or `ORGANIZATION`. Defaults to `ACCOUNT`.
3148

3249
## Attributes Reference
3350

0 commit comments

Comments
 (0)