Skip to content

StratusGrid/terraform-account-starter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

87 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Contact Us | Stratusphere FinOps | StratusGrid Home | Blog

Terraform Account Starter

GitHub: StratusGrid/terraform-account-starter

This is to showcase the use of many of the StratusGrid modules working together using terraform.

It will initiate a fully configured AWS account with config and logging set up in all 4 US regions, with terraform state and cloudtrail in us-east-1

Recommended first steps if using this as the account code

  • Enable IAM Billing access while logged in as root under My Account
  • Delete the default VPCs in all regions you will be using (at least all regions with config rules...)
  • Tag the default RDS DB Security Groups in all regions with your required tags (cli to do so is below)
  • Determine if you're enabling centralized logging
  • Block S3 Public Access Account Wide - See here
# If multiple environments share an account don't do this, or pick a single env
aws rds add-tags-to-resource --resource-name "arn:aws:rds:us-east-1:<account_number>:secgrp:default" --tags "[{\"Key\": \"Environment\",\"Value\": \"<env>\"},{\"Key\": \"Customer\",\"Value\": \"Shared\"}]" --region us-east-1
aws rds add-tags-to-resource --resource-name "arn:aws:rds:us-east-2:<account_number>:secgrp:default" --tags "[{\"Key\": \"Environment\",\"Value\": \"<env>\"},{\"Key\": \"Customer\",\"Value\": \"Shared\"}]" --region us-east-2
aws rds add-tags-to-resource --resource-name "arn:aws:rds:us-west-1:<account_number>:secgrp:default" --tags "[{\"Key\": \"Environment\",\"Value\": \"<env>\"},{\"Key\": \"Customer\",\"Value\": \"Shared\"}]" --region us-west-1
aws rds add-tags-to-resource --resource-name "arn:aws:rds:us-west-2:<account_number>:secgrp:default" --tags "[{\"Key\": \"Environment\",\"Value\": \"<env>\"},{\"Key\": \"Customer\",\"Value\": \"Shared\"}]" --region us-west-2

Centralized Logging

This repo is fully configured to allow for centralized logging with S3 and it's controlled via a few variables. To enable centralized logging set the following variables log_archive_retention, aws_org_id, s3_destination_bucket_name, logging_account_id to the required values and uncomment this block in s3-bucket-logging.tf. If the apply file you're doing is for the log archive account these vars should be modified enable_centralized_logging, log_archive_account in addition to the prior variables with the proper values set.

SNS Topics

Once the repo is applied, please go to SNS in the correct region (Most likely us-east-1) and set the appropriate subscriptions for InfraStructure Alerts and Billing Alerts.

enable_centralized_logging = true
s3_destination_bucket_name = var.s3_destination_bucket_name
iam_role_s3_replication_arn = module.iam_role_s3[0].iam_role_arn
logging_account_id = var.logging_account_id

StratusGrid Standards we assume

  • All resource names shall use _ and not -s
  • StratusGrid mostly follows the file names outlined here, we use a providers.tf file for provider specific information.
  • StratusGrid mainly uses the AWS provider, and this provider supports provider level tagging. We use that whenever possible, some resources don't explicitly support it so tags need to be checked.
  • The old naming standard for common files such as inputs, outputs, providers, etc was to prefix them with a -, this is no longer true as it's not POSIX compliant. Our pre-commit hooks will fail with this old standard.
  • StratusGrid generally follows the TerraForm standards outlined here

Repo Knowledge

This repo has several base requirements

  • This repo is based upon the AWS ~> 4.9 provider
  • The following packages are installed via brew: tflint, terrascan, terraform-docs, gitleaks, tfsec, pre-commit', 'sops, go
  • This assumes SOPs v3.7.2
  • If you encounter an error like declare: -g: invalid option reference this and install Bash 5
  • If you need more tflint plugins, please edit the .tflint.hcl file with the instructions from here
  • It's highly recommend that you follow the Git Pre-Commit Instructions below, these will run in GitHub though they should be ran locally to reduce issues
  • By default Terraform docs will always run so our auto generated docs are always up to date
  • This repo has been tested with awsume

SOPs and Terraform

See the README_SOPs.md for how to use and configure SOPs.

TFSec

See the pre-commit tfsec documentation here, this includes on how to bypass warnings

Terrascan

