Repository: cloud-custodian/cloud-custodian

Issue:
Add support for Kinesis Firehose destination encryption
This one is a bit tricky, in that there are multiple possible types of destinations, each requiring a different KMS key.


Discussion:

Resolving patch:
diff --git a/c7n/resources/kinesis.py b/c7n/resources/kinesis.py
--- a/c7n/resources/kinesis.py
+++ b/c7n/resources/kinesis.py
@@ -13,6 +13,8 @@
 # limitations under the License.
 from __future__ import absolute_import, division, print_function, unicode_literals
 
+import jmespath
+
 from c7n.actions import Action
 from c7n.manager import resources
 from c7n.query import QueryResourceManager
@@ -127,6 +129,90 @@ def process(self, resources):
                 DeliveryStreamName=r['DeliveryStreamName'])
 
 
+@DeliveryStream.action_registry.register('encrypt-s3-destination')
+class FirehoseEncryptS3Destination(Action):
+    """Action to set encryption key a Firehose S3 destination
+
+    :example:
+
+    .. code-block:: yaml
+
+            policies:
+              - name: encrypt-s3-destination
+                resource: firehose
+                filters:
+                  - KmsMasterKeyId: absent
+                actions:
+                  - type: encrypt-s3-destination
+                    key_arn: <arn of KMS key/alias>
+    """
+    schema = type_schema(
+        'encrypt-s3-destination',
+        key_arn={'type': 'string'}, required=('key_arn',))
+
+    permissions = ("firehose:UpdateDestination",)
+
+    DEST_MD = {
+        'SplunkDestinationDescription': {
+            'update': 'SplunkDestinationUpdate',
+            'clear': ['S3BackupMode'],
+            'encrypt_path': 'S3DestinationDescription.EncryptionConfiguration',
+            'remap': [('S3DestinationDescription', 'S3Update')]
+        },
+        'ElasticsearchDestinationDescription': {
+            'update': 'ElasticsearchDestinationUpdate',
+            'clear': ['S3BackupMode'],
+            'encrypt_path': 'S3DestinationDescription.EncryptionConfiguration',
+            'remap': [('S3DestinationDescription', 'S3Update')],
+        },
+        'ExtendedS3DestinationDescription': {
+            'update': 'ExtendedS3DestinationUpdate',
+            'clear': ['S3BackupMode'],
+            'encrypt_path': 'EncryptionConfiguration',
+            'remap': []
+        },
+        'RedshiftDestinationDescription': {
+            'update': 'RedshiftDestinationUpdate',
+            'clear': ['S3BackupMode', "ClusterJDBCURL", "CopyCommand", "Username"],
+            'encrypt_path': 'S3DestinationDescription.EncryptionConfiguration',
+            'remap': [('S3DestinationDescription', 'S3Update')]
+        },
+    }
+
+    def process(self, resources):
+        client = local_session(self.manager.session_factory).client('firehose')
+        key = self.data.get('key_arn')
+        for r in resources:
+            if not r['DeliveryStreamStatus'] == 'ACTIVE':
+                continue
+            version = r['VersionId']
+            name = r['DeliveryStreamName']
+            d = r['Destinations'][0]
+            destination_id = d['DestinationId']
+
+            for dtype, dmetadata in self.DEST_MD.items():
+                if dtype not in d:
+                    continue
+                dinfo = d[dtype]
+                for k in dmetadata['clear']:
+                    dinfo.pop(k, None)
+                if dmetadata['encrypt_path']:
+                    encrypt_info = jmespath.search(dmetadata['encrypt_path'], dinfo)
+                else:
+                    encrypt_info = dinfo
+                encrypt_info.pop('NoEncryptionConfig', None)
+                encrypt_info['KMSEncryptionConfig'] = {'AWSKMSKeyARN': key}
+
+                for old_k, new_k in dmetadata['remap']:
+                    if old_k in dinfo:
+                        dinfo[new_k] = dinfo.pop(old_k)
+                params = dict(DeliveryStreamName=name,
+                              DestinationId=destination_id,
+                              CurrentDeliveryStreamVersionId=version)
+                params[dmetadata['update']] = dinfo
+                client.update_destination(**params)
+
+
 @resources.register('kinesis-analytics')
 class AnalyticsApp(QueryResourceManager):
 


