Skip to content

Coalfire-CF/terraform-aws-account-setup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Coalfire

terraform-aws-account-setup

Description

The AWS account set up module creates the initial account configuration for your project, including IAM roles, KMS keys, S3 installs bucket, and more.

FedRAMP Compliance: High

Dependencies

Resource List

Resources that are created as a part of this module include:

  • IAM role, policies, and instance profiles for Packer to assume during AMI creation (optional: one account can build and store Packer AMIs and share them with other accounts).
  • KMS keys and typically required IAM permissions for commonly used services (S3, ELB, RDS, EBS, etc.).
  • S3 buckets:
    • ELB Access Logs bucket is optional. With multiple accounts: you can designate one as a centralized logging account and have other accounts send ELB logs to one account's bucket, this is not possible with S3 access logs where the bucket must be in the same account & region).
    • Set 'create_s3_elb_accesslogs_bucket' to 'true' if this is run in an account where you want the logs to be sent.
  • Optional: Security core module resources (Terraform state resources should only exist in the AWS Management account and AWS GOV ORG Root account).

Cross-Account Permissions

There are 3 supported deployment configurations regarding IAM cross-account permissions. Sharing principally concerns S3 Buckets (where applicable) and KMS Key permissions.

Sharing based on AWS ORG (Recommended, easier to maintain since permissions are granted via AWS Organization ID instead of individual account IDs):

### Sharing ###
  is_organization                        = true # Should be "false" if setting "application_account_numbers"
  organization_id                        = "your-organization-id"

Standalone account (No cross-account sharing: Set "is_organization" to "false" (default is "true"), and you can omit "application_account_numbers" and "organization_id"):

### Sharing ###
  is_organization                        = false # Should be "false" if setting "application_account_numbers"

Sharing is based on a list of AWS Account IDs:

### Sharing ###
  application_account_numbers            = ["account-number1", "account-number2", "account-number3"]
  is_organization                        = false # Should be "false" if setting "application_account_numbers"

AWS Backups

AWS Backups are based on the presence of a tag and can be applied to S3 buckets. The configuration depends on "s3_backup_settings" and "s3_backup_policy". At a minimum, "s3_backup_policy" must be defined in order for the S3 buckets to be tagged. "s3_backup_settings" is an optional map variable that lets you enable or disable AWS Backups on individual S3 buckets that this pak creates. The default value will NOT tag the S3 Access Logs, ELB Access Logs, or Cloudtrail buckets for AWS Backup. This is an opinionated default that assumes that a SIEM solution will ingest and store these logs, so having a backup is a waste of money. But if this is not true, then you can individually override this as shown in the example above. Example:

### AWS Backup ###
  s3_backup_policy = "aws-backup-${var.resource_prefix}-default-policy"
  s3_backup_settings = {
    accesslogs = {
      enable_backup = true # Normally "false" because we're assuming that a SIEM will ingest and store these logs
    }
    elb-accesslogs = {
      enable_backup = true # Normally "false" because we're assuming that a SIEM will ingest and store these logs
    }
    backups = {
      enable_backup = true
    }
    installs = {
      enable_backup = true
    }
    fedrampdoc = {
      enable_backup = true
    }
    cloudtrail = {
      enable_backup = true # Normally "false" because we're assuming that a SIEM will ingest and store these logs
    }
    config = {
      enable_backup = true
    }
  }

Usage

"Management plane" account: Terraform state is stored here, Packer AMIs are built here. This is different from the AWS GOV ORG Root account where AWS ORG should have been deployed.

module "account-setup" {
   source = "github.com/Coalfire-CF/terraform-aws-account-setup?ref=vx.x.x"

   aws_region         = var.aws_region
   default_aws_region = var.default_aws_region
   account_number     = var.account_number
   resource_prefix    = var.resource_prefix

   ### Cloudtrail ###
   create_cloudtrail                      = var.create_cloudtrail # false
   cloudwatch_log_group_retention_in_days = var.cloudwatch_log_group_retention_in_days # 30

