Skip to content

Commit

Permalink
Merge pull request #34055 from sQu4rks/f-verified-access-group-kms-su…
Browse files Browse the repository at this point in the history
…pport

Feature: Add KMS Support to Verified Access Group
  • Loading branch information
ewbankkit authored Feb 8, 2024
2 parents a974706 + f25da9d commit 5e1d978
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 4 deletions.
3 changes: 3 additions & 0 deletions .changelog/34055.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_verifiedaccess_group: Add `sse_configuration` argument
```
88 changes: 85 additions & 3 deletions internal/service/ec2/verifiedaccess_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,25 @@ func ResourceVerifiedAccessGroup() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},
"sse_configuration": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"customer_managed_key_enabled": {
Type: schema.TypeBool,
Optional: true,
},
"kms_key_arn": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: verify.ValidARN,
},
},
},
},
names.AttrTags: tftags.TagsSchema(),
names.AttrTagsAll: tftags.TagsSchemaComputed(),
"verifiedaccess_group_arn": {
Expand Down Expand Up @@ -99,6 +118,10 @@ func resourceVerifiedAccessGroupCreate(ctx context.Context, d *schema.ResourceDa
input.PolicyDocument = aws.String(v.(string))
}

if v, ok := d.GetOk("sse_configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
input.SseSpecification = expandVerifiedAccessSseSpecificationRequest(v.([]interface{})[0].(map[string]interface{}))
}

output, err := conn.CreateVerifiedAccessGroup(ctx, input)

if err != nil {
Expand Down Expand Up @@ -131,6 +154,13 @@ func resourceVerifiedAccessGroupRead(ctx context.Context, d *schema.ResourceData
d.Set("description", group.Description)
d.Set("last_updated_time", group.LastUpdatedTime)
d.Set("owner", group.Owner)
if v := group.SseSpecification; v != nil {
if err := d.Set("sse_configuration", flattenVerifiedAccessSseSpecificationResponse(v)); err != nil {
return sdkdiag.AppendErrorf(diags, "setting sse_configuration: %s", err)
}
} else {
d.Set("sse_configuration", nil)
}
d.Set("verifiedaccess_group_arn", group.VerifiedAccessGroupArn)
d.Set("verifiedaccess_group_id", group.VerifiedAccessGroupId)
d.Set("verifiedaccess_instance_id", group.VerifiedAccessInstanceId)
Expand All @@ -152,7 +182,7 @@ func resourceVerifiedAccessGroupUpdate(ctx context.Context, d *schema.ResourceDa
var diags diag.Diagnostics
conn := meta.(*conns.AWSClient).EC2Client(ctx)

if d.HasChangesExcept("policy_document", "tags", "tags_all") {
if d.HasChangesExcept("policy_document", "tags", "tags_all", "sse_configuration") {
input := &ec2.ModifyVerifiedAccessGroupInput{
ClientToken: aws.String(id.UniqueId()),
VerifiedAccessGroupId: aws.String(d.Id()),
Expand All @@ -174,19 +204,35 @@ func resourceVerifiedAccessGroupUpdate(ctx context.Context, d *schema.ResourceDa
}

if d.HasChange("policy_document") {
input := &ec2.ModifyVerifiedAccessGroupPolicyInput{
in := &ec2.ModifyVerifiedAccessGroupPolicyInput{
PolicyDocument: aws.String(d.Get("policy_document").(string)),
VerifiedAccessGroupId: aws.String(d.Id()),
PolicyEnabled: aws.Bool(true),
}

_, err := conn.ModifyVerifiedAccessGroupPolicy(ctx, input)
_, err := conn.ModifyVerifiedAccessGroupPolicy(ctx, in)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating Verified Access Group (%s) policy: %s", d.Id(), err)
}
}

if d.HasChange("sse_configuration") {
in := &ec2.ModifyVerifiedAccessGroupPolicyInput{
VerifiedAccessGroupId: aws.String(d.Id()),
}

if v, ok := d.GetOk("sse_configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil {
in.SseSpecification = expandVerifiedAccessSseSpecificationRequest(v.([]interface{})[0].(map[string]interface{}))
}

_, err := conn.ModifyVerifiedAccessGroupPolicy(ctx, in)

if err != nil {
return sdkdiag.AppendErrorf(diags, "updating SSE on Verified Access Group (%s) policy: %s", d.Id(), err)
}
}

return append(diags, resourceVerifiedAccessGroupRead(ctx, d, meta)...)
}

Expand All @@ -210,3 +256,39 @@ func resourceVerifiedAccessGroupDelete(ctx context.Context, d *schema.ResourceDa

return diags
}

func expandVerifiedAccessSseSpecificationRequest(tfMap map[string]interface{}) *types.VerifiedAccessSseSpecificationRequest {
if tfMap == nil {
return nil
}

apiObject := &types.VerifiedAccessSseSpecificationRequest{}

if v, ok := tfMap["kms_key_arn"].(string); ok && v != "" {
apiObject.KmsKeyArn = aws.String(v)
}

if v, ok := tfMap["customer_managed_key_enabled"].(bool); ok {
apiObject.CustomerManagedKeyEnabled = aws.Bool(v)
}

return apiObject
}

func flattenVerifiedAccessSseSpecificationResponse(apiObject *types.VerifiedAccessSseSpecificationResponse) []interface{} {
if apiObject == nil {
return nil
}

tfMap := map[string]interface{}{}

if v := apiObject.CustomerManagedKeyEnabled; v != nil {
tfMap["customer_managed_key_enabled"] = aws.ToBool(v)
}

if v := apiObject.KmsKeyArn; v != nil {
tfMap["kms_key_arn"] = aws.ToString(v)
}

return []interface{}{tfMap}
}
114 changes: 114 additions & 0 deletions internal/service/ec2/verifiedaccess_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,102 @@ func TestAccVerifiedAccessGroup_basic(t *testing.T) {
resource.TestCheckResourceAttrSet(resourceName, "verifiedaccess_group_arn"),
resource.TestCheckResourceAttrSet(resourceName, "verifiedaccess_group_id"),
resource.TestCheckResourceAttrSet(resourceName, "verifiedaccess_instance_id"),
resource.TestCheckResourceAttr(resourceName, "sse_configuration.0.customer_managed_key_enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "sse_configuration.0.kms_key_arn", ""),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccVerifiedAccessGroup_kms(t *testing.T) {
ctx := acctest.Context(t)
var v types.VerifiedAccessGroup
resourceName := "aws_verifiedaccess_group.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
policyDoc := "permit(principal, action, resource) \nwhen {\ncontext.http_request.method == \"GET\"\n};"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
testAccPreCheckVerifiedAccess(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, names.EC2),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckVerifiedAccessGroupDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccVerifiedAccessGroupConfig_kms(rName, policyDoc),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckVerifiedAccessGroupExists(ctx, resourceName, &v),
resource.TestCheckResourceAttrSet(resourceName, "creation_time"),
resource.TestCheckResourceAttr(resourceName, "sse_configuration.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "sse_configuration.0.customer_managed_key_enabled"),
resource.TestCheckResourceAttrSet(resourceName, "sse_configuration.0.kms_key_arn"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccVerifiedAccessGroup_updateKMS(t *testing.T) {
ctx := acctest.Context(t)
var v types.VerifiedAccessGroup
resourceName := "aws_verifiedaccess_group.test"
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
policyDoc := "permit(principal, action, resource) \nwhen {\ncontext.http_request.method == \"GET\"\n};"
description := sdkacctest.RandString(100)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() {
acctest.PreCheck(ctx, t)
testAccPreCheckVerifiedAccess(ctx, t)
},
ErrorCheck: acctest.ErrorCheck(t, names.EC2),
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
CheckDestroy: testAccCheckVerifiedAccessGroupDestroy(ctx),
Steps: []resource.TestStep{
{
Config: testAccVerifiedAccessGroupConfig_policy(rName, description, policyDoc),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckVerifiedAccessGroupExists(ctx, resourceName, &v),
resource.TestCheckResourceAttrSet(resourceName, "creation_time"),
resource.TestCheckResourceAttr(resourceName, "deletion_time", ""),
resource.TestCheckResourceAttr(resourceName, "description", description),
resource.TestCheckResourceAttrSet(resourceName, "last_updated_time"),
acctest.CheckResourceAttrAccountID(resourceName, "owner"),
resource.TestCheckResourceAttr(resourceName, "policy_document", policyDoc),
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
resource.TestCheckResourceAttrSet(resourceName, "verifiedaccess_group_arn"),
resource.TestCheckResourceAttrSet(resourceName, "verifiedaccess_group_id"),
resource.TestCheckResourceAttrSet(resourceName, "verifiedaccess_instance_id"),
resource.TestCheckResourceAttr(resourceName, "sse_configuration.0.customer_managed_key_enabled", "false"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccVerifiedAccessGroupConfig_kms(rName, policyDoc),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckVerifiedAccessGroupExists(ctx, resourceName, &v),
resource.TestCheckResourceAttrSet(resourceName, "creation_time"),
resource.TestCheckResourceAttr(resourceName, "sse_configuration.#", "1"),
resource.TestCheckResourceAttrSet(resourceName, "sse_configuration.0.customer_managed_key_enabled"),
resource.TestCheckResourceAttr(resourceName, "sse_configuration.0.customer_managed_key_enabled", "true"),
resource.TestCheckResourceAttrSet(resourceName, "sse_configuration.0.kms_key_arn"),
),
},
{
Expand Down Expand Up @@ -366,6 +462,24 @@ resource "aws_verifiedaccess_group" "test" {
`)
}

