Repository: bridgecrewio/checkov

Issue:
Add new check: Classic ELB - Access Logging Enabled 
access_logs - aws_elb: https://www.terraform.io/docs/providers/aws/r/elb.html
AWS::ElasticLoadBalancer AccessLoggingPolicy: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb-accessloggingpolicy.html



Discussion:

Resolving patch:
diff --git a/checkov/terraform/checks/resource/aws/ELBAccessLogs.py b/checkov/terraform/checks/resource/aws/ELBAccessLogs.py
new file mode 100644
--- /dev/null
+++ b/checkov/terraform/checks/resource/aws/ELBAccessLogs.py
@@ -0,0 +1,18 @@
+from checkov.common.models.enums import CheckResult, CheckCategories
+from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
+
+
+class ELBAccessLogs(BaseResourceCheck):
+    def __init__(self):
+        name = "Ensure the ELB has access logging enabled"
+        id = "CKV_AWS_90"
+        supported_resources = ['aws_elb']
+        categories = [CheckCategories.LOGGING]
+        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
+
+    def scan_resource_conf(self, conf):
+        if ('access_logs' in conf) and (('enabled' not in conf['access_logs'][0]) or (conf['access_logs'][0]['enabled'] == [True])):
+            return CheckResult.PASSED    
+        return CheckResult.FAILED
+
+check = ELBAccessLogs()
diff --git a/checkov/terraform/checks/resource/aws/ELBv2AccessLogs.py b/checkov/terraform/checks/resource/aws/ELBv2AccessLogs.py
new file mode 100644
--- /dev/null
+++ b/checkov/terraform/checks/resource/aws/ELBv2AccessLogs.py
@@ -0,0 +1,17 @@
+from checkov.common.models.enums import CheckResult, CheckCategories
+from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
+
+class ELBv2AccessLogs(BaseResourceCheck):
+    def __init__(self):
+        name = "Ensure the ELBv2 (Application/Network) has access logging enabled"
+        id = "CKV_AWS_91"
+        supported_resources = ['aws_lb', 'aws_alb']
+        categories = [CheckCategories.LOGGING]
+        super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
+
+    def scan_resource_conf(self, conf):
+        if ('access_logs' in conf) and ('enabled' in conf['access_logs'][0]) and (conf['access_logs'][0]['enabled'] == [True]):
+            return CheckResult.PASSED
+        return CheckResult.FAILED
+
+check = ELBv2AccessLogs()


Test patch:
diff --git a/tests/terraform/checks/resource/aws/test_ELBAccessLogs.py b/tests/terraform/checks/resource/aws/test_ELBAccessLogs.py
new file mode 100644
--- /dev/null
+++ b/tests/terraform/checks/resource/aws/test_ELBAccessLogs.py
@@ -0,0 +1,99 @@
+import unittest
+import hcl2
+
+from checkov.terraform.checks.resource.aws.ELBAccessLogs import check
+from checkov.common.models.enums import CheckResult
+
+
+class TestELBAccessLogs(unittest.TestCase):
+
+    def test_failure_elb_1(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_elb" "test" {
+            name = "test-lb-tf"
+            availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
+
+            listener {
+              instance_port     = 8000
+              instance_protocol = "http"
+              lb_port           = 80
+              lb_protocol       = "http"
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_elb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_failure_elb_2(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_elb" "test" {
+            name = "test-lb-tf"
+            availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
+
+            listener {
+              instance_port     = 8000
+              instance_protocol = "http"
+              lb_port           = 80
+              lb_protocol       = "http"
+            }
+
+            access_logs {
+              bucket  = aws_s3_bucket.lb_logs.bucket
+              enabled = false   
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_elb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)           
+
+    def test_success_elb_1(self):
+        hcl_res = hcl2.loads("""
+        resource "aws_elb" "test" {
+            name = "test-lb-tf"
+            availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
+
+            listener {
+              instance_port     = 8000
+              instance_protocol = "http"
+              lb_port           = 80
+              lb_protocol       = "http"
+            }
+
+            access_logs {
+              bucket  = aws_s3_bucket.lb_logs.bucket
+              enabled = true
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_elb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)
+
+    def test_success_elb_2(self):
+        hcl_res = hcl2.loads("""
+        resource "aws_elb" "test" {
+            name = "test-lb-tf"
+            availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]
+
+            listener {
+              instance_port     = 8000
+              instance_protocol = "http"
+              lb_port           = 80
+              lb_protocol       = "http"
+            }
+
+            access_logs {
+              bucket  = aws_s3_bucket.lb_logs.bucket
+              # The default value for enabled is true              
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_elb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)          
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tests/terraform/checks/resource/aws/test_ELBv2AccessLogs.py b/tests/terraform/checks/resource/aws/test_ELBv2AccessLogs.py
new file mode 100644
--- /dev/null
+++ b/tests/terraform/checks/resource/aws/test_ELBv2AccessLogs.py
@@ -0,0 +1,119 @@
+import unittest
+import hcl2
+
+from checkov.terraform.checks.resource.aws.ELBv2AccessLogs import check
+from checkov.common.models.enums import CheckResult
+
+
+class TestELBAccessLogs(unittest.TestCase):
+
+    def test_failure_lb_1(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_lb" "test" {
+            name               = "test-lb-tf"
+
+            access_logs {
+              bucket  = aws_s3_bucket.lb_logs.bucket
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_lb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_failure_lb_2(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_lb" "test" {
+            name               = "test-lb-tf"
+
+            access_logs {
+              bucket  = aws_s3_bucket.lb_logs.bucket
+              enabled = false
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_lb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_failure_lb_3(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_lb" "test" {
+            name               = "test-lb-tf"
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_lb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)        
+
+    def test_failure_alb_1(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_alb" "test" {
+            name               = "test-lb-tf"
+
+            access_logs {
+              bucket  = aws_s3_bucket.lb_logs.bucket
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_alb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_failure_alb_2(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_alb" "test" {
+            name               = "test-lb-tf"
+
+            access_logs {
+              bucket  = aws_s3_bucket.lb_logs.bucket
+              enabled = false
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_alb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_failure_alb_3(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_alb" "test" {
+            name               = "test-lb-tf"
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_alb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.FAILED, scan_result)
+
+    def test_success_lb(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_lb" "test" {
+            name               = "test-lb-tf"
+
+            access_logs {
+              bucket  = aws_s3_bucket.lb_logs.bucket
+              enabled = true
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_lb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)
+
+    def test_success_alb(self):
+        hcl_res = hcl2.loads("""
+          resource "aws_alb" "test" {
+            name               = "test-lb-tf"
+
+            access_logs {
+              bucket  = aws_s3_bucket.lb_logs.bucket
+              enabled = true
+            }
+          }
+        """)
+        resource_conf = hcl_res['resource'][0]['aws_alb']['test']
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)
+
+if __name__ == '__main__':
+    unittest.main()