Skip to content

Commit

Permalink
resource/aws_glue_crawler: Use IAM timeout constant for retries, add …
Browse files Browse the repository at this point in the history
…LakeFormation permissions retries and configuration to tests

Reference: #16752

Previously:

```
=== CONT  TestAccAWSGlueCrawler_CatalogTarget
resource_aws_glue_crawler_test.go:719: Step 1/3 error: Error running apply:
Error: error creating Glue crawler: InvalidInputException: Insufficient Lake Formation permission(s) on tf-acc-test-1833852258513360098_table_0 (Service: AmazonDataCatalog; Status Code: 400; Error Code: AccessDeniedException; Request ID: 34c98eb1-4821-4ff5-897b-a9ef0acb7567; Proxy: null)
--- FAIL: TestAccAWSGlueCrawler_CatalogTarget (20.93s)

=== CONT  TestAccAWSGlueCrawler_CatalogTarget_Multiple
resource_aws_glue_crawler_test.go:791: Step 1/4 error: Error running apply:
Error: error creating Glue crawler: InvalidInputException: Insufficient Lake Formation permission(s) on tf-acc-test-3733486415820405861_table_0 (Service: AmazonDataCatalog; Status Code: 400; Error Code: AccessDeniedException; Request ID: 914fed0e-b5dd-4243-859d-f38341bb1ead; Proxy: null)
--- FAIL: TestAccAWSGlueCrawler_CatalogTarget_Multiple (22.48s)
```

Output from acceptance testing in AWS Commercial:

```
--- PASS: TestAccAWSGlueCrawler_CatalogTarget (73.93s)
--- PASS: TestAccAWSGlueCrawler_CatalogTarget_Multiple (116.15s)
--- PASS: TestAccAWSGlueCrawler_Classifiers (114.19s)
--- PASS: TestAccAWSGlueCrawler_Configuration (94.89s)
--- PASS: TestAccAWSGlueCrawler_Description (88.94s)
--- PASS: TestAccAWSGlueCrawler_disappears (55.16s)
--- PASS: TestAccAWSGlueCrawler_DynamodbTarget (96.79s)
--- PASS: TestAccAWSGlueCrawler_DynamodbTarget_scanAll (81.31s)
--- PASS: TestAccAWSGlueCrawler_DynamodbTarget_scanRate (114.15s)
--- PASS: TestAccAWSGlueCrawler_JdbcTarget (65.58s)
--- PASS: TestAccAWSGlueCrawler_JdbcTarget_Exclusions (95.61s)
--- PASS: TestAccAWSGlueCrawler_JdbcTarget_Multiple (62.19s)
--- PASS: TestAccAWSGlueCrawler_lineageConfig (119.41s)
--- PASS: TestAccAWSGlueCrawler_mongoDBTarget (54.79s)
--- PASS: TestAccAWSGlueCrawler_mongoDBTarget_multiple (119.08s)
--- PASS: TestAccAWSGlueCrawler_mongoDBTarget_scan_all (115.39s)
--- PASS: TestAccAWSGlueCrawler_recrawlPolicy (115.84s)
--- PASS: TestAccAWSGlueCrawler_RemoveTablePrefix (89.98s)
--- PASS: TestAccAWSGlueCrawler_Role_ARN_NoPath (60.10s)
--- PASS: TestAccAWSGlueCrawler_Role_ARN_Path (64.04s)
--- PASS: TestAccAWSGlueCrawler_Role_Name_Path (58.68s)
--- PASS: TestAccAWSGlueCrawler_S3Target (49.10s)
--- PASS: TestAccAWSGlueCrawler_S3Target_ConnectionName (44.01s)
--- PASS: TestAccAWSGlueCrawler_S3Target_Exclusions (47.69s)
--- PASS: TestAccAWSGlueCrawler_S3Target_Multiple (76.37s)
--- PASS: TestAccAWSGlueCrawler_Schedule (119.23s)
--- PASS: TestAccAWSGlueCrawler_SchemaChangePolicy (89.88s)
--- PASS: TestAccAWSGlueCrawler_SecurityConfiguration (96.75s)
--- PASS: TestAccAWSGlueCrawler_TablePrefix (101.47s)
--- PASS: TestAccAWSGlueCrawler_Tags (114.07s)
```

