Repository: cloudtools/troposphere

Issue:
Add support for AWS::EMR::SecurityConfiguration Resource
AWS recently introduced the CloudFormation resource AWS::EMR::SecurityConfiguration. 

I'm working on adding that functionality to Troposphere


Discussion:

Resolving patch:
diff --git a/examples/EMR_Cluster.py b/examples/EMR_Cluster.py
--- a/examples/EMR_Cluster.py
+++ b/examples/EMR_Cluster.py
@@ -11,6 +11,32 @@
                 )
 
 
+kms_key = 'arn:aws:kms:us-east-1:123456789012:key/1234-1234-1234-1234-1234'
+
+security_configuration = {
+    'EncryptionConfiguration': {
+        'EnableInTransitEncryption': 'true',
+        'InTransitEncryptionConfiguration': {
+            'TLSCertificateConfiguration': {
+                'CertificateProviderType': 'PEM',
+                'S3Object': 's3://MyConfigStore/artifacts/MyCerts.zip'
+            }
+        },
+        'EnableAtRestEncryption': 'true',
+        'AtRestEncryptionConfiguration': {
+            'S3EncryptionConfiguration': {
+                'EncryptionMode': 'SSE-KMS',
+                'AwsKmsKey': kms_key
+            },
+            'LocalDiskEncryptionConfiguration': {
+                'EncryptionKeyProviderType': 'AwsKms',
+                'AwsKmsKey': kms_key
+            }
+        }
+    }
+}
+
+
 def generate_rules(rules_name):
     global emr, scaling_policy
 
@@ -127,10 +153,17 @@ def generate_rules(rules_name):
 
 # EMR Cluster Resource
 
+security_config = template.add_resource(emr.SecurityConfiguration(
+    'EMRSecurityConfiguration',
+    Name="EMRSampleClusterSecurityConfiguration",
+    SecurityConfiguration=security_configuration,
+))
+
 cluster = template.add_resource(emr.Cluster(
     "EMRSampleCluster",
     Name="EMR Sample Cluster",
     ReleaseLabel='emr-4.4.0',
+    SecurityConfiguration=Ref(security_config),
     BootstrapActions=[emr.BootstrapActionConfig(
         Name='Dummy bootstrap action',
         ScriptBootstrapAction=emr.ScriptBootstrapActionConfig(
diff --git a/troposphere/emr.py b/troposphere/emr.py
--- a/troposphere/emr.py
+++ b/troposphere/emr.py
@@ -38,6 +38,15 @@ def additional_info_validator(xs):
     return xs
 
 
+class SecurityConfiguration(AWSObject):
+    resource_type = "AWS::EMR::SecurityConfiguration"
+
+    props = {
+        'Name': (basestring, False),
+        'SecurityConfiguration': (dict, True)
+    }
+
+
 class Application(AWSProperty):
     props = {
         'AdditionalInfo': (additional_info_validator, False),
@@ -234,6 +243,7 @@ class Cluster(AWSObject):
         'LogUri': (basestring, False),
         'Name': (basestring, True),
         'ReleaseLabel': (basestring, False),
+        'SecurityConfiguration': (basestring, False),
         'ServiceRole': (basestring, True),
         'AutoScalingRole': (basestring, False),
         'Tags': (list, False),


Test patch:
diff --git a/tests/examples_output/EMR_Cluster.template b/tests/examples_output/EMR_Cluster.template
--- a/tests/examples_output/EMR_Cluster.template
+++ b/tests/examples_output/EMR_Cluster.template
@@ -270,6 +270,9 @@
                 },
                 "Name": "EMR Sample Cluster",
                 "ReleaseLabel": "emr-4.4.0",
+                "SecurityConfiguration": {
+                    "Ref": "EMRSecurityConfiguration"
+                },
                 "ServiceRole": {
                     "Ref": "EMRServiceRole"
                 },
@@ -283,6 +286,34 @@
             },
             "Type": "AWS::EMR::Cluster"
         },
+        "EMRSecurityConfiguration": {
+            "Properties": {
+                "Name": "EMRSampleClusterSecurityConfiguration",
+                "SecurityConfiguration": {
+                    "EncryptionConfiguration": {
+                        "AtRestEncryptionConfiguration": {
+                            "LocalDiskEncryptionConfiguration": {
+                                "AwsKmsKey": "arn:aws:kms:us-east-1:123456789012:key/1234-1234-1234-1234-1234",
+                                "EncryptionKeyProviderType": "AwsKms"
+                            },
+                            "S3EncryptionConfiguration": {
+                                "AwsKmsKey": "arn:aws:kms:us-east-1:123456789012:key/1234-1234-1234-1234-1234",
+                                "EncryptionMode": "SSE-KMS"
+                            }
+                        },
+                        "EnableAtRestEncryption": "true",
+                        "EnableInTransitEncryption": "true",
+                        "InTransitEncryptionConfiguration": {
+                            "TLSCertificateConfiguration": {
+                                "CertificateProviderType": "PEM",
+                                "S3Object": "s3://MyConfigStore/artifacts/MyCerts.zip"
+                            }
+                        }
+                    }
+                }
+            },
+            "Type": "AWS::EMR::SecurityConfiguration"
+        },
         "EMRServiceRole": {
             "Properties": {
                 "AssumeRolePolicyDocument": {
diff --git a/tests/test_emr.py b/tests/test_emr.py
--- a/tests/test_emr.py
+++ b/tests/test_emr.py
@@ -11,6 +11,31 @@
                     CoolDown="300"
                 )
 
+kms_key = 'arn:aws:kms:us-east-1:123456789012:key/1234-1234-1234-1234-1234'
+
+security_configuration = {
+    'EncryptionConfiguration': {
+        'EnableInTransitEncryption': 'true',
+        'InTransitEncryptionConfiguration': {
+            'TLSCertificateConfiguration': {
+                'CertificateProviderType': 'PEM',
+                'S3Object': 's3://MyConfigStore/artifacts/MyCerts.zip'
+            }
+        },
+        'EnableAtRestEncryption': 'true',
+        'AtRestEncryptionConfiguration': {
+            'S3EncryptionConfiguration': {
+                'EncryptionMode': 'SSE-KMS',
+                'AwsKmsKey': kms_key
+            },
+            'LocalDiskEncryptionConfiguration': {
+                'EncryptionKeyProviderType': 'AwsKms',
+                'AwsKmsKey': kms_key
+            }
+        }
+    }
+}
+
 
 class TestEMR(unittest.TestCase):
 
@@ -46,6 +71,12 @@ def generate_rules(self, rules_name):
         return rules
 
     def test_allow_string_cluster(self):
+        cluster_security_configuration = emr.SecurityConfiguration(
+                'emrsecurityconfiguration',
+                Name="EMRSecurityConfiguration",
+                SecurityConfiguration=security_configuration
+            )
+
         spot = "2"
         withSpotPrice = "WithSpotPrice"
         cluster = emr.Cluster(
@@ -108,6 +139,7 @@ def test_allow_string_cluster(self):
             LogUri="s3://cluster-logs",
             Name="EMR Cluster",
             ReleaseLabel="emr-5.5.0",
+            SecurityConfiguration=Ref(cluster_security_configuration),
             ServiceRole="EMRServiceRole",
             AutoScalingRole="EMR_AutoScaling_DefaultRole",
             VisibleToAllUsers="true",