Giter Club home page Giter Club logo

terraform-aws-mcaf-landing-zone's Introduction

terraform-aws-mcaf-landing-zone

Terraform module to setup and manage various components of the SBP AWS Landing Zone.

Overview of Landing Zone tools & services:

The SBP AWS Landing Zone consists of 3 repositories:

Basic configuration

module "landing_zone" {
  source             = "github.com/schubergphilis/terraform-aws-mcaf-landing-zone?ref=VERSION"
  tags               = var.tags

  control_tower_account_ids = {
    audit   = "012345678902"
    logging = "012345678903"
  }
}

Detailed configuration

AWS SES Root Accounts mail forwarder

Setting the ses_root_accounts_mail_forward variable creates the necessary AWS Simple Email Service (SES) resources to accept mail sent to an AWS hosted domain and forward it to an external recipient or recipients. This can be used to enable secure mailboxes/IT service catalog aliases for all root accounts. Emails are received via AWS SES and forwarded to an email forwarder lambda which sends the email to the destination email server as specified in the recipient_mapping variable of ses_root_accounts_mail_forward.

Before setting the ses_root_accounts_mail_forward variable, make sure that an AWS Route53 hosted zone is created. For example aws.yourcompany.com. Pass this domain using the domain variable of ses_root_accounts_mail_forward.

Example:

ses_root_accounts_mail_forward = {
  domain     = "aws.yourcompany.com"
  from_email = "[email protected]"

  recipient_mapping = {
    "[email protected]" = [
      "[email protected]"
    ]
  }
}

By default, you have to create the email addresses for the accounts created using the MCAF Account Vending Machine (AVM) module yourself. Using this functionality you can pass aliases of the mailbox created. E.g. root+<account-name>@aws.yourcompany.com.

AWS CloudTrail

By default, all CloudTrail logs will be stored in a S3 bucket in the logging account of your AWS Organization. However, this module also supports creating an additional CloudTrail configuration to publish logs to any S3 bucket chosen by you. This trail will be set at the Organization level, meaning that logs from all accounts will be published to the provided bucket.

NOTE: Before enabling this feature, make sure that the bucket policy authorizing CloudTrail to deliver logs is in place and that you have enabled trusted access between AWS Organizations and CloudTrail. If these two steps are not in place, Terraform will fail to create the trail.

Example:

additional_auditing_trail = {
  name   = "additional_auditing_trail"
  bucket = "bucket_name"
}

AWS Config Rules

This module provisions by default a set of basic AWS Config Rules. In order to add extra rules, a list of rule identifiers can be passed via the variable aws_config using the attribute rule_identifiers.

If you would like to authorize other accounts to aggregate AWS Config data, the account IDs and regions can also be passed via the variable aws_config using the attributes aggregator_account_ids and aggregator_regions respectively.

NOTE: This module already authorizes the audit account to aggregate Config data from all other accounts in the organization, so there is no need to specify the audit account ID in the aggregator_account_ids list.

Example:

aws_config = {
  aggregator_account_ids = ["123456789012"]
  aggregator_regions     = ["eu-west-1"]
  rule_identifiers       = ["ACCESS_KEYS_ROTATED", "ALB_WAF_ENABLED"]
}

AWS GuardDuty

This module supports enabling GuardDuty at the organization level which means that all new accounts that are created in, or added to, the organization are added as a member accounts of the audit account GuardDuty detector.

This feature can be controlled via the aws_guardduty variable and is enabled by default. With aws_guardduty_s3_protection you control if you want to have GuardDuty protecting S3, it is turned on by default.

Note: In case you are migrating an existing AWS organization to this module, all existing accounts except for the master and logging accounts have to be enabled like explained here.

AWS SSO

This module supports managing AWS SSO resources to control user access to all accounts belonging to the AWS Organization.

This feature can be controlled via the aws_sso_permission_sets variable by passing a map (key-value pair) where every key corresponds to an AWS SSO Permission Set name and the value follows the structure below:

  • assignments: list of maps (key-value pair) of AWS Account IDs as keys and a list of AWS SSO Group names that should have access to the account using the permission set defined
  • inline_policy: valid IAM policy in JSON format (maximum length of 10240 characters)
  • managed_policy_arns: list of strings that contain the ARN's of the managed policies that should be attached to the permission set
  • session_duration: length of time in the ISO-8601 standard

Example:

  aws_sso_permission_sets = {
    PlatformAdmin = {
      inline_policy    = file("${path.module}/template_files/sso/platform_admin.json")
      session_duration = "PT2H"

      managed_policy_arns = [
        "arn:aws:iam::aws:policy/ReadOnlyAccess"
      ]

      assignments = [
        {
          for account in [ 123456789012, 012456789012 ] : account => [
            okta_group.aws["AWSPlatformAdmins"].name
          ]
        },
        {
          for account in [ 925556789012 ] : account => [
            okta_group.aws["AWSPlatformUsers"].name
          ]
        }
      ]
    }
    PlatformUser = {
      session_duration = "PT12H"

      managed_policy_arns = [
        "arn:aws:iam::aws:policy/ReadOnlyAccess",
        "arn:aws:iam::aws:policy/AWSSupportAccess"
      ]

      assignments = [
        {
          for account in [ 123456789012, 012456789012 ] : account => [
            okta_group.aws["AWSPlatformAdmins"].name,
            okta_group.aws["AWSPlatformUsers"].name
          ]
        }
      ]

      inline_policy = jsonencode(
        {
          Version = "2012-10-17",
          Statement = concat(
            [
              {
                Effect   = "Allow",
                Action   = "support:*",
                Resource = "*"
              }
            ],
            jsondecode(data.aws_iam_policy.lambda_readonly.policy).Statement
          )
        }
      )
    }
  }