func testAccVerifiedAccessGroupConfig_kms(rName, policyDoc string) string {
return acctest.ConfigCompose(testAccVerifiedAccessGroupConfig_base(rName), fmt.Sprintf(`
resource "aws_kms_key" "test_key" {
description = "KMS key for Verified Access Group test"
}
resource "aws_verifiedaccess_group" "test" {
verifiedaccess_instance_id = aws_verifiedaccess_instance_trust_provider_attachment.test.verifiedaccess_instance_id
policy_document = %[1]q
sse_configuration {
kms_key_arn = aws_kms_key.test_key.arn
customer_managed_key_enabled = true
}
}
`, policyDoc))
}

func testAccVerifiedAccessGroupConfig_tags1(rName, tagKey1, tagValue1 string) string {
return acctest.ConfigCompose(testAccVerifiedAccessGroupConfig_base(rName), fmt.Sprintf(`
resource "aws_verifiedaccess_group" "test" {
Expand Down
21 changes: 20 additions & 1 deletion website/docs/r/verifiedaccess_group.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,22 @@ resource "aws_verifiedaccess_group" "example" {
}
```

### Usage with KMS Key

```terraform
resource "aws_kms_key" "test_key" {
description = "KMS key for Verified Access Group test"
}
resource "aws_verifiedaccess_group" "test" {
verifiedaccess_instance_id = aws_verifiedaccess_instance_trust_provider_attachment.test.verifiedaccess_instance_id
server_side_encryption_configuration {
kms_key_arn = aws_kms_key.test_key.arn
}
}
```

## Argument Reference

The following arguments are required:
Expand All @@ -29,8 +45,11 @@ The following arguments are required:
The following arguments are optional:

* `description` - (Optional) Description of the verified access group.
* `tags` - (Optional) Key-value mapping of resource tags. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.
* `policy_document` - (Optional) The policy document that is associated with this resource.
* `sse_configuration` - (Optional) Configuration block to use KMS keys for server-side encryption.
* `cmk_enabled` - (Optional) Boolean flag to indicate that the CMK should be used.
* `kms_key_arn` - (Optional) ARN of the KMS key to use.
* `tags` - (Optional) Key-value mapping of resource tags. If configured with a provider [`default_tags` configuration block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#default_tags-configuration-block) present, tags with matching keys will overwrite those defined at the provider-level.

## Attribute Reference

Expand Down

0 comments on commit 5e1d978

Please sign in to comment.