Skip to content

Commit

Permalink
Merge branch 'issue-11721' of ssh://github.com/StevenKGER/terraform-p…
Browse files Browse the repository at this point in the history
…rovider-aws into StevenKGER-issue-11721
  • Loading branch information
bflad committed Sep 16, 2020
2 parents e1516b7 + 7460249 commit 212b6dd
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 24 deletions.
99 changes: 85 additions & 14 deletions aws/resource_aws_kinesis_firehose_delivery_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,9 +620,18 @@ func flattenKinesisFirehoseDeliveryStream(d *schema.ResourceData, s *firehose.De
sseOptions := map[string]interface{}{
"enabled": false,
}
if s.DeliveryStreamEncryptionConfiguration != nil && aws.StringValue(s.DeliveryStreamEncryptionConfiguration.Status) == firehose.DeliveryStreamEncryptionStatusEnabled {
if s.DeliveryStreamEncryptionConfiguration != nil &&
aws.StringValue(s.DeliveryStreamEncryptionConfiguration.Status) == firehose.DeliveryStreamEncryptionStatusEnabled {
sseOptions["enabled"] = true

if v := s.DeliveryStreamEncryptionConfiguration.KeyARN; v != nil {
sseOptions["kms_key_arn"] = aws.StringValue(v)
}
if v := s.DeliveryStreamEncryptionConfiguration.KeyType; v != nil {
sseOptions["kms_key_type"] = aws.StringValue(v)
}
}

if err := d.Set("server_side_encryption", []map[string]interface{}{sseOptions}); err != nil {
return fmt.Errorf("error setting server_side_encryption: %s", err)
}
Expand Down Expand Up @@ -726,6 +735,18 @@ func resourceAwsKinesisFirehoseDeliveryStream() *schema.Resource {
Optional: true,
Default: false,
},

"kms_key_type": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice(firehose.KeyType_Values(), false),
},

"kms_key_arn": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validateArn,
},
},
},
},
Expand Down Expand Up @@ -2198,9 +2219,18 @@ func resourceAwsKinesisFirehoseDeliveryStreamCreate(d *schema.ResourceData, meta
d.Set("arn", s.DeliveryStreamARN)

if v, ok := d.GetOk("server_side_encryption"); ok && !isKinesisFirehoseDeliveryStreamOptionDisabled(v) {
_, err := conn.StartDeliveryStreamEncryption(&firehose.StartDeliveryStreamEncryptionInput{
DeliveryStreamName: aws.String(sn),
})
options := getOptionsOfConfigurationUnit(v)
startInput := &firehose.StartDeliveryStreamEncryptionInput{
DeliveryStreamName: aws.String(sn),
DeliveryStreamEncryptionConfigurationInput: &firehose.DeliveryStreamEncryptionConfigurationInput{},
}
if v, ok := options["kms_key_arn"].(string); ok && v != "" {
startInput.DeliveryStreamEncryptionConfigurationInput.KeyARN = aws.String(v)
}
if v, ok := options["kms_key_type"].(string); ok && v != "" {
startInput.DeliveryStreamEncryptionConfigurationInput.KeyType = aws.String(v)
}
_, err := conn.StartDeliveryStreamEncryption(startInput)
if err != nil {
return fmt.Errorf("error starting Kinesis Firehose Delivery Stream (%s) encryption: %s", sn, err)
}
Expand All @@ -2217,6 +2247,7 @@ func validateAwsKinesisFirehoseSchema(d *schema.ResourceData) error {

_, s3Exists := d.GetOk("s3_configuration")
_, extendedS3Exists := d.GetOk("extended_s3_configuration")
encryptionOptionsInterface, encryptionOptionExists := d.GetOk("server_side_encryption")

if d.Get("destination").(string) == firehoseDestinationTypeExtendedS3 {
if !extendedS3Exists {
Expand All @@ -2241,6 +2272,28 @@ func validateAwsKinesisFirehoseSchema(d *schema.ResourceData) error {
}
}

if encryptionOptionExists {
encryptionOptions := getOptionsOfConfigurationUnit(encryptionOptionsInterface)
if encryptionOptions["enabled"] == false &&
(encryptionOptions["kms_key_type"] != "" || encryptionOptions["kms_key_arn"] != "") {
return fmt.Errorf("when encryption is disabled, no encryption options can be specified")
}
if encryptionOptions["enabled"] == true {
if encryptionOptions["kms_key_type"] == firehose.KeyTypeAwsOwnedCmk &&
encryptionOptions["kms_key_arn"] != "" {
return fmt.Errorf("encryption using the AWS_OWNED_CMK option must not have kms_key_arn specified")
}
if encryptionOptions["kms_key_type"] != firehose.KeyTypeAwsOwnedCmk &&
encryptionOptions["kms_key_type"] != firehose.KeyTypeCustomerManagedCmk {
return fmt.Errorf("kms_key_type has to be specified, when server-side-encryption is enabled")
}
if encryptionOptions["kms_key_type"] == firehose.KeyTypeCustomerManagedCmk &&
(encryptionOptions["kms_key_arn"] == nil || encryptionOptions["kms_key_arn"] == "") {
return fmt.Errorf("encryption using the CUSTOMER_MANAGED_CMK option requires kms_key_arn specified")
}
}
}

return nil
}

Expand Down Expand Up @@ -2335,6 +2388,7 @@ func resourceAwsKinesisFirehoseDeliveryStreamUpdate(d *schema.ResourceData, meta

if d.HasChange("server_side_encryption") {
_, n := d.GetChange("server_side_encryption")
newOptions := getOptionsOfConfigurationUnit(n)
if isKinesisFirehoseDeliveryStreamOptionDisabled(n) {
_, err := conn.StopDeliveryStreamEncryption(&firehose.StopDeliveryStreamEncryptionInput{
DeliveryStreamName: aws.String(sn),
Expand All @@ -2347,15 +2401,27 @@ func resourceAwsKinesisFirehoseDeliveryStreamUpdate(d *schema.ResourceData, meta
return fmt.Errorf("error waiting for Kinesis Firehose Delivery Stream (%s) encryption to be disabled: %s", sn, err)
}
} else {
_, err := conn.StartDeliveryStreamEncryption(&firehose.StartDeliveryStreamEncryptionInput{
startInput := &firehose.StartDeliveryStreamEncryptionInput{
DeliveryStreamName: aws.String(sn),
})
}
startInput.DeliveryStreamEncryptionConfigurationInput =
&firehose.DeliveryStreamEncryptionConfigurationInput{}
startInput.DeliveryStreamEncryptionConfigurationInput.KeyType =
aws.String(newOptions["kms_key_type"].(string))
if newOptions["kms_key_type"] != firehose.KeyTypeAwsOwnedCmk {
startInput.DeliveryStreamEncryptionConfigurationInput.KeyARN =
aws.String(newOptions["kms_key_arn"].(string))
}
_, err := conn.StartDeliveryStreamEncryption(startInput)

if err != nil {
return fmt.Errorf("error starting Kinesis Firehose Delivery Stream (%s) encryption: %s", sn, err)
return fmt.Errorf(
"error starting Kinesis Firehose Delivery Stream (%s) encryption: %s", sn, err)
}

if err := waitForKinesisFirehoseDeliveryStreamSSEEnabled(conn, sn); err != nil {
return fmt.Errorf("error waiting for Kinesis Firehose Delivery Stream (%s) encryption to be enabled: %s", sn, err)
return fmt.Errorf("error waiting for Kinesis Firehose Delivery Stream (%s) "+
"encryption to be enabled: %s", sn, err)
}
}
}
Expand Down Expand Up @@ -2511,17 +2577,22 @@ func waitForKinesisFirehoseDeliveryStreamSSEDisabled(conn *firehose.Firehose, de
}

func isKinesisFirehoseDeliveryStreamOptionDisabled(v interface{}) bool {
options := v.([]interface{})
if len(options) == 0 || options[0] == nil {
return true
}
m := options[0].(map[string]interface{})
optionMap := getOptionsOfConfigurationUnit(v)

var enabled bool

if v, ok := m["enabled"]; ok {
if v, ok := optionMap["enabled"]; ok {
enabled = v.(bool)
}

return !enabled
}

// helper to get options of a unit
func getOptionsOfConfigurationUnit(v interface{}) map[string]interface{} {
options := v.([]interface{})
if len(options) == 0 || options[0] == nil {
return nil
}
return options[0].(map[string]interface{})
}
92 changes: 82 additions & 10 deletions aws/resource_aws_kinesis_firehose_delivery_stream_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,36 +192,69 @@ func TestAccAWSKinesisFirehoseDeliveryStream_s3basicWithSSE(t *testing.T) {
CheckDestroy: testAccCheckKinesisFirehoseDeliveryStreamDestroy,
Steps: []resource.TestStep{
{
Config: testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSE(rName, rInt, true),
Config: testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSE(rName, rInt, false, ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckKinesisFirehoseDeliveryStreamExists(resourceName, &stream),
testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil, nil, nil),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.#", "1"),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.0.enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.0.enabled", "false"),
),
},
{
Config: testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSE(rName, rInt, false),
Config: config,
PlanOnly: true,
},
{
Config: testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSE(rName, rInt, true, "AWS_OWNED_CMK"),
Check: resource.ComposeTestCheckFunc(
testAccCheckKinesisFirehoseDeliveryStreamExists(resourceName, &stream),
testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil, nil, nil),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.#", "1"),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.0.enabled", "false"),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.0.enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.0.kms_key_type", "AWS_OWNED_CMK"),
),
},
},
})
}

func TestAccAWSKinesisFirehoseDeliveryStream_s3basicWithSSEAndCMK(t *testing.T) {
var stream firehose.DeliveryStreamDescription
rInt := acctest.RandInt()
rName := fmt.Sprintf("terraform-kinesis-firehose-basictest-%d", rInt)
config := fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamConfig_s3basic,
rInt, rInt, rInt, rInt) + testAccKinesisFirehoseDeliveryStreamKmsKeyConfig(rName)
resourceName := "aws_kinesis_firehose_delivery_stream.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckKinesisFirehoseDeliveryStreamDestroy,
Steps: []resource.TestStep{
{
Config: config,
PlanOnly: true,
Config: testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSEAndCMK(rName, rInt, true, "CUSTOMER_MANAGED_CMK"),
Check: resource.ComposeTestCheckFunc(
testAccCheckKinesisFirehoseDeliveryStreamExists(resourceName, &stream),
testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil, nil, nil),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.#", "1"),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.0.enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.0.kms_key_type", "CUSTOMER_MANAGED_CMK"),
resource.TestCheckResourceAttrPair(resourceName, "server_side_encryption.0.kms_key_arn", "aws_kms_key.fh_test", "arn"),
),
},
{
Config: testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSE(rName, rInt, true),
Config: testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSEAndCMK(rName, rInt, false, ""),
Check: resource.ComposeTestCheckFunc(
testAccCheckKinesisFirehoseDeliveryStreamExists(resourceName, &stream),
testAccCheckAWSKinesisFirehoseDeliveryStreamAttributes(&stream, nil, nil, nil, nil, nil),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.#", "1"),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.0.enabled", "true"),
resource.TestCheckResourceAttr(resourceName, "server_side_encryption.0.enabled", "false"),
),
},
{
Config: config,
PlanOnly: true,
},
},
})
}
Expand Down Expand Up @@ -1800,8 +1833,39 @@ resource "aws_kinesis_firehose_delivery_stream" "test" {
}
`

func testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSE(rName string, rInt int, sseEnabled bool) string {
func testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSE(rName string, rInt int, sseEnabled bool, kmsType string) string {
kmsConfiguration := ""
if kmsType == firehose.KeyTypeAwsOwnedCmk {
kmsConfiguration = fmt.Sprintf(`kms_key_type = "%s"`, firehose.KeyTypeAwsOwnedCmk)
}
return fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamBaseConfig, rInt, rInt, rInt) +
fmt.Sprintf(`
resource "aws_kinesis_firehose_delivery_stream" "test" {
depends_on = [aws_iam_role_policy.firehose]
name = "%s"
destination = "s3"
s3_configuration {
role_arn = aws_iam_role.firehose.arn
bucket_arn = aws_s3_bucket.bucket.arn
}
server_side_encryption {
enabled = %t
%s
}
}
`, rName, sseEnabled, kmsConfiguration)
}

func testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithSSEAndCMK(rName string, rInt int, sseEnabled bool, kmsType string) string {
kmsConfiguration := ""
if kmsType == firehose.KeyTypeCustomerManagedCmk {
kmsConfiguration = fmt.Sprintf(`kms_key_type = "%s"
kms_key_arn = "${aws_kms_key.fh_test.arn}"`, kmsType)
}
return fmt.Sprintf(testAccKinesisFirehoseDeliveryStreamBaseConfig, rInt, rInt, rInt) +
testAccKinesisFirehoseDeliveryStreamKmsKeyConfig(rName) +
fmt.Sprintf(`
resource "aws_kinesis_firehose_delivery_stream" "test" {
depends_on = [aws_iam_role_policy.firehose]
Expand All @@ -1815,9 +1879,17 @@ resource "aws_kinesis_firehose_delivery_stream" "test" {
server_side_encryption {
enabled = %t
%s
}
}
`, rName, sseEnabled)
`, rName, sseEnabled, kmsConfiguration)
}

func testAccKinesisFirehoseDeliveryStreamKmsKeyConfig(rName string) string {
return fmt.Sprintf(`
resource "aws_kms_key" "fh_test" {
description = "Terraform acc test %s"
}`, rName)
}

func testAccKinesisFirehoseDeliveryStreamConfig_s3basicWithTags(rName string, rInt int) string {
Expand Down
2 changes: 2 additions & 0 deletions website/docs/r/kinesis_firehose_delivery_stream.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ The `kinesis_source_configuration` object supports the following:
The `server_side_encryption` object supports the following:

* `enabled` - (Optional) Whether to enable encryption at rest. Default is `false`.
* `kms_key_type`- (Required, when `enabled` is `true`) The type of encryption. Valid values are `AWS_OWNED_CMK` and `CUSTOMER_MANAGED_CMK`
* `kms_key_arn` - (Required, when `kms_key_type` is `CUSTOMER_MANAGED_CMK`) The ARN of the key used for encryption.

The `s3_configuration` object supports the following:

Expand Down

0 comments on commit 212b6dd

Please sign in to comment.