Terrascan can't do comment based rule skips for modules, so they must be specific in the .config/terrascan.yaml file otherwise it will always fail. Several config options have to be specified in the .pre-commit-config.yaml as they can't be specified in the terrascan config file due to a lack of support.

Terraform validate

Terraform Validate can't be used in the Git Pre-Commit hooks as several resources are generated at run time

Template Documentation

A sample template Git Repo with how we should setup client infrastructure, in this case it's the StratusGrid Account Starter Template. More details are available here in confluence.

Documentation

This repo is self documenting via Terraform Docs, please see the note at the bottom.

The way that this repo is structured is supposed to be an infrastructure starter, as well as a base psuedo code repo. Each file is generally self contained except where it can't be. All variables are in variables.tf, all data is in data.tf, and etc.

billing-alerts.tf

This file contains the SG module for billing alert anomalies. If you wish to enable Slack Alerts please edit this file for the Slack SSM Parameters.

`config-recorder.tf1

This file contains the SG module for configuring AWS Config Recorder, this is only enabled if control_tower_enabled == false.

config-rules.tf

This file contains the SG module for configuring AWS Config, this is only enabled if control_tower_enabled == false.

data.tf

This data file contains all references for data providers, these are fairly generic.

ec2-default-instance-profile.tf

The file contains the SG module for building our EC2 Instance IAM Role that enables SSM, and CloudWatch Publishing.

ecs-account-settings.tf

This file contains the ECS account settings to enable long ARN formats and Container Insights

eventbridge.tf

This file contains the event bridge rule for if ECS, RDS, EC@, Backups, or DynamoDB don't meed the required tagging, this is only enabled if control_tower_enabled == false.

guardduty.tf

This file contains the module for creating GuardDuty notifications Events and Topics. Subscriptions are not configured through the module, so must be manually configured at this time.

iam-cicd.tf

This file contains the policy and role for assumption by the CICD pipeline processes in the Tooling account, if it exists. Note that the resources will only be created if the "tooling_account_id" parameter is filled in with a valid AWS account ID.

iam-cross-account-trust-maps.tf

This file contains the SG module for configuring IAM for cross account trusts, this is only enabled if aws_sso_enabled == false except for the IAM self service module.

iam-password-policy.tf

This file contains the resource for the IAM local users

iam-policy-restricted-admin.tf

This file contains the SG module for configuring the IAM restricted-admin-role role, this is only enabled if aws_sso_enabled == false.

iam-policy-restricted-approver.tf

This file contains the SG module for configuring the IAM cross-account-role-admin role, this is only enabled if aws_sso_enabled == false.

iam-policy-restricted-read-only.tf

This file contains the SG module for configuring the IAM restricted-read-role role, this is only enabled if aws_sso_enabled == false.

iam-s3-replication.tf

This file contains the IAM policy for centralized logging, this is only enabled if log_archive_account == true && enable_centralized_logging == true.

lambda-cloudwatch-cpu-creditbalance-alerts.tf

This file contains the SG module for CloudWatch to fire an alert to SNS whenever the CPU credit balance runs low.

lambda-cloudwatch-ebs-burstbalance-alerts.tf

This file contains the SG module for CloudWatch to fire an alert to SNS whenever the Burst Balance credit balance runs low.

LICENSE

This is the standard Apache 2.0 License as defined here.

locals.tf

All local values that aren't file specific.

outputs.tf

The StratusGrid standard for Terraform Outputs.

provider.tf

This file contains the necessary provider(s) and there configurations.

README_SOPS.md

This is the readme file for SOPS and how

README.md

It's` this file! I'm always updated via TF Docs!

s3-bucket-cloudtrail.tf

This contains the SG module for setting up a cloudtrail to an S3 Bucket and an SNS Topic.

s3-bucket-logging.tf

This contains the SG module for setting up a logging bucket, it's replicated once for each US based region. This file needs to have parts uncommented if using centralized logging.

s3-bucket-terraform-state.tf

This contains the SG module for setting up our TF centralized remote state S3 bucket and KMS Key.

s3-centralized-logging.tf

This contains all of the S3 related components for centralized logging.

service-limits.tf

This contains the SG module for sending service limits to an SNS Topic or to Slack.

sns-topics.tf

This contains the SNS topic for all Infrastructure Alerts.

sops.tf

