Repository: cdklabs/cdk-validator-cfnguard (language: python)

Issue:
(Batch 2) Add a batch of the remaining Control Tower proactive rules.



Discussion / hints:

Fix patch:
diff --git a/.projen/deps.json b/.projen/deps.json
index f8f395a..0f905c5 100644
--- a/.projen/deps.json
+++ b/.projen/deps.json
@@ -8,10 +8,20 @@
       "name": "@octokit/types",
       "type": "build"
     },
+    {
+      "name": "@types/fs-extra",
+      "version": "11.0.1",
+      "type": "build"
+    },
     {
       "name": "@types/jest",
       "type": "build"
     },
+    {
+      "name": "@types/klaw",
+      "version": "3.0.3",
+      "type": "build"
+    },
     {
       "name": "@types/mock-fs",
       "type": "build"
@@ -61,6 +71,11 @@
       "version": "^8",
       "type": "build"
     },
+    {
+      "name": "fs-extra",
+      "version": "^11.1.1",
+      "type": "build"
+    },
     {
       "name": "jest",
       "type": "build"
@@ -87,6 +102,11 @@
       "version": "~5.0.0",
       "type": "build"
     },
+    {
+      "name": "klaw",
+      "version": "^4.1.0",
+      "type": "build"
+    },
     {
       "name": "mock-fs",
       "type": "build"
diff --git a/.projen/tasks.json b/.projen/tasks.json
index 1716343..e64990d 100644
--- a/.projen/tasks.json
+++ b/.projen/tasks.json
@@ -357,19 +357,19 @@
           "exec": "yarn upgrade npm-check-updates"
         },
         {
-          "exec": "npm-check-updates --dep dev --upgrade --target=minor --reject='aws-cdk-lib,jsii'"
+          "exec": "npm-check-updates --dep dev --upgrade --target=minor --reject='@types/fs-extra,@types/klaw,aws-cdk-lib,jsii'"
         },
         {
-          "exec": "npm-check-updates --dep optional --upgrade --target=minor --reject='aws-cdk-lib,jsii'"
+          "exec": "npm-check-updates --dep optional --upgrade --target=minor --reject='@types/fs-extra,@types/klaw,aws-cdk-lib,jsii'"
         },
         {
-          "exec": "npm-check-updates --dep peer --upgrade --target=minor --reject='aws-cdk-lib,jsii'"
+          "exec": "npm-check-updates --dep peer --upgrade --target=minor --reject='@types/fs-extra,@types/klaw,aws-cdk-lib,jsii'"
         },
         {
-          "exec": "npm-check-updates --dep prod --upgrade --target=minor --reject='aws-cdk-lib,jsii'"
+          "exec": "npm-check-updates --dep prod --upgrade --target=minor --reject='@types/fs-extra,@types/klaw,aws-cdk-lib,jsii'"
         },
         {
-          "exec": "npm-check-updates --dep bundle --upgrade --target=minor --reject='aws-cdk-lib,jsii'"
+          "exec": "npm-check-updates --dep bundle --upgrade --target=minor --reject='@types/fs-extra,@types/klaw,aws-cdk-lib,jsii'"
         },
         {
           "exec": "yarn install --check-files"
diff --git a/.projenrc.ts b/.projenrc.ts
index f845c75..aa2d9c8 100644
--- a/.projenrc.ts
+++ b/.projenrc.ts
@@ -19,6 +19,10 @@ const project = new CdklabsJsiiProject({
     'constructs',
     'aws-cdk-lib@^2.71.0',
     'jsii@^5.0.0',
+    'fs-extra@^11.1.1',
+    '@types/fs-extra@11.0.1',
+    'klaw@^4.1.0',
+    '@types/klaw@3.0.3',
   ],
   name: '@cdklabs/cdk-validator-cfnguard',
   jsiiVersion: '~5.0.0',
diff --git a/package.json b/package.json
index c90aa0d..c403aa5 100644
--- a/package.json
+++ b/package.json
@@ -44,7 +44,9 @@
   "devDependencies": {
     "@octokit/rest": "^19.0.7",
     "@octokit/types": "^9.1.2",
+    "@types/fs-extra": "11.0.1",
     "@types/jest": "^27",
+    "@types/klaw": "3.0.3",
     "@types/mock-fs": "^4.13.1",
     "@types/node": "^16",
     "@typescript-eslint/eslint-plugin": "^5",
@@ -56,12 +58,14 @@
     "eslint-import-resolver-node": "^0.3.7",
     "eslint-import-resolver-typescript": "^3.5.5",
     "eslint-plugin-import": "^2.27.5",
+    "fs-extra": "^11.1.1",
     "jest": "^27",
     "jest-junit": "^15",
     "jsii": "~5.0.0",
     "jsii-diff": "^1.80.0",
     "jsii-docgen": "^7.2.1",
     "jsii-pacmak": "^1.80.0",
+    "klaw": "^4.1.0",
     "mock-fs": "^5.2.0",
     "npm-check-updates": "^16",
     "projen": "^0.71.22",
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-1.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-1.guard
new file mode 100644
index 0000000..63f29c3
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-1.guard
@@ -0,0 +1,143 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   ec2_launch_template_imdsv2_check
+# 
+# Description:
+#   This control checks whether your Amazon EC2 launch templates are configured with Instance Metadata Service Version 2 (IMDSv2).
+# 
+# Reports on:
+#   AWS::EC2::LaunchTemplate
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any EC2 launch template resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 launch template resource
+#       And: 'LaunchTemplateData' has not been provided or 'LaunchTemplateData.MetadataOptions.HttpEndpoint' has
+#             been provided and is equal to 'disabled'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 launch template resource
+#       And: 'LaunchTemplateData' has been provided
+#       And: 'MetadataOptions.HttpEndpoint' in 'LaunchTemplateData' has not been provided or has been provided and
+#            is equal to 'enabled'
+#       And: 'MetadataOptions.HttpTokens' in 'LaunchTemplateData' has not been provided
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 launch template resource
+#       And: 'LaunchTemplateData' has been provided
+#       And: 'MetadataOptions.HttpEndpoint' in 'LaunchTemplateData' has not been provided or has been provided and
+#            is equal to 'enabled'
+#       And: 'MetadataOptions.HttpTokens' in 'LaunchTemplateData' has been provided and set to a value other than 'required'
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 launch template resource
+#       And: 'LaunchTemplateData' has been provided
+#       And: 'MetadataOptions.HttpEndpoint' in 'LaunchTemplateData' has not been provided or has been provided and
+#            is equal to 'enabled'
+#       And: 'MetadataOptions.HttpTokens' in 'LaunchTemplateData' has been provided and set to 'required'
+#      Then: PASS
+
+#
+# Constants
+#
+let EC2_LAUNCH_TEMPLATE_TYPE = "AWS::EC2::LaunchTemplate"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_launch_templates = Resources.*[ Type == %EC2_LAUNCH_TEMPLATE_TYPE ]
+
+#
+# Primary Rules
+#
+rule ec2_launch_template_imdsv2_check when is_cfn_template(%INPUT_DOCUMENT)
+                                           %ec2_launch_templates not empty {
+    check(%ec2_launch_templates.Properties)
+        <<
+        [CT.EC2.PR.1]: Require an Amazon EC2 launch template to have IMDSv2 configured
+            [FIX]: Within the 'LaunchTemplateData' property, provide a 'MetadataOptions' configuration and set the value of 'HttpTokens' to 'required'.
+        >>
+}
+
+rule ec2_launch_template_imdsv2_check when is_cfn_hook(%INPUT_DOCUMENT, %EC2_LAUNCH_TEMPLATE_TYPE) {
+    check(%INPUT_DOCUMENT.%EC2_LAUNCH_TEMPLATE_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.1]: Require an Amazon EC2 launch template to have IMDSv2 configured
+            [FIX]: Within the 'LaunchTemplateData' property, provide a 'MetadataOptions' configuration and set the value of 'HttpTokens' to 'required'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(launch_template) {
+    %launch_template [
+        # Scenario 2
+        filter_launch_template_imds_enabled(this)
+    ] {
+        LaunchTemplateData exists
+        LaunchTemplateData is_struct
+
+        LaunchTemplateData {
+            # Scenario 3, 4 and 5
+            MetadataOptions exists
+            MetadataOptions is_struct
+            MetadataOptions {
+                HttpTokens exists
+                HttpTokens == "required"
+            }
+        }
+    }
+}
+
+rule filter_launch_template_imds_enabled(launch_template) {
+    %launch_template {
+        LaunchTemplateData exists
+        LaunchTemplateData is_struct
+        LaunchTemplateData {
+            MetadataOptions not exists or
+            filter_metadata_options_imds_enabled(this)
+        }
+    }
+}
+
+rule filter_metadata_options_imds_enabled(metadata_options) {
+    %metadata_options {
+        MetadataOptions is_struct
+        MetadataOptions {
+            HttpEndpoint not exists or
+            HttpEndpoint == "enabled"
+        }
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-10.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-10.guard
new file mode 100644
index 0000000..b236ff5
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-10.guard
@@ -0,0 +1,109 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   ec2_launch_template_monitoring_enabled_check
+# 
+# Description:
+#   This control checks whether the Amazon EC2 launch template has detailed monitoring enabled.
+# 
+# Reports on:
+#   AWS::EC2::LaunchTemplate
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document does not contain any EC2 launch template resources
+#       Then: SKIP
+#   Scenario: 2
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 launch template resource
+#        And: 'LaunchTemplateData.Monitoring.Enabled' has not been provided or has been provided and is empty.
+#       Then: FAIL
+#   Scenario: 3
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 launch template resource
+#        And: 'LaunchTemplateData.Monitoring.Enabled' has been provided
+#        And: 'LaunchTemplateData.Monitoring.Enabled' is equal to a value other than bool(true)
+#       Then: FAIL
+#   Scenario: 4
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 launch template resource
+#        And: 'LaunchTemplateData.Monitoring.Enabled' has been provided
+#        And: 'LaunchTemplateData.Monitoring.Enabled' is equal to bool(true)
+#       Then: PASS
+
+#
+# Constants
+#
+let EC2_LAUNCH_TEMPLATE_TYPE = "AWS::EC2::LaunchTemplate"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_launch_templates = Resources.*[ Type == %EC2_LAUNCH_TEMPLATE_TYPE ]
+
+#
+# Primary Rules
+#
+rule ec2_launch_template_monitoring_enabled_check when is_cfn_template(this)
+                                                       %ec2_launch_templates not empty {
+    check(%ec2_launch_templates.Properties)
+        <<
+        [CT.EC2.PR.10]: Require Amazon EC2 launch templates to have Amazon CloudWatch detailed monitoring activated
+            [FIX]: In 'LaunchTemplateData', provide a 'Monitoring' configuration with 'Enabled' set to 'true'.
+        >>
+}
+
+rule ec2_launch_template_monitoring_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %EC2_LAUNCH_TEMPLATE_TYPE) {
+    check(%INPUT_DOCUMENT.%EC2_LAUNCH_TEMPLATE_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.10]: Require Amazon EC2 launch templates to have Amazon CloudWatch detailed monitoring activated
+            [FIX]: In 'LaunchTemplateData', provide a 'Monitoring' configuration with 'Enabled' set to 'true'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(ec2_launch_template) {
+    %ec2_launch_template {
+        # Scenario 2
+        LaunchTemplateData exists
+        LaunchTemplateData is_struct
+
+        LaunchTemplateData {
+            Monitoring exists
+            Monitoring is_struct
+
+            # Scenario 3 and 4
+            Monitoring {
+                Enabled exists
+                Enabled == true
+            }
+
+        }
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-11.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-11.guard
new file mode 100644
index 0000000..ac5e91d
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-11.guard
@@ -0,0 +1,97 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# 
+# Rule Identifier:
+#   subnet_auto_assign_public_ip_disabled_check
+# 
+# Description:
+#   This control checks whether your Amazon VPC subnets automatically assign public IP addresses.
+# 
+# Reports on:
+#   AWS::EC2::Subnet
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any EC2 subnet resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 subnet resource
+#       And: 'MapPublicIpOnLaunch' is present and set to bool(true)
+#      Then: FAIL
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 subnet resource
+#       And: 'MapPublicIpOnLaunch' is not present
+#      Then: PASS
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 subnet resource
+#       And: 'MapPublicIpOnLaunch' is present and set to bool(false)
+#      Then: PASS
+
+#
+# Constants
+#
+let EC2_SUBNET_TYPE  = "AWS::EC2::Subnet"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_subnets = Resources.*[ Type == %EC2_SUBNET_TYPE ]
+
+#
+# Primary Rules
+#
+rule subnet_auto_assign_public_ip_disabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                      %ec2_subnets not empty {
+    check(%ec2_subnets.Properties)
+        <<
+        [CT.EC2.PR.11]: Require that an Amazon EC2 subnet does not automatically assign public IP addresses
+            [FIX]: Omit the 'MapPublicIpOnLaunch' property to use the default configuration, or set the 'MapPublicIpOnLaunch' property to 'false'.
+        >>
+}
+
+rule subnet_auto_assign_public_ip_disabled_check when is_cfn_hook(%INPUT_DOCUMENT, %EC2_SUBNET_TYPE) {
+    check(%INPUT_DOCUMENT.%EC2_SUBNET_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.11]: Require that an Amazon EC2 subnet does not automatically assign public IP addresses
+            [FIX]: Omit the 'MapPublicIpOnLaunch' property to use the default configuration, or set the 'MapPublicIpOnLaunch' property to 'false'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(ec2_subnet) {
+    %ec2_subnet {
+        # Scenario 3
+        MapPublicIpOnLaunch not exists or
+        # Scenarios 2 and 4
+        MapPublicIpOnLaunch == false
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-12.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-12.guard
new file mode 100644
index 0000000..f4acf47
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-12.guard
@@ -0,0 +1,102 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   ec2_instance_multiple_eni_check
+# 
+# Description:
+#   This control checks whether your Amazon Elastic Compute Cloud (Amazon EC2) instance uses multiple ENIs (Elastic Network Interfaces).
+# 
+# Reports on:
+#   AWS::EC2::Instance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon EC2 instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 instance resource
+#       And: 'NetworkInterfaces' is not present or is present and contains 0 configurations
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 instance resource
+#       And: 'NetworkInterfaces' is present and contains >1 configurations
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 instance resource
+#       And: 'NetworkInterfaces' is present
+#       And: 'NetworkInterfaces' is present and contains 1 configuration
+#      Then: PASS
+
+#
+# Constants
+#
+let EC2_INSTANCE_TYPE = "AWS::EC2::Instance"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_instances = Resources.*[ Type == %EC2_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule ec2_instance_multiple_eni_check when is_cfn_template(%INPUT_DOCUMENT)
+                                          %ec2_instances not empty {
+    check(%ec2_instances.Properties)
+        <<
+        [CT.EC2.PR.12]: Require an Amazon EC2 instance to configure one ENI only
+            [FIX]: Configure Amazon EC2 instances with only one ENI.
+        >>
+
+}
+
+rule ec2_instance_multiple_eni_check when is_cfn_hook(%INPUT_DOCUMENT, %EC2_INSTANCE_TYPE) {
+
+    check(%INPUT_DOCUMENT.%EC2_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.12]: Require an Amazon EC2 instance to configure one ENI only
+            [FIX]: Configure Amazon EC2 instances with only one ENI.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(ec2_instance) {
+    %ec2_instance [
+        # Scenario 2
+        NetworkInterfaces exists
+        NetworkInterfaces is_list
+        NetworkInterfaces not empty
+    ] {
+        # Scenario 3 and 4
+        NetworkInterfaces[1] not exists
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-2.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-2.guard
new file mode 100644
index 0000000..7249e53
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-2.guard
@@ -0,0 +1,146 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   ec2_launch_template_token_hop_limit_check
+# 
+# Description:
+#   This control checks whether an Amazon EC2 launch template has a metadata token hop limit set to '1'.
+# 
+# Reports on:
+#   AWS::EC2::LaunchTemplate
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document does not contain any EC2 launch template resources
+#       Then: SKIP
+#   Scenario: 2
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 launch template resource
+#        And: 'LaunchTemplateData.MetadataOptions' has been provided
+#        And: 'LaunchTemplateData.MetadataOptions.HttpEndpoint' has been provided and is equal to 'disabled'
+#       Then: SKIP
+#   Scenario: 3
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 launch template resource
+#        And: 'LaunchTemplateData.MetadataOptions' has been provided
+#        And: 'LaunchTemplateData.MetadataOptions.HttpEndpoint' has not been provided or has been provided and is
+#             equal to 'enabled'
+#        And: 'LaunchTemplateData.MetadataOptions.HttpPutResponseHopLimit' has been provided and is not equal to
+#             an integer of 1.
+#       Then: FAIL
+#   Scenario: 4
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 launch template resource
+#        And: 'LaunchTemplateData.MetadataOptions' has not been provided
+#       Then: PASS
+#   Scenario: 5
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 launch template resource
+#        And: 'LaunchTemplateData.MetadataOptions' has been provided
+#        And: 'LaunchTemplateData.MetadataOptions.HttpEndpoint' has not been provided or has been provided and is
+#             equal to 'enabled'
+#        And: 'LaunchTemplateData.MetadataOptions.HttpPutResponseHopLimit' has not been provided
+#       Then: PASS
+#   Scenario: 6
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 launch template resource
+#        And: 'LaunchTemplateData.MetadataOptions' has been provided
+#        And: 'LaunchTemplateData.MetadataOptions.HttpEndpoint' has not been provided or has been provided and is
+#             equal to 'enabled'
+#        And: 'LaunchTemplateData.MetadataOptions.HttpPutResponseHopLimit' has been provided and is equal to an
+#             integer of 1.
+#       Then: PASS
+
+#
+# Constants
+#
+let EC2_LAUNCH_TEMPLATE_TYPE = "AWS::EC2::LaunchTemplate"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_launch_templates = Resources.*[ Type == %EC2_LAUNCH_TEMPLATE_TYPE ]
+
+#
+# Primary Rules
+#
+rule ec2_launch_template_token_hop_limit_check when is_cfn_template(this)
+                                                    %ec2_launch_templates not empty {
+    check(%ec2_launch_templates.Properties)
+        <<
+        [CT.EC2.PR.2]: Require that Amazon EC2 launch templates restrict the token hop limit to a maximum of one
+            [FIX]: Within the 'LaunchTemplateData' property, provide a 'MetadataOptions' configuration with the value of 'HttpPutResponseLimit' set to '1', or omit the 'HttpPutResponseLimit' property to adopt the AWS CloudFormation default value of '1'.
+        >>
+}
+
+rule ec2_launch_template_token_hop_limit_check when is_cfn_hook(%INPUT_DOCUMENT, %EC2_LAUNCH_TEMPLATE_TYPE) {
+    check(%INPUT_DOCUMENT.%EC2_LAUNCH_TEMPLATE_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.2]: Require that Amazon EC2 launch templates restrict the token hop limit to a maximum of one
+            [FIX]: Within the 'LaunchTemplateData' property, provide a 'MetadataOptions' configuration with the value of 'HttpPutResponseLimit' set to '1', or omit the 'HttpPutResponseLimit' property to adopt the AWS CloudFormation default value of '1'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(ec2_launch_template) {
+  %ec2_launch_template[
+      # Scenario 2, 3 and 4
+      filter_launch_template(this)
+  ] {
+      # Scenario 5 and 6
+      LaunchTemplateData {
+          MetadataOptions not exists or
+          MetadataOptions {
+              HttpPutResponseHopLimit not exists or
+              HttpPutResponseHopLimit == 1
+          }
+      }
+  }
+}
+
+rule filter_launch_template(ec2_launch_template) {
+  %ec2_launch_template {
+      LaunchTemplateData exists
+      LaunchTemplateData is_struct
+      LaunchTemplateData {
+          MetadataOptions not exists or
+          filter_metadata_options_provided(this)
+      }
+  }
+}
+
+rule filter_metadata_options_provided(options) {
+  %options {
+      MetadataOptions is_struct
+      MetadataOptions {
+          HttpEndpoint not exists or
+          HttpEndpoint == "enabled"
+      }
+  }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+  %doc {
+    AWSTemplateFormatVersion exists  or
+    Resources exists
+  }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-3.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-3.guard
new file mode 100644
index 0000000..54fa438
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-3.guard
@@ -0,0 +1,169 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   vpc_sg_open_only_to_authorized_ports_check
+# 
+# Description:
+#   This control checks whether security groups that allow unrestricted incoming traffic ('0.0.0.0/0' or '::/0'), only allow inbound TCP or UDP connections on authorized ports.
+# 
+# Reports on:
+#   AWS::EC2::SecurityGroup, AWS::EC2::SecurityGroupIngress
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon EC2 security group or EC2 security group ingress resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 security group resource or EC2 security group ingress resource
+#       And: The EC2 security group or EC2 security group ingress resource has no rules allowing inbound traffic
+#            from source '0.0.0.0/0' or '::/0'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 security group resource or EC2 security group ingress resource
+#       And: The EC2 security group or EC2 security group ingress resource has rules allowing inbound traffic
+#            from source '0.0.0.0/0' or '::/0'
+#       And: The EC2 security group or EC2 security group ingress resource has a rule that allows all traffic
+#            ('IpProtocol' is set to '-1' or another protocol number)
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 security group resource or EC2 security group ingress resource
+#       And: The EC2 security group or EC2 security group ingress resource has rules allowing inbound traffic
+#            from source '0.0.0.0/0' or '::/0'
+#       And: The EC2 security group or EC2 security group ingress resource has no rules that allow all traffic
+#            ('IpProtocol' is not set to '-1' or another protocol number)
+#       And: Ports allowed are not in the list of allowed ports
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 security group resource or EC2 security group ingress resource
+#       And: The EC2 security group or EC2 security group ingress resource has rules allowing inbound traffic
+#            from source '0.0.0.0/0' or '::/0'
+#       And: The EC2 security group or EC2 security group ingress resource has no rules that allow all traffic
+#            ('IpProtocol' is not set to '-1' or another protocol number)
+#       And: Ports allowed are in the list of allowed ports
+#      Then: PASS
+
+#
+# Constants
+#
+let SECURITY_GROUP_TYPE = "AWS::EC2::SecurityGroup"
+let SECURITY_GROUP_INGRESS_TYPE = "AWS::EC2::SecurityGroupIngress"
+let ALLOWED_PORTS = [80, 443]
+let AUTHORIZED_PROTOCOLS = ["tcp", "udp", "icmp", "icmpv6"]
+let UNRESTRICTED_IPV4_RANGES = ["0.0.0.0/0"]
+let UNRESTRICTED_IPV6_RANGES = ["::/0"]
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_security_groups = Resources[
+    Type == %SECURITY_GROUP_TYPE
+]
+let ec2_security_group_ingress_rules = Resources[
+    Type == %SECURITY_GROUP_INGRESS_TYPE
+]
+
+#
+# Primary Rules
+#
+rule vpc_sg_open_only_to_authorized_ports_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                     %ec2_security_groups not empty {
+
+    check_security_group(%ec2_security_groups.Properties)
+        <<
+        [CT.EC2.PR.3]: Require an Amazon EC2 security group to allow incoming traffic on authorized ports only
+            [FIX]: Ensure that security groups with ingress rules that allow TCP or UDP traffic from '0.0.0.0/0' or ' only allow traffic from ports 80 or 443.
+        >>
+}
+
+rule vpc_sg_open_only_to_authorized_ports_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                     %ec2_security_group_ingress_rules not empty {
+
+    check_ingress_rule(%ec2_security_group_ingress_rules.Properties)
+        <<
+        [CT.EC2.PR.3]: Require an Amazon EC2 security group to allow incoming traffic on authorized ports only
+            [FIX]: Ensure that security groups with ingress rules that allow TCP or UDP traffic from '0.0.0.0/0' or ' only allow traffic from ports 80 or 443.
+        >>
+}
+
+rule vpc_sg_open_only_to_authorized_ports_check when is_cfn_hook(%INPUT_DOCUMENT, %SECURITY_GROUP_TYPE) {
+
+    check_security_group(%INPUT_DOCUMENT.%SECURITY_GROUP_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.3]: Require an Amazon EC2 security group to allow incoming traffic on authorized ports only
+            [FIX]: Ensure that security groups with ingress rules that allow TCP or UDP traffic from '0.0.0.0/0' or ' only allow traffic from ports 80 or 443.
+        >>
+}
+
+rule vpc_sg_open_only_to_authorized_ports_check when is_cfn_hook(%INPUT_DOCUMENT, %SECURITY_GROUP_INGRESS_TYPE) {
+
+    check_ingress_rule(%INPUT_DOCUMENT.%SECURITY_GROUP_INGRESS_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.3]: Require an Amazon EC2 security group to allow incoming traffic on authorized ports only
+            [FIX]: Ensure that security groups with ingress rules that allow TCP or UDP traffic from '0.0.0.0/0' or ' only allow traffic from ports 80 or 443.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check_security_group(security_group) {
+    %security_group [
+        SecurityGroupIngress exists
+        SecurityGroupIngress is_list
+        SecurityGroupIngress not empty
+    ] {
+        SecurityGroupIngress[*] {
+            check_ingress_rule(this)
+        }
+    }
+}
+
+rule check_ingress_rule(ingress_rule) {
+    %ingress_rule[ CidrIp in %UNRESTRICTED_IPV4_RANGES or
+                   CidrIpv6 in %UNRESTRICTED_IPV6_RANGES ] {
+        # Scenario 3
+        IpProtocol exists
+        IpProtocol in %AUTHORIZED_PROTOCOLS
+
+        when IpProtocol in ["tcp", "udp"] {
+            FromPort exists
+            ToPort exists
+            # Scenarios 4 and 5
+            check_ports(FromPort, ToPort)
+        }
+    }
+}
+
+rule check_ports(from_port, to_port) {
+    %from_port in %ALLOWED_PORTS
+    %to_port in %ALLOWED_PORTS
+    %from_port in %to_port
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-4.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-4.guard
new file mode 100644
index 0000000..d77847f
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-4.guard
@@ -0,0 +1,174 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   vpc_sg_restricted_common_ports_check
+# 
+# Description:
+#   This control checks whether Amazon EC2 security groups allow unrestricted incoming TCP or UDP traffic to ports '3389', '20', '23', '110', '143', '3306', '8080', '1433', '9200', '9300', '25', '445', '135', '21', '1434', '4333', '5432', '5500', '5601', '22', '3000', '5000', '8088', '8888'.
+# 
+# Reports on:
+#   AWS::EC2::SecurityGroup, AWS::EC2::SecurityGroupIngress
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation Hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any EC2 security group or EC2 security group ingress resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 security group resource or EC2 security group ingress resource
+#       And: EC2 security group or EC2 security group ingress resource has no rules allowing inbound traffic
+#            from source '0.0.0.0/0' or '::/0'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 security group resource or EC2 security group ingress resource
+#       And: EC2 security group or EC2 security group ingress resource has rules allowing inbound traffic
+#            from source '0.0.0.0/0' or '::/0'
+#       And: EC2 security group or EC2 security group ingress resource has a rule that allows all traffic
+#            ('IpProtocol' is set to '-1' or another protocol number)
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 security group resource or EC2 security group ingress resource
+#       And: EC2 security group or EC2 security group ingress resource has rules allowing inbound traffic
+#            from source '0.0.0.0/0' or '::/0'
+#       And: EC2 security group or EC2 security group ingress resource has no rules that allow all traffic
+#            ('IpProtocol' is not set to '-1' or another protocol number)
+#       And: Ports allowed are in the list of blocked ports
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 security group resource or EC2 security group ingress resource
+#       And: EC2 security group or EC2 security group ingress resource has rules allowing inbound traffic
+#            from source '0.0.0.0/0' or '::/0'
+#       And: EC2 security group or EC2 security group ingress resource has no rules that allow all traffic
+#            ('IpProtocol' is not set to '-1' or another protocol number)
+#       And: Ports allowed are not in the list of blocked ports
+#      Then: PASS
+
+#
+# Constants
+#
+let SECURITY_GROUP_TYPE = "AWS::EC2::SecurityGroup"
+let SECURITY_GROUP_INGRESS_TYPE = "AWS::EC2::SecurityGroupIngress"
+let BLOCKED_PORTS = [3389, 20, 23, 110, 143, 3306, 8080, 1433, 9200, 9300, 25, 445, 135, 21, 1434, 4333, 5432, 5500,
+                     5601, 22, 3000, 5000, 8088, 8888]
+let AUTHORIZED_PROTOCOLS = ["tcp", "udp", "icmp", "icmpv6"]
+let UNRESTRICTED_IPV4_RANGES = ["0.0.0.0/0"]
+let UNRESTRICTED_IPV6_RANGES = ["::/0"]
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_security_groups = Resources[
+    Type == %SECURITY_GROUP_TYPE
+]
+let ec2_security_group_ingress_rules = Resources[
+    Type == %SECURITY_GROUP_INGRESS_TYPE
+]
+
+#
+# Primary Rules
+#
+rule vpc_sg_restricted_common_ports_check when is_cfn_template(%INPUT_DOCUMENT)
+                                               %ec2_security_groups not empty {
+
+    check_security_group(%ec2_security_groups.Properties)
+        <<
+        [CT.EC2.PR.4]: Require that an Amazon EC2 security group does not allow incoming traffic for high-risk ports
+            [FIX]: Remove Amazon EC2 security group ingress rules that allow traffic from '0.0.0.0/0' or '::/0' to high risk ports: '3389', '20', '23', '110', '143', '3306', '8080', '1433', '9200', '9300', '25', '445', '135', '21', '1434', '4333', '5432', '5500', '5601', '22', '3000', '5000', '8088', '8888'.
+        >>
+}
+
+rule vpc_sg_restricted_common_ports_check when is_cfn_template(%INPUT_DOCUMENT)
+                                               %ec2_security_group_ingress_rules not empty {
+
+    check_ingress_rule(%ec2_security_group_ingress_rules.Properties)
+        <<
+        [CT.EC2.PR.4]: Require that an Amazon EC2 security group does not allow incoming traffic for high-risk ports
+            [FIX]: Remove Amazon EC2 security group ingress rules that allow traffic from '0.0.0.0/0' or '::/0' to high risk ports: '3389', '20', '23', '110', '143', '3306', '8080', '1433', '9200', '9300', '25', '445', '135', '21', '1434', '4333', '5432', '5500', '5601', '22', '3000', '5000', '8088', '8888'.
+        >>
+}
+
+rule vpc_sg_restricted_common_ports_check when is_cfn_hook(%INPUT_DOCUMENT, %SECURITY_GROUP_TYPE) {
+
+    check_security_group(%INPUT_DOCUMENT.%SECURITY_GROUP_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.4]: Require that an Amazon EC2 security group does not allow incoming traffic for high-risk ports
+            [FIX]: Remove Amazon EC2 security group ingress rules that allow traffic from '0.0.0.0/0' or '::/0' to high risk ports: '3389', '20', '23', '110', '143', '3306', '8080', '1433', '9200', '9300', '25', '445', '135', '21', '1434', '4333', '5432', '5500', '5601', '22', '3000', '5000', '8088', '8888'.
+        >>
+}
+
+rule vpc_sg_restricted_common_ports_check when is_cfn_hook(%INPUT_DOCUMENT, %SECURITY_GROUP_INGRESS_TYPE) {
+
+    check_ingress_rule(%INPUT_DOCUMENT.%SECURITY_GROUP_INGRESS_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.4]: Require that an Amazon EC2 security group does not allow incoming traffic for high-risk ports
+            [FIX]: Remove Amazon EC2 security group ingress rules that allow traffic from '0.0.0.0/0' or '::/0' to high risk ports: '3389', '20', '23', '110', '143', '3306', '8080', '1433', '9200', '9300', '25', '445', '135', '21', '1434', '4333', '5432', '5500', '5601', '22', '3000', '5000', '8088', '8888'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check_security_group(security_group) {
+    %security_group [
+        SecurityGroupIngress exists
+        SecurityGroupIngress is_list
+        SecurityGroupIngress not empty
+    ] {
+        SecurityGroupIngress[*] {
+            check_ingress_rule(this)
+        }
+    }
+}
+
+rule check_ingress_rule(ingress_rule) {
+    %ingress_rule[ CidrIp in %UNRESTRICTED_IPV4_RANGES or
+                   CidrIpv6 in %UNRESTRICTED_IPV6_RANGES ] {
+        # Scenario 3
+        IpProtocol exists
+        IpProtocol in %AUTHORIZED_PROTOCOLS
+
+        when IpProtocol in ["tcp", "udp"] {
+            FromPort exists
+            ToPort exists
+
+            let ingress_block = this
+
+            %BLOCKED_PORTS.* {
+                # Scenarios 4 and 5
+                check_ports(this, %ingress_block.FromPort, %ingress_block.ToPort)
+            }
+        }
+    }
+}
+
+rule check_ports(port, FromPort, ToPort) {
+    %FromPort > %port or
+    %ToPort < %port
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/ec2/ct-ec2-pr-5.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-5.guard
similarity index 100%
rename from rules/control-tower/ec2/ct-ec2-pr-5.guard
rename to rules/control-tower/cfn-guard/ec2/ct-ec2-pr-5.guard
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-6.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-6.guard
new file mode 100644
index 0000000..7a53e0f
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-6.guard
@@ -0,0 +1,96 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   ec2_transit_gateway_auto_vpc_attach_disabled_check
+# 
+# Description:
+#   This control checks whether Amazon EC2 transit gateways are configured to accept Amazon VPC attachment requests automatically.
+# 
+# Reports on:
+#   AWS::EC2::TransitGateway
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any EC2 transit gateway resources
+#      Then: SKIP
+#   Scenario: 2
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 transit gateway resource
+#        And: 'AutoAcceptSharedAttachments' configuration has been provided and is set to a value other than 'disable'
+#       Then: FAIL
+#   Scenario: 3
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 transit gateway resource
+#        And: 'AutoAcceptSharedAttachments' configuration has not been provided
+#       Then: PASS
+#   Scenario: 4
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an EC2 transit gateway resource
+#        And: 'AutoAcceptSharedAttachments' configuration has been provided and set to 'disable'
+#       Then: PASS
+
+#
+# Constants
+#
+let EC2_TRANSIT_GATEWAY_TYPE = "AWS::EC2::TransitGateway"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_transit_gateway = Resources.*[ Type == %EC2_TRANSIT_GATEWAY_TYPE ]
+
+#
+# Primary Rules
+#
+rule ec2_transit_gateway_auto_vpc_attach_disabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                             %ec2_transit_gateway not empty {
+    check(%ec2_transit_gateway.Properties)
+        <<
+        [CT.EC2.PR.6]: Require that Amazon EC2 transit gateways refuse automatic Amazon VPC attachment requests
+            [FIX]: Omit the 'AutoAcceptSharedAttachments' property or set the property to 'disable'.
+        >>
+}
+
+rule ec2_transit_gateway_auto_vpc_attach_disabled_check when is_cfn_hook(%INPUT_DOCUMENT, %EC2_TRANSIT_GATEWAY_TYPE) {
+    check(%INPUT_DOCUMENT.%EC2_TRANSIT_GATEWAY_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.6]: Require that Amazon EC2 transit gateways refuse automatic Amazon VPC attachment requests
+            [FIX]: Omit the 'AutoAcceptSharedAttachments' property or set the property to 'disable'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(ec2_transit_gateway) {
+    %ec2_transit_gateway {
+        # Scenario 3
+        AutoAcceptSharedAttachments not exists or
+        # Scenario 2 and 4
+        AutoAcceptSharedAttachments == "disable"
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/ec2/ct-ec2-pr-7.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-7.guard
similarity index 100%
rename from rules/control-tower/ec2/ct-ec2-pr-7.guard
rename to rules/control-tower/cfn-guard/ec2/ct-ec2-pr-7.guard
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-8.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-8.guard
new file mode 100644
index 0000000..310f35e
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-8.guard
@@ -0,0 +1,183 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   ec2_instance_no_public_ip_check
+# 
+# Description:
+#   This control checks whether your Amazon EC2 instance is configured to associate a public IP address.
+# 
+# Reports on:
+#   AWS::EC2::Instance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any EC2 instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 instance resource
+#       And: 'NetworkInterfaces' is not present on the EC2 instance resource or is an empty list
+#       And: 'SubnetId' is not provided as a top-level resource property
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 instance resource
+#       And: 'NetworkInterfaces' is present on the EC2 instance resource as a non-empty list
+#       And: 'NetworkInterfaceId' is present for a configuration in 'NetworkInterfaces' and is a non-empty string or
+#             valid local reference
+#      Then: SKIP
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 instance resource
+#       And: 'NetworkInterfaces' is not provided
+#       And: 'SubnetId' is provided as a top-level resource property
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 instance resource
+#       And: 'NetworkInterfaces' is present on the EC2 instance resource with one or more configurations
+#       And: 'NetworkInterfaceId' is not present or is present and and is an empty string or invalid local reference for
+#            a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is not present for a configuration in 'NetworkInterfaces'
+#      Then: FAIL
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 instance resource
+#       And: 'NetworkInterfaces' is present on the EC2 instance resource
+#       And: 'NetworkInterfaceId' is not present or is present and and is an empty string or invalid local reference for
+#            a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is present for a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is set to bool(true)
+#      Then: FAIL
+#   Scenario: 7
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an EC2 instance resource
+#       And: 'NetworkInterfaces' is present on the EC2 instance resource
+#       And: 'NetworkInterfaceId' is not present or is present and and is an empty string or invalid local reference for
+#            a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is present for a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is set to bool(false)
+#      Then: PASS
+
+#
+# Constants
+#
+let EC2_INSTANCE_TYPE = "AWS::EC2::Instance"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_instances = Resources.*[ Type == %EC2_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule ec2_instance_no_public_ip_check when is_cfn_template(%INPUT_DOCUMENT)
+                                          %ec2_instances not empty {
+    check(%ec2_instances.Properties)
+        <<
+        [CT.EC2.PR.8]: Require any Amazon EC2 instance to have a non-public IP address
+            [FIX]: Specify network interfaces using the 'NetworkInterfaces' property instead of the root level 'SubnetId' property. Set 'AssociatePublicIpAddress' to false within each 'NetworkInterfaces' configuration.
+        >>
+}
+
+rule ec2_instance_no_public_ip_check when is_cfn_hook(%INPUT_DOCUMENT, %EC2_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%EC2_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.8]: Require any Amazon EC2 instance to have a non-public IP address
+            [FIX]: Specify network interfaces using the 'NetworkInterfaces' property instead of the root level 'SubnetId' property. Set 'AssociatePublicIpAddress' to false within each 'NetworkInterfaces' configuration.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(ec2_instance) {
+    %ec2_instance[ SubnetId exists ] {
+        # Scenario 5
+        SubnetId not exists
+    }
+
+    %ec2_instance[
+        # Scenario 2
+        NetworkInterfaces exists
+        NetworkInterfaces is_list
+        NetworkInterfaces not empty
+    ] {
+        NetworkInterfaces[
+            # Scenario 3 and 4
+            filter_network_interfaces(this)
+        ] {
+            # Scenario 6
+            AssociatePublicIpAddress exists
+            # Scenarios 7 and 8
+            AssociatePublicIpAddress == false
+        }
+    }
+}
+
+rule filter_network_interfaces(network_interface) {
+    %network_interface {
+        NetworkInterfaceId not exists or
+        filter_property_is_empty_string(NetworkInterfaceId) or
+        filter_exclude_valid_local_reference(%INPUT_DOCUMENT, NetworkInterfaceId, "AWS::EC2::NetworkInterface")
+     }
+}
+
+rule filter_property_is_empty_string(value) {
+    %value {
+        this is_string
+        this == /\A\s*\z/
+    }
+}
+
+rule filter_exclude_valid_local_reference(doc, reference_properties, referenced_resource_type) {
+    %reference_properties {
+        this not is_string
+        this is_struct
+
+        when this.'Fn::GetAtt' exists {
+            'Fn::GetAtt' {
+                when filter_query_template_resources(%doc, this[0], %referenced_resource_type) {
+                    this not exists
+                }
+                this exists
+            }
+        }
+        when this.'Fn::GetAtt' not exists {
+            this exists
+        }
+    }
+}
+
+rule filter_query_template_resources(doc, resource_key, referenced_resource_type) {
+    let referenced_resource = %doc.Resources[ keys == %resource_key ]
+    %referenced_resource not empty
+    %referenced_resource {
+        Type in %referenced_resource_type
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-9.guard b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-9.guard
new file mode 100644
index 0000000..c1a47ee
--- /dev/null
+++ b/rules/control-tower/cfn-guard/ec2/ct-ec2-pr-9.guard
@@ -0,0 +1,182 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   ec2_launch_template_public_ip_disabled_check
+# 
+# Description:
+#   This control checks whether your Amazon EC2 launch templates are configured to assign public IP addresses to network interfaces.
+# 
+# Reports on:
+#   AWS::EC2::LaunchTemplate
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon EC2 launch template resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 launch template resource
+#       And: 'NetworkInterfaces' is not provided in 'LaunchTemplateData'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 launch template resource
+#       And: 'LaunchTemplateData.NetworkInterfaces' is present on the Amazon EC2 launch template resource as a non empty list
+#       And: 'NetworkInterfaceId' is present for a configuration in 'NetworkInterfaces' and is a non-empty string or
+#             valid local reference
+#      Then: SKIP
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 launch template resource
+#       And: 'LaunchTemplateData.NetworkInterfaces' is present on the Amazon EC2 launch template resource
+#       And: 'NetworkInterfaceId' is not present or is present and is an empty string or invalid local reference for
+#            a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is not present for a configuration in 'NetworkInterfaces'
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 launch template resource
+#       And: 'LaunchTemplateData.NetworkInterfaces' is present on the Amazon EC2 launch template resource
+#       And: 'NetworkInterfaceId' is not present or is present and is an empty string or invalid local reference for
+#            a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is present for a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is set to bool(true)
+#      Then: FAIL
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon EC2 launch template resource
+#       And: 'LaunchTemplateData.NetworkInterfaces' is present on the Amazon EC2 launch template resource
+#       And: 'NetworkInterfaceId' is not present or is present and is an empty string or invalid local reference for
+#            a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is present for a configuration in 'NetworkInterfaces'
+#       And: 'AssociatePublicIpAddress' is set to bool(false)
+#      Then: PASS
+
+#
+# Constants
+#
+let EC2_LAUNCH_TEMPLATE_TYPE = "AWS::EC2::LaunchTemplate"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let ec2_launch_templates = Resources.*[ Type == %EC2_LAUNCH_TEMPLATE_TYPE ]
+
+#
+# Primary Rules
+#
+rule ec2_launch_template_public_ip_disabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                       %ec2_launch_templates not empty {
+    check(%ec2_launch_templates.Properties)
+        <<
+        [CT.EC2.PR.9]: Require any Amazon EC2 launch template not to auto-assign public IP addresses to network interfaces
+            [FIX]: Set 'AssociatePublicIpAddress' to 'false' within each 'NetworkInterfaces' configuration in 'LaunchTemplateData'.
+        >>
+}
+
+rule ec2_launch_template_public_ip_disabled_check when is_cfn_hook(%INPUT_DOCUMENT, %EC2_LAUNCH_TEMPLATE_TYPE) {
+    check(%INPUT_DOCUMENT.%EC2_LAUNCH_TEMPLATE_TYPE.resourceProperties)
+        <<
+        [CT.EC2.PR.9]: Require any Amazon EC2 launch template not to auto-assign public IP addresses to network interfaces
+            [FIX]: Set 'AssociatePublicIpAddress' to 'false' within each 'NetworkInterfaces' configuration in 'LaunchTemplateData'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(ec2_launch_templates) {
+    %ec2_launch_templates[
+        # Scenario 2
+        filter_launch_template(this)
+    ] {
+        LaunchTemplateData {
+            NetworkInterfaces[
+                # Scenario 3 and 4
+                filter_network_interfaces(this)
+            ] {
+                # Scenario 5 and 6
+                AssociatePublicIpAddress exists
+                AssociatePublicIpAddress == false
+            }
+        }
+    }
+}
+
+rule filter_launch_template(ec2_launch_template) {
+    %ec2_launch_template {
+        LaunchTemplateData exists
+        LaunchTemplateData is_struct
+        LaunchTemplateData {
+            NetworkInterfaces exists
+            NetworkInterfaces is_list
+            NetworkInterfaces not empty
+        }
+    }
+}
+
+rule filter_network_interfaces(network_interface) {
+    %network_interface {
+        NetworkInterfaceId not exists or
+        filter_property_is_empty_string(NetworkInterfaceId) or
+        filter_exclude_valid_local_reference(%INPUT_DOCUMENT, NetworkInterfaceId, "AWS::EC2::NetworkInterface")
+    }
+}
+
+rule filter_property_is_empty_string(value) {
+    %value {
+        this is_string
+        this == /\A\s*\z/
+    }
+}
+
+rule filter_exclude_valid_local_reference(doc, reference_properties, referenced_resource_type) {
+    %reference_properties {
+        this not is_string
+        this is_struct
+
+        when this.'Fn::GetAtt' exists {
+            'Fn::GetAtt' {
+                when query_for_resource(%doc, this[0], %referenced_resource_type) {
+                    this not exists
+                }
+                this exists
+            }
+        }
+        when this.'Fn::GetAtt' not exists {
+            this exists
+        }
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
+
+rule query_for_resource(doc, resource_key, referenced_resource_type) {
+    let referenced_resource = %doc.Resources[ keys == %resource_key ]
+    %referenced_resource not empty
+    %referenced_resource {
+        Type == %referenced_resource_type
+    }
+}
diff --git a/rules/control-tower/iam/ct-iam-pr-2.guard b/rules/control-tower/cfn-guard/identityandaccessmanagement/ct-iam-pr-2.guard
similarity index 100%
rename from rules/control-tower/iam/ct-iam-pr-2.guard
rename to rules/control-tower/cfn-guard/identityandaccessmanagement/ct-iam-pr-2.guard
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-1.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-1.guard
new file mode 100644
index 0000000..3fdfe4d
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-1.guard
@@ -0,0 +1,124 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_multi_az_support_check
+# 
+# Description:
+#   This control checks whether high availability is configured for your Amazon RDS database instances.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#            'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#            'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MultiAZ' has not been specified
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#            'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MultiAZ' has been specified
+#       And: 'MultiAZ' has been set to bool(false)
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#            'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MultiAZ' has been specified
+#       And: 'MultiAZ' has been set to bool(true)
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2",
+    "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_multi_az_support_check when is_cfn_template(%INPUT_DOCUMENT)
+                                              %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.1]: Require that an Amazon RDS database instance is configured with multiple Availability Zones
+            [FIX]: Set 'MultiAZ' to 'true'.
+        >>
+}
+
+rule rds_instance_multi_az_support_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.1]: Require that an Amazon RDS database instance is configured with multiple Availability Zones
+            [FIX]: Set 'MultiAZ' to 'true'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [filter_engine(this)] {
+       # Scenario 3
+       MultiAZ exists
+       # Scenario 4 and 5
+       MultiAZ == true
+    }
+}
+
+rule filter_engine(db_properties) {
+    %db_properties {
+        # Scenario 2
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-10.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-10.guard
new file mode 100644
index 0000000..4dfd31f
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-10.guard
@@ -0,0 +1,124 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_copy_tags_to_snapshots_enabled_check
+# 
+# Description:
+#   This control checks whether Amazon RDS DB instances are configured to copy all tags to snapshots created.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'CopyTagsToSnapshot' has not been specified
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'CopyTagsToSnapshot' has been specified
+#       And: 'CopyTagsToSnapshot' has been set to bool(false)
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'CopyTagsToSnapshot' has been specified
+#       And: 'CopyTagsToSnapshot' has been set to bool(true)
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2",
+    "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_copy_tags_to_snapshots_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                      %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.10]: Require an Amazon RDS database instance to copy tags to snapshots
+            [FIX]: Set 'CopyTagsToSnapshot' to 'true'.
+        >>
+}
+
+rule rds_instance_copy_tags_to_snapshots_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.10]: Require an Amazon RDS database instance to copy tags to snapshots
+            [FIX]: Set 'CopyTagsToSnapshot' to 'true'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [filter_engine(this)] {
+       # Scenario: 3
+       CopyTagsToSnapshot exists
+       # Scenario: 4 and 5
+       CopyTagsToSnapshot == true
+    }
+}
+
+rule filter_engine(db_properties) {
+    %db_properties {
+        # Scenario: 2
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-11.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-11.guard
new file mode 100644
index 0000000..2adbcc9
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-11.guard
@@ -0,0 +1,159 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_deployed_in_vpc_check
+# 
+# Description:
+#   This control checks whether an Amazon RDS database (DB) instance is deployed in a VPC (that is, an EC2 VPC instance).
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#            'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#            'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'DBSubnetGroupName' has not been specified
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#            'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'DBSubnetGroupName' has been specified but is an empty string
+#            or invalid local reference to a DB Subnet Group
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#            'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'DBSubnetGroupName' has been specified but is a non-empty string
+#            or valid local reference to a DB Subnet Group
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2",
+    "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_deployed_in_vpc_check when is_cfn_template(%INPUT_DOCUMENT)
+                                             %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.11]: Require an Amazon RDS database instance to have a VPC configuration
+            [FIX]: Set a 'DBSubnetGroupName'.
+        >>
+}
+
+rule rds_instance_deployed_in_vpc_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.11]: Require an Amazon RDS database instance to have a VPC configuration
+            [FIX]: Set a 'DBSubnetGroupName'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [filter_engine(this)] {
+       # Scenario: 3
+       DBSubnetGroupName exists
+
+       # Scenario: 4 and 5
+       check_db_subnet_group(DBSubnetGroupName)
+    }
+}
+
+rule filter_engine(db_properties) {
+    %db_properties {
+        # Scenario: 2
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+rule check_db_subnet_group(db_subnet_group) {
+   %db_subnet_group {
+      check_is_string_and_not_empty(this) or
+      check_local_references(%INPUT_DOCUMENT, this, "AWS::RDS::DBSubnetGroup")
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
+
+rule check_is_string_and_not_empty(value) {
+    %value {
+        this is_string
+        this != /\A\s*\z/
+    }
+}
+
+rule check_local_references(doc, reference_properties, referenced_resource_type) {
+    %reference_properties {
+        'Fn::GetAtt' {
+            query_for_resource(%doc, this[0], %referenced_resource_type)
+                <<Local Stack reference was invalid>>
+        } or Ref {
+            query_for_resource(%doc, this, %referenced_resource_type)
+                <<Local Stack reference was invalid>>
+        }
+    }
+}
+
+rule query_for_resource(doc, resource_key, referenced_resource_type) {
+    let referenced_resource = %doc.Resources[ keys == %resource_key ]
+    %referenced_resource not empty
+    %referenced_resource {
+        Type == %referenced_resource_type
+    }
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-12.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-12.guard
new file mode 100644
index 0000000..f5ae790
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-12.guard
@@ -0,0 +1,127 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_cluster_event_notifications_configured_check
+# 
+# Description:
+#   This control checks whether your Amazon RDS event subscriptions for RDS clusters are configured to notify on event categories of 'maintenance' and 'failure.'
+# 
+# Reports on:
+#   AWS::RDS::EventSubscription
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon RDS event subscription resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is not 'db-cluster'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is 'db-cluster'
+#       And: 'Enabled' is not provided or set to bool(false)
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-cluster'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' does not contain both 'maintenance' and 'failure'
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-cluster'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' does not exist or is an empty list
+#      Then: PASS
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-cluster'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' contains both 'maintenance' and 'failure'
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_EVENTSUBSCRIPTION_TYPE = "AWS::RDS::EventSubscription"
+let INPUT_DOCUMENT = this
+let EVENT_CATEGORIES = ["maintenance","failure"]
+let EVENT_SOURCE_TYPE = "db-cluster"
+
+#
+# Assignments
+#
+let rds_event_subscriptions = Resources.*[ Type == %RDS_EVENTSUBSCRIPTION_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_cluster_event_notifications_configured_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                           %rds_event_subscriptions not empty {
+    check(%rds_event_subscriptions.Properties)
+        <<
+        [CT.RDS.PR.12]: Require an Amazon RDS event subscription to have critical cluster events configured
+            [FIX]: When 'SourceType' is set to 'db-cluster', set 'Enabled' to true and ensure that 'EventCategories' contains both 'maintenance' and 'failure' values.
+        >>
+}
+
+rule rds_cluster_event_notifications_configured_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_EVENTSUBSCRIPTION_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_EVENTSUBSCRIPTION_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.12]: Require an Amazon RDS event subscription to have critical cluster events configured
+            [FIX]: When 'SourceType' is set to 'db-cluster', set 'Enabled' to true and ensure that 'EventCategories' contains both 'maintenance' and 'failure' values.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(resource) {
+    %resource [ SourceType == %EVENT_SOURCE_TYPE ] {
+        Enabled exists
+        # Scenario 4
+        Enabled == true
+        # Scenario 5
+        EventCategories not exists or
+        # Scenario 6
+        check_event_categories_for_required_events(EventCategories)
+    }
+}
+
+rule check_event_categories_for_required_events(event_categories) {
+    %event_categories {
+        this exists
+        this is_list
+        this empty or
+        %EVENT_CATEGORIES.* in this
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-13.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-13.guard
new file mode 100644
index 0000000..1b7a059
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-13.guard
@@ -0,0 +1,125 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_deletion_protection_enabled_check
+# 
+# Description:
+#   This control checks whether an Amazon Relational Database Service (Amazon RDS) instance has deletion protection activated.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'DeletionProtection' has not been specified
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'DeletionProtection' has been specified
+#       And: 'DeletionProtection' has been set to bool(false)
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'DeletionProtection' has been specified
+#       And: 'DeletionProtection' has been set to bool(true)
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2",
+    "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_deletion_protection_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                         %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.13]: Require any Amazon RDS instance to have deletion protection configured
+            [FIX]: Set 'DeletionProtection' to 'true'.
+        >>
+}
+
+rule rds_instance_deletion_protection_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.13]: Require any Amazon RDS instance to have deletion protection configured
+            [FIX]: Set 'DeletionProtection' to 'true'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [filter_engine(this)] {
+       #Scenario: 3
+       DeletionProtection exists
+       #Scenario: 4 and 5
+       DeletionProtection == true
+    }
+}
+
+rule filter_engine(db_properties) {
+    %db_properties {
+        #Scenario: 2
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-14.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-14.guard
new file mode 100644
index 0000000..f5cbbbb
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-14.guard
@@ -0,0 +1,201 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_logging_enabled_check
+# 
+# Description:
+#   This rules checks whether Amazon Relational Database Service (RDS) instances have all available log types configured for export to Amazon CloudWatch Logs.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb',
+#            'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb',
+#            'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'EnableCloudwatchLogsExports' has not been specified or has been specified
+#             and is an empty list
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb',
+#            'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'EnableCloudwatchLogsExports' has been specified and is a non-empty list
+#       And: One or more log types in 'EnableCloudwatchLogsExports' are not supported by the specified 'Engine'
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb',
+#            'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'EnableCloudwatchLogsExports' has been specified and is a non-empty list
+#       And: 'EnableCloudwatchLogsExports' does not contain all log types supported by the specified 'Engine'
+#      Then: FAIL
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine'  is one of 'mariadb', 'mysql'
+#       And: 'EnableCloudwatchLogsExports' has been specified
+#       And: 'EnableCloudwatchLogsExports' value is a non-empty and all supported log types
+#             are enabled - 'audit', 'error', 'general', 'slowquery'
+#      Then: PASS
+#   Scenario: 7
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is 'postgres'
+#       And: 'EnableCloudwatchLogsExports' has been specified
+#       And: 'EnableCloudwatchLogsExports' value is a non-empty and all supported log types
+#             are enabled - 'postgresql', 'upgrade'
+#      Then: PASS
+#   Scenario: 8
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex',
+#            'sqlserver-web'
+#       And: 'EnableCloudwatchLogsExports' has been specified
+#       And: 'EnableCloudwatchLogsExports' value is a non-empty and all supported log types
+#             are enabled - 'agent', 'error'
+#      Then: PASS
+#   Scenario: 9
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb',
+#       And: 'EnableCloudwatchLogsExports' has been specified
+#       And: 'EnableCloudwatchLogsExports' value is a non-empty and all supported log types
+#             are enabled - 'alert', 'audit', 'listener', 'oemagent', 'trace'
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2",
+    "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+
+let MYSQL_OR_MARIA_ENGINES_SUBTYPES = [ "mariadb", "mysql" ]
+let POSTGRES_ENGINES_SUBTYPES = [ "postgres" ]
+let SQLSERVER_ENGINES_SUBTYPES = [ "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ]
+let ORACLE_ENGINES_SUBTYPES = [ "oracle-ee", "oracle-se2", "oracle-se1", "oracle-se" ]
+
+let MYSQL_OR_MARIA_SUPPORTED_LOG_TYPES = [ "audit", "error", "general", "slowquery" ]
+let POSTGRES_SUPPORTED_LOG_TYPES = [ "postgresql", "upgrade" ]
+let SQLSERVER_SUPPORTED_LOG_TYPES = [ "agent", "error" ]
+let ORACLE_SUPPORTED_LOG_TYPES = [ "alert", "audit", "listener", "oemagent", "trace" ]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_logging_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                             %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.14]: Require an Amazon RDS database instance to have logging configured
+            [FIX]: Specify 'EnableCloudwatchLogsExports' with a list of all supported log types for the Amazon RDS database instance engine.
+        >>
+}
+
+rule rds_instance_logging_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.14]: Require an Amazon RDS database instance to have logging configured
+            [FIX]: Specify 'EnableCloudwatchLogsExports' with a list of all supported log types for the Amazon RDS database instance engine.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [filter_engine(this)] {
+        # Scenario: 3
+        EnableCloudwatchLogsExports exists
+        check_is_list_and_not_empty(EnableCloudwatchLogsExports)
+
+        # Scenario: 4 and 5
+        when Engine IN %MYSQL_OR_MARIA_ENGINES_SUBTYPES {
+            %MYSQL_OR_MARIA_SUPPORTED_LOG_TYPES.* IN EnableCloudwatchLogsExports[*]
+            EnableCloudwatchLogsExports.* IN %MYSQL_OR_MARIA_SUPPORTED_LOG_TYPES[*]
+        }
+
+        # Scenario: 4 and 6
+        when Engine IN %POSTGRES_ENGINES_SUBTYPES {
+            %POSTGRES_SUPPORTED_LOG_TYPES.* IN EnableCloudwatchLogsExports[*]
+            EnableCloudwatchLogsExports.* IN %POSTGRES_SUPPORTED_LOG_TYPES[*]
+        }
+
+        # Scenario: 4 and 7
+        when Engine IN %SQLSERVER_ENGINES_SUBTYPES {
+            %SQLSERVER_SUPPORTED_LOG_TYPES.* in EnableCloudwatchLogsExports[*]
+            EnableCloudwatchLogsExports.* IN %SQLSERVER_SUPPORTED_LOG_TYPES[*]
+        }
+
+        # Scenario: 4 and 8
+        when Engine IN %ORACLE_ENGINES_SUBTYPES {
+            %ORACLE_SUPPORTED_LOG_TYPES.* in EnableCloudwatchLogsExports[*]
+            EnableCloudwatchLogsExports.* IN %ORACLE_SUPPORTED_LOG_TYPES[*]
+        }
+    }
+}
+
+rule filter_engine(db_properties) {
+    %db_properties {
+        # Scenario: 2
+        Engine exists
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+#
+# Utility Rules
+#
+rule check_is_list_and_not_empty(value) {
+    %value {
+        this is_list
+        this not empty
+    }
+}
+
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-15.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-15.guard
new file mode 100644
index 0000000..31a8fde
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-15.guard
@@ -0,0 +1,128 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_db_security_group_not_allowed_check
+# 
+# Description:
+#   This control checks whether any Amazon Relational Database Services (RDS) database (DB) security groups are created by, or associated to, an RDS DB instance, because DB security groups are intended for the EC2-Classic platform only.
+# 
+# Reports on:
+#   AWS::RDS::DBSecurityGroup, AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document does not contain any DB security group resources
+#        And: The input document does not contain any RDS DB instance resources
+#       Then: SKIP
+#   Scenario: 2
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains a DB security group resource
+#       Then: FAIL
+#   Scenario: 3
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document does not contain any DBsecurity group resources
+#        And: The input document contains an RDS DB instance resource
+#        And: 'DBSecurityGroups' has been specified on the RDS DB instance as a non empty list
+#       Then: FAIL
+#   Scenario: 4
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document does not contain any DB security group resources
+#        And: The input document contains an RDS DB instance resource
+#        And: 'DBSecurityGroups' has not been specified on the RDS DB instance or specified as an empty list
+#       Then: PASS
+
+#
+# Constants
+#
+let DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let DB_SECURITY_GROUP_TYPE = "AWS::RDS::DBSecurityGroup"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let db_instances = Resources.*[ Type == %DB_INSTANCE_TYPE ]
+let db_security_groups = Resources.*[ Type == %DB_SECURITY_GROUP_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_db_security_group_not_allowed_check when is_cfn_template(this)
+                                                  %db_security_groups not empty {
+    check_db_security_group(%db_security_groups)
+        <<
+        [CT.RDS.PR.15]: Require that an Amazon RDS instance does not create DB security groups
+            [FIX]: Omit the 'DBSecurityGroups' property. Instead, configure Amazon VPC security groups by means of the 'VPCSecurityGroups' property.
+        >>
+}
+
+rule rds_db_security_group_not_allowed_check when is_cfn_template(this)
+                                                  %db_instances not empty {
+    check_db_instance(%db_instances.Properties)
+        <<
+        [CT.RDS.PR.15]: Require that an Amazon RDS instance does not create DB security groups
+            [FIX]: Omit the 'DBSecurityGroups' property. Instead, configure Amazon VPC security groups by means of the 'VPCSecurityGroups' property.
+        >>
+}
+
+rule rds_db_security_group_not_allowed_check when is_cfn_hook(%INPUT_DOCUMENT, %DB_SECURITY_GROUP_TYPE) {
+    check_db_security_group(%INPUT_DOCUMENT.%DB_SECURITY_GROUP_TYPE)
+        <<
+        [CT.RDS.PR.15]: Require that an Amazon RDS instance does not create DB security groups
+            [FIX]: Omit the 'DBSecurityGroups' property. Instead, configure Amazon VPC security groups by means of the 'VPCSecurityGroups' property.
+        >>
+}
+
+rule rds_db_security_group_not_allowed_check when is_cfn_hook(%INPUT_DOCUMENT, %DB_INSTANCE_TYPE) {
+    check_db_instance(%INPUT_DOCUMENT.%DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.15]: Require that an Amazon RDS instance does not create DB security groups
+            [FIX]: Omit the 'DBSecurityGroups' property. Instead, configure Amazon VPC security groups by means of the 'VPCSecurityGroups' property.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check_db_security_group(db_security_group) {
+    # Scenario 2
+    %db_security_group empty
+}
+
+rule check_db_instance(db_instance) {
+    %db_instance {
+        # Scenario 3 and 4
+        DBSecurityGroups not exists or
+        check_is_empty_list(this)
+    }
+}
+
+rule check_is_empty_list(db_instance_configuration) {
+    %db_instance_configuration {
+        DBSecurityGroups is_list
+        DBSecurityGroups empty
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/rds/ct-rds-pr-16.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-16.guard
similarity index 100%
rename from rules/control-tower/rds/ct-rds-pr-16.guard
rename to rules/control-tower/cfn-guard/rds/ct-rds-pr-16.guard
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-17.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-17.guard
new file mode 100644
index 0000000..c942250
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-17.guard
@@ -0,0 +1,127 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_event_notifications_configured_check
+# 
+# Description:
+#   This control checks whether your Amazon RDS event subscriptions for RDS instances are configured to notify on event categories of 'maintenance', 'failure', and 'configuration change'.
+# 
+# Reports on:
+#   AWS::RDS::EventSubscription
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon RDS event subscription Resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is not 'db-instance'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is 'db-instance'
+#       And: 'Enabled' is not provided or set to bool(false)
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-instance'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' does not contain 'maintenance', 'failure', and 'configuration change'
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-instance'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' does not exist or is an empty list
+#      Then: PASS
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-instance'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' contains 'maintenance', 'failure', and 'configuration change'
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_EVENTSUBSCRIPTION_TYPE = "AWS::RDS::EventSubscription"
+let INPUT_DOCUMENT = this
+let EVENT_CATEGORIES = ["maintenance","failure","configuration change"]
+let EVENT_SOURCE_TYPE = "db-instance"
+
+#
+# Assignments
+#
+let rds_event_subscriptions = Resources.*[ Type == %RDS_EVENTSUBSCRIPTION_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_event_notifications_configured_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                            %rds_event_subscriptions not empty  {
+    check(%rds_event_subscriptions.Properties)
+        <<
+        [CT.RDS.PR.17]: Require an Amazon RDS event notification subscription to have critical database instance events configured
+            [FIX]: When 'SourceType' is set to 'db-instance', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'maintenance', 'failure', and 'configuration change' values.
+        >>
+}
+
+rule rds_instance_event_notifications_configured_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_EVENTSUBSCRIPTION_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_EVENTSUBSCRIPTION_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.17]: Require an Amazon RDS event notification subscription to have critical database instance events configured
+            [FIX]: When 'SourceType' is set to 'db-instance', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'maintenance', 'failure', and 'configuration change' values.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(resource) {
+    %resource [ SourceType == %EVENT_SOURCE_TYPE ] {
+        Enabled exists
+        # Scenario 4
+        Enabled == true
+        # Scenario 5
+        EventCategories not exists or
+        # Scenario 6
+        check_event_categories_for_required_events(EventCategories)
+    }
+}
+
+rule check_event_categories_for_required_events(event_categories) {
+    %event_categories {
+        this exists
+        this is_list
+        this empty or
+        %EVENT_CATEGORIES.* in this
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-18.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-18.guard
new file mode 100644
index 0000000..0d60d61
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-18.guard
@@ -0,0 +1,127 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_pg_event_notifications_configured_check
+# 
+# Description:
+#   This control checks whether your Amazon RDS event subscriptions for RDS parameter groups are configured to notify on event categories of 'configuration change.'
+# 
+# Reports on:
+#   AWS::RDS::EventSubscription
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon RDS event subscription resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is not 'db-parameter-group'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is 'db-parameter-group'
+#       And: 'Enabled' is not provided or set to bool(false)
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-parameter-group'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' does not contain 'configuration change'
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-parameter-group'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' does not exist or is an empty list
+#      Then: PASS
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-parameter-group'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' contains 'configuration change'
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_EVENTSUBSCRIPTION_TYPE = "AWS::RDS::EventSubscription"
+let INPUT_DOCUMENT = this
+let EVENT_CATEGORIES = ["configuration change"]
+let EVENT_SOURCE_TYPE = "db-parameter-group"
+
+#
+# Assignments
+#
+let rds_event_subscriptions = Resources.*[ Type == %RDS_EVENTSUBSCRIPTION_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_pg_event_notifications_configured_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                      %rds_event_subscriptions not empty  {
+    check(%rds_event_subscriptions.Properties)
+        <<
+        [CT.RDS.PR.18]: Require an Amazon RDS event notification subscription to have critical database parameter group events configured
+            [FIX]: When 'SourceType' is set to 'db-parameter-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'configuration change' as a value.
+        >>
+}
+
+rule rds_pg_event_notifications_configured_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_EVENTSUBSCRIPTION_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_EVENTSUBSCRIPTION_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.18]: Require an Amazon RDS event notification subscription to have critical database parameter group events configured
+            [FIX]: When 'SourceType' is set to 'db-parameter-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'configuration change' as a value.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(resource) {
+    %resource [ SourceType == %EVENT_SOURCE_TYPE ] {
+        Enabled exists
+        # Scenario 4
+        Enabled == true
+        # Scenario 5
+        EventCategories not exists or
+        # Scenario 6
+        check_event_categories_for_required_events(EventCategories)
+    }
+}
+
+rule check_event_categories_for_required_events(event_categories) {
+    %event_categories {
+        this exists
+        this is_list
+        this empty or
+        %EVENT_CATEGORIES.* in this
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-19.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-19.guard
new file mode 100644
index 0000000..4ab9fe2
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-19.guard
@@ -0,0 +1,127 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_sg_event_notifications_configured_check
+# 
+# Description:
+#   This control checks whether your Amazon RDS event subscriptions for RDS security groups are configured to notify on event categories of 'failure' and 'configuration change'
+# 
+# Reports on:
+#   AWS::RDS::EventSubscription
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon RDS event subscription resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription Resource
+#       And: 'SourceType' is provided and is not 'db-security-group'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is 'db-security-group'
+#       And: 'Enabled' is not provided or set to bool(false)
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-security-group'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' does not contain both 'failure' and 'configuration change'
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-security-group'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' does not exist or is an empty list
+#      Then: PASS
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS event subscription resource
+#       And: 'SourceType' is provided and is 'db-security-group'
+#       And: 'Enabled' is provided and set to bool(true)
+#       And: 'EventCategories' contains both 'failure' and 'configuration change'
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_EVENTSUBSCRIPTION_TYPE = "AWS::RDS::EventSubscription"
+let INPUT_DOCUMENT = this
+let EVENT_CATEGORIES = ["failure","configuration change"]
+let EVENT_SOURCE_TYPE = "db-security-group"
+
+#
+# Assignments
+#
+let rds_event_subscriptions = Resources.*[ Type == %RDS_EVENTSUBSCRIPTION_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_sg_event_notifications_configured_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                      %rds_event_subscriptions not empty  {
+    check(%rds_event_subscriptions.Properties)
+        <<
+        [CT.RDS.PR.19]: Require an Amazon RDS event notifications subscription to have critical database security group events configured
+            [FIX]: When 'SourceType' is set to 'db-security-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains both 'failure' and 'configuration change' values.
+        >>
+}
+
+rule rds_sg_event_notifications_configured_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_EVENTSUBSCRIPTION_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_EVENTSUBSCRIPTION_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.19]: Require an Amazon RDS event notifications subscription to have critical database security group events configured
+            [FIX]: When 'SourceType' is set to 'db-security-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains both 'failure' and 'configuration change' values.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(resource) {
+    %resource [ SourceType == %EVENT_SOURCE_TYPE ] {
+        Enabled exists
+        # Scenario 4
+        Enabled == true
+        # Scenario 5
+        EventCategories not exists or
+        # Scenario 6
+        check_event_categories_for_required_events(EventCategories)
+    }
+}
+
+rule check_event_categories_for_required_events(event_categories) {
+    %event_categories {
+        this exists
+        this is_list
+        this empty or
+        %EVENT_CATEGORIES.* in this
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-2.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-2.guard
new file mode 100644
index 0000000..3c8305e
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-2.guard
@@ -0,0 +1,186 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_enhanced_monitoring_enabled_check
+# 
+# Description:
+#   This control checks whether enhanced monitoring is activated for Amazon RDS instances.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee',
+#            'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee',
+#            'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MonitoringInterval' has not been specified
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee',
+#            'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MonitoringInterval' has been specified
+#       And: 'MonitoringInterval' has been set to '0'
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee',
+#            'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MonitoringInterval' has been specified
+#       And: 'MonitoringInterval' has not been set to a value from the list 1, 5, 10, 15, 30, 60
+#      Then: FAIL
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee',
+#            'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MonitoringInterval' has been specified
+#       And: 'MonitoringInterval' has been set to a value from the list 1, 5, 10, 15, 30, 60
+#       And: 'MonitoringRoleArn' has not been specified or specified as an empty string
+#      Then: FAIL
+#   Scenario: 7
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-se1', 'oracle-se', 'postgres', 'sqlserver-ee',
+#            'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MonitoringInterval' has been specified
+#       And: 'MonitoringInterval' has been set to a value from the list 1, 5, 10, 15, 30, 60
+#       And: 'MonitoringRoleArn' has been specified with a non-empty string or valid local reference
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "aurora", "aurora-mysql", "aurora-postgresql", "mariadb", "mysql",
+    "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb",
+    "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+let ALLOWED_EM_VALUES = [1, 5, 10, 15, 30, 60]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_enhanced_monitoring_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                         %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.2]: Require an Amazon RDS database instance or cluster to have enhanced monitoring configured
+            [FIX]: Set 'MonitoringInterval' to a supported value (1, 5, 10, 15, 30, 60), and set 'MonitoringRoleArn' to the ARN of an AWS IAM role.
+        >>
+}
+
+rule rds_instance_enhanced_monitoring_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.2]: Require an Amazon RDS database instance or cluster to have enhanced monitoring configured
+            [FIX]: Set 'MonitoringInterval' to a supported value (1, 5, 10, 15, 30, 60), and set 'MonitoringRoleArn' to the ARN of an AWS IAM role.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [filter_engine(this)] {
+        # Scenario: 3, 4, 5, 6 and 7
+        MonitoringInterval exists
+        MonitoringInterval in %ALLOWED_EM_VALUES
+        # Scenario: 6 and 7
+        MonitoringRoleArn exists
+        check_for_valid_monitor_role_arn(MonitoringRoleArn)
+    }
+}
+
+rule filter_engine(db_properties) {
+    %db_properties {
+        # Scenario: 2
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+rule check_for_valid_monitor_role_arn(iam_role_arn) {
+   %iam_role_arn {
+      check_is_string_and_not_empty(this) or
+      check_local_references(%INPUT_DOCUMENT, this, "AWS::IAM::Role")
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
+
+rule check_is_string_and_not_empty(value) {
+    %value {
+        this is_string
+        this != /\A\s*\z/
+    }
+}
+
+rule check_local_references(doc, reference_properties, referenced_resource_type) {
+    %reference_properties {
+        'Fn::GetAtt' {
+            query_for_resource(%doc, this[0], %referenced_resource_type)
+                <<Local Stack reference was invalid>>
+        } or Ref {
+            query_for_resource(%doc, this, %referenced_resource_type)
+                <<Local Stack reference was invalid>>
+        }
+    }
+}
+
+rule query_for_resource(doc, resource_key, referenced_resource_type) {
+    let referenced_resource = %doc.Resources[ keys == %resource_key ]
+    %referenced_resource not empty
+    %referenced_resource {
+        Type == %referenced_resource_type
+    }
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-20.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-20.guard
new file mode 100644
index 0000000..49595d4
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-20.guard
@@ -0,0 +1,167 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_no_default_ports_check
+# 
+# Description:
+#   This control checks whether Amazon Relational Database Service (RDS) database instances are configured for default database port for their specific engine types.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of  'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb',
+#            'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of  'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb',
+#            'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'Port' has not been specified
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of  'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb',
+#            'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'Port' has been specified
+#       And: 'Port' value is default port (includes mysql/mariadb port '3306', sqlserver
+#            port '1433', postgres port '5432', and oracle port '1521')
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine'  is one of 'mariadb', 'mysql'
+#       And: 'Port' has been specified
+#       And: 'Port' value is not equal to '3306'
+#      Then: PASS
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is 'postgres'
+#       And: 'Port' has been specified
+#       And: 'Port' value is not equal to '5432'
+#      Then: PASS
+#   Scenario: 7
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'Port' has been specified
+#       And: 'Port' value is not equal to '1433'
+#      Then: PASS
+#   Scenario: 8
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'oracle-ee', 'oracle-se2', 'oracle-ee-cdb', 'oracle-se2-cdb',
+#       And: 'Port' has been specified
+#       And: 'Port' value is not equal to '1521'
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let ORACLE_ENGINES = [ "oracle-ee", "oracle-se2", "oracle-se1", "oracle-se" ]
+let SQLSERVER_ENGINES = [ "sqlserver-ee", "sqlserver-se", "sqlserver-ex", "sqlserver-web" ]
+let MYSQL_OR_MARIA_ENGINES = [ "mariadb", "mysql" ]
+let POSTGRES_ENGINES = [ "postgres" ]
+let MYSQL_MARIA_DEFAULT_PORTS = [3306, "3306"]
+let POSTGRES_DEFAULT_PORTS = [5432, "5432"]
+let SQL_DEFAULT_PORTS = [1433, "1433"]
+let ORACLE_DEFAULT_PORTS = [1521, "1521"]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_no_default_ports_check when is_cfn_template(%INPUT_DOCUMENT)
+                                              %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.20]: Require an Amazon RDS database instance not to use a database engine default port
+            [FIX]: Set a value for 'Port' that is different than the default value for the Amazon RDS DB instance engine type.
+        >>
+}
+
+rule rds_instance_no_default_ports_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.20]: Require an Amazon RDS database instance not to use a database engine default port
+            [FIX]: Set a value for 'Port' that is different than the default value for the Amazon RDS DB instance engine type.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    # Scenario: 4 and 5
+    %rds_db_instance[ filter_engine(this, %MYSQL_OR_MARIA_ENGINES) ] {
+        check_port(Port, %MYSQL_MARIA_DEFAULT_PORTS)
+    }
+    # Scenario: 4 and 6
+    %rds_db_instance[ filter_engine(this, %POSTGRES_ENGINES) ] {
+        check_port(Port, %POSTGRES_DEFAULT_PORTS)
+    }
+    # Scenario: 4 and 7
+    %rds_db_instance[ filter_engine(this, %SQLSERVER_ENGINES) ] {
+        check_port(Port, %SQL_DEFAULT_PORTS)
+    }
+    # Scenario: 4 and 8
+    %rds_db_instance[ filter_engine(this, %ORACLE_ENGINES) ] {
+        check_port(Port, %ORACLE_DEFAULT_PORTS)
+    }
+}
+
+rule filter_engine(db_properties, engine) {
+    %db_properties {
+        # Scenario: 2
+        Engine exists
+        Engine is_string
+        Engine in %engine
+    }
+}
+
+rule check_port(port, default_ports) {
+    # Scenario: 3
+    %port exists
+    %port not in %default_ports
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-21.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-21.guard
new file mode 100644
index 0000000..e445dbd
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-21.guard
@@ -0,0 +1,102 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_cluster_default_admin_check
+# 
+# Description:
+#   This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has changed the administrator username from its default value.
+# 
+# Reports on:
+#   AWS::RDS::DBCluster
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB cluster resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'MasterUsername' has not been provided
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'MasterUsername' has been provided and it is set to 'admin' or 'postgres'
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'MasterUsername' has been provided and is not set to 'admin' or 'postgres'
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster"
+let DISALLOWED_MASTER_USERNAMES = ["admin", "postgres"]
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_cluster_default_admin_check when is_cfn_template(%INPUT_DOCUMENT)
+                                          %db_clusters not empty {
+    check(%db_clusters.Properties)
+        <<
+        [CT.RDS.PR.21]: Require an Amazon RDS DB cluster to have a unique administrator username
+            [FIX]: Set 'MasterUsername' to a value other than 'admin' or 'postgres'.
+        >>
+}
+
+rule rds_cluster_default_admin_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.21]: Require an Amazon RDS DB cluster to have a unique administrator username
+            [FIX]: Set 'MasterUsername' to a value other than 'admin' or 'postgres'.
+        >>
+}
+
+rule check(db_cluster) {
+    %db_cluster [
+        # scenario 2
+        filter_master_username_provided(this)
+    ] {
+        # scenario 3 and 4
+        MasterUsername not in %DISALLOWED_MASTER_USERNAMES
+    }
+}
+
+#
+# Utility Rules
+#
+rule filter_master_username_provided(dbcluster_properties) {
+    %dbcluster_properties{
+        MasterUsername exists
+    }
+}
+
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-22.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-22.guard
new file mode 100644
index 0000000..03131cb
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-22.guard
@@ -0,0 +1,115 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_default_admin_check
+# 
+# Description:
+#   This control checks whether an Amazon RDS database has changed the adminstrator username from its default value.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MasterUsername' has been specified and is one of 'postgres' or 'admin'
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'MasterUsername' has been specified and is not one of 'postgres' or 'admin'
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2",
+    "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+let RDS_DEFAULT_USERNAMES = [ "postgres", "admin" ]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_default_admin_check when is_cfn_template(%INPUT_DOCUMENT)
+                                           %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.22]: Require an Amazon RDS database instance to have a unique administrator username
+            [FIX]: Set 'MasterUsername' to a value other than 'postgres' or 'admin'.
+        >>
+}
+
+rule rds_instance_default_admin_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.22]: Require an Amazon RDS database instance to have a unique administrator username
+            [FIX]: Set 'MasterUsername' to a value other than 'postgres' or 'admin'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [ filter_engine_and_master_username_provided(this) ] {
+        # Scenario: 3 and 4
+        MasterUsername not in %RDS_DEFAULT_USERNAMES
+    }
+}
+
+rule filter_engine_and_master_username_provided(db_properties) {
+    %db_properties {
+        # Scenario: 2
+        MasterUsername exists
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-23.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-23.guard
new file mode 100644
index 0000000..f20b675
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-23.guard
@@ -0,0 +1,97 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_public_access_check
+# 
+# Description:
+#   This rule checks whether Amazon Relational Database Service (RDS) database (DB) instances are publicly accessible, as determined by checking the 'PubliclyAccessible' configuration property.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document does not contain any RDS DB instance resources
+#       Then: SKIP
+#   Scenario: 2
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB instance resource
+#        And: 'PubliclyAccessible' has not been specified
+#       Then: FAIL
+#   Scenario: 3
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB instance resource
+#        And: 'PubliclyAccessible' is present and is a value other than bool(false)
+#       Then: FAIL
+#   Scenario: 4
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB instance resource
+#        And: 'PubliclyAccessible' has been specified and set to bool(false)
+#       Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_public_access_check when is_cfn_template(%INPUT_DOCUMENT)
+                                           %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.23]: Require an Amazon RDS database instance to not be publicly accessible
+            [FIX]: Set the value of 'PubliclyAccessible' to 'false'.
+        >>
+}
+
+rule rds_instance_public_access_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.23]: Require an Amazon RDS database instance to not be publicly accessible
+            [FIX]: Set the value of 'PubliclyAccessible' to 'false'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance{
+       #Scenario: 2
+       PubliclyAccessible exists
+       #Scenario: 3 and 4
+       PubliclyAccessible == false
+
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-24.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-24.guard
new file mode 100644
index 0000000..b3a3091
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-24.guard
@@ -0,0 +1,122 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_storage_encrypted_check
+# 
+# Description:
+#   This control checks whether storage encryption is enabled for your Amazon RDS database (DB) instance.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS DB instance resource
+#       And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#            'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an Amazon RDS DB instance resource
+#        And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#        And: 'StorageEncrypted' has not been provided
+#       Then: FAIL
+#   Scenario: 4
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an Amazon RDS DB instance resource
+#        And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#        And: 'StorageEncrypted' has been provided and set to bool(false)
+#       Then: FAIL
+#   Scenario: 5
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB instance resource
+#        And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#        And: 'StorageEncrypted' has been provided and set to bool(true)
+#       Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2",
+    "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_storage_encrypted_check when is_cfn_template(%INPUT_DOCUMENT)
+                                               %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.24]: Require an Amazon RDS database instance to have encryption at rest configured
+            [FIX]: The parameter 'StorageEncrypted' must be set to true for RDS DB Instances.
+        >>
+}
+
+rule rds_instance_storage_encrypted_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.24]: Require an Amazon RDS database instance to have encryption at rest configured
+            [FIX]: The parameter 'StorageEncrypted' must be set to true for RDS DB Instances.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [filter_restore_and_engine(this)] {
+        #Scenario: 3
+        StorageEncrypted exists
+        #Scenario: 4 and 5
+        StorageEncrypted == true
+    }
+}
+
+rule filter_restore_and_engine(db_properties) {
+    %db_properties {
+        #Scenario: 2
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-3.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-3.guard
new file mode 100644
index 0000000..26e7d32
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-3.guard
@@ -0,0 +1,95 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_cluster_deletion_protection_enabled_check
+# 
+# Description:
+#   This control checks whether your Amazon Relational Database Service (Amazon RDS) cluster has deletion protection activated.
+# 
+# Reports on:
+#   AWS::RDS::DBCluster
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#  None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon RDS DB cluster resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS DB cluster resource
+#       And: 'DeletionProtection' has not been specified
+#      Then: FAIL
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS DB cluster resource
+#       And: 'DeletionProtection' has been specified
+#       And: 'DeletionProtection' has been set to bool(false)
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon RDS DB cluster resource
+#       And: 'DeletionProtection' has been specified
+#       And: 'DeletionProtection' has been set to bool(true)
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_cluster_deletion_protection_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                        %db_clusters not empty {
+    check(%db_clusters.Properties)
+        <<
+        [CT.RDS.PR.3]: Require an Amazon RDS cluster to have deletion protection configured
+            [FIX]: Set the value of the 'DeletionProtection' parameter to true.
+        >>
+}
+
+rule rds_cluster_deletion_protection_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.3]: Require an Amazon RDS cluster to have deletion protection configured
+            [FIX]: Set the value of the 'DeletionProtection' parameter to true.
+        >>
+}
+
+rule check(properties) {
+    %properties {
+        # Scenario 2
+        DeletionProtection exists
+        # Scenario 3 and 4
+        DeletionProtection == true
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-4.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-4.guard
new file mode 100644
index 0000000..64193ff
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-4.guard
@@ -0,0 +1,114 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_cluster_iam_authentication_enabled_check
+# 
+# Description:
+#   This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has AWS IAM database authentication activated.
+# 
+# Reports on:
+#   AWS::RDS::DBCluster
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation document or CloudFormation hook document
+#       And: The input document does not contain any RDS DB cluster resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation document or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'Engine' provided is not one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation document or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql'
+#       And: 'EnableIAMDatabaseAuthentication' has not been provided
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation document or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql'
+#       And: 'EnableIAMDatabaseAuthentication' has been provided
+#       And: 'EnableIAMDatabaseAuthentication' has been set to a value other than bool(true)
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation document or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql'
+#       And: 'EnableIAMDatabaseAuthentication' has been provided
+#       And: 'EnableIAMDatabaseAuthentication' has been set to bool(true)
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster"
+let SUPPORTED_DB_CLUSTER_ENGINES = ["aurora", "aurora-mysql","aurora-postgresql"]
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_cluster_iam_authentication_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                       %db_clusters not empty {
+    check(%db_clusters.Properties)
+        <<
+        [CT.RDS.PR.4]: Require an Amazon RDS database cluster to have AWS IAM database authentication configured
+            [FIX]: Set 'EnableIAMDatabaseAuthentication' to 'true'.
+        >>
+}
+
+rule rds_cluster_iam_authentication_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.4]: Require an Amazon RDS database cluster to have AWS IAM database authentication configured
+            [FIX]: Set 'EnableIAMDatabaseAuthentication' to 'true'.
+        >>
+}
+
+rule check(db_cluster) {
+    %db_cluster [
+        # Scenario 2
+        filter_engine(this)
+    ] {
+       # Scenario 3
+       EnableIAMDatabaseAuthentication exists
+       # Scenario 4 and 5
+       EnableIAMDatabaseAuthentication == true
+    }
+}
+
+rule filter_engine(cluster_properties) {
+    %cluster_properties {
+        Engine exists
+        Engine in %SUPPORTED_DB_CLUSTER_ENGINES
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-5.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-5.guard
new file mode 100644
index 0000000..50e999a
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-5.guard
@@ -0,0 +1,133 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_automatic_minor_version_upgrade_enabled_check
+# 
+# Description:
+#   This control checks whether automatic minor version upgrades are enabled for an Amazon RDS database instance.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', 'oracle-se2-cdb',
+#            'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web',
+#            'postgres'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', 'oracle-se2-cdb',
+#            'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web',
+#            'postgres'
+#       And: 'AutoMinorVersionUpgrade' has been specified
+#       And: 'AutoMinorVersionUpgrade' has been set to bool(false)
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', 'oracle-se2-cdb',
+#            'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web',
+#            'postgres'
+#       And: 'AutoMinorVersionUpgrade' has not been specified
+#      Then: PASS
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'aurora', 'aurora-mysql', 'aurora-postgresql', 'mariadb', 'mysql',
+#            'oracle-ee', 'oracle-ee-cdb', 'oracle-se2', 'oracle-se2-cdb',
+#            'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web',
+#            'postgres'
+#       And: 'AutoMinorVersionUpgrade' has been specified
+#       And: 'AutoMinorVersionUpgrade' has been set to bool(true)
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "aurora", "aurora-mysql", "aurora-postgresql", "mariadb", "mysql",
+    "oracle-ee", "oracle-ee-cdb", "oracle-se2", "oracle-se2-cdb",
+    "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_automatic_minor_version_upgrade_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                               %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.5]: Require an Amazon RDS database instance to have minor version upgrades configured
+            [FIX]: Omit the 'AutoMinorVersionUpgrade' property or set it to 'true'.
+        >>
+}
+
+rule rds_instance_automatic_minor_version_upgrade_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.5]: Require an Amazon RDS database instance to have minor version upgrades configured
+            [FIX]: Omit the 'AutoMinorVersionUpgrade' property or set it to 'true'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [ filter_engine(this) ] {
+        # Scenario: 4
+        AutoMinorVersionUpgrade not exists or
+        # Scenario: 3 and 5
+        AutoMinorVersionUpgrade == true
+    }
+}
+
+rule filter_engine(db_properties) {
+    %db_properties {
+        # Scenario: 2
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-6.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-6.guard
new file mode 100644
index 0000000..891afa6
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-6.guard
@@ -0,0 +1,142 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   aurora_cluster_backtracking_enabled_check
+# 
+# Description:
+#   This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has backtracking enabled.
+# 
+# Reports on:
+#   AWS::RDS::DBCluster
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#    Scenario: 1
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document does not contain any RDS DB cluster resources
+#       Then: SKIP
+#    Scenario: 2
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB cluster resource
+#        And: 'Engine' provided is not one of 'aurora' or 'aurora-mysql'
+#       Then: SKIP
+#    Scenario: 3
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB cluster resource
+#        And: 'Engine' provided is one of 'aurora' or 'aurora-mysql'
+#        And: 'EngineMode' provided is not one of 'provisioned' or 'parallelquery'
+#       Then: SKIP
+#    Scenario: 4
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB cluster resource
+#        And: 'ServerlessV2ScalingConfiguration' is provided
+#        And: 'Engine' provided is 'aurora-mysql'
+#        And: 'EngineVersion' provided is '8.0.mysql_aurora.3.02.0' or higher
+#       Then: SKIP
+#    Scenario: 5
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB cluster resource
+#        And: 'Engine' provided is one of 'aurora' or 'aurora-mysql'
+#        And: 'EngineMode' is not provided or 'EngineMode' provided is one of 'provisioned' or 'parallelquery'
+#        And: 'BacktrackWindow' has not been provided
+#       Then: FAIL
+#    Scenario: 6
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB cluster resource
+#        And: 'Engine' provided is one of 'aurora' or 'aurora-mysql'
+#        And: 'EngineMode' is not provided or 'EngineMode' provided is one of 'provisioned' or 'parallelquery'
+#        And: 'BacktrackWindow' has been provided and is set to 0
+#       Then: FAIL
+#    Scenario: 7
+#      Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#        And: The input document contains an RDS DB cluster resource
+#        And: 'Engine' provided is one of 'aurora' or 'aurora-mysql'
+#        And: 'EngineMode' is not provided or 'EngineMode' provided is one of 'provisioned' or 'parallelquery'
+#        And: 'BacktrackWindow' has been provided and is set to a value > 0
+#       Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster"
+let SUPPORTED_DB_CLUSTER_ENGINES = ["aurora", "aurora-mysql"]
+let SUPPORTED_DB_CLUSTER_ENGINE_MODES = ["provisioned", "parallelquery"]
+let AURORA_SERVERLESS_V2_SUPPORTED_ENGINE = ["aurora-mysql"]
+let AURORA_V3_SERVERLESS_V2_NOT_SUPPORTED_PATTERN = /^8\.0\.mysql_aurora\.3\.01\./
+let AURORA_V3_SERVERLESS_V2_SUPPORTED_PATTERN = /^8\.0\.mysql_aurora\.3/
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ]
+
+#
+# Primary Rules
+#
+rule aurora_cluster_backtracking_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                    %db_clusters not empty {
+    check(%db_clusters.Properties)
+        <<
+        [CT.RDS.PR.6]: Require an Amazon RDS database cluster to have backtracking configured
+            [FIX]: Set 'BacktrackWindow' to a number between '1' and '259200'.
+        >>
+}
+
+rule aurora_cluster_backtracking_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.6]: Require an Amazon RDS database cluster to have backtracking configured
+            [FIX]: Set 'BacktrackWindow' to a number between '1' and '259200'.
+        >>
+}
+
+rule check(db_cluster) {
+    %db_cluster [
+        filter_engine_enginemode_and_serverless_v2(this)
+    ] {
+        # Scenario 5
+        BacktrackWindow exists
+        # Scenario 6 and 7
+        BacktrackWindow > 0
+    }
+}
+
+rule filter_engine_enginemode_and_serverless_v2(db_cluster) {
+    # Scenario 2 and 3
+    %db_cluster {
+        Engine exists
+        Engine in %SUPPORTED_DB_CLUSTER_ENGINES
+        EngineMode not exists or
+        EngineMode in %SUPPORTED_DB_CLUSTER_ENGINE_MODES
+    }
+    #Scenario 4
+    %db_cluster [
+        ServerlessV2ScalingConfiguration exists
+        Engine in %AURORA_SERVERLESS_V2_SUPPORTED_ENGINE
+    ] {
+        EngineVersion in %AURORA_V3_SERVERLESS_V2_NOT_SUPPORTED_PATTERN or
+        EngineVersion not in %AURORA_V3_SERVERLESS_V2_SUPPORTED_PATTERN
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-7.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-7.guard
new file mode 100644
index 0000000..4c51353
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-7.guard
@@ -0,0 +1,116 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_iam_authentication_enabled_check
+# 
+# Description:
+#   This control checks whether an Amazon RDS database (DB) instance has AWS IAM database authentication activated.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not in-scope database engines - 'mariadb', 'mysql', 'postgres'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is in-scope database engines - 'mariadb', 'mysql', 'postgres'
+#       And: 'EnableIAMDatabaseAuthentication' has not been specified
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is in-scope database engines - 'mariadb', 'mysql', 'postgres'
+#       And: 'EnableIAMDatabaseAuthentication' has been specified
+#       And: 'EnableIAMDatabaseAuthentication' has been set to bool(false)
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is in-scope database engines - 'mariadb', 'mysql', 'postgres'
+#       And: 'EnableIAMDatabaseAuthentication' has been specified
+#       And: 'EnableIAMDatabaseAuthentication' has been set to bool(true)
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = ["mariadb", "mysql", "postgres"]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_iam_authentication_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                        %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.7]: Require Amazon RDS database instances to have AWS IAM authentication configured
+            [FIX]: Set 'EnableIAMDatabaseAuthentication' to 'true'.
+        >>
+}
+
+rule rds_instance_iam_authentication_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.7]: Require Amazon RDS database instances to have AWS IAM authentication configured
+            [FIX]: Set 'EnableIAMDatabaseAuthentication' to 'true'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [filter_engine(this)] {
+        #Scenario: 3
+        EnableIAMDatabaseAuthentication exists
+        #Scenario: 4 and 5
+        EnableIAMDatabaseAuthentication == true
+    }
+}
+
+rule filter_engine(db_properties) {
+    %db_properties {
+        #Scenario: 2
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-8.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-8.guard
new file mode 100644
index 0000000..113b6d6
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-8.guard
@@ -0,0 +1,132 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_instance_backup_enabled_check
+# 
+# Description:
+#   This control checks whether Amazon RDS database (DB) instances have automated backups enabled, and verifies that the backup retention period is greater than or equal to seven (7) days.
+# 
+# Reports on:
+#   AWS::RDS::DBInstance
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB instance resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is not one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'BackupRetentionPeriod' has been specified
+#       And: 'BackupRetentionPeriod' has been set to 0 (backup disabled)
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'BackupRetentionPeriod' has not been specified
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'BackupRetentionPeriod' has been specified
+#       And: 'BackupRetentionPeriod' has been set to < 7
+#      Then: FAIL
+#   Scenario: 6
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB instance resource
+#       And: 'Engine' is one of 'mariadb', 'mysql', 'oracle-ee', 'oracle-ee-cdb', 'oracle-se2',
+#             'oracle-se2-cdb', 'postgres', 'sqlserver-ee', 'sqlserver-se', 'sqlserver-ex', 'sqlserver-web'
+#       And: 'BackupRetentionPeriod' has been specified
+#       And: 'BackupRetentionPeriod' has been set to an integer >= 7
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_INSTANCE_TYPE = "AWS::RDS::DBInstance"
+let INPUT_DOCUMENT = this
+let SUPPORTED_RDS_INSTANCE_ENGINES = [
+    "mariadb", "mysql", "oracle-ee", "oracle-ee-cdb", "oracle-se2",
+    "oracle-se2-cdb", "postgres", "sqlserver-ee", "sqlserver-se",
+    "sqlserver-ex", "sqlserver-web"
+]
+
+#
+# Assignments
+#
+let rds_db_instances = Resources.*[ Type == %RDS_DB_INSTANCE_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_instance_backup_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                            %rds_db_instances not empty {
+    check(%rds_db_instances.Properties)
+        <<
+        [CT.RDS.PR.8]: Require an Amazon RDS database instance to have automatic backups configured
+            [FIX]: Set 'BackupRetentionPeriod' to an integer value between 7 and 35 days (inclusive).
+        >>
+}
+
+rule rds_instance_backup_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_INSTANCE_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_INSTANCE_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.8]: Require an Amazon RDS database instance to have automatic backups configured
+            [FIX]: Set 'BackupRetentionPeriod' to an integer value between 7 and 35 days (inclusive).
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(rds_db_instance) {
+    %rds_db_instance [ filter_db_identifier_and_engine(this) ] {
+        # Scenario: 3, 4, 5 and 6
+        BackupRetentionPeriod exists
+        BackupRetentionPeriod >= 7
+    }
+}
+
+rule filter_db_identifier_and_engine(db_properties) {
+    %db_properties {
+        # Scenario: 2
+        Engine exists
+        Engine is_string
+        Engine in %SUPPORTED_RDS_INSTANCE_ENGINES
+    }
+}
+
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/rds/ct-rds-pr-9.guard b/rules/control-tower/cfn-guard/rds/ct-rds-pr-9.guard
new file mode 100644
index 0000000..a0a41fe
--- /dev/null
+++ b/rules/control-tower/cfn-guard/rds/ct-rds-pr-9.guard
@@ -0,0 +1,114 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   rds_cluster_copy_tags_to_snapshots_enabled_check
+# 
+# Description:
+#   This control checks whether an Amazon RDS DB cluster is configured to copy all tags to snapshots created.
+# 
+# Reports on:
+#   AWS::RDS::DBCluster
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any RDS DB cluster resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'Engine' provided is not one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql'
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql'
+#       And: 'CopyTagsToSnapshot' has not been provided
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql'
+#       And: 'CopyTagsToSnapshot' has been provided
+#       And: 'CopyTagsToSnapshot' has been set to a value other than bool(true)
+#      Then: FAIL
+#   Scenario: 5
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an RDS DB cluster resource
+#       And: 'Engine' provided is one of 'aurora' or 'aurora-mysql' or 'aurora-postgresql'
+#       And: 'CopyTagsToSnapshot' has been provided
+#       And: 'CopyTagsToSnapshot' has been set to bool(true)
+#      Then: PASS
+
+#
+# Constants
+#
+let RDS_DB_CLUSTER_TYPE = "AWS::RDS::DBCluster"
+let SUPPORTED_DB_CLUSTER_ENGINES = ["aurora", "aurora-mysql","aurora-postgresql"]
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let db_clusters = Resources.*[ Type == %RDS_DB_CLUSTER_TYPE ]
+
+#
+# Primary Rules
+#
+rule rds_cluster_copy_tags_to_snapshots_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                                           %db_clusters not empty {
+    check(%db_clusters.Properties)
+        <<
+        [CT.RDS.PR.9]: Require an Amazon RDS database cluster to copy tags to snapshots
+            [FIX]: Set 'CopyTagsToSnapshot' to 'true'.
+        >>
+}
+
+rule rds_cluster_copy_tags_to_snapshots_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %RDS_DB_CLUSTER_TYPE) {
+    check(%INPUT_DOCUMENT.%RDS_DB_CLUSTER_TYPE.resourceProperties)
+        <<
+        [CT.RDS.PR.9]: Require an Amazon RDS database cluster to copy tags to snapshots
+            [FIX]: Set 'CopyTagsToSnapshot' to 'true'.
+        >>
+}
+
+rule check(db_cluster) {
+    %db_cluster [
+        # Scenario 2
+        filter_engine(this)
+    ] {
+       # Scenario 3
+       CopyTagsToSnapshot exists
+       # Scenario 4 and 5
+       CopyTagsToSnapshot == true
+    }
+}
+
+rule filter_engine(cluster_properties) {
+    %cluster_properties {
+        Engine exists
+        Engine in %SUPPORTED_DB_CLUSTER_ENGINES
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/s3/ct-s3-pr-1.guard b/rules/control-tower/cfn-guard/s3/ct-s3-pr-1.guard
similarity index 86%
rename from rules/control-tower/s3/ct-s3-pr-1.guard
rename to rules/control-tower/cfn-guard/s3/ct-s3-pr-1.guard
index 9e95e2f..b77466d 100644
--- a/rules/control-tower/s3/ct-s3-pr-1.guard
+++ b/rules/control-tower/cfn-guard/s3/ct-s3-pr-1.guard
@@ -1,24 +1,22 @@
-
 # ###################################
 ##       Rule Specification        ##
 #####################################
-#
+# 
 # Rule Identifier:
 #   s3_bucket_level_public_access_prohibited_check
-#
+# 
 # Description:
-#   Checks whether Amazon Simple Storage Service (Amazon S3) buckets have a bucket-level Block Public Access (BPA)
-#   configuration.
-#
+#   This control checks whether your Amazon Simple Storage Service (Amazon S3) bucket has a bucket-level Block Public Access (BPA) configuration.
+# 
 # Reports on:
 #   AWS::S3::Bucket
-#
+# 
 # Evaluates:
 #   AWS CloudFormation, AWS CloudFormation hook
-#
+# 
 # Rule Parameters:
 #   None
-#
+# 
 # Scenarios:
 #   Scenario: 1
 #     Given: The input document is an AWS CloudFormation or CloudFormation hook document
@@ -70,7 +68,7 @@ rule s3_bucket_level_public_access_prohibited_check when is_cfn_template(%INPUT_
     check(%s3_buckets.Properties)
         <<
         [CT.S3.PR.1]: Require an Amazon S3 bucket to have block public access settings configured
-        [FIX]: The parameters 'BlockPublicAcls', 'BlockPublicPolicy', 'IgnorePublicAcls', 'RestrictPublicBuckets' must be set to true under the bucket-level 'PublicAccessBlockConfiguration'.
+            [FIX]: The parameters 'BlockPublicAcls', 'BlockPublicPolicy', 'IgnorePublicAcls', 'RestrictPublicBuckets' must be set to true under the bucket-level 'PublicAccessBlockConfiguration'.
         >>
 }
 
@@ -78,7 +76,7 @@ rule s3_bucket_level_public_access_prohibited_check when is_cfn_hook(%INPUT_DOCU
     check(%INPUT_DOCUMENT.%S3_BUCKET_TYPE.resourceProperties)
         <<
         [CT.S3.PR.1]: Require an Amazon S3 bucket to have block public access settings configured
-        [FIX]: The parameters 'BlockPublicAcls', 'BlockPublicPolicy', 'IgnorePublicAcls', 'RestrictPublicBuckets' must be set to true under the bucket-level 'PublicAccessBlockConfiguration'.
+            [FIX]: The parameters 'BlockPublicAcls', 'BlockPublicPolicy', 'IgnorePublicAcls', 'RestrictPublicBuckets' must be set to true under the bucket-level 'PublicAccessBlockConfiguration'.
         >>
 }
 
diff --git a/rules/control-tower/s3/ct-s3-pr-2.guard b/rules/control-tower/cfn-guard/s3/ct-s3-pr-2.guard
similarity index 90%
rename from rules/control-tower/s3/ct-s3-pr-2.guard
rename to rules/control-tower/cfn-guard/s3/ct-s3-pr-2.guard
index 870a75b..27f0bae 100644
--- a/rules/control-tower/s3/ct-s3-pr-2.guard
+++ b/rules/control-tower/cfn-guard/s3/ct-s3-pr-2.guard
@@ -1,22 +1,22 @@
 # ###################################
 ##       Rule Specification        ##
 #####################################
-#
+# 
 # Rule Identifier:
 #   s3_bucket_logging_enabled_check
-#
+# 
 # Description:
-#   This control checks whether server access logging is enabled for Amazon S3 buckets.
-#
+#   This control checks whether server access logging is enabled for your Amazon S3 bucket.
+# 
 # Reports on:
 #   AWS::S3::Bucket
-#
+# 
 # Evaluates:
 #   AWS CloudFormation, AWS CloudFormation hook
-#
+# 
 # Rule Parameters:
 #   None
-#
+# 
 # Scenarios:
 #   Scenario: 1
 #     Given: The input document is an AWS CloudFormation or CloudFormation hook document
@@ -31,7 +31,7 @@
 #     Given: The input document is an AWS CloudFormation or CloudFormation hook document
 #       And: The input document contains an Amazon S3 bucket resource
 #       And: 'LoggingConfiguration' has been provided
-#       And: 'LoggingConfiguration.DestinationBucketName' has been provided with an empty string or non-valid local
+#       And: 'LoggingConfiguration.DestinationbucketName' has been provided with an empty string or non-valid local
 #            reference
 #      Then: FAIL
 #   Scenario: 4
@@ -66,7 +66,7 @@ rule s3_bucket_logging_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
     check(%s3_buckets.Properties)
         <<
         [CT.S3.PR.2]: Require an Amazon S3 bucket to have server access logging configured
-        [FIX]: Set a 'LoggingConfiguration' on the S3 Bucket and optionally set 'DestinationBucketName' to an S3 bucket configured to receive S3 Access Logs.
+            [FIX]: Set a 'LoggingConfiguration' on the S3 Bucket and optionally set 'DestinationBucketName' to an S3 bucket configured to receive S3 Access Logs.
         >>
 }
 
@@ -74,7 +74,7 @@ rule s3_bucket_logging_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %S3_BUCKE
     check(%INPUT_DOCUMENT.%S3_BUCKET_TYPE.resourceProperties)
         <<
         [CT.S3.PR.2]: Require an Amazon S3 bucket to have server access logging configured
-        [FIX]: Set a 'LoggingConfiguration' on the S3 bucket and optionally set 'DestinationBucketName' to an S3 bucket configured to receive S3 Access Logs.
+            [FIX]: Set a 'LoggingConfiguration' on the S3 Bucket and optionally set 'DestinationBucketName' to an S3 bucket configured to receive S3 Access Logs.
         >>
 }
 
diff --git a/rules/control-tower/cfn-guard/s3/ct-s3-pr-3.guard b/rules/control-tower/cfn-guard/s3/ct-s3-pr-3.guard
new file mode 100644
index 0000000..1255001
--- /dev/null
+++ b/rules/control-tower/cfn-guard/s3/ct-s3-pr-3.guard
@@ -0,0 +1,126 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   s3_version_lifecycle_policy_check
+# 
+# Description:
+#   This control checks whether your Amazon Simple Storage Service (Amazon S3) version-enabled bucket has a lifecycle policy configured.
+# 
+# Reports on:
+#   AWS::S3::Bucket
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon S3 bucket resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon S3 bucket Resource
+#       And: The S3 bucket does not have versioning enabled (VersioningConfiguration is missing or
+#            VersioningConfiguration.Status is set to Suspended)
+#      Then: SKIP
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon S3 bucket Resource
+#       And: The S3 bucket has versioning enabled (VersioningConfiguration.Status is set to 'Enabled')
+#       And: 'LifecycleConfiguration' has been been provided and there are no 'Rules' with 'Status' set to 'Enabled'
+#            present in the 'LifecycleConfiguration'
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon S3 bucket Resource
+#       And: The S3 bucket has versioning enabled (VersioningConfiguration.Status is set to 'Enabled')
+#       And: 'LifecycleConfiguration' has been been provided and there is at least one 'Rule' with 'Status' set to
+#            'Enabled' in the 'LifecycleConfiguration'
+#      Then: PASS
+
+#
+# Constants
+#
+let S3_BUCKET_TYPE = "AWS::S3::Bucket"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let s3_buckets = Resources.*[ Type == %S3_BUCKET_TYPE ]
+
+#
+# Primary Rules
+#
+rule s3_version_lifecycle_policy_check when is_cfn_template(%INPUT_DOCUMENT)
+                                            %s3_buckets not empty {
+    check(%s3_buckets.Properties)
+        <<
+        [CT.S3.PR.3]: Require an Amazon S3 buckets to have versioning configured and a lifecycle policy
+            [FIX]: Configure versioning-enabled buckets with at least one active lifecycle rule.
+        >>
+}
+
+rule s3_version_lifecycle_policy_check when is_cfn_hook(%INPUT_DOCUMENT, %S3_BUCKET_TYPE) {
+    check(%INPUT_DOCUMENT.%S3_BUCKET_TYPE.resourceProperties)
+        <<
+        [CT.S3.PR.3]: Require an Amazon S3 buckets to have versioning configured and a lifecycle policy
+            [FIX]: Configure versioning-enabled buckets with at least one active lifecycle rule.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(s3_bucket) {
+    %s3_bucket [
+        filter_s3_buckets_with_versioning_enabled(this)
+    ] {
+        # Scenario 2
+        LifecycleConfiguration exists
+        LifecycleConfiguration is_struct
+
+        LifecycleConfiguration {
+            # Scenario 3 and 4
+            Rules exists
+            Rules is_list
+            Rules not empty
+
+            some Rules[*] {
+                Status exists
+                Status == "Enabled"
+            }
+        }
+    }
+}
+
+rule filter_s3_buckets_with_versioning_enabled(s3_bucket) {
+    %s3_bucket {
+        VersioningConfiguration exists
+        VersioningConfiguration is_struct
+
+        VersioningConfiguration {
+            Status exists
+            Status == "Enabled"
+        }
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/s3/ct-s3-pr-4.guard b/rules/control-tower/cfn-guard/s3/ct-s3-pr-4.guard
new file mode 100644
index 0000000..92988ef
--- /dev/null
+++ b/rules/control-tower/cfn-guard/s3/ct-s3-pr-4.guard
@@ -0,0 +1,126 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   s3_event_notifications_enabled_check
+# 
+# Description:
+#   This control checks whether Amazon S3 events notifications are enabled on your Amazon S3 bucket.
+# 
+# Reports on:
+#   AWS::S3::Bucket
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon S3 bucket resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon S3 bucket resource
+#       And: 'NotificationConfiguration' has not been provided
+#      Then: FAIL
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon S3 bucket resource
+#       And: 'NotificationConfiguration' has been provided
+#       And:  At least one of 'EventBridgeConfiguration.EventBridgeEnabled', 'LambdaConfigurations',
+#             'QueueConfigurations', or 'TopicConfigurations' have not been provided or provided as empty lists.
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon S3 bucket resource
+#       And: 'NotificationConfiguration' has been provided
+#       And: 'EventBridgeConfiguration.EventBridgeEnabled' is set to bool(true) or 'LambdaConfigurations',
+#            'QueueConfigurations', or 'TopicConfigurations' have been provided with at least one configuration
+#      Then: PASS
+
+#
+# Constants
+#
+let S3_BUCKET_TYPE = "AWS::S3::Bucket"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let s3_buckets = Resources.*[ Type == %S3_BUCKET_TYPE ]
+
+#
+# Primary Rules
+#
+rule s3_event_notifications_enabled_check when is_cfn_template(%INPUT_DOCUMENT)
+                                               %s3_buckets not empty {
+    check(%s3_buckets.Properties)
+        <<
+        [CT.S3.PR.4]: Require an Amazon S3 bucket to have event notifications configured
+            [FIX]: Set a 'NotificationConfiguration' parameter on your bucket with one of 'EventBridgeConfiguration', 'LambdaConfigurations', 'QueueConfigurations' or 'TopicConfigurations.'
+        >>
+}
+
+rule s3_event_notifications_enabled_check when is_cfn_hook(%INPUT_DOCUMENT, %S3_BUCKET_TYPE) {
+    check(%INPUT_DOCUMENT.%S3_BUCKET_TYPE.resourceProperties)
+        <<
+        [CT.S3.PR.4]: Require an Amazon S3 bucket to have event notifications configured
+            [FIX]: Set a 'NotificationConfiguration' parameter on your bucket with one of 'EventBridgeConfiguration', 'LambdaConfigurations', 'QueueConfigurations' or 'TopicConfigurations.'
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(s3_bucket) {
+    %s3_bucket {
+       # Scenario 2
+       NotificationConfiguration exists
+       NotificationConfiguration is_struct
+       NotificationConfiguration {
+            # Scenario 3 and 4
+            EventBridgeConfiguration exists or
+            LambdaConfigurations exists or
+            QueueConfigurations exists or
+            TopicConfigurations exists
+
+            check_event_bridge_notifications(EventBridgeConfiguration) or
+            check_other_notifications(LambdaConfigurations) or
+            check_other_notifications(QueueConfigurations) or
+            check_other_notifications(TopicConfigurations)
+       }
+    }
+}
+
+rule check_event_bridge_notifications(configuration) {
+    %configuration {
+        this is_struct
+        EventBridgeEnabled exists
+        EventBridgeEnabled == true
+    }
+}
+
+rule check_other_notifications(configuration) {
+    %configuration {
+        this is_list
+        this not empty
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/s3/ct-s3-pr-5.guard b/rules/control-tower/cfn-guard/s3/ct-s3-pr-5.guard
new file mode 100644
index 0000000..1a59417
--- /dev/null
+++ b/rules/control-tower/cfn-guard/s3/ct-s3-pr-5.guard
@@ -0,0 +1,89 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   s3_bucket_acl_prohibited_check
+# 
+# Description:
+#   This control checks whether your Amazon Simple Storage Service (Amazon S3) bucket allows user permissions through access control lists.
+# 
+# Reports on:
+#   AWS::S3::Bucket
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any Amazon S3 bucket resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon S3 bucket resource
+#       And: 'AccessControl' has been provided on the S3 bucket resource
+#      Then: FAIL
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an Amazon S3 bucket resource
+#       And: 'AccessControl' has not been provided on the S3 bucket resource
+#      Then: PASS
+
+#
+# Constants
+#
+let S3_BUCKET_TYPE = "AWS::S3::Bucket"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let s3_buckets = Resources.*[ Type == %S3_BUCKET_TYPE ]
+
+#
+# Primary Rules
+#
+rule s3_bucket_acl_prohibited_check when is_cfn_template(%INPUT_DOCUMENT)
+                                         %s3_buckets not empty {
+    check(%s3_buckets.Properties)
+        <<
+        [CT.S3.PR.5]: Require that an Amazon S3 bucket does not manage user access with an access control list (ACL)
+            [FIX]: Manage access to Amazon S3 buckets with bucket resource policies and IAM identity policies instead.
+        >>
+}
+
+rule s3_bucket_acl_prohibited_check when is_cfn_hook(%INPUT_DOCUMENT, %S3_BUCKET_TYPE) {
+    check(this.%S3_BUCKET_TYPE.resourceProperties)
+        <<
+        [CT.S3.PR.5]: Require that an Amazon S3 bucket does not manage user access with an access control list (ACL)
+            [FIX]: Manage access to Amazon S3 buckets with bucket resource policies and IAM identity policies instead.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(s3_bucket) {
+    %s3_bucket {
+       # Scenario 2 and 3
+       AccessControl not exists
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/cfn-guard/s3/ct-s3-pr-6.guard b/rules/control-tower/cfn-guard/s3/ct-s3-pr-6.guard
new file mode 100644
index 0000000..6529c8f
--- /dev/null
+++ b/rules/control-tower/cfn-guard/s3/ct-s3-pr-6.guard
@@ -0,0 +1,112 @@
+# ###################################
+##       Rule Specification        ##
+#####################################
+# 
+# Rule Identifier:
+#   s3_lifecycle_policy_check
+# 
+# Description:
+#   This control checks whether a lifecycle rule is configured for Amazon S3 buckets.
+# 
+# Reports on:
+#   AWS::S3::Bucket
+# 
+# Evaluates:
+#   AWS CloudFormation, AWS CloudFormation Hook
+# 
+# Rule Parameters:
+#   None
+# 
+# Scenarios:
+#   Scenario: 1
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document does not contain any S3 bucket resources
+#      Then: SKIP
+#   Scenario: 2
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an S3 bucket resource
+#       And: 'LifecycleConfiguration.Rules' has not been been provided or has been provided where 'Rules' is an
+#             empty list
+#      Then: FAIL
+#   Scenario: 3
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an S3 bucket resource
+#       And: The S3 bucket has versioning enabled (VersioningConfiguration.Status is set to 'Enabled')
+#       And: 'LifecycleConfiguration.Rules' has been been provided as a non-empty list
+#       And: There are no 'Rules' with 'Status' set to 'Enabled' present in the 'LifecycleConfiguration'
+#      Then: FAIL
+#   Scenario: 4
+#     Given: The input document is an AWS CloudFormation or CloudFormation hook document
+#       And: The input document contains an S3 bucket resource
+#       And: The S3 bucket has versioning enabled (VersioningConfiguration.Status is set to 'Enabled')
+#       And: 'LifecycleConfiguration.Rules' has been been provided as a non-empty list
+#       And: There is at least one entry in 'LifecycleConfiguration.Rules' with 'Status' set to 'Enabled'
+#      Then: PASS
+
+#
+# Constants
+#
+let S3_BUCKET_TYPE = "AWS::S3::Bucket"
+let INPUT_DOCUMENT = this
+
+#
+# Assignments
+#
+let s3_buckets = Resources.*[ Type == %S3_BUCKET_TYPE ]
+
+#
+# Primary Rules
+#
+rule s3_lifecycle_policy_check when is_cfn_template(%INPUT_DOCUMENT)
+                                    %s3_buckets not empty {
+    check(%s3_buckets.Properties)
+        <<
+        [CT.S3.PR.6]: Require an Amazon S3 bucket to have lifecycle policies configured
+            [FIX]: Configure at least one active lifecycle rule in 'LifecycleConfiguration.Rules' by setting 'Status' on a rule to 'Enabled'.
+        >>
+}
+
+rule s3_lifecycle_policy_check when is_cfn_hook(%INPUT_DOCUMENT, %S3_BUCKET_TYPE) {
+    check(%INPUT_DOCUMENT.%S3_BUCKET_TYPE.resourceProperties)
+        <<
+        [CT.S3.PR.6]: Require an Amazon S3 bucket to have lifecycle policies configured
+            [FIX]: Configure at least one active lifecycle rule in 'LifecycleConfiguration.Rules' by setting 'Status' on a rule to 'Enabled'.
+        >>
+}
+
+#
+# Parameterized Rules
+#
+rule check(s3_bucket) {
+    %s3_bucket {
+        # Scenario 2
+        LifecycleConfiguration exists
+        LifecycleConfiguration is_struct
+
+        LifecycleConfiguration {
+            # Scenario 3 and 4
+            Rules exists
+            Rules is_list
+            Rules not empty
+
+            some Rules[*] {
+                Status exists
+                Status == "Enabled"
+            }
+        }
+    }
+}
+
+#
+# Utility Rules
+#
+rule is_cfn_template(doc) {
+    %doc {
+        AWSTemplateFormatVersion exists  or
+        Resources exists
+    }
+}
+
+rule is_cfn_hook(doc, RESOURCE_TYPE) {
+    %doc.%RESOURCE_TYPE.resourceProperties exists
+}
diff --git a/rules/control-tower/s3/ct-s3-pr-7.guard b/rules/control-tower/cfn-guard/s3/ct-s3-pr-7.guard
similarity index 100%
rename from rules/control-tower/s3/ct-s3-pr-7.guard
rename to rules/control-tower/cfn-guard/s3/ct-s3-pr-7.guard
diff --git a/rules/control-tower/s3/ct-s3-pr-8.guard b/rules/control-tower/cfn-guard/s3/ct-s3-pr-8.guard
similarity index 100%
rename from rules/control-tower/s3/ct-s3-pr-8.guard
rename to rules/control-tower/cfn-guard/s3/ct-s3-pr-8.guard
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-1.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-1.metadata.json
new file mode 100644
index 0000000..2099510
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-1.metadata.json
@@ -0,0 +1,49 @@
+{
+    "Behavior": "PROACTIVE",
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon EC2 launch templates are configured with Instance Metadata Service Version 2 (IMDSv2).",
+    "DisplayName": "Require an Amazon EC2 launch template to have IMDSv2 configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Use IMDSv2",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::LaunchTemplate"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.1",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.5",
+            "Name": "Enforce least privilege"
+        },
+        {
+            "Id": "CO.10",
+            "Name": "Protect configurations"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.EC2.8",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Within the 'LaunchTemplateData' property, provide a 'MetadataOptions' configuration and set the value of 'HttpTokens' to 'required'.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-10.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-10.metadata.json
new file mode 100644
index 0000000..14ac591
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-10.metadata.json
@@ -0,0 +1,39 @@
+{
+    "Behavior": "PROACTIVE",
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether the Amazon EC2 launch template has detailed monitoring enabled.",
+    "DisplayName": "Require Amazon EC2 launch templates to have Amazon CloudWatch detailed monitoring activated",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Configure monitoring for Auto Scaling instances",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/autoscaling/ec2/userguide/enable-as-instance-metrics.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::LaunchTemplate"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.10",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.1",
+            "Name": "Establish logging and monitoring"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "In 'LaunchTemplateData', provide a 'Monitoring' configuration with 'Enabled' set to 'true'.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-11.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-11.metadata.json
new file mode 100644
index 0000000..ac31860
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-11.metadata.json
@@ -0,0 +1,78 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-21",
+                "AC-3",
+                "AC-3(7)",
+                "AC-4",
+                "AC-4(21)",
+                "AC-6",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(20)",
+                "SC-7(21)",
+                "SC-7(3)",
+                "SC-7(4)",
+                "SC-7(9)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "1.3.6",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon VPC subnets automatically assign public IP addresses.",
+    "DisplayName": "Require that an Amazon EC2 subnet does not automatically assign public IP addresses",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Amazon EC2 instance IP addressing",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::Subnet"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.11",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.EC2.15",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Omit the 'MapPublicIpOnLaunch' property to use the default configuration, or set the 'MapPublicIpOnLaunch' property to 'false'.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-12.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-12.metadata.json
new file mode 100644
index 0000000..b432395
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-12.metadata.json
@@ -0,0 +1,59 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-4(21)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon Elastic Compute Cloud (Amazon EC2) instance uses multiple ENIs (Elastic Network Interfaces).",
+    "DisplayName": "Require an Amazon EC2 instance to configure one ENI only",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Amazon EC2 instance IP addressing",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-public-addresses"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::Instance"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.12",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.EC2.17",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Configure Amazon EC2 instances with only one ENI.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-2.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-2.metadata.json
new file mode 100644
index 0000000..a17e18b
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-2.metadata.json
@@ -0,0 +1,43 @@
+{
+    "Behavior": "PROACTIVE",
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether an Amazon EC2 launch template has a metadata token hop limit set to '1'.",
+    "DisplayName": "Require that Amazon EC2 launch templates restrict the token hop limit to a maximum of one",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "HttpPutResponseHopLimit for instance metadata should equal to the desired value (1)",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/configuring-instance-metadata-service.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::LaunchTemplate"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.2",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.5",
+            "Name": "Enforce least privilege"
+        },
+        {
+            "Id": "CO.10",
+            "Name": "Protect configurations"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Within the 'LaunchTemplateData' property, provide a 'MetadataOptions' configuration with the value of 'HttpPutResponseLimit' set to '1', or omit the 'HttpPutResponseLimit' property to adopt the AWS CloudFormation default value of '1'.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-3.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-3.metadata.json
new file mode 100644
index 0000000..051d403
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-3.metadata.json
@@ -0,0 +1,77 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-4",
+                "AC-4(21)",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(21)",
+                "SC-7(4)",
+                "SC-7(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "1.3.6",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether security groups that allow unrestricted incoming traffic ('0.0.0.0/0' or '::/0'), only allow inbound TCP or UDP connections on authorized ports.",
+    "DisplayName": "Require an Amazon EC2 security group to allow incoming traffic on authorized ports only",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Instructions for configuring VPC Security Groups",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::SecurityGroup",
+        "AWS::EC2::SecurityGroupIngress"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.3",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        },
+        {
+            "Id": "CO.5",
+            "Name": "Enforce least privilege"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.EC2.18",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Ensure that security groups with ingress rules that allow TCP or UDP traffic from '0.0.0.0/0' or ' only allow traffic from ports 80 or 443.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-4.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-4.metadata.json
new file mode 100644
index 0000000..d8a23d4
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-4.metadata.json
@@ -0,0 +1,75 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-4",
+                "AC-4(21)",
+                "CM-7",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(21)",
+                "SC-7(4)",
+                "SC-7(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "1.3.6",
+                "2.2",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether Amazon EC2 security groups allow unrestricted incoming TCP or UDP traffic to ports '3389', '20', '23', '110', '143', '3306', '8080', '1433', '9200', '9300', '25', '445', '135', '21', '1434', '4333', '5432', '5500', '5601', '22', '3000', '5000', '8088', '8888'.",
+    "DisplayName": "Require that an Amazon EC2 security group does not allow incoming traffic for high-risk ports",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Instructions for configuring VPC Security Groups",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::SecurityGroup",
+        "AWS::EC2::SecurityGroupIngress"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.4",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.EC2.19",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Remove Amazon EC2 security group ingress rules that allow traffic from '0.0.0.0/0' or '::/0' to high risk ports: '3389', '20', '23', '110', '143', '3306', '8080', '1433', '9200', '9300', '25', '445', '135', '21', '1434', '4333', '5432', '5500', '5601', '22', '3000', '5000', '8088', '8888'.",
+    "Severity": "CRITICAL",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-5.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-5.metadata.json
new file mode 100644
index 0000000..747e0ff
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-5.metadata.json
@@ -0,0 +1,78 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "CIS AWS Benchmark 1.4",
+            "Ids": [
+                "5.1"
+            ]
+        },
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-4(21)",
+                "CA-9(1)",
+                "CM-2",
+                "CM-2(2)",
+                "CM-7",
+                "SC-7",
+                "SC-7(21)",
+                "SC-7(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "2.2",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether the Amazon EC2 network ACL inbound entry allows unrestricted incoming traffic ('0.0.0.0/0' or '::/0') for SSH or RDP.",
+    "DisplayName": "Require any Amazon EC2 network ACL to prevent ingress from 0.0.0.0/0 to port 22 or port 3389",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Custom Network ACL",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html#custom-network-acl"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::NetworkAclEntry"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.5",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.EC2.21",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "For Amazon EC2 network ACL entries that allow inbound connectivity on port 22 or port 3389, provide a CIDR range in 'CidrBlock' or 'Ipv6CidrBlock' that does not allow traffic from all sources.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-6.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-6.metadata.json
new file mode 100644
index 0000000..92938cd
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-6.metadata.json
@@ -0,0 +1,56 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-4(21)",
+                "CA-9(1)",
+                "CM-2"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.4"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether Amazon EC2 transit gateways are configured to accept Amazon VPC attachment requests automatically.",
+    "DisplayName": "Require that Amazon EC2 transit gateways refuse automatic Amazon VPC attachment requests",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Transit gateways - Accept a shared attachment",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/vpc/latest/tgw/tgw-transit-gateways.html#tgw-accept-shared-attachment"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::TransitGateway"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.6",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Omit the 'AutoAcceptSharedAttachments' property or set the property to 'disable'.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-7.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-7.metadata.json
new file mode 100644
index 0000000..72775eb
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-7.metadata.json
@@ -0,0 +1,68 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-9(1)",
+                "CM-3(6)",
+                "SC-13",
+                "SC-28",
+                "SC-28(1)",
+                "SC-7(10)",
+                "SI-7(6)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.2",
+                "3.4",
+                "8.2.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your standalone Amazon EC2 EBS volumes and new EC2 EBS volumes created through EC2 instance block device mappings are encrypted at rest.",
+    "DisplayName": "Require that an Amazon EBS volume attached to an Amazon EC2 instance is encrypted at rest",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Amazon EBS encryption",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::Instance",
+        "AWS::EC2::Volume"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.7",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.2",
+            "Name": "Encrypt data at rest"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.EC2.3",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'Encryption' to true on EC2 EBS Volumes.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-8.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-8.metadata.json
new file mode 100644
index 0000000..d6961f6
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-8.metadata.json
@@ -0,0 +1,78 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-21",
+                "AC-3",
+                "AC-3(7)",
+                "AC-4",
+                "AC-4(21)",
+                "AC-6",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(20)",
+                "SC-7(21)",
+                "SC-7(3)",
+                "SC-7(4)",
+                "SC-7(9)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "1.3.6",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon EC2 instance is configured to associate a public IP address.",
+    "DisplayName": "Require any Amazon EC2 instance to have a non-public IP address",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Amazon EC2 instance IP addressing",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-public-addresses"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::Instance"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.8",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.EC2.9",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Specify network interfaces using the 'NetworkInterfaces' property instead of the root level 'SubnetId' property. Set 'AssociatePublicIpAddress' to false within each 'NetworkInterfaces' configuration.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/ec2/ct-ec2-pr-9.metadata.json b/rules/control-tower/metadata/ec2/ct-ec2-pr-9.metadata.json
new file mode 100644
index 0000000..b8d1e8d
--- /dev/null
+++ b/rules/control-tower/metadata/ec2/ct-ec2-pr-9.metadata.json
@@ -0,0 +1,72 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-21",
+                "AC-3",
+                "AC-3(7)",
+                "AC-4",
+                "AC-4(21)",
+                "AC-6",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(20)",
+                "SC-7(21)",
+                "SC-7(3)",
+                "SC-7(4)",
+                "SC-7(9)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "1.3.6",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon EC2 launch templates are configured to assign public IP addresses to network interfaces.",
+    "DisplayName": "Require any Amazon EC2 launch template not to auto-assign public IP addresses to network interfaces",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Checks if Amazon EC2 Launch Templates are set to assign public IP addresses to Network Interfaces.",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-launchtemplate-networkinterface.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::EC2::LaunchTemplate"
+    ],
+    "EvaluatedServices": [
+        "Amazon EC2"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.EC2.PR.9",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'AssociatePublicIpAddress' to 'false' within each 'NetworkInterfaces' configuration in 'LaunchTemplateData'.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/identityandaccessmanagement/ct-iam-pr-2.metadata.json b/rules/control-tower/metadata/identityandaccessmanagement/ct-iam-pr-2.metadata.json
new file mode 100644
index 0000000..011b0e1
--- /dev/null
+++ b/rules/control-tower/metadata/identityandaccessmanagement/ct-iam-pr-2.metadata.json
@@ -0,0 +1,78 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "CIS AWS Benchmark 1.4",
+            "Ids": [
+                "1.16"
+            ]
+        },
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-2",
+                "AC-2(1)",
+                "AC-3",
+                "AC-3(15)",
+                "AC-3(7)",
+                "AC-5",
+                "AC-6",
+                "AC-6(10)",
+                "AC-6(2)",
+                "AC-6(3)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.2",
+                "7.1.1",
+                "7.1.2",
+                "7.2.1",
+                "7.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether AWS Identity and Access Management (IAM) customer managed policies do not include \"Effect\": \"Allow\" with \"Action\": \"*\" over \"Resource\": \"*\".",
+    "DisplayName": "Require that AWS Identity and Access Management (IAM) customer-managed policies do not contain a statement that includes \"*\" in the Action and Resource elements",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "IAM Least Privilege Guidance",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::IAM::ManagedPolicy"
+    ],
+    "EvaluatedServices": [
+        "AWS Identity and Access Management (IAM)"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.IAM.PR.2",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.5",
+            "Name": "Enforce least privilege"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.IAM.1",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Remove AWS IAM inline policy statements with \"Effect\": \"Allow\" that permit \"Action\": \"*\" over \"Resource\": \"*\".",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-1.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-1.metadata.json
new file mode 100644
index 0000000..a772d6b
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-1.metadata.json
@@ -0,0 +1,57 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CP-10",
+                "CP-6(2)",
+                "SC-36",
+                "SC-5(2)",
+                "SI-13(5)"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether high availability is configured for your Amazon RDS database instances.",
+    "DisplayName": "Require that an Amazon RDS database instance is configured with multiple Availability Zones",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Multi-AZ DB instance deployments",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.MultiAZSingleStandby.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.1",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.9",
+            "Name": "Improve availability"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.5",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'MultiAZ' to 'true'.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-10.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-10.metadata.json
new file mode 100644
index 0000000..a53f3d9
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-10.metadata.json
@@ -0,0 +1,62 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-9(1)",
+                "CM-2",
+                "CM-2(2)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.2",
+                "2.4"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether Amazon RDS DB instances are configured to copy all tags to snapshots created.",
+    "DisplayName": "Require an Amazon RDS database instance to copy tags to snapshots",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Copying tags to DB instance snapshots",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Tagging.html#USER_Tagging.CopyTags"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.10",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.10",
+            "Name": "Protect configurations"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.17",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'CopyTagsToSnapshot' to 'true'.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-11.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-11.metadata.json
new file mode 100644
index 0000000..cbf2f5d
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-11.metadata.json
@@ -0,0 +1,73 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-4",
+                "AC-4(21)",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(20)",
+                "SC-7(21)",
+                "SC-7(4)",
+                "SC-7(9)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "1.3.6",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether an Amazon RDS database (DB) instance is deployed in a VPC (that is, an EC2 VPC instance).",
+    "DisplayName": "Require an Amazon RDS database instance to have a VPC configuration",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Amazon Virtual Private Cloud VPCs and Amazon RDS",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.11",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.18",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set a 'DBSubnetGroupName'.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-12.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-12.metadata.json
new file mode 100644
index 0000000..15aa694
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-12.metadata.json
@@ -0,0 +1,54 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-7",
+                "SI-2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon RDS event subscriptions for RDS clusters are configured to notify on event categories of 'maintenance' and 'failure.'",
+    "DisplayName": "Require an Amazon RDS event subscription to have critical cluster events configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Configuring Amazon RDS event notification",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::EventSubscription"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.12",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.11",
+            "Name": "Prepare for incident response"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.19",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "When 'SourceType' is set to 'db-cluster', set 'Enabled' to true and ensure that 'EventCategories' contains both 'maintenance' and 'failure' values.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-13.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-13.metadata.json
new file mode 100644
index 0000000..a602381
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-13.metadata.json
@@ -0,0 +1,61 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CM-3",
+                "SC-5(2)",
+                "SI-13(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether an Amazon Relational Database Service (Amazon RDS) instance has deletion protection activated.",
+    "DisplayName": "Require any Amazon RDS instance to have deletion protection configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Deleting Aurora DB clusters and DB instances",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_DeleteCluster.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.13",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.9",
+            "Name": "Improve availability"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.8",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'DeletionProtection' to 'true'.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-14.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-14.metadata.json
new file mode 100644
index 0000000..04e47cb
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-14.metadata.json
@@ -0,0 +1,81 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-2(4)",
+                "AC-4(26)",
+                "AC-6(9)",
+                "AU-10",
+                "AU-12",
+                "AU-2",
+                "AU-3",
+                "AU-6(3)",
+                "AU-6(4)",
+                "CA-7",
+                "SC-7(10)",
+                "SC-7(9)",
+                "SI-3(8)",
+                "SI-4(20)",
+                "SI-7(8)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "10.1",
+                "10.2.1",
+                "10.2.2",
+                "10.2.3",
+                "10.2.4",
+                "10.2.5",
+                "10.2.6",
+                "10.2.7",
+                "10.3.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This rules checks whether Amazon Relational Database Service (RDS) instances have all available log types configured for export to Amazon CloudWatch Logs.",
+    "DisplayName": "Require an Amazon RDS database instance to have logging configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Publishing database logs to Amazon CloudWatch Logs",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_LogAccess.Procedural.UploadtoCloudWatch.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.14",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.1",
+            "Name": "Establish logging and monitoring"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.9",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Specify 'EnableCloudwatchLogsExports' with a list of all supported log types for the Amazon RDS database instance engine.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-15.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-15.metadata.json
new file mode 100644
index 0000000..04c334b
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-15.metadata.json
@@ -0,0 +1,69 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-4",
+                "AC-4(21)",
+                "CM-8(1)",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(21)",
+                "SC-7(4)",
+                "SC-7(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "1.3.6",
+                "2.1",
+                "2.2",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether any Amazon Relational Database Services (RDS) database (DB) security groups are created by, or associated to, an RDS DB instance, because DB security groups are intended for the EC2-Classic platform only.",
+    "DisplayName": "Require that an Amazon RDS instance does not create DB security groups",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Provide access to your DB instance in your VPC by creating a security group",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_SettingUp.html#CHAP_SettingUp.SecurityGroup"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance",
+        "AWS::RDS::DBSecurityGroup"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.15",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Omit the 'DBSecurityGroups' property. Instead, configure Amazon VPC security groups by means of the 'VPCSecurityGroups' property.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-16.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-16.metadata.json
new file mode 100644
index 0000000..78368a5
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-16.metadata.json
@@ -0,0 +1,65 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "CIS AWS Benchmark 1.4",
+            "Ids": [
+                "2.3.1"
+            ]
+        },
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-9(1)",
+                "CM-3(6)",
+                "SC-13",
+                "SC-28",
+                "SC-28(1)",
+                "SC-7(10)",
+                "SI-7(6)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "3.4",
+                "8.2.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether the storage encryption is configured on Amazon Relational Database Service (RDS) database (DB) clusters that are not being restored from an existing cluster.",
+    "DisplayName": "Require an Amazon RDS database cluster to have encryption at rest configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Encrypting Amazon Aurora resources",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Overview.Encryption.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBCluster"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.16",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.2",
+            "Name": "Encrypt data at rest"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'StorageEncrypted' to 'true'.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-17.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-17.metadata.json
new file mode 100644
index 0000000..ab50e5b
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-17.metadata.json
@@ -0,0 +1,54 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-7",
+                "SI-2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon RDS event subscriptions for RDS instances are configured to notify on event categories of 'maintenance', 'failure', and 'configuration change'.",
+    "DisplayName": "Require an Amazon RDS event notification subscription to have critical database instance events configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Configuring Amazon RDS event notification",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::EventSubscription"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.17",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.11",
+            "Name": "Prepare for incident response"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.20",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "When 'SourceType' is set to 'db-instance', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'maintenance', 'failure', and 'configuration change' values.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-18.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-18.metadata.json
new file mode 100644
index 0000000..53efb73
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-18.metadata.json
@@ -0,0 +1,54 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-7",
+                "SI-2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon RDS event subscriptions for RDS parameter groups are configured to notify on event categories of 'configuration change.'",
+    "DisplayName": "Require an Amazon RDS event notification subscription to have critical database parameter group events configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Configuring Amazon RDS event notification",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::EventSubscription"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.18",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.11",
+            "Name": "Prepare for incident response"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.21",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "When 'SourceType' is set to 'db-parameter-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains 'configuration change' as a value.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-19.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-19.metadata.json
new file mode 100644
index 0000000..da389bd
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-19.metadata.json
@@ -0,0 +1,54 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-7",
+                "SI-2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon RDS event subscriptions for RDS security groups are configured to notify on event categories of 'failure' and 'configuration change'",
+    "DisplayName": "Require an Amazon RDS event notifications subscription to have critical database security group events configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Configuring Amazon RDS event notification",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::EventSubscription"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.19",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.11",
+            "Name": "Prepare for incident response"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.22",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "When 'SourceType' is set to 'db-security-group', set 'Enabled' to true and ensure that the parameter 'EventCategories' contains both 'failure' and 'configuration change' values.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-2.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-2.metadata.json
new file mode 100644
index 0000000..fd2d987
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-2.metadata.json
@@ -0,0 +1,54 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-7",
+                "SI-2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether enhanced monitoring is activated for Amazon RDS instances.",
+    "DisplayName": "Require an Amazon RDS database instance or cluster to have enhanced monitoring configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Monitoring OS metrics with Enhanced Monitoring",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Monitoring.OS.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.2",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.1",
+            "Name": "Establish logging and monitoring"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.6",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'MonitoringInterval' to a supported value (1, 5, 10, 15, 30, 60), and set 'MonitoringRoleArn' to the ARN of an AWS IAM role.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-20.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-20.metadata.json
new file mode 100644
index 0000000..5c4db48
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-20.metadata.json
@@ -0,0 +1,70 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-4",
+                "AC-4(21)",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(21)",
+                "SC-7(4)",
+                "SC-7(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether Amazon Relational Database Service (RDS) database instances are configured for default database port for their specific engine types.",
+    "DisplayName": "Require an Amazon RDS database instance not to use a database engine default port",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Connecting to an Amazon RDS DB instance",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_CommonTasks.Connect.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.20",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.23",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set a value for 'Port' that is different than the default value for the Amazon RDS DB instance engine type.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-21.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-21.metadata.json
new file mode 100644
index 0000000..342af1e
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-21.metadata.json
@@ -0,0 +1,53 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-9(1)",
+                "CM-2"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has changed the administrator username from its default value.",
+    "DisplayName": "Require an Amazon RDS DB cluster to have a unique administrator username",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Creating an Amazon Aurora DB cluster",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.CreateInstance.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBCluster"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.21",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.10",
+            "Name": "Protect configurations"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'MasterUsername' to a value other than 'admin' or 'postgres'.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-22.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-22.metadata.json
new file mode 100644
index 0000000..2c9f913
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-22.metadata.json
@@ -0,0 +1,65 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-9(1)",
+                "CM-2"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether an Amazon RDS database has changed the adminstrator username from its default value.",
+    "DisplayName": "Require an Amazon RDS database instance to have a unique administrator username",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Security best practices for Amazon RDS",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_BestPractices.Security.html"
+        },
+        {
+            "DisplayName": "Creating an Amazon RDS DB instance",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.22",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.10",
+            "Name": "Protect configurations"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.25",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'MasterUsername' to a value other than 'postgres' or 'admin'.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-23.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-23.metadata.json
new file mode 100644
index 0000000..408a114
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-23.metadata.json
@@ -0,0 +1,78 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-21",
+                "AC-3",
+                "AC-3(7)",
+                "AC-4",
+                "AC-4(21)",
+                "AC-6",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(20)",
+                "SC-7(21)",
+                "SC-7(3)",
+                "SC-7(4)",
+                "SC-7(9)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "1.3.6",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This rule checks whether Amazon Relational Database Service (RDS) database (DB) instances are publicly accessible, as determined by checking the 'PubliclyAccessible' configuration property.",
+    "DisplayName": "Require an Amazon RDS database instance to not be publicly accessible",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Working with a DB instance in a VPC",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_VPC.WorkingWithRDSInstanceinaVPC.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.23",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.6",
+            "Name": "Limit network access"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.2",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set the value of 'PubliclyAccessible' to 'false'.",
+    "Severity": "CRITICAL",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-24.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-24.metadata.json
new file mode 100644
index 0000000..cb5a6f7
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-24.metadata.json
@@ -0,0 +1,72 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "CIS AWS Benchmark 1.4",
+            "Ids": [
+                "2.3.1"
+            ]
+        },
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-9(1)",
+                "CM-3(6)",
+                "SC-13",
+                "SC-28",
+                "SC-28(1)",
+                "SC-7(10)",
+                "SI-7(6)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "3.4",
+                "8.2.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether storage encryption is enabled for your Amazon RDS database (DB) instance.",
+    "DisplayName": "Require an Amazon RDS database instance to have encryption at rest configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Encrypting Amazon RDS resources",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.Encryption.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.24",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.2",
+            "Name": "Encrypt data at rest"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.3",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "The parameter 'StorageEncrypted' must be set to true for RDS DB Instances.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-3.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-3.metadata.json
new file mode 100644
index 0000000..77a3640
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-3.metadata.json
@@ -0,0 +1,53 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CM-3",
+                "SC-5(2)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon Relational Database Service (Amazon RDS) cluster has deletion protection activated.",
+    "DisplayName": "Require an Amazon RDS cluster to have deletion protection configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Deletion protection for Aurora clusters",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_DeleteCluster.html#USER_DeletionProtection"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBCluster"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.3",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.9",
+            "Name": "Improve availability"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set the value of the 'DeletionProtection' parameter to true.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-4.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-4.metadata.json
new file mode 100644
index 0000000..783ab5d
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-4.metadata.json
@@ -0,0 +1,59 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-2(1)",
+                "AC-3",
+                "AC-3(15)",
+                "AC-3(7)",
+                "AC-6"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "7.1.1",
+                "7.2.1",
+                "7.2.2",
+                "8.7"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has AWS IAM database authentication activated.",
+    "DisplayName": "Require an Amazon RDS database cluster to have AWS IAM database authentication configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "IAM database authentication",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBCluster"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.4",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.15",
+            "Name": "Use strong authentication"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'EnableIAMDatabaseAuthentication' to 'true'.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-5.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-5.metadata.json
new file mode 100644
index 0000000..db4bc1a
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-5.metadata.json
@@ -0,0 +1,62 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "SI-2",
+                "SI-2(2)",
+                "SI-2(4)",
+                "SI-2(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "6.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether automatic minor version upgrades are enabled for an Amazon RDS database instance.",
+    "DisplayName": "Require an Amazon RDS database instance to have minor version upgrades configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Upgrading a DB instance engine version",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.Upgrading.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.5",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.12",
+            "Name": "Manage vulnerabilities"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.13",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Omit the 'AutoMinorVersionUpgrade' property or set it to 'true'.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-6.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-6.metadata.json
new file mode 100644
index 0000000..6e1bfae
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-6.metadata.json
@@ -0,0 +1,57 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CP-10",
+                "CP-6",
+                "CP-6(1)",
+                "CP-6(2)",
+                "CP-9",
+                "SI-13(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "3.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether an Amazon Relational Database Service (RDS) database (DB) cluster has backtracking enabled.",
+    "DisplayName": "Require an Amazon RDS database cluster to have backtracking configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Backtracking an Aurora DB cluster",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Backtrack.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBCluster"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.6",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.8",
+            "Name": "Improve resiliency"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'BacktrackWindow' to a number between '1' and '259200'.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-7.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-7.metadata.json
new file mode 100644
index 0000000..f6994f2
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-7.metadata.json
@@ -0,0 +1,71 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-2(1)",
+                "AC-3",
+                "AC-3(15)",
+                "AC-3(7)",
+                "AC-6"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "7.1.1",
+                "7.2.1",
+                "7.2.2",
+                "8.7"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether an Amazon RDS database (DB) instance has AWS IAM database authentication activated.",
+    "DisplayName": "Require Amazon RDS database instances to have AWS IAM authentication configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "IAM database authentication for MariaDB, MySQL, and PostgreSQL",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html"
+        },
+        {
+            "DisplayName": "IAM authentication with Amazon RDS for MariaDB",
+            "Type": "Blog Post",
+            "Url": "https://aws.amazon.com/blogs/database/iam-authentication-with-amazon-rds-for-mariadb/"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.7",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.15",
+            "Name": "Use strong authentication"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.10",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'EnableIAMDatabaseAuthentication' to 'true'.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-8.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-8.metadata.json
new file mode 100644
index 0000000..24f2a01
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-8.metadata.json
@@ -0,0 +1,67 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CP-10",
+                "CP-6",
+                "CP-6(1)",
+                "CP-6(2)",
+                "CP-9",
+                "SC-5(2)",
+                "SI-12",
+                "SI-13(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "10.7",
+                "3.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether Amazon RDS database (DB) instances have automated backups enabled, and verifies that the backup retention period is greater than or equal to seven (7) days.",
+    "DisplayName": "Require an Amazon RDS database instance to have automatic backups configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Working with backups",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithAutomatedBackups.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBInstance"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.8",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.8",
+            "Name": "Improve resiliency"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.RDS.11",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'BackupRetentionPeriod' to an integer value between 7 and 35 days (inclusive).",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/rds/ct-rds-pr-9.metadata.json b/rules/control-tower/metadata/rds/ct-rds-pr-9.metadata.json
new file mode 100644
index 0000000..9102a67
--- /dev/null
+++ b/rules/control-tower/metadata/rds/ct-rds-pr-9.metadata.json
@@ -0,0 +1,55 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-9(1)",
+                "CM-2",
+                "CM-2(2)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.2",
+                "2.4"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether an Amazon RDS DB cluster is configured to copy all tags to snapshots created.",
+    "DisplayName": "Require an Amazon RDS database cluster to copy tags to snapshots",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Copying tags to DB cluster snapshots",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/USER_Tagging.html#USER_Tagging.CopyTagsCluster"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::RDS::DBCluster"
+    ],
+    "EvaluatedServices": [
+        "Amazon RDS"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.RDS.PR.9",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.10",
+            "Name": "Protect configurations"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set 'CopyTagsToSnapshot' to 'true'.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/s3/ct-s3-pr-1.metadata.json b/rules/control-tower/metadata/s3/ct-s3-pr-1.metadata.json
new file mode 100644
index 0000000..377daed
--- /dev/null
+++ b/rules/control-tower/metadata/s3/ct-s3-pr-1.metadata.json
@@ -0,0 +1,84 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "CIS AWS Benchmark 1.4",
+            "Ids": [
+                "2.1.5"
+            ]
+        },
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-21",
+                "AC-3",
+                "AC-3(7)",
+                "AC-4",
+                "AC-4(21)",
+                "AC-6",
+                "SC-7",
+                "SC-7(11)",
+                "SC-7(16)",
+                "SC-7(20)",
+                "SC-7(21)",
+                "SC-7(3)",
+                "SC-7(4)",
+                "SC-7(9)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "1.2.1",
+                "1.3",
+                "1.3.1",
+                "1.3.2",
+                "1.3.4",
+                "1.3.6",
+                "2.2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon Simple Storage Service (Amazon S3) bucket has a bucket-level Block Public Access (BPA) configuration.",
+    "DisplayName": "Require an Amazon S3 bucket to have block public access settings configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "S3 Block Public Access",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::S3::Bucket"
+    ],
+    "EvaluatedServices": [
+        "Amazon S3"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.S3.PR.1",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.5",
+            "Name": "Enforce least privilege"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.S3.8",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "The parameters 'BlockPublicAcls', 'BlockPublicPolicy', 'IgnorePublicAcls', 'RestrictPublicBuckets' must be set to true under the bucket-level 'PublicAccessBlockConfiguration'.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/s3/ct-s3-pr-2.metadata.json b/rules/control-tower/metadata/s3/ct-s3-pr-2.metadata.json
new file mode 100644
index 0000000..91bbdbd
--- /dev/null
+++ b/rules/control-tower/metadata/s3/ct-s3-pr-2.metadata.json
@@ -0,0 +1,83 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "CIS AWS Benchmark 1.4",
+            "Ids": [
+                "3.6"
+            ]
+        },
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-2(4)",
+                "AC-4(26)",
+                "AC-6(9)",
+                "AU-10",
+                "AU-12",
+                "AU-2",
+                "AU-3",
+                "AU-6(3)",
+                "AU-6(4)",
+                "CA-7",
+                "SC-7(9)",
+                "SI-3(8)",
+                "SI-4(20)",
+                "SI-7(8)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "10.1",
+                "10.2.1",
+                "10.2.3",
+                "10.2.4",
+                "10.3.1",
+                "2.2"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether server access logging is enabled for your Amazon S3 bucket.",
+    "DisplayName": "Require an Amazon S3 bucket to have server access logging configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Logging requests using server access logging",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::S3::Bucket"
+    ],
+    "EvaluatedServices": [
+        "Amazon S3"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.S3.PR.2",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.1",
+            "Name": "Establish logging and monitoring"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.S3.9",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set a 'LoggingConfiguration' on the S3 Bucket and optionally set 'DestinationBucketName' to an S3 bucket configured to receive S3 Access Logs.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/s3/ct-s3-pr-3.metadata.json b/rules/control-tower/metadata/s3/ct-s3-pr-3.metadata.json
new file mode 100644
index 0000000..f9b3ed4
--- /dev/null
+++ b/rules/control-tower/metadata/s3/ct-s3-pr-3.metadata.json
@@ -0,0 +1,70 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AU-9(2)",
+                "CP-10",
+                "CP-6(2)",
+                "CP-9",
+                "SC-5(2)",
+                "SI-13(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "10.5.3",
+                "10.7",
+                "3.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon Simple Storage Service (Amazon S3) version-enabled bucket has a lifecycle policy configured.",
+    "DisplayName": "Require an Amazon S3 buckets to have versioning configured and a lifecycle policy",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Managing your storage lifecycle",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::S3::Bucket"
+    ],
+    "EvaluatedServices": [
+        "Amazon S3"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.S3.PR.3",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.7",
+            "Name": "Optimize costs"
+        },
+        {
+            "Id": "CO.9",
+            "Name": "Improve availability"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.S3.10",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Configure versioning-enabled buckets with at least one active lifecycle rule.",
+    "Severity": "HIGH",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/s3/ct-s3-pr-4.metadata.json b/rules/control-tower/metadata/s3/ct-s3-pr-4.metadata.json
new file mode 100644
index 0000000..7ea7c68
--- /dev/null
+++ b/rules/control-tower/metadata/s3/ct-s3-pr-4.metadata.json
@@ -0,0 +1,56 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "CA-7",
+                "SI-3(8)",
+                "SI-4",
+                "SI-4(4)"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether Amazon S3 events notifications are enabled on your Amazon S3 bucket.",
+    "DisplayName": "Require an Amazon S3 bucket to have event notifications configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Amazon S3 Event Notifications",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/NotificationHowTo.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::S3::Bucket"
+    ],
+    "EvaluatedServices": [
+        "Amazon S3"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.S3.PR.4",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.1",
+            "Name": "Establish logging and monitoring"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.S3.11",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set a 'NotificationConfiguration' parameter on your bucket with one of 'EventBridgeConfiguration', 'LambdaConfigurations', 'QueueConfigurations' or 'TopicConfigurations.'",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/s3/ct-s3-pr-5.metadata.json b/rules/control-tower/metadata/s3/ct-s3-pr-5.metadata.json
new file mode 100644
index 0000000..2138100
--- /dev/null
+++ b/rules/control-tower/metadata/s3/ct-s3-pr-5.metadata.json
@@ -0,0 +1,64 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-2(1)",
+                "AC-3",
+                "AC-3(15)",
+                "AC-3(7)",
+                "AC-6"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "7.1.1",
+                "7.2.3"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether your Amazon Simple Storage Service (Amazon S3) bucket allows user permissions through access control lists.",
+    "DisplayName": "Require that an Amazon S3 bucket does not manage user access with an access control list (ACL)",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Bucket policies and user policies",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-iam-policies.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::S3::Bucket"
+    ],
+    "EvaluatedServices": [
+        "Amazon S3"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.S3.PR.5",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.5",
+            "Name": "Enforce least privilege"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.S3.12",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Manage access to Amazon S3 buckets with bucket resource policies and IAM identity policies instead.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/s3/ct-s3-pr-6.metadata.json b/rules/control-tower/metadata/s3/ct-s3-pr-6.metadata.json
new file mode 100644
index 0000000..b173b24
--- /dev/null
+++ b/rules/control-tower/metadata/s3/ct-s3-pr-6.metadata.json
@@ -0,0 +1,70 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AU-9(2)",
+                "CP-10",
+                "CP-6(2)",
+                "CP-9",
+                "SC-5(2)",
+                "SI-13(5)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "10.5.3",
+                "10.7",
+                "3.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether a lifecycle rule is configured for Amazon S3 buckets.",
+    "DisplayName": "Require an Amazon S3 bucket to have lifecycle policies configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Managing your storage lifecycle",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::S3::Bucket"
+    ],
+    "EvaluatedServices": [
+        "Amazon S3"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.S3.PR.6",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.7",
+            "Name": "Optimize costs"
+        },
+        {
+            "Id": "CO.9",
+            "Name": "Improve availability"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.S3.13",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Configure at least one active lifecycle rule in 'LifecycleConfiguration.Rules' by setting 'Status' on a rule to 'Enabled'.",
+    "Severity": "LOW",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/s3/ct-s3-pr-7.metadata.json b/rules/control-tower/metadata/s3/ct-s3-pr-7.metadata.json
new file mode 100644
index 0000000..fb924fa
--- /dev/null
+++ b/rules/control-tower/metadata/s3/ct-s3-pr-7.metadata.json
@@ -0,0 +1,76 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "CIS AWS Benchmark 1.4",
+            "Ids": [
+                "2.1.1"
+            ]
+        },
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AU-9",
+                "CA-9(1)",
+                "CM-3(6)",
+                "SC-13",
+                "SC-28",
+                "SC-28(1)",
+                "SC-7(10)",
+                "SI-7(6)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "10.5",
+                "10.5.2",
+                "2.2",
+                "3.4",
+                "8.2.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether default server-side encryption is enabled on your Amazon S3 bucket.",
+    "DisplayName": "Require an Amazon S3 bucket to have server-side encryption configured",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "Setting default server-side encryption behavior for Amazon S3 buckets",
+            "Type": "AWS Documentation",
+            "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-encryption.html"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::S3::Bucket"
+    ],
+    "EvaluatedServices": [
+        "Amazon S3"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.S3.PR.7",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.2",
+            "Name": "Encrypt data at rest"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.S3.4",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Set an encryption rule in 'BucketEncryption.ServerSideEncryptionConfiguration' with a 'ServerSideEncryptionByDefault.SSEAlgorithm' configuration of 'AES256' or 'aws:kms'.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/rules/control-tower/metadata/s3/ct-s3-pr-8.metadata.json b/rules/control-tower/metadata/s3/ct-s3-pr-8.metadata.json
new file mode 100644
index 0000000..93a8800
--- /dev/null
+++ b/rules/control-tower/metadata/s3/ct-s3-pr-8.metadata.json
@@ -0,0 +1,78 @@
+{
+    "Behavior": "PROACTIVE",
+    "ComplianceFrameworkMappings": [
+        {
+            "ComplianceFramework": "CIS AWS Benchmark 1.4",
+            "Ids": [
+                "2.1.2"
+            ]
+        },
+        {
+            "ComplianceFramework": "NIST 800-53 Rev 5",
+            "Ids": [
+                "AC-17(2)",
+                "AC-4",
+                "IA-5(1)",
+                "SC-12(3)",
+                "SC-13",
+                "SC-23",
+                "SC-23(3)",
+                "SC-7(4)",
+                "SC-8",
+                "SC-8(1)",
+                "SC-8(2)",
+                "SI-7(6)"
+            ]
+        },
+        {
+            "ComplianceFramework": "PCI DSS version 3.2.1",
+            "Ids": [
+                "2.2",
+                "4.1",
+                "8.2.1"
+            ]
+        }
+    ],
+    "ControlOwner": "AWS Control Tower",
+    "DeploymentMechanism": "AWS CloudFormation Hook",
+    "DeploymentOwner": "AWS Control Tower",
+    "Description": "This control checks whether Amazon S3 bucket policies require requests to use Secure Socket Layer (SSL).",
+    "DisplayName": "Require that Amazon S3 bucket requests use Secure Sockets Layer",
+    "DocumentationReferences": [
+        {
+            "DisplayName": "What S3 bucket policy should I use to comply with the AWS Config rule s3-bucket-ssl-requests-only?",
+            "Type": "AWS Documentation",
+            "Url": "https://aws.amazon.com/premiumsupport/knowledge-center/s3-bucket-policy-for-config-rule/"
+        }
+    ],
+    "EvaluatedResourceTypes": [
+        "AWS::S3::BucketPolicy"
+    ],
+    "EvaluatedServices": [
+        "Amazon S3"
+    ],
+    "Guidance": "Elective",
+    "Id": "CT.S3.PR.8",
+    "ImplementationType": "CloudFormation guard rule",
+    "MinimumSupportedRuntimeVersion": "2.1",
+    "Objectives": [
+        {
+            "Id": "CO.3",
+            "Name": "Encrypt data in transit"
+        }
+    ],
+    "RegionalPreference": "REGIONAL",
+    "Relationships": [
+        {
+            "ControlId": "SH.S3.5",
+            "ControlOwner": "AWS Security Hub",
+            "RelationshipType": "Can be used with (Inclusive)"
+        }
+    ],
+    "ReleaseDate": "2022-11-28",
+    "RemediationMessage": "Configure an Amazon S3 bucket policy statement that denies access to all principals and actions for the S3 bucket and bucket objects when a secure transport protocol is not in use.",
+    "Severity": "MEDIUM",
+    "TargetOuType": "CUSTOM",
+    "Version": "1",
+    "Visibility": "PUBLIC"
+}
\ No newline at end of file
diff --git a/src/plugin.ts b/src/plugin.ts
index 9c59a15..0c1ac26 100644
--- a/src/plugin.ts
+++ b/src/plugin.ts
@@ -69,7 +69,7 @@ export class CfnGuardValidator implements IPolicyValidationPluginBeta1 {
     this.name = 'cdk-validator-cfnguard';
     this.disabledRules = props.disabledRules ?? [];
     if (props.controlTowerRulesEnabled ?? true) {
-      this.rulesPaths.push(path.join(__dirname, '..', 'rules', 'control-tower'));
+      this.rulesPaths.push(path.join(__dirname, '..', 'rules/control-tower/cfn-guard'));
     }
     this.rulesPaths.push(...props.rules ?? []);
     const osPlatform = os.platform();
diff --git a/yarn.lock b/yarn.lock
index 74ede6b..5684d83 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -999,6 +999,14 @@
   dependencies:
     "@babel/types" "^7.3.0"
 
+"@types/fs-extra@11.0.1":
+  version "11.0.1"
+  resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.1.tgz#f542ec47810532a8a252127e6e105f487e0a6ea5"
+  integrity sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==
+  dependencies:
+    "@types/jsonfile" "*"
+    "@types/node" "*"
+
 "@types/glob@*":
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/@types/glob/-/glob-8.1.0.tgz#b63e70155391b0584dce44e7ea25190bbc38f2fc"
@@ -1056,6 +1064,20 @@
   resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
   integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
 
+"@types/jsonfile@*":
+  version "6.1.1"
+  resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.1.tgz#ac84e9aefa74a2425a0fb3012bdea44f58970f1b"
+  integrity sha512-GSgiRCVeapDN+3pqA35IkQwasaCh/0YFH5dEF6S88iDvEn901DjOeH3/QPY+XYP1DFzDZPvIvfeEgk+7br5png==
+  dependencies:
+    "@types/node" "*"
+
+"@types/klaw@3.0.3":
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/@types/klaw/-/klaw-3.0.3.tgz#68c02ecfe6b313ef5b93876d44ac5266808c6a01"
+  integrity sha512-mXlRDFbTLpVysvxahXUQav0hFctgu3Fqr2xmSrpf/ptO/FwOp7SFEGsJkEihwshMbof3/BIiVJ/o42cuOOuv6g==
+  dependencies:
+    "@types/node" "*"
+
 "@types/minimatch@^5.1.2":
   version "5.1.2"
   resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca"
@@ -2899,6 +2921,15 @@ fs-extra@^10.1.0:
     jsonfile "^6.0.1"
     universalify "^2.0.0"
 
+fs-extra@^11.1.1:
+  version "11.1.1"
+  resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d"
+  integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==
+  dependencies:
+    graceful-fs "^4.2.0"
+    jsonfile "^6.0.1"
+    universalify "^2.0.0"
+
 fs-extra@^8.1.0:
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
@@ -4472,6 +4503,11 @@ kind-of@^6.0.3:
   resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
   integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
 
+klaw@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/klaw/-/klaw-4.1.0.tgz#5df608067d8cb62bbfb24374f8e5d956323338f3"
+  integrity sha512-1zGZ9MF9H22UnkpVeuaGKOjfA2t6WrfdrJmGjy16ykcjnKQDmHVX+KI477rpbGevz/5FD4MC3xf1oxylBgcaQw==
+
 kleur@^3.0.3:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"


Test patch:
diff --git a/test/plugin.integ.test.ts b/test/plugin.integ.test.ts
index e734c6b..bfd01b3 100644
--- a/test/plugin.integ.test.ts
+++ b/test/plugin.integ.test.ts
@@ -8,11 +8,11 @@ import {
 } from 'aws-cdk-lib';
 import { CfnGuardValidator } from '../src';
 
-
 beforeEach(() => {
   jest.spyOn(console, 'error').mockImplementation(() => {});
   jest.spyOn(console, 'log').mockImplementation(() => {});
 });
+
 describe('CfnGuardValidator', () => {
   test('synth fails', () => {
     // GIVEN
@@ -46,7 +46,7 @@ describe('CfnGuardValidator', () => {
         new CfnGuardValidator({
           controlTowerRulesEnabled: false,
           rules: [
-            path.join(__dirname, '../rules/control-tower/s3/ct-s3-pr-1.guard'),
+            path.join(__dirname, '../rules/control-tower/cfn-guard/s3/ct-s3-pr-1.guard'),
           ],
         }),
       ],
diff --git a/test/plugin.test.ts b/test/plugin.test.ts
index f4b981c..ebb153b 100644
--- a/test/plugin.test.ts
+++ b/test/plugin.test.ts
@@ -15,8 +15,10 @@ beforeEach(() => {
     [path.join(__dirname, 'test-data')]: mock.load(path.join(__dirname, 'test-data')),
     [path.join(__dirname, '../rules')]: {
       'control-tower': {
-        amazon_s3: {
-          's3-rule.guard': '',
+        'cfn-guard': {
+          amazon_s3: {
+            's3-rule.guard': '',
+          },
         },
       },
     },
@@ -37,11 +39,13 @@ describe('CfnGuardPlugin', () => {
     mock({
       [path.join(__dirname, '../rules')]: {
         'control-tower': {
-          s3: {
-            'ct-s3-rule.guard': '',
-          },
-          efs: {
-            'ct-efs-rule.guard': '',
+          'cfn-guard': {
+            s3: {
+              'ct-s3-rule.guard': '',
+            },
+            efs: {
+              'ct-efs-rule.guard': '',
+            },
           },
         },
       },
@@ -57,20 +61,20 @@ describe('CfnGuardPlugin', () => {
     expect(execMock).toHaveBeenCalledTimes(4);
     expect(execMock).toHaveBeenNthCalledWith(1, expect.arrayContaining([
       '--rules',
-      path.join(__dirname, '../rules/control-tower/efs/ct-efs-rule.guard'),
+      path.join(__dirname, '../rules/control-tower/cfn-guard/efs/ct-efs-rule.guard'),
       '--data',
       'template-path-1',
     ]), { json: true });
     expect(execMock).toHaveBeenNthCalledWith(2, expect.arrayContaining([
       '--rules',
-      path.join(__dirname, '../rules/control-tower/efs/ct-efs-rule.guard'),
+      path.join(__dirname, '../rules/control-tower/cfn-guard/efs/ct-efs-rule.guard'),
       '--data',
       'template-path-2',
     ]), { json: true });
     expect(execMock).toHaveBeenNthCalledWith(3, expect.arrayContaining([
       expect.stringMatching(/.*bin\/\w+\/cfn-guard$/),
       '--rules',
-      path.join(__dirname, '../rules/control-tower/s3/ct-s3-rule.guard'),
+      path.join(__dirname, '../rules/control-tower/cfn-guard/s3/ct-s3-rule.guard'),
       '--data',
       'template-path-1',
       '--output-format',
@@ -80,7 +84,7 @@ describe('CfnGuardPlugin', () => {
     ]), { json: true });
     expect(execMock).toHaveBeenNthCalledWith(4, expect.arrayContaining([
       '--rules',
-      path.join(__dirname, '../rules/control-tower/s3/ct-s3-rule.guard'),
+      path.join(__dirname, '../rules/control-tower/cfn-guard/s3/ct-s3-rule.guard'),
       '--data',
       'template-path-2',
     ]), { json: true });
@@ -91,11 +95,13 @@ describe('CfnGuardPlugin', () => {
     mock({
       [path.join(__dirname, '../rules')]: {
         'control-tower': {
-          s3: {
-            'ct-s3-rule.guard': '',
-          },
-          efs: {
-            'ct-efs-rule.guard': '',
+          'cfn-guard': {
+            s3: {
+              'ct-s3-rule.guard': '',
+            },
+            efs: {
+              'ct-efs-rule.guard': '',
+            },
           },
         },
       },
@@ -113,7 +119,7 @@ describe('CfnGuardPlugin', () => {
     expect(execMock).toHaveBeenCalledTimes(1);
     expect(execMock).toHaveBeenCalledWith(expect.arrayContaining([
       '--rules',
-      path.join(__dirname, '../rules/control-tower/efs/ct-efs-rule.guard'),
+      path.join(__dirname, '../rules/control-tower/cfn-guard/efs/ct-efs-rule.guard'),
       '--data',
       'template.json',
     ]), { json: true });
diff --git a/test/rules/control-tower/ec2/ct-ec2-pr-5.test.ts b/test/rules/control-tower/ec2/ct-ec2-pr-5.test.ts
index 3ba0fa7..2b66e68 100644
--- a/test/rules/control-tower/ec2/ct-ec2-pr-5.test.ts
+++ b/test/rules/control-tower/ec2/ct-ec2-pr-5.test.ts
@@ -16,7 +16,7 @@ beforeEach(() => {
 });
 
 const GUARD_RULE_CHECK_NAME = 'nacl_no_unrestricted_ssh_rdp_check';
-const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/ec2/ct-ec2-pr-5.guard');
+const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/cfn-guard/ec2/ct-ec2-pr-5.guard');
 const VALIDATOR_CONFIG = { rules: [GUARD_RULE_PATH], controlTowerRulesEnabled: false };
 
 describe('CT.EC2.PR.5', () => {
diff --git a/test/rules/control-tower/ec2/ct-ec2-pr-7.test.ts b/test/rules/control-tower/ec2/ct-ec2-pr-7.test.ts
index 5a6dc0c..e158ba8 100644
--- a/test/rules/control-tower/ec2/ct-ec2-pr-7.test.ts
+++ b/test/rules/control-tower/ec2/ct-ec2-pr-7.test.ts
@@ -25,7 +25,7 @@ beforeEach(() => {
 });
 
 const GUARD_RULE_CHECK_NAME = 'ec2_encrypted_volumes_check';
-const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/ec2/ct-ec2-pr-7.guard');
+const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/cfn-guard/ec2/ct-ec2-pr-7.guard');
 const VALIDATOR_CONFIG = { rules: [GUARD_RULE_PATH], controlTowerRulesEnabled: false };
 
 describe('CT.EC2.PR.7', () => {
diff --git a/test/rules/control-tower/iam/ct-iam-pr-2.test.ts b/test/rules/control-tower/iam/ct-iam-pr-2.test.ts
index a540209..2404451 100644
--- a/test/rules/control-tower/iam/ct-iam-pr-2.test.ts
+++ b/test/rules/control-tower/iam/ct-iam-pr-2.test.ts
@@ -5,7 +5,7 @@ import { CfnGuardValidator } from '../../../../src';
 import { GUARD_RULE_VALIDATION_FAILED_MESSAGE_PATTERN } from '../../../constants';
 
 const GUARD_RULE_CHECK_NAME = 'iam_managed_policy_no_statements_with_admin_access_check';
-const GUARD_RULE_PATH = path.join(__dirname, '../../../../rules/control-tower/iam/ct-iam-pr-2.guard');
+const GUARD_RULE_PATH = path.join(__dirname, '../../../../rules/control-tower/cfn-guard/identityandaccessmanagement/ct-iam-pr-2.guard');
 const VALIDATOR_CONFIG = { rules: [GUARD_RULE_PATH], controlTowerRulesEnabled: false };
 
 beforeEach(() => {
diff --git a/test/rules/control-tower/metadata.test.ts b/test/rules/control-tower/metadata.test.ts
new file mode 100644
index 0000000..a46be90
--- /dev/null
+++ b/test/rules/control-tower/metadata.test.ts
@@ -0,0 +1,27 @@
+import { join } from 'path';
+import { pathExists } from 'fs-extra';
+import klaw from 'klaw';
+
+describe('Metadata files', () => {
+  test('a metadata file exists for each rule file', async () => {
+    for await (const ruleFile of klaw(join(__dirname, '../../../rules/control-tower/cfn-guard'))) {
+      if (ruleFile.stats.isDirectory()) { continue; }
+      const metadataPath = ruleFile.path
+        .replace('/control-tower/cfn-guard/', '/control-tower/metadata/')
+        .replace('.guard', '.metadata.json');
+      console.log(metadataPath);
+      expect(await pathExists(metadataPath)).toBe(true);
+    }
+  });
+
+  test('a guard file exists for each metadata file', async () => {
+    for await (const metadataFile of klaw(join(__dirname, '../../../rules/control-tower/metadata'))) {
+      if (metadataFile.stats.isDirectory()) { continue; }
+      const ruleFilePath = metadataFile.path
+        .replace('/control-tower/metadata/', '/control-tower/cfn-guard/')
+        .replace('.metadata.json', '.guard');
+      console.log(ruleFilePath);
+      expect(await pathExists(ruleFilePath)).toBe(true);
+    }
+  });
+});
\ No newline at end of file
diff --git a/test/rules/control-tower/rds/ct-rds-pr-16.test.ts b/test/rules/control-tower/rds/ct-rds-pr-16.test.ts
index 92c98f1..b0bdc74 100644
--- a/test/rules/control-tower/rds/ct-rds-pr-16.test.ts
+++ b/test/rules/control-tower/rds/ct-rds-pr-16.test.ts
@@ -18,7 +18,7 @@ beforeEach(() => {
 });
 
 const GUARD_RULE_CHECK_NAME = 'rds_cluster_storage_encrypted_check';
-const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/rds/ct-rds-pr-16.guard');
+const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/cfn-guard/rds/ct-rds-pr-16.guard');
 const VALIDATOR_CONFIG = { rules: [GUARD_RULE_PATH], controlTowerRulesEnabled: false };
 
 describe('CT.RDS.PR.16', () => {
diff --git a/test/rules/control-tower/s3/ct-s3-pr-1.test.ts b/test/rules/control-tower/s3/ct-s3-pr-1.test.ts
index 94f3dab..4ac26a2 100644
--- a/test/rules/control-tower/s3/ct-s3-pr-1.test.ts
+++ b/test/rules/control-tower/s3/ct-s3-pr-1.test.ts
@@ -18,7 +18,7 @@ beforeEach(() => {
 });
 
 const GUARD_RULE_CHECK_NAME = 's3_bucket_level_public_access_prohibited_check';
-const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/s3/ct-s3-pr-1.guard');
+const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/cfn-guard/s3/ct-s3-pr-1.guard');
 const VALIDATOR_CONFIG = { rules: [GUARD_RULE_PATH], controlTowerRulesEnabled: false };
 
 describe('CT.S3.PR.1', () => {
diff --git a/test/rules/control-tower/s3/ct-s3-pr-2.test.ts b/test/rules/control-tower/s3/ct-s3-pr-2.test.ts
index c716f5c..c4fc27a 100644
--- a/test/rules/control-tower/s3/ct-s3-pr-2.test.ts
+++ b/test/rules/control-tower/s3/ct-s3-pr-2.test.ts
@@ -11,7 +11,7 @@ import { CfnGuardValidator } from '../../../../src';
 import { GUARD_RULE_VALIDATION_FAILED_MESSAGE_PATTERN } from '../../../constants';
 
 const GUARD_RULE_CHECK_NAME = 's3_bucket_logging_enabled_check';
-const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/s3/ct-s3-pr-2.guard');
+const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/cfn-guard/s3/ct-s3-pr-2.guard');
 const VALIDATOR_CONFIG = { rules: [GUARD_RULE_PATH], controlTowerRulesEnabled: false };
 
 beforeEach(() => {
diff --git a/test/rules/control-tower/s3/ct-s3-pr-7.test.ts b/test/rules/control-tower/s3/ct-s3-pr-7.test.ts
index c82ead7..56441cb 100644
--- a/test/rules/control-tower/s3/ct-s3-pr-7.test.ts
+++ b/test/rules/control-tower/s3/ct-s3-pr-7.test.ts
@@ -13,7 +13,7 @@ import { CfnGuardValidator } from '../../../../src';
 import { GUARD_RULE_VALIDATION_FAILED_MESSAGE_PATTERN } from '../../../constants';
 
 const GUARD_RULE_CHECK_NAME = 's3_bucket_default_encryption_enabled_check';
-const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/s3/ct-s3-pr-7.guard');
+const GUARD_RULE_PATH = join(__dirname, '../../../../rules/control-tower/cfn-guard/s3/ct-s3-pr-7.guard');
 const VALIDATOR_CONFIG = { rules: [GUARD_RULE_PATH], controlTowerRulesEnabled: false };
 
 beforeEach(() => {
diff --git a/test/rules/control-tower/s3/ct-s3-pr-8.test.ts b/test/rules/control-tower/s3/ct-s3-pr-8.test.ts
index a498ac7..315d250 100644
--- a/test/rules/control-tower/s3/ct-s3-pr-8.test.ts
+++ b/test/rules/control-tower/s3/ct-s3-pr-8.test.ts
@@ -9,7 +9,7 @@ import {
 import { CfnGuardValidator } from '../../../../src';
 
 const GUARD_RULE_CHECK_NAME = 's3_bucket_policy_ssl_requests_only_check';
-const GUARD_RULE_PATH = path.join(__dirname, '../../../../rules/control-tower/s3/ct-s3-pr-8.guard');
+const GUARD_RULE_PATH = path.join(__dirname, '../../../../rules/control-tower/cfn-guard/s3/ct-s3-pr-8.guard');
 const VALIDATOR_CONFIG = { rules: [GUARD_RULE_PATH], controlTowerRulesEnabled: false };
 
 beforeEach(() => {