Terraform Aws Secure Baseline is a terraform module to set up your AWS account with the secure baseline configuration based on CIS Amazon Web Services Foundations.

Terraform Module Registry

A terraform module to set up your AWS account with the reasonably secure configuration baseline. Most configurations are based on CIS Amazon Web Services Foundations v1.2.0.

Starting from v0.10.0, this module requires Terraform v0.12 or later. Please use v0.9.0 if you need to use Terraform v0.11 or ealier.


1 . Identity and Access Management:

  • Set up IAM Password Policy.
  • Create separated IAM roles for defining privileges and assigning them to entities such as IAM users and groups.
  • Create an IAM role for contacting AWS support for incident handling.
  • Enable AWS Config rules to audit root account status.

2. Logging & Monitoring:

  • Enable CloudTrail in all regions and deliver events to CloudWatch Logs.
  • CloudTrail logs are encrypted using AWS Key Management Service.
  • All logs are stored in the S3 bucket with access logging enabled.
  • Logs are automatically archived into Amazon Glacier after the given period(defaults to 90 days).
  • Set up CloudWatch alarms to notify you when critical changes happen in your AWS account.
  • Enable AWS Config in all regions to automatically take configuration snapshots.
  • Enable SecurityHub and subscribe CIS benchmark standard.

3. Networking:

  • Remove all rules associated with default route tables, default network ACLs and default security groups in the default VPC in all regions.
  • Enable AWS Config rules to audit unrestricted common ports in Security Group rules.
  • Enable VPC Flow Logs with the default VPC in all regions.
  • Enable GuardDuty in all regions.

Also Read – SKA : Simple Karma Attack


data “aws_caller_identity” “current” {}
data “aws_region” “current” {}