This file creates all of the required SOPS configuration KMS info for other repos to build off of.

state.tfnot

The StratusGrid standard for Terraform remote state management. Rename this file to state.tf once you're ready to migrate to the remote state.

tags.tf

The StratusGrid standard for provider/module level tagging.

variables.tf

All variables related to this repo for all facets. One day this should be broken up into each file, maybe maybe not.

versions.tf

This file contains the required Terraform versions, as well as the required providers and their versions.

Documentation of Misc Config Files

This section is supposed to outline what the misc configuration files do and what is there purpose

.config/.terraform-docs.yml

This file auto generates your README.md file.

.config/terrascan.yaml

This file has all of the configuration options required for Terrascan, this is where you would skip rules to.

.github/sync-repo-settings.yaml

This file is our standard for how GitHub branch protection rules should be setup.

.github/workflows/pre-commit.yml

This file contains the instructions for Github workflows, in specific this file run pre-commit and will allow the PR to pass or fail. This is a safety check and extras for if pre-commit isn't run locally.

.vscode/settings.json

This file is a vscode workspace settings file.

.gitignore

This is your gitignore, and contains a slew of default standards.

.pre-commit-config.yaml

This file is the GIT pre-commit file and contains all of it's configuration options

.prettierignore

This file is the ignore file for the prettier pre-commit actions. Specific files like our SOPS config files have to be ignored.

.python-version

Specifies the Python version that the actions/setup-python in GitHub Actions should use.

.terraform.lock.hcl

This file contains the hashes of the Terraform providers and modules we're using.

.tflint.hcl

This file contains the plugin data for TFLint to run.


Requirements

Name Version
terraform >= 1.3
aws ~> 4.9

Resources

Name Type
aws_cloudwatch_event_rule.required_tags resource
aws_cloudwatch_event_target.aws_backup_to_sns resource
aws_ebs_encryption_by_default.this resource
aws_ecs_account_setting_default.aws_vpc_trunking resource
aws_ecs_account_setting_default.container_insights resource
aws_ecs_account_setting_default.container_instance_long_arn_format resource
aws_ecs_account_setting_default.service_long_arn_format resource
aws_ecs_account_setting_default.task_long_arn_format resource
aws_iam_account_password_policy.strict resource
aws_iam_policy.approver_restrictions resource
aws_iam_policy.cicd resource
aws_iam_policy.read_only_restrictions resource
aws_iam_policy.restricted_admin resource
aws_iam_policy.s3_role_assumption resource
aws_kms_alias.sns_topics resource
aws_kms_alias.sops resource
aws_kms_key.sns_topics resource
aws_kms_key.sops resource
aws_s3_account_public_access_block.this resource
aws_s3_bucket.central_logging resource
aws_s3_bucket_acl.central_logging resource
aws_s3_bucket_lifecycle_configuration.central_logging resource
aws_s3_bucket_policy.central_logging resource
aws_s3_bucket_public_access_block.central_logging resource
aws_s3_bucket_server_side_encryption_configuration.central_logging resource
aws_s3_bucket_versioning.central_logging resource
aws_sns_topic.infrastructure_alerts resource

Inputs