   ### Secrets Manager ### (EC2 Keypair) 
   ssh_key_name        = var.ssh_key_name
   ssh_key_secret_name = var.ssh_key_secret_name
   
   ### KMS ### (Optional)
   additional_kms_keys = [
      {
         name   = "elasticache"
         policy = "${data.aws_iam_policy_document.elasticache_key_policy.json}"
      }
   ]

   ### Packer ###
   create_packer_iam = var.create_packer_iam # true (Packer AMIs will be built and kept on this account and shared with other accounts (share accounts is provided to Packer as a variable at build time)

   ### Terraform ###
   create_security_core = var.create_security_core # true (Terraform state will be kept on this account)

   ### Sharing ###
   is_organization = var.is_organization # true (Should be "false" if setting "application_account_numbers")
   organization_id = var.organization_id

   ### AWS Backup ###
   s3_backup_policy = "aws-backup-${var.resource_prefix}-default-policy"
}

Optional: "AWS ORG Member account". This code is not intended to be deployed in every account unless there's a clear need for supporting infrastructure. Does not need Terraform resources (S3 bucket to store state, DynamoDB table for state lock since these will be stored in MGMT account), Packer AMIs will not be built in this account, is not a Management account for AWS Organizations, does not need to share IAM permissions (s3 buckets, KMS keys) to any other account. The default configuration also creates individually owned Customer KMS Keys.

module "account-setup" {
   source = "github.com/Coalfire-CF/terraform-aws-account-setup?ref=vx.x.x"

   # Use the OrganizationAccountAccessRole in member account to deploy resources into it using MGMT account CLI credentials
   providers = { 
      aws = aws.example-member-account
   }

   ## GLOBAL ##
   aws_region         = var.aws_region
   default_aws_region = var.default_aws_region
   account_number     = var.account_number
   resource_prefix    = var.resource_prefix

   ### Sharing ###
   is_organization = var.is_organization
   organization_id = var.organization_id

   ### Secrets Manager ### (EC2 Keypair) 
   ssh_key_name        = var.ssh_key_name
   ssh_key_secret_name = var.ssh_key_secret_name

   ### AWS Backup ###
   s3_backup_policy = "aws-backup-${var.resource_prefix}-default-policy"

   ### Disable Resources Not Needed ###
   create_nfw_kms_key          = false
   create_config_kms_key       = false
   create_s3_config_bucket     = false
   create_s3_fedrampdoc_bucket = false
}

The 'OrganizationAccountAccessRole' roles are automatically created in each AWS GOV ORG member account (including MGMT) when they are added to the ORG and should by default only be assumed by the ORG root account. You will need to make sure that the MGMT plane account has access to assume the 'OrganizationAccountAccessRole' in each required member account it needs to deploy resources to by reviewing the trust relationship of the roles.

(Optional) Custom Resource Names

It is possible to specify custom resource names for most resources deployed by this module, in order to conform to a given naming convention. The following inputs are supported:

cloudtrail_name                 
cloudtrail_bucket_name          
cloudtrail_log_group_name       
cloudtrail_iam_role_name        
packer_iam_role_name            
packer_iam_policy_name          
packer_iam_instanceprofile_name
packer_s3_kmsgrant_name         
packer_ebs_kmsgrant_name        
accesslogs_bucket_name          
config_bucket_name              
backups_bucket_name             
elb_accesslogs_bucket_name      
fedrampdoc_bucket_name          
installs_bucket_name            

Example code

module "account-setup" {
   source = "github.com/Coalfire-CF/terraform-aws-account-setup?ref=vx.x.x"
   
   ...