module “secure_baseline” {
source = “nozaq/secure-baseline/aws”

audit_log_bucket_name = “YOUR_BUCKET_NAME”
aws_account_id = data.aws_caller_identity.current.account_id
region = data.aws_region.current.name
support_iam_role_principal_arn = “YOUR_IAM_USER”

providers = {
aws = aws
aws.ap-northeast-1 = aws.ap-northeast-1
aws.ap-northeast-2 = aws.ap-northeast-2
aws.ap-south-1 = aws.ap-south-1
aws.ap-southeast-1 = aws.ap-southeast-1
aws.ap-southeast-2 = aws.ap-southeast-2
aws.ca-central-1 = aws.ca-central-1
aws.eu-central-1 = aws.eu-central-1
aws.eu-north-1 = aws.eu-north-1
aws.eu-west-1 = aws.eu-west-1
aws.eu-west-2 = aws.eu-west-2
aws.eu-west-3 = aws.eu-west-3
aws.sa-east-1 = aws.sa-east-1
aws.us-east-1 = aws.us-east-1
aws.us-east-2 = aws.us-east-2
aws.us-west-1 = aws.us-west-1
aws.us-west-2 = aws.us-west-2

Check the example to understand how these providers are defined. Note that you need to define a provider for each AWS region and pass them to the module.

Currently this is the recommended way to handle multiple regions in one module. Detailed information can be found at Providers within Modules – Terraform Docs.

A new S3 bucket to store audit logs is automatically created by default, while the external S3 bucket can be specified.

It is useful when you already have a centralized S3 bucket to store all logs. Please see external-bucket example for more detail.

Managing multiple accounts in AWS Organization

When you have multiple AWS accounts in your AWS Organization, secure-baseline module configures the separated environment for each AWS account.

You can change this behavior to centrally manage security information and audit logs from all accounts in one master account.

Check organization example for more detail.


This module is composed of several submodules and each of which can be used independently. Modules in Package Sub-directories – Terraform describes how to source a submodule.

  • alarm-baseline
  • cloudtrail-baseline
  • guardduty-baseline
  • iam-baseline
  • vpc-baseline
  • secure-bucket


account_typeThe type of the AWS account. The possible values are individualmaster and member . Specify master and member to set up centalized logging for multiple accounts in AWS Organization. Use individual` otherwise.string"individual"no
alarm_namespaceThe namespace in which all alarms are set up.string"CISBenchmark"no
alarm_sns_topic_nameThe name of the SNS Topic which will be notified when any alarm is performed.string"CISAlarm"no
allow_users_to_change_passwordWhether to allow users to change their own password.string"true"no
audit_log_bucket_force_destroyA boolean that indicates all objects should be deleted from the audit log bucket so that the bucket can be destroyed without error. These objects are not recoverable.string"false"no
audit_log_bucket_nameThe name of the S3 bucket to store various audit logs.stringn/ayes
audit_log_lifecycle_glacier_transition_daysThe number of days after log creation when the log file is archived into Glacier.string"90"no
aws_account_idThe AWS Account ID number of the account.stringn/ayes
cloudtrail_cloudwatch_logs_group_nameThe name of CloudWatch Logs group to which CloudTrail events are delivered.string"cloudtrail-multi-region"no
cloudtrail_iam_role_nameThe name of the IAM Role to be used by CloudTrail to delivery logs to CloudWatch Logs group.string"CloudTrail-CloudWatch-Delivery-Role"no
cloudtrail_iam_role_policy_nameThe name of the IAM Role Policy to be used by CloudTrail to delivery logs to CloudWatch Logs group.string"CloudTrail-CloudWatch-Delivery-Policy"no
cloudtrail_key_deletion_window_in_daysDuration in days after which the key is deleted after destruction of the resource, must be between 7 and 30 days. Defaults to 30 days.string"10"no
cloudtrail_nameThe name of the trail.string"cloudtrail-multi-region"no
cloudtrail_s3_key_prefixThe prefix used when CloudTrail delivers events to the S3 bucket.string"cloudtrail"no
cloudwatch_logs_retention_in_daysNumber of days to retain logs for. CIS recommends 365 days. Possible values are: 0, 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653. Set to 0 to keep logs indefinitely.string"365"no
config_aggregator_nameThe name of the organizational AWS Config Configuration Aggregator.string"organization-aggregator"no
config_aggregator_name_prefixThe prefix of the name for the IAM role attached to the organizational AWS Config Configuration Aggregator.string"config-for-organization-role"no
config_delivery_frequencyThe frequency which AWS Config sends a snapshot into the S3 bucket.string"One_Hour"no
config_iam_role_nameThe name of the IAM Role which AWS Config will use.string"Config-Recorder"no
config_iam_role_policy_nameThe name of the IAM Role Policy which AWS Config will use.string"Config-Recorder-Policy"no
config_s3_bucket_key_prefixThe prefix used when writing AWS Config snapshots into the S3 bucket.string"config"no
config_sns_topic_nameThe name of the SNS Topic to be used to notify configuration changes.string"ConfigChanges"no
guardduty_disable_email_notificationBoolean whether an email notification is sent to the accounts.string"false"no
guardduty_finding_publishing_frequencySpecifies the frequency of notifications sent for subsequent finding occurrences.string"SIX_HOURS"no
guardduty_invitation_messageMessage for invitation.string"This is an automatic invitation message from guardduty-baseline module."no
manager_iam_role_nameThe name of the IAM Manager role.string"IAM-Manager"no
manager_iam_role_policy_nameThe name of the IAM Manager role policy.string"IAM-Manager-Policy"no
master_account_idThe ID of the master AWS account to which the current AWS account is associated. Required if account\_type is member.string""no
master_iam_role_nameThe name of the IAM Master role.string"IAM-Master"no
master_iam_role_policy_nameThe name of the IAM Master role policy.string"IAM-Master-Policy"no
max_password_ageThe number of days that an user password is valid.string"90"no
member_accountsA list of IDs and emails of AWS accounts which associated as member accounts.object[]no
minimum_password_lengthMinimum length to require for user passwords.string"14"no
password_reuse_preventionThe number of previous passwords that users are prevented from reusing.string"24"no
regionThe AWS region in which global resources are set up.stringn/ayes
require_lowercase_charactersWhether to require lowercase characters for user passwords.string"true"no
require_numbersWhether to require numbers for user passwords.string"true"no
require_symbolsWhether to require symbols for user passwords.string"true"no
require_uppercase_charactersWhether to require uppercase characters for user passwords.string"true"no
support_iam_role_nameThe name of the the support role.string"IAM-Support"no
support_iam_role_policy_nameThe name of the support role policy.string"IAM-Support-Role"no
support_iam_role_principal_arnThe ARN of the IAM principal element by which the support role could be assumed.stringn/ayes
tagsSpecifies object tags key and value. This applies to all resources created by this module.map{}no
target_regionsA list of regions to set up with this module.list[ "ap-northeast-1", "ap-northeast-2", "ap-south-1", "ap-southeast-1", "ap-southeast-2", "ca-central-1", "eu-central-1", "eu-north-1", "eu-west-1", "eu-west-2", "eu-west-3", "sa-east-1", "us-east-1", "us-east-2", "us-west-1", "us-west-2" ]no
use_external_audit_log_bucketA boolean that indicates whether the specific audit log bucket already exists. Create a new S3 bucket if it is set to false.string"false"no
vpc_iam_role_nameThe name of the IAM Role which VPC Flow Logs will use.string"VPC-Flow-Logs-Publisher"no
vpc_iam_role_policy_nameThe name of the IAM Role Policy which VPC Flow Logs will use.string"VPC-Flow-Logs-Publish-Policy"no
vpc_log_group_nameThe name of CloudWatch Logs group to which VPC Flow Logs are delivered.string"default-vpc-flow-logs"no
vpc_log_retention_in_daysNumber of days to retain logs for. CIS recommends 365 days. Possible values are: 0, 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653. Set to 0 to keep logs indefinitely.string"365"no


alarm_sns_topicThe SNS topic to which CloudWatch Alarms will be sent.
audit_bucketThe S3 bucket used for storing audit logs.
cloudtrailThe trail for recording events in all regions.
cloudtrail_kms_keyThe KMS key used for encrypting CloudTrail events.
cloudtrail_log_delivery_iam_roleThe IAM role used for delivering CloudTrail events to CloudWatch Logs.
cloudtrail_log_groupThe CloudWatch Logs log group which stores CloudTrail events.
config_configuration_recorderThe configuration recorder in each region.
config_iam_roleThe IAM role used for delivering AWS Config records to CloudWatch Logs.
config_sns_topicThe SNS topic that AWS Config delivers notifications to.
default_network_aclThe default network ACL.
default_route_tableThe default route table.
default_security_groupThe ID of the default security group.
default_vpcThe default VPC.
guardduty_detectorThe GuardDuty detector in each region.
manager_iam_roleThe IAM role used for the manager user.
master_iam_roleThe IAM role used for the master user.
support_iam_roleThe IAM role used for the support user.
vpc_flow_logs_groupThe CloudWatch Logs log group which stores VPC Flow Logs in each region.
vpc_flow_logs_iam_roleThe IAM role used for delivering VPC Flow Logs to CloudWatch Logs.