Skip to content

Commit f35da9e

Browse files
authored
Merge pull request #45471 from data-storyteller/f-kinesisanalyticsv2-support-application-encryption
[Enhancement] r/aws_kinesisanalyticsv2_application: add application_encryption_configuration block
2 parents 5265262 + e74b646 commit f35da9e

File tree

4 files changed

+248
-1
lines changed

4 files changed

+248
-1
lines changed

.changelog/45356.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
```release-note:enhancement
2+
resource/aws_kinesisanalyticsv2_application: Add `application_configuration.application_encryption_configuration` argument
3+
```
4+
5+
```release-note:enhancement
6+
resource/aws_kinesisanalyticsv2_application: Support `FLINK-1_20` as a valid value for `runtime_environment`
7+
```

internal/service/kinesisanalyticsv2/application.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,26 @@ func resourceApplication() *schema.Resource {
120120
},
121121
},
122122
},
123+
"application_encryption_configuration": {
124+
Type: schema.TypeList,
125+
Optional: true,
126+
Computed: true,
127+
MaxItems: 1,
128+
Elem: &schema.Resource{
129+
Schema: map[string]*schema.Schema{
130+
names.AttrKeyID: {
131+
Type: schema.TypeString,
132+
Optional: true,
133+
ValidateFunc: verify.ValidARN,
134+
},
135+
"key_type": {
136+
Type: schema.TypeString,
137+
Required: true,
138+
ValidateDiagFunc: enum.Validate[awstypes.KeyType](),
139+
},
140+
},
141+
},
142+
},
123143
"application_snapshot_configuration": {
124144
Type: schema.TypeList,
125145
Optional: true,
@@ -970,6 +990,12 @@ func resourceApplicationUpdate(ctx context.Context, d *schema.ResourceData, meta
970990
updateApplication = true
971991
}
972992

993+
if d.HasChange("application_configuration.0.application_encryption_configuration") {
994+
applicationConfigurationUpdate.ApplicationEncryptionConfigurationUpdate = expandApplicationEncryptionConfigurationUpdate(d.Get("application_configuration.0.application_encryption_configuration").([]any))
995+
996+
updateApplication = true
997+
}
998+
973999
if d.HasChange("application_configuration.0.application_snapshot_configuration") {
9741000
applicationConfigurationUpdate.ApplicationSnapshotConfigurationUpdate = expandApplicationSnapshotConfigurationUpdate(d.Get("application_configuration.0.application_snapshot_configuration").([]any))
9751001

@@ -1823,6 +1849,10 @@ func expandApplicationConfiguration(vApplicationConfiguration []any) *awstypes.A
18231849
applicationConfiguration.ApplicationCodeConfiguration = applicationCodeConfiguration
18241850
}
18251851

1852+
if vApplicationEncryptionConfiguration, ok := mApplicationConfiguration["application_encryption_configuration"].([]any); ok && len(vApplicationEncryptionConfiguration) > 0 && vApplicationEncryptionConfiguration[0] != nil {
1853+
applicationConfiguration.ApplicationEncryptionConfiguration = expandApplicationEncryptionConfiguration(vApplicationEncryptionConfiguration)
1854+
}
1855+
18261856
if vApplicationSnapshotConfiguration, ok := mApplicationConfiguration["application_snapshot_configuration"].([]any); ok && len(vApplicationSnapshotConfiguration) > 0 && vApplicationSnapshotConfiguration[0] != nil {
18271857
applicationSnapshotConfiguration := &awstypes.ApplicationSnapshotConfiguration{}
18281858

@@ -2710,6 +2740,10 @@ func flattenApplicationConfigurationDescription(applicationConfigurationDescript
27102740
mApplicationConfiguration["application_code_configuration"] = []any{mApplicationCodeConfiguration}
27112741
}
27122742

2743+
if applicationEncryptionConfigurationDescription := applicationConfigurationDescription.ApplicationEncryptionConfigurationDescription; applicationEncryptionConfigurationDescription != nil {
2744+
mApplicationConfiguration["application_encryption_configuration"] = flattenApplicationEncryptionConfigurationDescription(applicationEncryptionConfigurationDescription)
2745+
}
2746+
27132747
if applicationSnapshotConfigurationDescription := applicationConfigurationDescription.ApplicationSnapshotConfigurationDescription; applicationSnapshotConfigurationDescription != nil {
27142748
mApplicationSnapshotConfiguration := map[string]any{
27152749
"snapshots_enabled": aws.ToBool(applicationSnapshotConfigurationDescription.SnapshotsEnabled),
@@ -3099,3 +3133,57 @@ func expandStopApplicationInput(d *schema.ResourceData) *kinesisanalyticsv2.Stop
30993133

31003134
return apiObject
31013135
}
3136+
3137+
func expandApplicationEncryptionConfiguration(vApplicationEncryptionConfiguration []any) *awstypes.ApplicationEncryptionConfiguration {
3138+
if len(vApplicationEncryptionConfiguration) == 0 || vApplicationEncryptionConfiguration[0] == nil {
3139+
return nil
3140+
}
3141+
3142+
mApplicationEncryptionConfiguration := vApplicationEncryptionConfiguration[0].(map[string]any)
3143+
applicationEncryptionConfiguration := &awstypes.ApplicationEncryptionConfiguration{}
3144+
3145+
if vKeyType, ok := mApplicationEncryptionConfiguration["key_type"].(string); ok && vKeyType != "" {
3146+
applicationEncryptionConfiguration.KeyType = awstypes.KeyType(vKeyType)
3147+
}
3148+
3149+
if vKeyID, ok := mApplicationEncryptionConfiguration[names.AttrKeyID].(string); ok && vKeyID != "" {
3150+
applicationEncryptionConfiguration.KeyId = aws.String(vKeyID)
3151+
}
3152+
3153+
return applicationEncryptionConfiguration
3154+
}
3155+
3156+
func expandApplicationEncryptionConfigurationUpdate(vApplicationEncryptionConfiguration []any) *awstypes.ApplicationEncryptionConfigurationUpdate {
3157+
if len(vApplicationEncryptionConfiguration) == 0 || vApplicationEncryptionConfiguration[0] == nil {
3158+
return nil
3159+
}
3160+
3161+
mApplicationEncryptionConfiguration := vApplicationEncryptionConfiguration[0].(map[string]any)
3162+
applicationEncryptionConfiguration := &awstypes.ApplicationEncryptionConfigurationUpdate{}
3163+
3164+
if vKeyType, ok := mApplicationEncryptionConfiguration["key_type"].(string); ok && vKeyType != "" {
3165+
applicationEncryptionConfiguration.KeyTypeUpdate = awstypes.KeyType(vKeyType)
3166+
}
3167+
3168+
if vKeyID, ok := mApplicationEncryptionConfiguration[names.AttrKeyID].(string); ok && vKeyID != "" {
3169+
applicationEncryptionConfiguration.KeyIdUpdate = aws.String(vKeyID)
3170+
}
3171+
3172+
return applicationEncryptionConfiguration
3173+
}
3174+
3175+
func flattenApplicationEncryptionConfigurationDescription(applicationEncryptionConfiguration *awstypes.ApplicationEncryptionConfigurationDescription) []any {
3176+
if applicationEncryptionConfiguration == nil {
3177+
return []any{}
3178+
}
3179+
3180+
mApplicationEncryptionConfiguration := map[string]any{
3181+
"key_type": applicationEncryptionConfiguration.KeyType,
3182+
}
3183+
3184+
if applicationEncryptionConfiguration.KeyId != nil {
3185+
mApplicationEncryptionConfiguration[names.AttrKeyID] = aws.ToString(applicationEncryptionConfiguration.KeyId)
3186+
}
3187+
3188+
return []any{mApplicationEncryptionConfiguration}
3189+
}

internal/service/kinesisanalyticsv2/application_test.go

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4215,6 +4215,68 @@ func TestAccKinesisAnalyticsV2Application_RunConfiguration_Update(t *testing.T)
42154215
})
42164216
}
42174217