   cloudtrail_name                 = "example-cloudtrail-mgmt"
   cloudtrail_bucket_name          = "example-s3-cloudtrail-mgmt"
   cloudtrail_log_group_name       = "example-loggroup-cloudtrail-mgmt"
   cloudtrail_iam_role_name        = "example-iamrole-cloudtrail-mgmt"
   packer_iam_role_name            = "example-iamrole-packer-mgmt"
   packer_iam_policy_name          = "example-iampolicy-packer-mgmt"
   packer_iam_instanceprofile_name = "example-instanceprof-packer-mgmt"
   packer_s3_kmsgrant_name         = "example-kmsgrant-packer-s3-mgmt"
   packer_ebs_kmsgrant_name        = "example-kmsgrant-packer-ebs-mgmt"
   accesslogs_bucket_name          = "example-s3-accesslogs-mgmt"
   config_bucket_name              = "example-s3-config-mgmt"
   backups_bucket_name             = "example-s3-backups-mgmt"
   elb_accesslogs_bucket_name      = "example-s3-elb-accesslogs-mgmt"
   fedrampdoc_bucket_name          = "example-s3-docs-mgmt"
   installs_bucket_name            = "example-s3-installs-mgmt"
   
   ...

}

Environment Setup

Establish a secure connection to the Management AWS account used for the build:

IAM user authentication:

- Download and install the AWS CLI (https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
- Log into the AWS Console and create AWS CLI Credentials (https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html)
- Configure the named profile used for the project, such as 'aws configure --profile example-mgmt'

SSO-based authentication (via IAM Identity Center SSO):

- Login to the AWS IAM Identity Center console, select the permission set for MGMT, and select the 'Access Keys' link.
- Choose the 'IAM Identity Center credentials' method to get the SSO Start URL and SSO Region values.
- Run the setup command 'aws configure sso --profile example-mgmt' and follow the prompts.
- Verify you can run AWS commands successfully, for example 'aws s3 ls --profile example-mgmt'.
- Run 'export AWS_PROFILE=example-mgmt' in your terminal to use the specific profile and avoid having to use '--profile' option.

Deployment

  1. Navigate to the Terraform project and create a parent directory in the upper level code, for example:

    ../{CLOUD}/terraform/{REGION}/management-account/example

    If multi-account management plane:

    ../{CLOUD}/terraform/{REGION}/{ACCOUNT_TYPE}-mgmt-account/example
  2. Create a properly defined main.tf file via the template found under 'Usage' while adjusting tfvars as needed. Note that many provided variables are outputs from other modules. For 'Member Account' directories make sure to use a Terraform alias use management account credentials/settings to create resources in member account. Example parent directory:

     ├── Example/
     │   ├── example.auto.tfvars   
     │   ├── main.tf
     │   ├── outputs.tf
     │   ├── providers.tf
     │   ├── required-providers.tf
     │   ├── remote-data.tf
     │   ├── variables.tf 
     │   ├── ...

    Optional: Example AWS GOV ORG Member Account 'providers.tf'. Set your alias to the account specified name ('example-member-account'). Alias should match the provider being used in main.tf file. Example:

    provider "aws" {
    region                 = var.aws_region
    skip_region_validation = true
    profile                = var.profile
    use_fips_endpoint      = true
    alias                  = "example-member-account"
    assume_role {
     role_arn = "arn:${local.partition}:iam::${local.example_member_account_account_id}:role/OrganizationAccountAccessRole"
     }
    }
  3. Configure Terraform local backend and stage remote backend. For the first run, the entire contents of the 'remote-data.tf' file must be commented out with terraform local added to facilitate local state setup, like below:

    //terraform {
    //  backend "s3" {
    //    bucket         = "{resource_prefix}-{region}-tf-state"
    //    region         = "{region}"
    //    key            = "{resource_prefix}-{region}-account-setup.tfstate"
    //    encrypt        = true
    //    use_lockfile   = true
    //  }
    //}
    terraform {
    backend "local"{}
    }

    Optional: AWS ORG Member Account example. In 'remote-data.tf', set the key to a directory structure in the format show in the example below:

    //terraform {
    //  backend "s3" {
    //    bucket         = "{resource_prefix}-{region}-tf-state"
    //    region         = "{region}"
    //    key            = "{account_name}/{region}/{resource_prefix}-{region}-account-setup.tfstate"
    //    encrypt        = true
    //    use_lockfile   = true
    //  }
    //}
    terraform {
    backend "local"{}
    }
  4. Initialize the Terraform working directory:

    terraform init

    Create an execution plan and verify the resources being created:

    terraform plan

    Apply the configuration:

    terraform apply
  5. After the deployment has succeeded, uncomment the contents of 'remote-state.tf' and remove the terraform local code block.

  6. Run 'terraform init -migrate-state' and follow the prompts to migrate the local state file to the appropriate S3 bucket in the management plane.

Requirements

Name Version
terraform >=1.10.0
aws ~> 5.0

Providers

Name Version
aws ~> 5.0
tls n/a

Modules

Name Source Version
additional_kms_keys github.com/Coalfire-CF/terraform-aws-kms v1.0.1
backup_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
cloudwatch_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
config_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
default_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
ebs_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
ecr_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
lambda_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
nfw_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
rds_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
s3-accesslogs github.com/Coalfire-CF/terraform-aws-s3 v1.0.4
s3-backups github.com/Coalfire-CF/terraform-aws-s3 v1.0.4
s3-cloudtrail github.com/Coalfire-CF/terraform-aws-s3 v1.0.4
s3-config github.com/Coalfire-CF/terraform-aws-s3 v1.0.4
s3-elb-accesslogs github.com/Coalfire-CF/terraform-aws-s3 v1.0.4
s3-fedrampdoc github.com/Coalfire-CF/terraform-aws-s3 v1.0.4
s3-installs github.com/Coalfire-CF/terraform-aws-s3 v1.0.4
s3_config_conformance_pack github.com/Coalfire-CF/terraform-aws-s3 v1.0.4
s3_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
security-core github.com/Coalfire-CF/terraform-aws-securitycore v0.0.24
sm_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
sns_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1
sqs_kms_key github.com/Coalfire-CF/terraform-aws-kms v1.0.1

Resources

Name Type
aws_cloudtrail.all_cloudtrail resource
aws_cloudwatch_log_group.cloudtrail_log_group resource
aws_iam_instance_profile.packer_profile resource
aws_iam_policy.cloudtrail-to-cloudwatch resource
aws_iam_policy.packer_policy resource
aws_iam_policy_attachment.cloudtrail-to-cloudwatch resource
aws_iam_policy_attachment.packer_access_attach_policy resource
aws_iam_role.cloudtrail-role resource
aws_iam_role.packer_role resource
aws_iam_service_linked_role.autoscale resource
aws_key_pair.generated_key resource
aws_kms_grant.packer_ebs resource
aws_kms_grant.packer_s3 resource
aws_s3_bucket_policy.cloudtrail_bucket_policy resource
aws_s3_bucket_policy.config_bucket_policy resource
aws_s3_bucket_policy.conformance_pack_bucket_policy resource
aws_secretsmanager_secret.keypair_secret resource
aws_secretsmanager_secret_version.keypair_secret_version resource
tls_private_key.ssh_key resource
aws_caller_identity.current data source
aws_elb_service_account.main data source
aws_iam_policy_document.additional_kms_keys data source
aws_iam_policy_document.cloudtrail_assume_role_policy_document data source
aws_iam_policy_document.cloudtrail_to_cloudwatch_policy_document data source
aws_iam_policy_document.cloudwatch_key data source
aws_iam_policy_document.config_key data source
aws_iam_policy_document.default_key_policy data source
aws_iam_policy_document.ebs_key data source
aws_iam_policy_document.ecr_kms_policy data source
aws_iam_policy_document.elb_accesslogs_bucket_policy data source
aws_iam_policy_document.kms_base_and_sharing_permissions data source
aws_iam_policy_document.log_bucket_policy data source
aws_iam_policy_document.packer_assume_role_policy_document data source
aws_iam_policy_document.packer_policy_document data source
aws_iam_policy_document.s3_accesslogs_bucket_policy data source
aws_iam_policy_document.s3_config_bucket_policy_doc data source
aws_iam_policy_document.s3_config_conformance_pack_bucket_policy_doc data source
aws_iam_policy_document.s3_key data source
aws_iam_policy_document.secrets_manager_key data source
aws_iam_policy_document.sns_key data source
aws_iam_policy_document.sqs_key data source
aws_partition.current data source

Inputs

Name Description Type Default Required
accesslogs_bucket_name (Optional) custom name for the access logs S3 bucket; if left undefined, a default name is created string null no
account_number The AWS account number resources are being deployed into string n/a yes
additional_kms_keys a list of maps of any additional KMS keys that need to be created list(map(string)) [] no
application_account_numbers AWS account numbers for all application accounts that might need shared access to resources like KMS keys list(string) [] no
aws_region The AWS region to create resources in string n/a yes
backups_bucket_name (Optional) custom name for the backups S3 bucket; if left undefined, a default name is created string null no
cloudtrail_bucket_name (Optional) custom name for the Cloudtrail S3 Bucket; if left undefined, a default name is created string null no
cloudtrail_iam_role_name (Optional) custom name for the Cloudtrail to Cloudwatch IAM role; if left undefined, a default name is created string null no
cloudtrail_log_group_name (Optional) custom name for the Cloudtrail log group in Cloudwatch; if left undefined, a default name is created string null no
cloudtrail_name (Optional) custom name for the Cloudtrail resource; if left undefined, a default name is created string null no
cloudwatch_log_group_retention_in_days The number of days to retain Cloudwatch logs number 30 no
config_bucket_name (Optional) custom name for the configuration S3 bucket; if left undefined, a default name is created string null no
create_autoscale_role Create AWS Autoscale IAM Role (needed for any autoscaling aws resources) bool true no
create_backup_kms_key create KMS key for AWS Backups bool true no
create_cloudtrail Whether or not to create cloudtrail resources bool false no
create_cloudwatch_kms_key create KMS key for AWS Cloudwatch bool true no
create_config_kms_key create KMS key for AWS Cloudwatch bool true no
create_default_kms_key create default kms key bool true no
create_ebs_kms_key create KMS key for ebs bool true no
create_ecr_kms_key create KMS key for ECR bool true no
create_lambda_kms_key create KMS key for lambda bool true no
create_nfw_kms_key create KMS key for NFW bool true no
create_packer_iam Whether or not to create Packer IAM resources bool false no
create_rds_kms_key create KMS key for rds bool true no
create_s3_accesslogs_bucket Create S3 Access Logs Bucket bool true no
create_s3_backups_bucket Create S3 Backups Bucket bool true no
create_s3_config_bucket Create S3 AWS Config Bucket for conformance pack storage bool true no
create_s3_elb_accesslogs_bucket Create S3 ELB Access Logs Bucket bool true no
create_s3_fedrampdoc_bucket Create S3 FedRAMP Documents Bucket bool true no
create_s3_installs_bucket Create S3 Installs Bucket bool true no
create_s3_kms_key create KMS key for S3 bool true no
create_security_core Whether or not to create Security Core resources bool false no
create_sm_kms_key create KMS key for secrets manager bool true no
create_sns_kms_key create KMS key for SNS bool true no
create_sqs_kms_key create KMS key for SQS bool true no
default_aws_region The default AWS region to create resources in string n/a yes
elb_accesslogs_bucket_name (Optional) custom name for the ELB access logs S3 bucket; if left undefined, a default name is created string null no
fedrampdoc_bucket_name (Optional) custom name for the FedRAMP docs S3 bucket; if left undefined, a default name is created string null no
installs_bucket_name (Optional) custom name for the installs S3 bucket; if left undefined, a default name is created string null no
is_organization Whether or not to enable certain settings for AWS Organization bool true no
kms_multi_region Indicates whether the KMS key is a multi-Region (true) or regional (false) key. bool false no
organization_id AWS Organization ID string null no
packer_additional_iam_principal_arns List of IAM Principal ARNs allowed to assume the Packer IAM Role list(string) [] no
packer_ebs_kmsgrant_name (Optional) custom name for the KMS grant allowing Packer to access the EBS KMS key; if left undefined, a default name is created string null no
packer_iam_instanceprofile_name (Optional) custom name for the Packer IAM instance profile; if left undefined, a default name is created string null no
packer_iam_policy_name (Optional) custom name for the Packer IAM policy; if left undefined, a default name is created string null no
packer_iam_role_name (Optional) custom name for the Packer IAM role; if left undefined, a default name is created string null no
packer_s3_kmsgrant_name (Optional) custom name for the KMS grant allowing Packer to access the S3 bucket KMS key; if left undefined, a default name is created string null no
resource_prefix The prefix for resources string n/a yes
s3_backup_policy S3 backup policy to use for S3 buckets in conjunction with AWS Backups, should match an existing policy string "" no
s3_backup_settings Map of S3 bucket types to their backup settings
map(object({
enable_backup = bool
}))
{
"accesslogs": {
"enable_backup": false
},
"backups": {
"enable_backup": true
},
"cloudtrail": {
"enable_backup": false
},
"config": {
"enable_backup": true
},
"elb-accesslogs": {
"enable_backup": false
},
"fedrampdoc": {
"enable_backup": true
},
"installs": {
"enable_backup": true
}
}
no
s3_tags Tags to be applied to S3 buckets map(any) {} no
ssh_key_name The name of the SSH key pair to use for EC2 instances. string "fedramp-mgmt-gov-key" no
ssh_key_secret_name The name of the secret in Secrets Manager that stores the private SSH key. string "/management/fedramp-mgmt-gov/ec2-key-pair" no

Outputs

Name Description
additional_kms_key_arns n/a
additional_kms_key_ids n/a
backup_kms_key_arn n/a
backup_kms_key_id n/a
cloudwatch_kms_key_arn n/a
cloudwatch_kms_key_id n/a
config_kms_key_arn n/a
config_kms_key_id n/a
ebs_kms_key_arn n/a
ebs_kms_key_id n/a
ecr_kms_key_arn n/a
ecr_kms_key_id n/a
lambda_kms_key_arn n/a
lambda_kms_key_id n/a
nfw_kms_key_arn n/a
nfw_kms_key_id n/a
packer_iam_role_arn n/a
packer_iam_role_name n/a
rds_kms_key_arn n/a
rds_kms_key_id n/a
s3_access_logs_arn n/a
s3_access_logs_id n/a
s3_backups_arn n/a
s3_backups_id n/a
s3_cloudtrail_arn n/a
s3_cloudtrail_id n/a
s3_config_arn n/a
s3_config_id n/a
s3_elb_access_logs_arn n/a
s3_elb_access_logs_id n/a
s3_fedrampdoc_arn n/a
s3_fedrampdoc_id n/a
s3_installs_arn n/a
s3_installs_id n/a
s3_kms_key_arn n/a
s3_kms_key_id n/a
s3_tstate_bucket_name n/a
sm_kms_key_arn n/a
sm_kms_key_id n/a
sns_kms_key_arn n/a
sns_kms_key_id n/a
sqs_kms_key_arn n/a
sqs_kms_key_id n/a

Contributing

If you're interested in contributing to our projects, please review the Contributing Guidelines. And send an email to our team to receive a copy of our CLA and start the onboarding process.

License

License

Copyright

Copyright © 2023 Coalfire Systems Inc.

Tree

.
|-- CHANGELOG.md
|-- CONTRIBUTING.md
|-- License.md
|-- README.md
|-- cloudtrail.tf
|-- coalfire_logo.png
|-- data.tf
|-- ec2-key-pair.tf
|-- iam.tf
|-- kms-iam.tf
|-- kms.tf
|-- locals.tf
|-- outputs.tf
|-- packer_iam.tf
|-- providers.tf
|-- release-please-config.json
|-- s3-accesslog.tf
|-- s3-aws-config.tf
|-- s3-backups.tf
|-- s3-cloudtrail.tf
|-- s3-elb-accesslog.tf
|-- s3-fedrampdoc.tf
|-- s3-installs.tf
|-- security-core.tf
|-- update-readme-tree.sh
|-- variables.tf

About

Coalfire AWS Account Setup Terraform Module

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Contributors 19