Datadog Integration

This module supports an optional Datadog-AWS integration. This integration makes it easier for you to forward metrics and logs from your AWS account to Datadog.

In order to enable the integration, you can pass an object to the variable datadog containing the following attributes:

In case you don't want to use the integration, you can configure the Datadog provider like in the example below:

provider "datadog" {
  validate = false
}

This should prevent the provider from asking you for a Datadog API Key and allow the module to be provisioned without the integration resources.

Monitoring IAM Activity

By default, this module monitors and notifies activities performed by the root user of all core accounts and AWS SSO Roles. All notifications will be sent to the SNS Topic LandingZone-IAMActivity in the audit account.

These are the type of events that will be monitored:

  • Any activity made by the root user of the account.
  • Any manual changes made by AWS SSO roles (read-only operations and console logins are not taken into account).

In case you would like to disable this functionality, you can set the variable monitor_iam_activity to false.

Organizations Policies: Service Control Policies (SCPs)

Service control policies (SCPs) are a type of organization policy that you can use to manage permissions in your organization. See this page for an introduction to SCPs and the value they add.

This module allows using various SCPs as described below. We try to adhere to best practices of not attaching SCPs to the root of the organisation when possible; in the event you need to pass a list of OU names, be sure to have the exact name as the matching is case sensitive.

Deny ability to disable Security Hub

Enabling this SCP removes a member account's ability to disable Security Hub.

This is SCP is enabled by default, but can be disabled by setting aws_deny_disabling_security_hub variable to false.

Deny ability to leave Organization

Enabling this SCP removes a member account's ability to leave the AWS organisation.

This is SCP is enabled by default, but can be disabled by setting aws_deny_leaving_org variable to false.

Require the use of Instance Metadata Service Version 2

By default, all EC2s still allow access to the original metadata service, which means that if an attacker finds an EC2 running a proxy or WAF, or finds and SSRF vulnerability, they likely can steal the IAM role of the EC2. By enforcing IMDSv2, you can mitigate that risk. Be aware that this potentially could break some applications that have not yet been updated to work with the new IMDSv2.

This is SCP is enabled by default, but can be disabled by setting aws_require_imdsv2 variable to false.

Restricting AWS Regions

If you would like to define which AWS Regions can be used in your AWS Organization, you can pass a list of region names to the variable aws_region_restrictions using the allowed attribute. This will trigger this module to deploy a Service Control Policy (SCP) designed by AWS and attach it to the root of your AWS Organization.

In case you would like to exempt specific IAM entities from the region restriction, you can pass a list of ARN patterns using the exceptions attribute. This can be useful for roles used by AWS ControlTower, for example, to avoid preventing it from managing all regions properly.

Example:

aws_region_restrictions = {
  allowed    = ["eu-west-1"]
  exceptions = ["arn:aws:iam::*:role/RoleAllowedToBypassRegionRestrictions"]
}

Restricting Root User Access

If you would like to restrict the root user's ability to log into accounts in an OU, you can pass a list of OU names to the aws_deny_root_user_ous variable.

Example showing SCP applied to all OUs except the Root OU:

data "aws_organizations_organization" "default" {}

data "aws_organizations_organizational_units" "default" {
  parent_id = data.aws_organizations_organization.default.roots[0].id
}

module "landing_zone" {
  ...

  aws_deny_root_user_ous = [
    for ou in data.aws_organizations_organizational_units.default.children : ou.name if ou.name != "Root"
  ]

Organizations Policies: Tag Policies

Tag policies are a type of policy that can help you standardize tags across resources in your organization's accounts. In a tag policy, you specify tagging rules applicable to resources when they are tagged. See this page for an introduction to tag policies and the value they add.

If you would like to enforce certain tags in an OU, you can pass a map of OU names containing the tags to the aws_required_tags variable. Be sure to pass the exact OU name as the matching is case sensitive. If the OU provided does not match any existing OU the tag policy is not created.

Example:

module "landing_zone" {
  ...

  aws_required_tags = {
    "Production" = [
      {
        name   = "Tag1"
        values = ["A", "B"]
      }
    ]
    "Non-Production" = [
      {
        name   = "Tag2"
        values = ["A", "B"]
      }
    ]
  }

SNS topic subscription

Topic Name Variable Content
aws-controltower-AggregateSecurityNotifications aws_config_sns_subscription Aggregated AWS Config notifications
LandingZone-SecurityHubFindings aws_security_hub_sns_subscription Aggregated Security Hub findings
LandingZone-IAMActivity monitor_iam_activity_sns_subscription IAM activity findings

Example for https protocol and specified webhook endpoint:

module "landing_zone" {
  ...