Test patch:
diff --git a/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-es", 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "185c72e8-1500-4e1b-8c3d-b788c467680d", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "185c72e8-1500-4e1b-8c3d-b788c467680d", 
+                "x-amz-id-2": "lf6igO0A1YstLI4QO7E04pkr5Q8CW2PlAKfyL9pBc9FsdL8FUIzBU4HYERnzptTxT5huZUfTjXmxt8M9GuBlknX8aj/+y5RY", 
+                "content-length": "90", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 11:03:22 GMT"
+            }
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json
@@ -0,0 +1,73 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "62194a84-62ce-4325-90b1-3139f7bcb726", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "62194a84-62ce-4325-90b1-3139f7bcb726", 
+                "x-amz-id-2": "D5QGHel9NOsRFFWiGRgrqxbWw6iczZjH3FtVi2tqwzZyJRtbh3dzp2c5/h0btNyQQwO+K7uaQzldMP0g9mqQQ/6g+VSx8ag+", 
+                "content-length": "1131", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 11:03:22 GMT"
+            }
+        }, 
+        "DeliveryStreamDescription": {
+            "DeliveryStreamType": "DirectPut", 
+            "HasMoreDestinations": false, 
+            "VersionId": "1", 
+            "CreateTimestamp": {
+                "hour": 7, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 22, 
+                "microsecond": 858000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 3
+            }, 
+            "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-es", 
+            "DeliveryStreamStatus": "ACTIVE", 
+            "DeliveryStreamName": "firehose-es", 
+            "Destinations": [
+                {
+                    "DestinationId": "destinationId-000000000001", 
+                    "ElasticsearchDestinationDescription": {
+                        "IndexName": "my-index", 
+                        "RetryOptions": {
+                            "DurationInSeconds": 300
+                        }, 
+                        "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                        "BufferingHints": {
+                            "IntervalInSeconds": 300, 
+                            "SizeInMBs": 5
+                        }, 
+                        "TypeName": "firehose", 
+                        "S3BackupMode": "FailedDocumentsOnly", 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }, 
+                        "DomainARN": "arn:aws:es:us-east-1:123456789:domain/this-es", 
+                        "S3DestinationDescription": {
+                            "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                            "BufferingHints": {
+                                "IntervalInSeconds": 300, 
+                                "SizeInMBs": 5
+                            }, 
+                            "EncryptionConfiguration": {
+                                "NoEncryptionConfig": "NoEncryption"
+                            }, 
+                            "CompressionFormat": "UNCOMPRESSED", 
+                            "CloudWatchLoggingOptions": {
+                                "Enabled": false
+                            }, 
+                            "BucketARN": "arn:aws:s3:::this-bucket"
+                        }, 
+                        "IndexRotationPeriod": "OneDay"
+                    }
+                }
+            ]
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json
@@ -0,0 +1,85 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "4e8d8ccf-2944-4cda-842a-c9f378f543b7", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "4e8d8ccf-2944-4cda-842a-c9f378f543b7", 
+                "x-amz-id-2": "oxrgC58fVQJQ1/Cpgogam55C4vg7bRRMOnfChcJxvrgjjrnqV8mWf1pLMhZodctToJ8Nub/11sSnwEAF9iIInvn1duHVWI6P", 
+                "content-length": "1221", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 11:07:03 GMT"
+            }
+        }, 
+        "DeliveryStreamDescription": {
+            "DeliveryStreamType": "DirectPut", 
+            "HasMoreDestinations": false, 
+            "LastUpdateTimestamp": {
+                "hour": 7, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 42, 
+                "microsecond": 15000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 6
+            }, 
+            "VersionId": "2", 
+            "CreateTimestamp": {
+                "hour": 7, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 22, 
+                "microsecond": 858000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 3
+            }, 
+            "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-es", 
+            "DeliveryStreamStatus": "ACTIVE", 
+            "DeliveryStreamName": "firehose-es", 
+            "Destinations": [
+                {
+                    "DestinationId": "destinationId-000000000001", 
+                    "ElasticsearchDestinationDescription": {
+                        "IndexName": "my-index", 
+                        "RetryOptions": {
+                            "DurationInSeconds": 300
+                        }, 
+                        "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                        "BufferingHints": {
+                            "IntervalInSeconds": 300, 
+                            "SizeInMBs": 5
+                        }, 
+                        "TypeName": "firehose", 
+                        "S3BackupMode": "FailedDocumentsOnly", 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }, 
+                        "DomainARN": "arn:aws:es:us-east-1:123456789:domain/this-es", 
+                        "S3DestinationDescription": {
+                            "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                            "BufferingHints": {
+                                "IntervalInSeconds": 300, 
+                                "SizeInMBs": 5
+                            }, 
+                            "EncryptionConfiguration": {
+                                "KMSEncryptionConfig": {
+                                    "AWSKMSKeyARN": "arn:aws:kms:us-east-1:123456789:alias/aws/s3"
+                                }
+                            }, 
+                            "CompressionFormat": "UNCOMPRESSED", 
+                            "CloudWatchLoggingOptions": {
+                                "Enabled": false
+                            }, 
+                            "BucketARN": "arn:aws:s3:::this-bucket"
+                        }, 
+                        "IndexRotationPeriod": "OneDay"
+                    }
+                }
+            ]
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json
@@ -0,0 +1,21 @@
+{
+    "status_code": 200, 
+    "data": {
+        "DeliveryStreamNames": [
+            "firehose-es"
+       ], 
+        "HasMoreDeliveryStreams": true, 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "864a5447-330a-4bff-8154-1d1a42c1bfdb", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "864a5447-330a-4bff-8154-1d1a42c1bfdb", 
+                "x-amz-id-2": "bgkSp4T+GGOME4SQcJdM+FL9Iyk6JyfZO9X6FG1s2NGkPC8nnVYOXVFBsYwG7W1xQ41A1DpGt1WXLoIUYewP1eKOOKWIIuh1", 
+                "content-length": "178", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 11:03:22 GMT"
+            }
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.UpdateDestination_1.json b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.UpdateDestination_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_elasticsearch_encrypt_s3_destination/firehose.UpdateDestination_1.json
@@ -0,0 +1,17 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "f254d2be-c2ae-4966-844e-55a9884424b8", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "f254d2be-c2ae-4966-844e-55a9884424b8", 
+                "x-amz-id-2": "6VoN2a/V1irZemnpcJ/o/LxU56uHbTs2ckMKT95zKAt/VZMc3jne+28u3jS3obLq5U8GJadbyb7DAaGu0KWlPWARquVDWS90", 
+                "content-length": "2", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 13:25:41 GMT"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-s3", 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "0ed5acef-a773-4508-8d10-b81f7806f681", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "0ed5acef-a773-4508-8d10-b81f7806f681", 
+                "x-amz-id-2": "//QjC0Ku7VvDsFo00dXUvkm6D3OE52ASVKJwc1qdy35zCWKK8qjwqHZSRtYSBdY4FSQchZzCEZgBg+eC4C11073eVgj5FbuY", 
+                "content-length": "90", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 09:40:17 GMT"
+            }
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json
@@ -0,0 +1,71 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "742a7504-923c-42c2-997b-f4fdc93e3b43", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "742a7504-923c-42c2-997b-f4fdc93e3b43", 
+                "x-amz-id-2": "ATheZNYuo1npTHs5ygPYuCtK+2F5WTNNjERyklXhj7ZCK10FuULaybasmxC/xxdbmUvisC0CRtaxaGgbHL0eM9gn5wq+w131", 
+                "content-length": "1065", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 09:40:17 GMT"
+            }
+        }, 
+        "DeliveryStreamDescription": {
+            "DeliveryStreamType": "DirectPut", 
+            "HasMoreDestinations": false, 
+            "VersionId": "1", 
+            "CreateTimestamp": {
+                "hour": 5, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 17, 
+                "microsecond": 694000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 40
+            }, 
+            "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-s3", 
+            "DeliveryStreamStatus": "ACTIVE", 
+            "DeliveryStreamName": "firehose-s3", 
+            "Destinations": [
+                {
+                    "DestinationId": "destinationId-000000000001", 
+                    "ExtendedS3DestinationDescription": {
+                        "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                        "BufferingHints": {
+                            "IntervalInSeconds": 300, 
+                            "SizeInMBs": 5
+                        }, 
+                        "EncryptionConfiguration": {
+                            "NoEncryptionConfig": "NoEncryption"
+                        }, 
+                        "CompressionFormat": "UNCOMPRESSED", 
+                        "S3BackupMode": "Disabled", 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }, 
+                        "BucketARN": "arn:aws:s3:::this-bucket"
+                    }, 
+                    "S3DestinationDescription": {
+                        "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                        "BufferingHints": {
+                            "IntervalInSeconds": 300, 
+                            "SizeInMBs": 5
+                        }, 
+                        "EncryptionConfiguration": {
+                            "NoEncryptionConfig": "NoEncryption"
+                        }, 
+                        "CompressionFormat": "UNCOMPRESSED", 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }, 
+                        "BucketARN": "arn:aws:s3:::this-bucket"
+                    }
+                }
+            ]
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json
@@ -0,0 +1,85 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "43cd96ac-35e0-4fcc-ae25-baab81e909db", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "43cd96ac-35e0-4fcc-ae25-baab81e909db", 
+                "x-amz-id-2": "XWC0VQCh6CBHRqvq8FffEHfD3JV2XyjpBqqVHYPzJAsp5JoBC7mzSa+JRJu38CSEGk/Hexsf+0HRdCI0ctD7FBHbr/KvPKi3", 
+                "content-length": "1208", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 09:55:43 GMT"
+            }
+        }, 
+        "DeliveryStreamDescription": {
+            "DeliveryStreamType": "DirectPut", 
+            "HasMoreDestinations": false, 
+            "LastUpdateTimestamp": {
+                "hour": 5, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 39, 
+                "microsecond": 301000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 54
+            }, 
+            "VersionId": "2", 
+            "CreateTimestamp": {
+                "hour": 5, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 17, 
+                "microsecond": 694000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 40
+            }, 
+            "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-s3", 
+            "DeliveryStreamStatus": "ACTIVE", 
+            "DeliveryStreamName": "firehose-s3", 
+            "Destinations": [
+                {
+                    "DestinationId": "destinationId-000000000001", 
+                    "ExtendedS3DestinationDescription": {
+                        "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                        "BufferingHints": {
+                            "IntervalInSeconds": 300, 
+                            "SizeInMBs": 5
+                        },
+                        "EncryptionConfiguration": {
+                            "KMSEncryptionConfig": {
+                                "AWSKMSKeyARN": "arn:aws:kms:us-east-1:123456789:alias/aws/s3"
+                            }
+                        }, 
+                        "CompressionFormat": "UNCOMPRESSED", 
+                        "S3BackupMode": "Disabled", 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }, 
+                        "BucketARN": "arn:aws:s3:::this-bucket"
+                    }, 
+                    "S3DestinationDescription": {
+                        "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                        "BufferingHints": {
+                            "IntervalInSeconds": 300, 
+                            "SizeInMBs": 5
+                        }, 
+                        "EncryptionConfiguration": {
+                            "KMSEncryptionConfig": {
+                                "AWSKMSKeyARN": "arn:aws:kms:us-east-1:123456789:alias/aws/s3"
+                            }
+                        }, 
+                        "CompressionFormat": "UNCOMPRESSED", 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }, 
+                        "BucketARN": "arn:aws:s3:::this-bucket"
+                    }
+                }
+            ]
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json
@@ -0,0 +1,21 @@
+{
+    "status_code": 200, 
+    "data": {
+        "DeliveryStreamNames": [
+            "firehose-s3"
+       ], 
+        "HasMoreDeliveryStreams": true, 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "e4746b0b-95d8-4858-bef9-6df7e02c1acb", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "e4746b0b-95d8-4858-bef9-6df7e02c1acb", 
+                "x-amz-id-2": "KGF8lrYZGw9EmwXwZVr87GPe8xswnqHcC9hz4TiIagUpr7AVhDgpo3sSAsFUK6WUcLjqpTPJaMxhAOcotn6nsv6DBnL2z7KX", 
+                "content-length": "164", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 09:40:17 GMT"
+            }
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.UpdateDestination_1.json b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.UpdateDestination_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_ext_s3_encrypt_s3_destination/firehose.UpdateDestination_1.json
@@ -0,0 +1,17 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "f254d2be-c2ae-4966-844e-55a9884424b8", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "f254d2be-c2ae-4966-844e-55a9884424b8", 
+                "x-amz-id-2": "6VoN2a/V1irZemnpcJ/o/LxU56uHbTs2ckMKT95zKAt/VZMc3jne+28u3jS3obLq5U8GJadbyb7DAaGu0KWlPWARquVDWS90", 
+                "content-length": "2", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 13:25:41 GMT"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-rs", 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "49f7b113-bcb9-4ece-8b3b-bc31ccc3fddb", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "49f7b113-bcb9-4ece-8b3b-bc31ccc3fddb", 
+                "x-amz-id-2": "rcdUh+w9bJyH7AW9HC3OSz4+Hs03BjyFm4xB8NuT2dA1GcvZb13vEqLOzCfwwXuD4VlChT20RPo3jwr41nMv4GJ5APfh5e8N", 
+                "content-length": "90", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 11:16:46 GMT"
+            }
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json
@@ -0,0 +1,72 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "77473e02-963b-435c-a870-b9beebd45a87", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "77473e02-963b-435c-a870-b9beebd45a87", 
+                "x-amz-id-2": "5ohkdbG6gm+UZKn28QviYDQUVVyBZ+wRplycHXvefpCZ2XqfMl6MT0N5B90CqK+xsekorNx0Rc0EbLQkrjZg4rYgpoiZF+CC", 
+                "content-length": "1122", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 11:16:46 GMT"
+            }
+        }, 
+        "DeliveryStreamDescription": {
+            "DeliveryStreamType": "DirectPut", 
+            "HasMoreDestinations": false, 
+            "VersionId": "1", 
+            "CreateTimestamp": {
+                "hour": 7, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 47, 
+                "microsecond": 512000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 16
+            }, 
+            "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-rs", 
+            "DeliveryStreamStatus": "ACTIVE", 
+            "DeliveryStreamName": "firehose-rs", 
+            "Destinations": [
+                {
+                    "DestinationId": "destinationId-000000000001", 
+                    "RedshiftDestinationDescription": {
+                        "Username": "test1234", 
+                        "S3DestinationDescription": {
+                            "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                            "BufferingHints": {
+                                "IntervalInSeconds": 300, 
+                                "SizeInMBs": 5
+                            }, 
+                            "EncryptionConfiguration": {
+                                "NoEncryptionConfig": "NoEncryption"
+                            }, 
+                            "CompressionFormat": "UNCOMPRESSED", 
+                            "CloudWatchLoggingOptions": {
+                                "Enabled": false
+                            }, 
+                            "BucketARN": "arn:aws:s3:::this-bucket"
+                        }, 
+                        "RetryOptions": {
+                            "DurationInSeconds": 3600
+                        }, 
+                        "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                        "ClusterJDBCURL": "jdbc:redshift://my-redshift-db.asdf.us-west-2.redshift.amazonaws.com:5432/mydb", 
+                        "CopyCommand": {
+                            "DataTableName": "mytable", 
+                            "CopyOptions": "JSON", 
+                            "DataTableColumns": "mycol"
+                        }, 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }, 
+                        "S3BackupMode": "Disabled"
+                    }
+                }
+            ]
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json
@@ -0,0 +1,74 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "5211a241-4aff-43a1-8a7c-695410ac8cfc", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "5211a241-4aff-43a1-8a7c-695410ac8cfc", 
+                "x-amz-id-2": "bRlQeOOJ/ApuIV0hDyQkm8Fs5+b3CF9p1Hs1AqTSLW24w/lr4kQ/lgmnsTEjt142UOFy2y7LY3pBRURLIfm+rTrrRIJq8vWj", 
+                "content-length": "1122", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 11:16:54 GMT"
+            }
+        }, 
+        "DeliveryStreamDescription": {
+            "DeliveryStreamType": "DirectPut", 
+            "HasMoreDestinations": false, 
+            "VersionId": "1", 
+            "CreateTimestamp": {
+                "hour": 7, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 47, 
+                "microsecond": 512000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 16
+            }, 
+            "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-rs", 
+            "DeliveryStreamStatus": "CREATING", 
+            "DeliveryStreamName": "firehose-rs", 
+            "Destinations": [
+                {
+                    "DestinationId": "destinationId-000000000001", 
+                    "RedshiftDestinationDescription": {
+                        "Username": "test1234", 
+                        "S3DestinationDescription": {
+                            "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                            "BufferingHints": {
+                                "IntervalInSeconds": 300, 
+                                "SizeInMBs": 5
+                            }, 
+                            "EncryptionConfiguration": {
+                                "KMSEncryptionConfig": {
+                                    "AWSKMSKeyARN": "arn:aws:kms:us-east-1:123456789:alias/aws/s3"
+                                }
+                            }, 
+                            "CompressionFormat": "UNCOMPRESSED", 
+                            "CloudWatchLoggingOptions": {
+                                "Enabled": false
+                            }, 
+                            "BucketARN": "arn:aws:s3:::this-bucket"
+                        }, 
+                        "RetryOptions": {
+                            "DurationInSeconds": 3600
+                        }, 
+                        "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                        "ClusterJDBCURL": "jdbc:redshift://my-redshift-db.asdf.us-west-2.redshift.amazonaws.com:5432/mydb", 
+                        "CopyCommand": {
+                            "DataTableName": "mytable", 
+                            "CopyOptions": "JSON", 
+                            "DataTableColumns": "mycol"
+                        }, 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }, 
+                        "S3BackupMode": "Disabled"
+                    }
+                }
+            ]
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json
@@ -0,0 +1,21 @@
+{
+    "status_code": 200, 
+    "data": {
+        "DeliveryStreamNames": [
+           "firehose-rs"
+       ], 
+        "HasMoreDeliveryStreams": true, 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "725031f1-606d-47e8-9ddc-db57f311805a", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "725031f1-606d-47e8-9ddc-db57f311805a", 
+                "x-amz-id-2": "HVPMnw1dx8Y5zdRhEsHKvsiqueSfqzhXLyWvy68aj43Xm9oNHhM7NSjq7WuSSmbWTAKF0e7EY3vyJ4rCLEVE+C6knBQuqZ2a", 
+                "content-length": "183", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 11:16:46 GMT"
+            }
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.UpdateDestination_1.json b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.UpdateDestination_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_redshift_encrypt_s3_destination/firehose.UpdateDestination_1.json
@@ -0,0 +1,17 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "f254d2be-c2ae-4966-844e-55a9884424b8", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "f254d2be-c2ae-4966-844e-55a9884424b8", 
+                "x-amz-id-2": "6VoN2a/V1irZemnpcJ/o/LxU56uHbTs2ckMKT95zKAt/VZMc3jne+28u3jS3obLq5U8GJadbyb7DAaGu0KWlPWARquVDWS90", 
+                "content-length": "2", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 13:25:41 GMT"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.CreateDeliveryStream_1.json
@@ -0,0 +1,18 @@
+{
+    "status_code": 200, 
+    "data": {
+        "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-splunk", 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "8a33cab2-ab49-499c-9db5-25d05e896055", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "8a33cab2-ab49-499c-9db5-25d05e896055", 
+                "x-amz-id-2": "XR19XBtDNlXuRfs1uIbxoPYEvU0U3DFxcWSgMlvnqeKgobGRp1L1EJ7pF46ichrys8HgJDy69UPm3NahBf5DtPo/M31op6ve", 
+                "content-length": "94", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 10:17:14 GMT"
+            }
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.DescribeDeliveryStream_1.json
@@ -0,0 +1,68 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "05bb73e0-8fb8-4b08-9529-53223cf25213", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "05bb73e0-8fb8-4b08-9529-53223cf25213", 
+                "x-amz-id-2": "ObogldPeE61Uh6lEztZ3isLgaAKt/RjYROfs2adHrlYOzt5jTVIbmLG2ce4ugWo8bMnIhTNj4OYa+sLF01WA8s9lBMghz6ab", 
+                "content-length": "1016", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 10:17:14 GMT"
+            }
+        }, 
+        "DeliveryStreamDescription": {
+            "DeliveryStreamType": "DirectPut", 
+            "HasMoreDestinations": false, 
+            "VersionId": "1", 
+            "CreateTimestamp": {
+                "hour": 6, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 15, 
+                "microsecond": 31000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 17
+            }, 
+            "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-splunk", 
+            "DeliveryStreamStatus": "ACTIVE", 
+            "DeliveryStreamName": "firehose-splunk", 
+            "Destinations": [
+                {
+                    "DestinationId": "destinationId-000000000001", 
+                    "SplunkDestinationDescription": {
+                        "S3DestinationDescription": {
+                            "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                            "BufferingHints": {
+                                "IntervalInSeconds": 300, 
+                                "SizeInMBs": 5
+                            }, 
+                            "EncryptionConfiguration": {
+                                "NoEncryptionConfig": "NoEncryption"
+                            }, 
+                            "CompressionFormat": "UNCOMPRESSED", 
+                            "CloudWatchLoggingOptions": {
+                                "Enabled": false
+                            }, 
+                            "BucketARN": "arn:aws:s3:::this-bucket"
+                        }, 
+                        "HECEndpointType": "Event", 
+                        "HECToken": "12345678-1234-1234-1234-1234567890AB", 
+                        "HECAcknowledgmentTimeoutInSeconds": 180, 
+                        "RetryOptions": {
+                            "DurationInSeconds": 300
+                        }, 
+                        "HECEndpoint": "https://www.mysplunk.com", 
+                        "S3BackupMode": "FailedEventsOnly", 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }
+                    }
+                }
+            ]
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.DescribeDeliveryStream_2.json
@@ -0,0 +1,80 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "d3881e95-b820-4949-bc2b-8db2fb5e87a9", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "d3881e95-b820-4949-bc2b-8db2fb5e87a9", 
+                "x-amz-id-2": "cwx3n4ArrheeUFIp/RsRiTC5Ih3xnd0v3a4CTd0d+Th2D4ARH+oHEGqJhLwVoobc/FfFNhqRHzq+pTu4gHgYbexmKnPfZlEM", 
+                "content-length": "1106", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 10:51:25 GMT"
+            }
+        }, 
+        "DeliveryStreamDescription": {
+            "DeliveryStreamType": "DirectPut", 
+            "HasMoreDestinations": false, 
+            "LastUpdateTimestamp": {
+                "hour": 6, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 47, 
+                "microsecond": 386000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 50
+            }, 
+            "VersionId": "2", 
+            "CreateTimestamp": {
+                "hour": 6, 
+                "__class__": "datetime", 
+                "month": 8, 
+                "second": 15, 
+                "microsecond": 31000, 
+                "year": 2018, 
+                "day": 15, 
+                "minute": 17
+            }, 
+            "DeliveryStreamARN": "arn:aws:firehose:us-east-1:123456789:deliverystream/firehose-splunk", 
+            "DeliveryStreamStatus": "ACTIVE", 
+            "DeliveryStreamName": "firehose-splunk", 
+            "Destinations": [
+                {
+                    "DestinationId": "destinationId-000000000001", 
+                    "SplunkDestinationDescription": {
+                        "S3DestinationDescription": {
+                            "RoleARN": "arn:aws:iam::123456789:role/firehose_delivery_role", 
+                            "BufferingHints": {
+                                "IntervalInSeconds": 300, 
+                                "SizeInMBs": 5
+                            }, 
+                            "EncryptionConfiguration": {
+                                "KMSEncryptionConfig": {
+                                    "AWSKMSKeyARN": "arn:aws:kms:us-east-1:123456789:alias/aws/s3"
+                                }
+                            }, 
+                            "CompressionFormat": "UNCOMPRESSED", 
+                            "CloudWatchLoggingOptions": {
+                                "Enabled": false
+                            }, 
+                            "BucketARN": "arn:aws:s3:::this-bucket"
+                        }, 
+                        "HECEndpointType": "Event", 
+                        "HECToken": "12345678-1234-1234-1234-1234567890AB", 
+                        "HECAcknowledgmentTimeoutInSeconds": 180, 
+                        "RetryOptions": {
+                            "DurationInSeconds": 300
+                        }, 
+                        "HECEndpoint": "https://www.mysplunk.com", 
+                        "S3BackupMode": "FailedEventsOnly", 
+                        "CloudWatchLoggingOptions": {
+                            "Enabled": false
+                        }
+                    }
+                }
+            ]
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.ListDeliveryStreams_1.json
@@ -0,0 +1,21 @@
+{
+    "status_code": 200, 
+    "data": {
+        "DeliveryStreamNames": [
+            "firehose-splunk" 
+        ], 
+        "HasMoreDeliveryStreams": true, 
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "531b176a-732f-44ad-8960-e0201ae79f8c", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "531b176a-732f-44ad-8960-e0201ae79f8c", 
+                "x-amz-id-2": "/xKsdsaKFMwevAELFoTcr4LVF9Fi5yxwoDmM/IPvXStJWoxl6heECuLHzQuV8eEJrDDc3VCGtUB65+SaV0odNWfcpCdY9YZu", 
+                "content-length": "173", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 10:17:14 GMT"
+            }
+        }
+    }
+}
diff --git a/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.UpdateDestination_1.json b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.UpdateDestination_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_firehose_splunk_encrypt_s3_destination/firehose.UpdateDestination_1.json
@@ -0,0 +1,17 @@
+{
+    "status_code": 200, 
+    "data": {
+        "ResponseMetadata": {
+            "RetryAttempts": 0, 
+            "HTTPStatusCode": 200, 
+            "RequestId": "f254d2be-c2ae-4966-844e-55a9884424b8", 
+            "HTTPHeaders": {
+                "x-amzn-requestid": "f254d2be-c2ae-4966-844e-55a9884424b8", 
+                "x-amz-id-2": "6VoN2a/V1irZemnpcJ/o/LxU56uHbTs2ckMKT95zKAt/VZMc3jne+28u3jS3obLq5U8GJadbyb7DAaGu0KWlPWARquVDWS90", 
+                "content-length": "2", 
+                "content-type": "application/x-amz-json-1.1", 
+                "date": "Wed, 15 Aug 2018 13:25:41 GMT"
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/test_kinesis.py b/tests/test_kinesis.py
--- a/tests/test_kinesis.py
+++ b/tests/test_kinesis.py
@@ -85,14 +85,14 @@ def test_hose_query(self):
         self.assertEqual(len(resources), 1)
         self.assertEqual(resources[0]["DeliveryStreamStatus"], "ACTIVE")
 
-    def test_hose_delete(self):
+    def test_firehose_delete(self):
         factory = self.replay_flight_data("test_kinesis_hose_delete")
         p = self.load_policy(
             {
                 "name": "khole",
                 "resource": "firehose",
                 "filters": [{"DeliveryStreamName": "sock-index-hose"}],
-                "actions": ["delete"],
+                "actions": ["delete"]
             },
             session_factory=factory,
         )
@@ -109,6 +109,93 @@ def test_hose_delete(self):
             "DELETING",
         )
 
+    def test_firehose_extended_s3_encrypt_s3_destination(self):
+        factory = self.replay_flight_data("test_firehose_ext_s3_encrypt_s3_destination")
+        p = self.load_policy(
+            {
+                "name": "khole",
+                "resource": "firehose",
+                "filters": [{"type": "value",
+                    "key": "Destinations[0].S3DestinationDescription.EncryptionConfiguration.NoEncryptionConfig",  # noqa: E501
+                             "value": "present"}],
+                "actions": [{"type": "encrypt-s3-destination",
+                             "key_arn": "arn:aws:kms:us-east-1:123456789:alias/aws/s3"}],
+            },
+            session_factory=factory,
+        )
+        resources = p.run()
+        self.assertEqual(len(resources), 1)
+        s = factory().client("firehose").describe_delivery_stream(
+            DeliveryStreamName="firehose-s3"
+        )['DeliveryStreamDescription']['Destinations'][0]
+        assert 'KMSEncryptionConfig' in s['S3DestinationDescription']['EncryptionConfiguration'].keys()  # noqa: E501
+
+    def test_firehose_splunk_encrypt_s3_destination(self):
+        factory = self.replay_flight_data("test_firehose_splunk_encrypt_s3_destination")
+        p = self.load_policy(
+            {
+                "name": "khole",
+                "resource": "firehose",
+                "filters": [{"type": "value",
+                    "key": "Destinations[0].SplunkDestinationDescription.S3DestinationDescription.EncryptionConfiguration.NoEncryptionConfig",  # noqa: E501
+                             "value": "present"}],
+                "actions": [{"type": "encrypt-s3-destination",
+                             "key_arn": "arn:aws:kms:us-east-1:123456789:alias/aws/s3"}],
+            },
+            session_factory=factory,
+        )
+        resources = p.run()
+        self.assertEqual(len(resources), 1)
+        s = factory().client("firehose").describe_delivery_stream(
+            DeliveryStreamName="firehose-splunk"
+        )['DeliveryStreamDescription']['Destinations'][0]['SplunkDestinationDescription']
+        assert 'KMSEncryptionConfig' in \
+            s['S3DestinationDescription']['EncryptionConfiguration'].keys()
+
+    def test_firehose_elasticsearch_encrypt_s3_destination(self):
+        factory = self.replay_flight_data("test_firehose_elasticsearch_encrypt_s3_destination")
+        p = self.load_policy(
+            {
+                "name": "khole",
+                "resource": "firehose",
+                "filters": [{"type": "value",
+                    "key": "Destinations[0].ElasticsearchDestinationDescription.S3DestinationDescription.EncryptionConfiguration.NoEncryptionConfig",  # noqa: E501
+                             "value": "present"}],
+                "actions": [{"type": "encrypt-s3-destination",
+                             "key_arn": "arn:aws:kms:us-east-1:123456789:alias/aws/s3"}],
+            },
+            session_factory=factory,
+        )
+        resources = p.run()
+        self.assertEqual(len(resources), 1)
+        s = factory().client("firehose").describe_delivery_stream(
+            DeliveryStreamName="firehose-splunk"
+        )['DeliveryStreamDescription']['Destinations'][0]['ElasticsearchDestinationDescription']
+        assert 'KMSEncryptionConfig' in \
+            s['S3DestinationDescription']['EncryptionConfiguration'].keys()
+
+    def test_firehose_redshift_encrypt_s3_destination(self):
+        factory = self.replay_flight_data("test_firehose_redshift_encrypt_s3_destination")
+        p = self.load_policy(
+            {
+                "name": "khole",
+                "resource": "firehose",
+                "filters": [{"type": "value",
+                    "key": "Destinations[0].RedshiftDestinationDescription.S3DestinationDescription.EncryptionConfiguration.NoEncryptionConfig",  # noqa: E501
+                             "value": "present"}],
+                "actions": [{"type": "encrypt-s3-destination",
+                             "key_arn": "arn:aws:kms:us-east-1:123456789:alias/aws/s3"}],
+            },
+            session_factory=factory,
+        )
+        resources = p.run()
+        self.assertEqual(len(resources), 1)
+        s = factory().client("firehose").describe_delivery_stream(
+            DeliveryStreamName="firehose-redshift"
+        )['DeliveryStreamDescription']['Destinations'][0]['RedshiftDestinationDescription']
+        assert 'KMSEncryptionConfig' in \
+            s['S3DestinationDescription']['EncryptionConfiguration'].keys()
+
     def test_app_query(self):
         factory = self.replay_flight_data("test_kinesis_analytics_query")
         p = self.load_policy(