Output from acceptance testing in AWS GovCloud (US):

```
--- PASS: TestAccAWSGlueCrawler_CatalogTarget (106.03s)
--- PASS: TestAccAWSGlueCrawler_CatalogTarget_Multiple (150.49s)
--- PASS: TestAccAWSGlueCrawler_Classifiers (112.27s)
--- PASS: TestAccAWSGlueCrawler_Configuration (80.77s)
--- PASS: TestAccAWSGlueCrawler_Description (83.16s)
--- PASS: TestAccAWSGlueCrawler_disappears (50.28s)
--- PASS: TestAccAWSGlueCrawler_DynamodbTarget (78.75s)
--- PASS: TestAccAWSGlueCrawler_DynamodbTarget_scanAll (105.33s)
--- PASS: TestAccAWSGlueCrawler_DynamodbTarget_scanRate (111.31s)
--- PASS: TestAccAWSGlueCrawler_JdbcTarget (82.87s)
--- PASS: TestAccAWSGlueCrawler_JdbcTarget_Exclusions (74.76s)
--- PASS: TestAccAWSGlueCrawler_JdbcTarget_Multiple (101.25s)
--- PASS: TestAccAWSGlueCrawler_lineageConfig (117.90s)
--- PASS: TestAccAWSGlueCrawler_mongoDBTarget (82.21s)
--- PASS: TestAccAWSGlueCrawler_mongoDBTarget_multiple (113.25s)
--- PASS: TestAccAWSGlueCrawler_mongoDBTarget_scan_all (103.75s)
--- PASS: TestAccAWSGlueCrawler_recrawlPolicy (112.81s)
--- PASS: TestAccAWSGlueCrawler_RemoveTablePrefix (79.86s)
--- PASS: TestAccAWSGlueCrawler_Role_ARN_NoPath (47.48s)
--- PASS: TestAccAWSGlueCrawler_Role_ARN_Path (39.29s)
--- PASS: TestAccAWSGlueCrawler_Role_Name_Path (40.08s)
--- PASS: TestAccAWSGlueCrawler_S3Target (78.72s)
--- PASS: TestAccAWSGlueCrawler_S3Target_ConnectionName (49.21s)
--- PASS: TestAccAWSGlueCrawler_S3Target_Exclusions (82.72s)
--- PASS: TestAccAWSGlueCrawler_S3Target_Multiple (101.74s)
--- PASS: TestAccAWSGlueCrawler_Schedule (103.16s)
--- PASS: TestAccAWSGlueCrawler_SchemaChangePolicy (71.90s)
--- PASS: TestAccAWSGlueCrawler_SecurityConfiguration (77.77s)
--- PASS: TestAccAWSGlueCrawler_TablePrefix (73.91s)
--- PASS: TestAccAWSGlueCrawler_Tags (100.25s)
```
  • Loading branch information
bflad committed Jan 22, 2021
1 parent 3b752ca commit b1698c9
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 7 deletions.
29 changes: 22 additions & 7 deletions aws/resource_aws_glue_crawler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import (
"log"
"regexp"
"strings"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/glue"
"github.com/hashicorp/aws-sdk-go-base/tfawserr"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/structure"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags"
iamwaiter "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/iam/waiter"
"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

Expand Down Expand Up @@ -290,16 +291,23 @@ func resourceAwsGlueCrawlerCreate(d *schema.ResourceData, meta interface{}) erro
}

// Retry for IAM eventual consistency
err = resource.Retry(1*time.Minute, func() *resource.RetryError {
err = resource.Retry(iamwaiter.PropagationTimeout, func() *resource.RetryError {
_, err = glueConn.CreateCrawler(crawlerInput)
if err != nil {
if isAWSErr(err, glue.ErrCodeInvalidInputException, "Service is unable to assume role") {
// InvalidInputException: Insufficient Lake Formation permission(s) on xxx
if tfawserr.ErrMessageContains(err, glue.ErrCodeInvalidInputException, "Insufficient Lake Formation permission") {
return resource.RetryableError(err)
}

if tfawserr.ErrMessageContains(err, glue.ErrCodeInvalidInputException, "Service is unable to assume role") {
return resource.RetryableError(err)
}

// InvalidInputException: Unable to retrieve connection tf-acc-test-8656357591012534997: User: arn:aws:sts::*******:assumed-role/tf-acc-test-8656357591012534997/AWS-Crawler is not authorized to perform: glue:GetConnection on resource: * (Service: AmazonDataCatalog; Status Code: 400; Error Code: AccessDeniedException; Request ID: 4d72b66f-9c75-11e8-9faf-5b526c7be968)
if isAWSErr(err, glue.ErrCodeInvalidInputException, "is not authorized") {
if tfawserr.ErrMessageContains(err, glue.ErrCodeInvalidInputException, "is not authorized") {
return resource.RetryableError(err)
}

return resource.NonRetryableError(err)
}
return nil
Expand Down Expand Up @@ -599,16 +607,23 @@ func resourceAwsGlueCrawlerUpdate(d *schema.ResourceData, meta interface{}) erro
}

// Retry for IAM eventual consistency
err = resource.Retry(1*time.Minute, func() *resource.RetryError {
err = resource.Retry(iamwaiter.PropagationTimeout, func() *resource.RetryError {
_, err := glueConn.UpdateCrawler(updateCrawlerInput)
if err != nil {
if isAWSErr(err, glue.ErrCodeInvalidInputException, "Service is unable to assume role") {
// InvalidInputException: Insufficient Lake Formation permission(s) on xxx
if tfawserr.ErrMessageContains(err, glue.ErrCodeInvalidInputException, "Insufficient Lake Formation permission") {
return resource.RetryableError(err)
}

if tfawserr.ErrMessageContains(err, glue.ErrCodeInvalidInputException, "Service is unable to assume role") {
return resource.RetryableError(err)
}

// InvalidInputException: Unable to retrieve connection tf-acc-test-8656357591012534997: User: arn:aws:sts::*******:assumed-role/tf-acc-test-8656357591012534997/AWS-Crawler is not authorized to perform: glue:GetConnection on resource: * (Service: AmazonDataCatalog; Status Code: 400; Error Code: AccessDeniedException; Request ID: 4d72b66f-9c75-11e8-9faf-5b526c7be968)
if isAWSErr(err, glue.ErrCodeInvalidInputException, "is not authorized") {
if tfawserr.ErrMessageContains(err, glue.ErrCodeInvalidInputException, "is not authorized") {
return resource.RetryableError(err)
}

return resource.NonRetryableError(err)
}
return nil
Expand Down
44 changes: 44 additions & 0 deletions aws/resource_aws_glue_crawler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1462,6 +1462,26 @@ resource "aws_iam_role_policy_attachment" "test-AWSGlueServiceRole" {
policy_arn = data.aws_iam_policy.AWSGlueServiceRole.arn
role = aws_iam_role.test.name
}
resource "aws_iam_role_policy" "LakeFormationDataAccess" {
role = aws_iam_role.test.name
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LakeFormationDataAccess",
"Effect": "Allow",
"Action": [
"lakeformation:GetDataAccess"
],
"Resource": "*"
}
]
}
EOF
}
`, rName)
}

Expand Down Expand Up @@ -2081,6 +2101,18 @@ resource "aws_glue_catalog_table" "test" {
}
}
resource "aws_lakeformation_permissions" "test" {
count = %[2]d
permissions = ["ALL"]
principal = aws_iam_role.test.arn
table {
database_name = aws_glue_catalog_database.test.name
name = aws_glue_catalog_table.test[count.index].name
}
}
resource "aws_glue_crawler" "test" {
depends_on = [aws_iam_role_policy_attachment.test-AWSGlueServiceRole]
Expand Down Expand Up @@ -2127,6 +2159,18 @@ resource "aws_glue_catalog_table" "test" {
}
}
resource "aws_lakeformation_permissions" "test" {
count = 2
permissions = ["ALL"]
principal = aws_iam_role.test.arn
table {
database_name = aws_glue_catalog_database.test[count.index].name
name = aws_glue_catalog_table.test[count.index].name
}
}
resource "aws_s3_bucket" "default" {
bucket = %[1]q
force_destroy = true
Expand Down

0 comments on commit b1698c9

Please sign in to comment.