  aws_config_sns_subscription = {
    endpoint = "https://app.datadoghq.com/intake/webhook/sns?api_key=qwerty0123456789"
    protocol = "https"
  }
}

Requirements

Name Version
terraform >= 1.0
aws >= 3.50.0, < 4.0.0

Providers

Name Version
aws >= 3.50.0, < 4.0.0
aws.audit >= 3.50.0, < 4.0.0
aws.logging >= 3.50.0, < 4.0.0

Inputs

Name Description Type Default Required
control_tower_account_ids Control Tower core account IDs
object({
audit = string
logging = string
})
n/a yes
tags Map of tags map(string) n/a yes
additional_auditing_trail CloudTrail configuration for additional auditing trail
object({
name = string
bucket = string
})
null no
aws_account_password_policy AWS account password policy parameters for the audit, logging and master account
object({
allow_users_to_change = bool
max_age = number
minimum_length = number
require_lowercase_characters = bool
require_numbers = bool
require_symbols = bool
require_uppercase_characters = bool
reuse_prevention_history = number
})
{
"allow_users_to_change": true,
"max_age": 90,
"minimum_length": 14,
"require_lowercase_characters": true,
"require_numbers": true,
"require_symbols": true,
"require_uppercase_characters": true,
"reuse_prevention_history": 24
}
no
aws_config AWS Config settings
object({
aggregator_account_ids = list(string)
aggregator_regions = list(string)
})
null no
aws_config_sns_subscription Subscription options for the aws-controltower-AggregateSecurityNotifications (AWS Config) SNS topic
map(object({
endpoint = string
protocol = string
}))
{} no
aws_deny_disabling_security_hub Enable SCP that denies accounts the ability to disable Security Hub bool true no
aws_deny_leaving_org Enable SCP that denies accounts the ability to leave the AWS organisation bool true no
aws_deny_root_user_ous List of AWS Organisation OUs to apply the "DenyRootUser" SCP to list(string) [] no
aws_ebs_encryption_by_default Set to true to enable AWS Elastic Block Store encryption by default bool true no
aws_guardduty Whether AWS GuardDuty should be enabled bool true no
aws_guardduty_s3_protection Whether AWS GuardDuty S3 protection should be enabled bool true no
aws_region_restrictions List of allowed AWS regions and principals that are exempt from the restriction
object({
allowed = list(string)
exceptions = list(string)
})
null no
aws_require_imdsv2 Enable SCP which requires EC2 instances to use V2 of the Instance Metadata Service bool true no
aws_required_tags AWS Required tags settings
map(list(object({
name = string
values = list(string)
})))
null no
aws_security_hub_product_arns A list of the ARNs of the products you want to import into Security Hub list(string) [] no
aws_security_hub_sns_subscription Subscription options for the LandingZone-SecurityHubFindings SNS topic
map(object({
endpoint = string
protocol = string
}))
{} no
aws_sso_permission_sets Map of AWS SSO Permission Sets with the AWS Accounts and the names of the AWS SSO Groups that should be granted access to each account
map(object({
assignments = list(map(list(string)))
inline_policy = string
managed_policy_arns = list(string)
session_duration = string
}))
{} no
datadog Datadog integration options for the core accounts
object({
api_key = string
enable_integration = bool
install_log_forwarder = bool
site_url = string
})
null no
datadog_excluded_regions List of regions where metrics collection will be disabled. list(string) [] no
kms_key_policy A valid KMS key policy JSON document string "" no
kms_key_policy_logging A valid KMS key policy JSON document for use with logging KMS key string "" no
monitor_iam_activity Whether IAM activity should be monitored bool true no
monitor_iam_activity_sns_subscription Subscription options for the LandingZone-IAMActivity SNS topic
map(object({
endpoint = string
protocol = string
}))
{} no
security_hub_create_cis_metric_filters Enable the creation of metric filters related to the CIS AWS Foundation Security Hub Standard bool true no
security_hub_standards_arns A list of the ARNs of the standards you want to enable in Security Hub list(string) null no
ses_root_accounts_mail_forward SES config to receive and forward root account emails
object({
domain = string
from_email = string
recipient_mapping = map(any)
})
null no

Outputs

Name Description
kms_key_arn ARN of KMS key for SSM encryption
kms_key_id ID of KMS key for SSM encryption
kms_key_logging_arn ARN of KMS key for logging account
kms_key_logging_id ID of KMS key for logging account
monitor_iam_activity_sns_topic_arn ARN of the SNS Topic in the Audit account for IAM activity monitoring notifications

License

Copyright: Schuberg Philis

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

terraform-aws-mcaf-landing-zone's People

Contributors

fernandogoncalves-me avatar marwinbaumannsbp avatar shoekstra avatar alirizwansbp avatar stefanwb avatar 64ne avatar wvanheerde avatar sgielen avatar masafari avatar martijnvdp avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.