Name Description Type Default Required
accounts_list This is a list of all AWS accounts with access to artifact bucket list(string)
[
""
]
no
append_name_suffix String to append to the name_suffix used on object names. This is optional, so start with dash if using like so: -mysuffix. This will result in prefix-objectname-env-mysuffix string "" no
aws_org_id AWS Org ID string n/a yes
aws_sso_enabled A boolean true/false for if Control Tower is deployed or will be deployed. By default this is true, and setting to true removes functions that are replaced by AWS SSO bool true no
control_tower_enabled A boolean true/false for if Control Tower is deployed or will be deployed. By default this is true, and setting to true removes functions that are imcompatible with Control Tower defaults/common guardrails bool true no
cost_anomaly_billing_threshold The amount over the normal billing threshold before alerting string "50" no
cost_anomaly_subscription_email The subscription email for AWS Cost Anomly Billing Alerts string n/a yes
enable_centralized_logging A boolean true/false to enable centralized logging to a log archive account bool n/a yes
env_name Environment name string to be used for decisions and name generation. Appended to name_suffix to create full_suffix string n/a yes
guardduty_notifications_enabled Toggles GuardDuty notifications. Should only be enabled if GuardDuty is enabled on the account. If GuardDuty is enabled Organization-wide via ControlTower, only enable for the delegated GuardDuty admin account. bool false no
log_archive_account A boolean true/false for is this is the log archive account in the AWS Organization, as this will control centralized logging bool n/a yes
log_archive_retention How many days to delete centralized logs number 365 no
logging_account_id Centralized Logging Account ID, This will only ever be used when enabling centralized logging string n/a yes
name_prefix String to use as prefix on object names string n/a yes
override_name_suffix String to completely override the name_suffix string "" no
payer_account A boolean true/false for if this is the payer, as this will control billing alerts string false no
prepend_name_suffix String to prepend to the name_suffix used on object names. This is optional, so start with dash if using like so: -mysuffix. This will result in prefix-objectname-mysuffix-env string "" no
region AWS Region to target string n/a yes
s3_destination_bucket_name Destination Bucket Name for S3 Centralized Logging Replication string "" no
s3_replication_iam_role_arn This is the ARN of the IAM role assumed by the source account which allows writing to the central logging bucket. string "" no
service_limit_email The subscription email for AWS Service Limits string n/a yes
source_repo URL of the repo which holds this code string n/a yes
tooling_account Indicates if the account currently being affected is the tooling account which runs CICD pipelines. bool false no
tooling_account_id The account number for the tooling account. Used in IAM policy/role for use by deployment pipelines. string "" no
trusted_users_account_arns Account which users are provisioned in and should be granted access to cross account roles. Enter like arn:aws:iam::123456789012:root list(string) [] no

Outputs

Name Description
account_id Account which terraform was run on
common_tags tags which should be applied to all taggable objects
ec2_default_instance_arn The ec2 default instance IAM role that was created ARN
iam_role_url_restricted_admin URL to assume restricted admin role in this account
iam_role_url_restricted_approver URL to assume restricted approver role in this account
iam_role_url_restricted_read_only URL to assume restricted read only role in this account
log_bucket_ids ID of logging bucket
name_prefix string to prepend to all resource names
name_suffix string to append to all resource names
sops_kms_id The KMS id you need to use for SOPs related files
terraform_state_bucket s3 bucket to store terraform state
terraform_state_config_s3_key key to use for terraform state key configuration - this is the s3 object key where the config will be stored
terraform_state_dynamodb_table dynamodb table to control terraform locking
terraform_state_kms_key_arn kms key to use for encrytption when storing/reading terraform state configuration

Assumptions we make

  • We assume a basic knowledge of terraform
  • We assume StratusGrid written and unwritten (Listen I know, if you find an unwritten standard please standardize and it document it) standards
  • We assume you know how to switch TF states to new envs
  • We assume that if you find something wrong or have an improvement you will submit a PR and run terraform-docs
  • Of all most importance, we assume that you read this or at least skimmed this README file

Just a note

First Run

When doing a first run update the init-tfvars tfvars file for the relevant values produced via the account starter. After the initial and the terraform state file is created. Rename state.tfnot to state.tf and run rm -rf .terraform. Then rerun the terraform init to migrate the state file to S3.

This is purely an example repo and it's subject to change for each and every client, please use your best judgement. While adhering to StratusGrids' Standards.

Apply this template via Terraform

Before this is applied, you need to configure the git hook on your local machine

#Verify you have bash5
brew install bash

# Test your pre-commit hooks - This will force them to run on all files
pre-commit run --all-files

# Add your pre-commit hooks forever
pre-commit install

Dev

terraform init -backend-config=./init-tfvars/dev.tfvars 
terraform apply -var-file ./apply-tfvars/dev.tfvars

Stg

terraform init -backend-config=./init-tfvars/stg.tfvars 
terraform apply -var-file ./apply-tfvars/stg.tfvars

Prd

terraform init -backend-config=./init-tfvars/prd.tfvars 
terraform apply -var-file ./apply-tfvars/prd.tfvars

Note: Before reading, uncomment the code for the environment that you wish to apply the code to. This goes for both the init-tfvars and apply-tfvars folders.

Contributors

Note, manual changes to the README will be overwritten when the documentation is updated. To update the documentation, run terraform-docs -c .config/.terraform-docs.yml .

About

Starting point for account level terraform. To be modified as needed.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages