Skip to content

Commit

Permalink
Merge pull request #23748 from DrFaust92/athena-workgroup
Browse files Browse the repository at this point in the history
r/athena_workgroup - add `acl_configuration` and `expected_bucket_owner` args
  • Loading branch information
ewbankkit authored Mar 18, 2022
2 parents 641af6a + 7072c5e commit 768612b
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 52 deletions.
3 changes: 3 additions & 0 deletions .changelog/23748.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_athena_workgroup: Add `acl_configuration` and `expected_bucket_owner` arguments to the `configuration.result_configuration` block
```
98 changes: 75 additions & 23 deletions internal/service/athena/workgroup.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ func ResourceWorkGroup() *schema.Resource {
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"acl_configuration": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"s3_acl_option": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice(athena.S3AclOption_Values(), false),
},
},
},
},
"encryption_configuration": {
Type: schema.TypeList,
Optional: true,
Expand All @@ -99,6 +113,10 @@ func ResourceWorkGroup() *schema.Resource {
},
},
},
"expected_bucket_owner": {
Type: schema.TypeString,
Optional: true,
},
"output_location": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -278,28 +296,22 @@ func resourceWorkGroupDelete(d *schema.ResourceData, meta interface{}) error {
func resourceWorkGroupUpdate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*conns.AWSClient).AthenaConn

workGroupUpdate := false

input := &athena.UpdateWorkGroupInput{
WorkGroup: aws.String(d.Get("name").(string)),
}

if d.HasChange("configuration") {
workGroupUpdate = true
input.ConfigurationUpdates = expandAthenaWorkGroupConfigurationUpdates(d.Get("configuration").([]interface{}))
}
if d.HasChangesExcept("tags", "tags_all") {
input := &athena.UpdateWorkGroupInput{
WorkGroup: aws.String(d.Get("name").(string)),
}

if d.HasChange("description") {
workGroupUpdate = true
input.Description = aws.String(d.Get("description").(string))
}
if d.HasChange("configuration") {
input.ConfigurationUpdates = expandAthenaWorkGroupConfigurationUpdates(d.Get("configuration").([]interface{}))
}

if d.HasChange("state") {
workGroupUpdate = true
input.State = aws.String(d.Get("state").(string))
}
if d.HasChange("description") {
input.Description = aws.String(d.Get("description").(string))
}

if workGroupUpdate {
if d.HasChange("state") {
input.State = aws.String(d.Get("state").(string))
}
_, err := conn.UpdateWorkGroup(input)

if err != nil {
Expand Down Expand Up @@ -420,8 +432,16 @@ func expandAthenaWorkGroupResultConfiguration(l []interface{}) *athena.ResultCon
resultConfiguration.EncryptionConfiguration = expandAthenaWorkGroupEncryptionConfiguration(v.([]interface{}))
}

if v, ok := m["output_location"]; ok && v.(string) != "" {
resultConfiguration.OutputLocation = aws.String(v.(string))
if v, ok := m["output_location"].(string); ok && v != "" {
resultConfiguration.OutputLocation = aws.String(v)
}

if v, ok := m["expected_bucket_owner"].(string); ok && v != "" {
resultConfiguration.ExpectedBucketOwner = aws.String(v)
}

if v, ok := m["acl_configuration"]; ok {
resultConfiguration.AclConfiguration = expandAthenaResultConfigurationAclConfig(v.([]interface{}))
}

return resultConfiguration
Expand All @@ -442,12 +462,24 @@ func expandAthenaWorkGroupResultConfigurationUpdates(l []interface{}) *athena.Re
resultConfigurationUpdates.RemoveEncryptionConfiguration = aws.Bool(true)
}

if v, ok := m["output_location"]; ok && v.(string) != "" {
resultConfigurationUpdates.OutputLocation = aws.String(v.(string))
if v, ok := m["output_location"].(string); ok && v != "" {
resultConfigurationUpdates.OutputLocation = aws.String(v)
} else {
resultConfigurationUpdates.RemoveOutputLocation = aws.Bool(true)
}

if v, ok := m["expected_bucket_owner"].(string); ok && v != "" {
resultConfigurationUpdates.ExpectedBucketOwner = aws.String(v)
} else {
resultConfigurationUpdates.RemoveExpectedBucketOwner = aws.Bool(true)
}

if v, ok := m["acl_configuration"]; ok {
resultConfigurationUpdates.AclConfiguration = expandAthenaResultConfigurationAclConfig(v.([]interface{}))
} else {
resultConfigurationUpdates.RemoveAclConfiguration = aws.Bool(true)
}

return resultConfigurationUpdates
}

Expand Down Expand Up @@ -511,6 +543,14 @@ func flattenAthenaWorkGroupResultConfiguration(resultConfiguration *athena.Resul
"output_location": aws.StringValue(resultConfiguration.OutputLocation),
}

if resultConfiguration.ExpectedBucketOwner != nil {
m["expected_bucket_owner"] = aws.StringValue(resultConfiguration.ExpectedBucketOwner)
}

if resultConfiguration.AclConfiguration != nil {
m["acl_configuration"] = flattenAthenaWorkGroupAclConfiguration(resultConfiguration.AclConfiguration)
}

return []interface{}{m}
}

Expand All @@ -526,3 +566,15 @@ func flattenAthenaWorkGroupEncryptionConfiguration(encryptionConfiguration *athe

return []interface{}{m}
}

func flattenAthenaWorkGroupAclConfiguration(aclConfig *athena.AclConfiguration) []interface{} {
if aclConfig == nil {
return []interface{}{}
}

m := map[string]interface{}{
"s3_acl_option": aws.StringValue(aclConfig.S3AclOption),
}

return []interface{}{m}
}
65 changes: 50 additions & 15 deletions internal/service/athena/workgroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
"github.com/hashicorp/terraform-provider-aws/internal/acctest"
"github.com/hashicorp/terraform-provider-aws/internal/conns"
tfathena "github.com/hashicorp/terraform-provider-aws/internal/service/athena"
)

func TestAccAthenaWorkGroup_basic(t *testing.T) {
Expand Down Expand Up @@ -53,6 +54,38 @@ func TestAccAthenaWorkGroup_basic(t *testing.T) {
})
}

func TestAccAthenaWorkGroup_aclConfig(t *testing.T) {
var workgroup1 athena.WorkGroup
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
resourceName := "aws_athena_workgroup.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acctest.PreCheck(t) },
ErrorCheck: acctest.ErrorCheck(t, athena.EndpointsID),
Providers: acctest.Providers,
CheckDestroy: testAccCheckWorkGroupDestroy,
Steps: []resource.TestStep{
{
Config: testAccAthenaWorkGroupConfigConfigurationResultConfigurationAclConfig(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckWorkGroupExists(resourceName, &workgroup1),
acctest.CheckResourceAttrRegionalARN(resourceName, "arn", "athena", fmt.Sprintf("workgroup/%s", rName)),
resource.TestCheckResourceAttr(resourceName, "configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "configuration.0.result_configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "configuration.0.result_configuration.0.acl_configuration.#", "1"),
resource.TestCheckResourceAttr(resourceName, "configuration.0.result_configuration.0.acl_configuration.0.s3_acl_option", "BUCKET_OWNER_FULL_CONTROL"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"force_destroy"},
},
},
})
}

func TestAccAthenaWorkGroup_disappears(t *testing.T) {
var workgroup1 athena.WorkGroup
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
Expand All @@ -68,7 +101,7 @@ func TestAccAthenaWorkGroup_disappears(t *testing.T) {
Config: testAccAthenaWorkGroupConfig(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckWorkGroupExists(resourceName, &workgroup1),
testAccCheckWorkGroupDisappears(&workgroup1),
acctest.CheckResourceDisappears(acctest.Provider, tfathena.ResourceWorkGroup(), resourceName),
),
ExpectNonEmptyPlan: true,
},
Expand Down Expand Up @@ -667,20 +700,6 @@ func testAccCheckWorkGroupExists(name string, workgroup *athena.WorkGroup) resou
}
}

func testAccCheckWorkGroupDisappears(workgroup *athena.WorkGroup) resource.TestCheckFunc {
return func(s *terraform.State) error {
conn := acctest.Provider.Meta().(*conns.AWSClient).AthenaConn

input := &athena.DeleteWorkGroupInput{
WorkGroup: workgroup.Name,
}

_, err := conn.DeleteWorkGroup(input)

return err
}
}

func testAccAthenaWorkGroupConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_athena_workgroup" "test" {
Expand Down Expand Up @@ -800,6 +819,22 @@ resource "aws_athena_workgroup" "test" {
`, rName, bucketName)
}

func testAccAthenaWorkGroupConfigConfigurationResultConfigurationAclConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_athena_workgroup" "test" {
name = %[1]q
configuration {
result_configuration {
acl_configuration {
s3_acl_option = "BUCKET_OWNER_FULL_CONTROL"
}
}
}
}
`, rName)
}

func testAccAthenaWorkGroupConfigConfigurationResultConfigurationEncryptionConfigurationEncryptionOptionSseS3(rName string) string {
return fmt.Sprintf(`
resource "aws_athena_workgroup" "test" {
Expand Down
26 changes: 12 additions & 14 deletions website/docs/r/athena_workgroup.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -43,33 +43,31 @@ The following arguments are supported:
* `tags` - (Optional) Key-value map of resource tags for the workgroup. If configured with a provider [`default_tags` configuration block](/docs/providers/aws/index.html#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
* `force_destroy` - (Optional) The option to delete the workgroup and its contents even if the workgroup contains any named queries.

### configuration Argument Reference

The `configuration` configuration block supports the following arguments:
### Configuration

* `bytes_scanned_cutoff_per_query` - (Optional) Integer for the upper data usage limit (cutoff) for the amount of bytes a single query in a workgroup is allowed to scan. Must be at least `10485760`.
* `enforce_workgroup_configuration` - (Optional) Boolean whether the settings for the workgroup override client-side settings. For more information, see [Workgroup Settings Override Client-Side Settings](https://docs.aws.amazon.com/athena/latest/ug/workgroups-settings-override.html). Defaults to `true`.
* `engine_version` - (Optional) Configuration block for the Athena Engine Versioning. For more information, see [Athena Engine Versioning](https://docs.aws.amazon.com/athena/latest/ug/engine-versions.html). Documented below.
* `engine_version` - (Optional) Configuration block for the Athena Engine Versioning. For more information, see [Athena Engine Versioning](https://docs.aws.amazon.com/athena/latest/ug/engine-versions.html). See [Engine Version](#engine-version) below.
* `publish_cloudwatch_metrics_enabled` - (Optional) Boolean whether Amazon CloudWatch metrics are enabled for the workgroup. Defaults to `true`.
* `result_configuration` - (Optional) Configuration block with result settings. Documented below.
* `result_configuration` - (Optional) Configuration block with result settings. See [Result Configuration](#result-configuration) below.
* `requester_pays_enabled` - (Optional) If set to true , allows members assigned to a workgroup to reference Amazon S3 Requester Pays buckets in queries. If set to false , workgroup members cannot query data from Requester Pays buckets, and queries that retrieve data from Requester Pays buckets cause an error. The default is false . For more information about Requester Pays buckets, see [Requester Pays Buckets](https://docs.aws.amazon.com/AmazonS3/latest/dev/RequesterPaysBuckets.html) in the Amazon Simple Storage Service Developer Guide.

#### engine_version Argument Reference

The `engine_version` configuration block within the `configuration` supports the following arguments:
#### Engine Version

* `selected_engine_version` - (Optional) The requested engine version. Defaults to `AUTO`.

#### result_configuration Argument Reference
#### Result Configuration

The `result_configuration` configuration block within the `configuration` supports the following arguments:

* `encryption_configuration` - (Optional) Configuration block with encryption settings. Documented below.
* `encryption_configuration` - (Optional) Configuration block with encryption settings. See [Encryption Configuration](#encryption-configuration) below.
* `acl_configuration` - (Optional) Indicates that an Amazon S3 canned ACL should be set to control ownership of stored query results. See [ACL Configuration](#acl-configuration) below.
* `expected_bucket_owner` - (Optional) The AWS account ID that you expect to be the owner of the Amazon S3 bucket.
* `output_location` - (Optional) The location in Amazon S3 where your query results are stored, such as `s3://path/to/query/bucket/`. For more information, see [Queries and Query Result Files](https://docs.aws.amazon.com/athena/latest/ug/querying.html).

##### encryption_configuration Argument Reference
##### ACL Configuration

* `s3_acl_option` - (Required) The Amazon S3 canned ACL that Athena should specify when storing query results. Valid value is `BUCKET_OWNER_FULL_CONTROL`.

The `encryption_configuration` configuration block within the `result_configuration` of the `configuration` supports the following arguments:
##### Encryption Configuration

* `encryption_option` - (Required) Indicates whether Amazon S3 server-side encryption with Amazon S3-managed keys (`SSE_S3`), server-side encryption with KMS-managed keys (`SSE_KMS`), or client-side encryption with KMS-managed keys (`CSE_KMS`) is used. If a query runs in a workgroup and the workgroup overrides client-side settings, then the workgroup's setting for encryption is used. It specifies whether query results must be encrypted, for all queries that run in this workgroup.
* `kms_key_arn` - (Optional) For `SSE_KMS` and `CSE_KMS`, this is the KMS key Amazon Resource Name (ARN).
Expand Down

0 comments on commit 768612b

Please sign in to comment.