4218+
func TestAccKinesisAnalyticsV2Application_ApplicationEncryptionConfiguration_update(t *testing.T) {
4219+
ctx := acctest.Context(t)
4220+
var v awstypes.ApplicationDetail
4221+
resourceName := "aws_kinesisanalyticsv2_application.test"
4222+
iamRoleResourceName := "aws_iam_role.test.0"
4223+
kmsKey1ResourceName := "aws_kms_key.test.0"
4224+
kmsKey2ResourceName := "aws_kms_key.test.1"
4225+
rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix)
4226+
4227+
resource.ParallelTest(t, resource.TestCase{
4228+
PreCheck: func() { acctest.PreCheck(ctx, t); testAccPreCheck(ctx, t) },
4229+
ErrorCheck: acctest.ErrorCheck(t, names.KinesisAnalyticsV2ServiceID),
4230+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories,
4231+
CheckDestroy: testAccCheckApplicationDestroy(ctx),
4232+
Steps: []resource.TestStep{
4233+
{
4234+
Config: testAccApplicationConfig_encryptionConfiguration(rName, "CUSTOMER_MANAGED_KEY", 0),
4235+
Check: resource.ComposeAggregateTestCheckFunc(
4236+
testAccCheckApplicationExists(ctx, resourceName, &v),
4237+
resource.TestCheckResourceAttr(resourceName, "application_configuration.#", "1"),
4238+
resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_encryption_configuration.#", "1"),
4239+
resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_encryption_configuration.0.key_type", "CUSTOMER_MANAGED_KEY"),
4240+
resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_encryption_configuration.0.key_id", kmsKey1ResourceName, names.AttrARN),
4241+
acctest.CheckResourceAttrRegionalARN(ctx, resourceName, names.AttrARN, "kinesisanalytics", fmt.Sprintf("application/%s", rName)),
4242+
resource.TestCheckResourceAttrPair(resourceName, "service_execution_role", iamRoleResourceName, names.AttrARN),
4243+
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "READY"),
4244+
resource.TestCheckResourceAttr(resourceName, "version_id", "1"),
4245+
),
4246+
},
4247+
{
4248+
Config: testAccApplicationConfig_encryptionConfiguration(rName, "CUSTOMER_MANAGED_KEY", 1),
4249+
Check: resource.ComposeAggregateTestCheckFunc(
4250+
testAccCheckApplicationExists(ctx, resourceName, &v),
4251+
resource.TestCheckResourceAttr(resourceName, "application_configuration.#", "1"),
4252+
resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_encryption_configuration.#", "1"),
4253+
resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_encryption_configuration.0.key_type", "CUSTOMER_MANAGED_KEY"),
4254+
resource.TestCheckResourceAttrPair(resourceName, "application_configuration.0.application_encryption_configuration.0.key_id", kmsKey2ResourceName, names.AttrARN),
4255+
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "READY"),
4256+
resource.TestCheckResourceAttr(resourceName, "version_id", "2"),
4257+
),
4258+
},
4259+
{
4260+
Config: testAccApplicationConfig_encryptionConfiguration(rName, "AWS_OWNED_KEY", 0),
4261+
Check: resource.ComposeAggregateTestCheckFunc(
4262+
testAccCheckApplicationExists(ctx, resourceName, &v),
4263+
resource.TestCheckResourceAttr(resourceName, "application_configuration.#", "1"),
4264+
resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_encryption_configuration.#", "1"),
4265+
resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_encryption_configuration.0.key_type", "AWS_OWNED_KEY"),
4266+
resource.TestCheckResourceAttr(resourceName, "application_configuration.0.application_encryption_configuration.0.key_id", ""),
4267+
resource.TestCheckResourceAttr(resourceName, names.AttrStatus, "READY"),
4268+
resource.TestCheckResourceAttr(resourceName, "version_id", "3"),
4269+
),
4270+
},
4271+
{
4272+
ResourceName: resourceName,
4273+
ImportState: true,
4274+
ImportStateVerify: true,
4275+
},
4276+
},
4277+
})
4278+
}
4279+
42184280
func testAccCheckApplicationDestroy(ctx context.Context) resource.TestCheckFunc {
42194281
return func(s *terraform.State) error {
42204282
conn := acctest.Provider.Meta().(*conns.AWSClient).KinesisAnalyticsV2Client(ctx)
@@ -6157,3 +6219,87 @@ resource "aws_kinesisanalyticsv2_application" "test" {
61576219
}
61586220
`, rName))
61596221
}
6222+
6223+
func testAccApplicationConfig_encryptionConfiguration(rName, keyType string, keyIndex int) string {
6224+
return acctest.ConfigCompose(
6225+
testAccApplicationConfig_baseServiceExecutionIAMRole(rName),
6226+
testAccApplicationConfig_baseFlinkApplication(rName),
6227+
testAccApplicationConfig_baseKMSKeys(rName, 2),
6228+
fmt.Sprintf(`
6229+
resource "aws_kinesisanalyticsv2_application" "test" {
6230+
name = %[1]q
6231+
runtime_environment = "FLINK-1_20"
6232+
service_execution_role = aws_iam_role.test[0].arn
6233+
6234+
application_configuration {
6235+
application_code_configuration {
6236+
code_content {
6237+
s3_content_location {
6238+
bucket_arn = aws_s3_bucket.test.arn
6239+
file_key = aws_s3_object.test[0].key
6240+
}
6241+
}
6242+
6243+
code_content_type = "ZIPFILE"
6244+
}
6245+
6246+
application_encryption_configuration {
6247+
key_type = %[2]q
6248+
%[3]s
6249+
}
6250+
}
6251+
}
6252+
`, rName, keyType, func() string {
6253+
if keyType == "CUSTOMER_MANAGED_KEY" {
6254+
return fmt.Sprintf(`key_id = aws_kms_key.test[%d].arn`, keyIndex)
6255+
}
6256+
return ""
6257+
}()))
6258+
}
6259+
6260+
func testAccApplicationConfig_baseKMSKeys(rName string, count int) string {
6261+
return fmt.Sprintf(`
6262+
resource "aws_kms_key" "test" {
6263+
count = %[2]d
6264+
6265+
description = "%[1]s-${count.index}"
6266+
deletion_window_in_days = 7
6267+
}
6268+
6269+
data "aws_caller_identity" "current" {}
6270+
6271+
resource "aws_kms_key_policy" "test" {
6272+
count = %[2]d
6273+
6274+
key_id = aws_kms_key.test[count.index].id
6275+
policy = jsonencode({
6276+
Id = %[1]q
6277+
Statement = [
6278+
{
6279+
Action = "kms:*"
6280+
Effect = "Allow"
6281+
Principal = {
6282+
AWS = data.aws_caller_identity.current.arn
6283+
}
6284+
6285+
Resource = "*"
6286+
Sid = "Enable IAM User Permissions"
6287+
},
6288+
{
6289+
Action = [
6290+
"kms:*",
6291+
]
6292+
Effect = "Allow"
6293+
Principal = {
6294+
Service = ["kinesisanalytics.amazonaws.com", "infrastructure.kinesisanalytics.amazonaws.com"]
6295+
}
6296+
6297+
Resource = "*"
6298+
Sid = "Enable IAM MSF Permissions"
6299+
},
6300+
]
6301+
Version = "2012-10-17"
6302+
})
6303+
}
6304+
`, rName, count)
6305+
}

website/docs/r/kinesisanalyticsv2_application.html.markdown

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ This resource supports the following arguments:
257257

258258
* `region` - (Optional) Region where this resource will be [managed](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints). Defaults to the Region set in the [provider configuration](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#aws-configuration-reference).
259259
* `name` - (Required) The name of the application.
260-
* `runtime_environment` - (Required) The runtime environment for the application. Valid values: `SQL-1_0`, `FLINK-1_6`, `FLINK-1_8`, `FLINK-1_11`, `FLINK-1_13`, `FLINK-1_15`, `FLINK-1_18`, `FLINK-1_19`.
260+
* `runtime_environment` - (Required) The runtime environment for the application. Valid values: `SQL-1_0`, `FLINK-1_6`, `FLINK-1_8`, `FLINK-1_11`, `FLINK-1_13`, `FLINK-1_15`, `FLINK-1_18`, `FLINK-1_19`, `FLINK-1_20`.
261261
* `service_execution_role` - (Required) The ARN of the [IAM role](/docs/providers/aws/r/iam_role.html) used by the application to access Kinesis data streams, Kinesis Data Firehose delivery streams, Amazon S3 objects, and other external resources.
262262
* `application_configuration` - (Optional) The application's configuration
263263
* `application_mode` - (Optional) The application's mode. Valid values are `STREAMING`, `INTERACTIVE`.
@@ -270,6 +270,7 @@ This resource supports the following arguments:
270270
The `application_configuration` object supports the following:
271271

272272
* `application_code_configuration` - (Required) The code location and type parameters for the application.
273+
* `application_encryption_configuration` - (Optional) The encryption configuration for the application. This can be used to encrypt data at rest in the application.
273274
* `application_snapshot_configuration` - (Optional) Describes whether snapshots are enabled for a Flink-based application.
274275
* `environment_properties` - (Optional) Describes execution properties for a Flink-based application.
275276
* `flink_application_configuration` - (Optional) The configuration of a Flink-based application.
@@ -282,6 +283,11 @@ The `application_code_configuration` object supports the following:
282283
* `code_content_type` - (Required) Specifies whether the code content is in text or zip format. Valid values: `PLAINTEXT`, `ZIPFILE`.
283284
* `code_content` - (Optional) The location and type of the application code.
284285

286+
The `application_encryption_configuration` object supports the following:
287+
288+
* `key_type` - (Required) The type of encryption key to use. Valid values: `CUSTOMER_MANAGED_KEY`, `AWS_OWNED_KEY`.
289+
* `key_id` - (Optional) The ARN of the KMS key to use for encryption. Required when `key_type` is set to `CUSTOMER_MANAGED_KEY`. The KMS key must be in the same region as the application.
290+
285291
The `code_content` object supports the following:
286292

287293
* `s3_content_location` - (Optional) Information about the Amazon S3 bucket containing the application code.

0 commit comments

Comments
 (0)