Repository: bridgecrewio/checkov

Issue:
Add new check: MSK - Check encryption at rest and in transit 
Kafka traffic should be encrypted at rest and also in transit between clients as well as nodes in the cluster

* At rest should specify a KMS key
* In transit should be set to TLS with in cluster set to true

CloudFormation and Terraform documentation as follows:  
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-msk-cluster.html
https://www.terraform.io/docs/providers/aws/r/msk_cluster.html




Discussion:

Resolving patch:
diff --git a/checkov/terraform/checks/resource/aws/MSKClusterEncryption.py b/checkov/terraform/checks/resource/aws/MSKClusterEncryption.py
new file mode 100644
--- /dev/null
+++ b/checkov/terraform/checks/resource/aws/MSKClusterEncryption.py
@@ -0,0 +1,27 @@
+from checkov.common.models.enums import CheckResult, CheckCategories
+from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
+
+
+class MSKClusterEncryption(BaseResourceCheck):
+    def __init__(self):
+        name = "Ensure MSK Cluster encryption in rest and transit is enabled"
+        id = "CKV_AWS_81"
+        supported_resources = ['aws_msk_cluster']
+        categories = [CheckCategories.ENCRYPTION]
+        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
+
+    def scan_resource_conf(self, conf):
+        if 'encryption_info' in conf.keys():
+            encryption = conf['encryption_info'][0]
+            if 'encryption_at_rest_kms_key_arn' in encryption:
+                if 'encryption_in_transit' in encryption:
+                    transit = encryption['encryption_in_transit'][0]
+                    if 'client_broker' in transit and transit['client_broker'] != 'TLS' or \
+                            'in_cluster' in transit and transit['in_cluster'] is False:
+                        return CheckResult.FAILED
+                    return CheckResult.PASSED
+                return CheckResult.PASSED
+        return CheckResult.FAILED
+
+
+check = MSKClusterEncryption()


Test patch:
diff --git a/tests/terraform/checks/resource/aws/test_MSKClusterEncryption.py b/tests/terraform/checks/resource/aws/test_MSKClusterEncryption.py
new file mode 100644
--- /dev/null
+++ b/tests/terraform/checks/resource/aws/test_MSKClusterEncryption.py
@@ -0,0 +1,101 @@
+import unittest
+
+from checkov.common.models.enums import CheckResult
+from checkov.terraform.checks.resource.aws.MSKClusterEncryption import check
+
+
+class TestMSKClusterEncryption(unittest.TestCase):
+
+    def test_failure(self):
+        resource_conf = {
+            "name": "test-project",
+        }
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_failure_no_kms(self):
+        resource_conf = {
+            "name": "test-project",
+            "encryption_info": [
+                {
+                    "encryption_in_transit": [
+                        {
+                            "client_broker": "TLS",
+                            "in_cluster": "true",
+                        }
+                    ],
+                }
+            ],
+        }
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_failure_non_tls(self):
+        resource_conf = {
+            "name": "test-project",
+            "encryption_info": [
+                {
+                    "encryption_at_rest_kms_key_arn": "aws_kms_key.kms.arn",
+                    "encryption_in_transit": [
+                        {
+                            "client_broker": "PLAINTEXT",
+                            "in_cluster": "true",
+                        }
+                    ],
+                }
+            ],
+        }
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_failure_in_cluster(self):
+        resource_conf = {
+            "name": "test-project",
+            "encryption_info": [
+                {
+                    "encryption_at_rest_kms_key_arn": "aws_kms_key.kms.arn",
+                    "encryption_in_transit": [
+                        {
+                            "client_broker": "TLS",
+                            "in_cluster": False,
+                        }
+                    ],
+                }
+            ],
+        }
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_success(self):
+        resource_conf = {
+            "name": "test-project",
+            "encryption_info": [
+                {
+                    "encryption_at_rest_kms_key_arn": "aws_kms_key.kms.arn",
+                    "encryption_in_transit": [
+                        {
+                            "client_broker": "TLS",
+                            "in_cluster": "true",
+                        }
+                    ],
+                }
+            ],
+        }
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)
+
+    def test_success_no_encrypt_block(self):
+        resource_conf = {
+            "name": "test-project",
+            "encryption_info": [
+                {
+                    "encryption_at_rest_kms_key_arn": "aws_kms_key.kms.arn",
+                }
+            ],
+        }
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)
+
+
+if __name__ == '__main__':
+    unittest.main()