diff --git a/aws/environments/production/_bootstrap/README.md b/aws/environments/production/_bootstrap/README.md new file mode 100644 index 0000000..809f90f --- /dev/null +++ b/aws/environments/production/_bootstrap/README.md @@ -0,0 +1,12 @@ +# Bootstrap + +This service contains the Terraform for establishing a standard AWS account baseline. Every new AWS account should run +this service once. + +## Deployment + +The services should be deployed in this order: + +1. `default-vpc` +2. `primary-kms-key` +3. `circleci` diff --git a/aws/environments/production/_bootstrap/primary-kms-key/.terraform.lock.hcl b/aws/environments/production/_bootstrap/primary-kms-key/.terraform.lock.hcl new file mode 100644 index 0000000..2f418f1 --- /dev/null +++ b/aws/environments/production/_bootstrap/primary-kms-key/.terraform.lock.hcl @@ -0,0 +1,25 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "4.67.0" + constraints = "~> 4.0" + hashes = [ + "h1:P43vwcDPG99x5WBbmqwUPgfJrfXf6/ucAIbGlRb7k1w=", + "zh:0843017ecc24385f2b45f2c5fce79dc25b258e50d516877b3affee3bef34f060", + "zh:19876066cfa60de91834ec569a6448dab8c2518b8a71b5ca870b2444febddac6", + "zh:24995686b2ad88c1ffaa242e36eee791fc6070e6144f418048c4ce24d0ba5183", + "zh:4a002990b9f4d6d225d82cb2fb8805789ffef791999ee5d9cb1fef579aeff8f1", + "zh:559a2b5ace06b878c6de3ecf19b94fbae3512562f7a51e930674b16c2f606e29", + "zh:6a07da13b86b9753b95d4d8218f6dae874cf34699bca1470d6effbb4dee7f4b7", + "zh:768b3bfd126c3b77dc975c7c0e5db3207e4f9997cf41aa3385c63206242ba043", + "zh:7be5177e698d4b547083cc738b977742d70ed68487ce6f49ecd0c94dbf9d1362", + "zh:8b562a818915fb0d85959257095251a05c76f3467caa3ba95c583ba5fe043f9b", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9c385d03a958b54e2afd5279cd8c7cbdd2d6ca5c7d6a333e61092331f38af7cf", + "zh:b3ca45f2821a89af417787df8289cb4314b273d29555ad3b2a5ab98bb4816b3b", + "zh:da3c317f1db2469615ab40aa6baba63b5643bae7110ff855277a1fb9d8eb4f2c", + "zh:dc6430622a8dc5cdab359a8704aec81d3825ea1d305bbb3bbd032b1c6adfae0c", + "zh:fac0d2ddeadf9ec53da87922f666e1e73a603a611c57bcbc4b86ac2821619b1d", + ] +} diff --git a/aws/environments/production/_bootstrap/primary-kms-key/README.md b/aws/environments/production/_bootstrap/primary-kms-key/README.md new file mode 100644 index 0000000..97e102b --- /dev/null +++ b/aws/environments/production/_bootstrap/primary-kms-key/README.md @@ -0,0 +1,52 @@ +# Primary (`default`) KMS Key + +Creates the primary KMS key with the default policy. + +## Prerequisites + +* [Secret OPerationS (sops)](https://github.com/getsops/sops) - An editor of encrypted files that supports YAML, JSON, + ENV, INI and BINARY formats and encrypts with AWS KMS, GCP KMS, Azure Key Vault, age, and PGP. + +## SOPS Example Usage + +```sh +KMS_ARN="arn:aws:kms:us-west-2:$(aws sts get-caller-identity --query 'Account' --output text):alias/primary" +sops --kms $(echo $KMS_ARN) +``` + +## Deployment + +```bash +terragrunt init +terragrunt apply +``` + + +## Requirements + +No requirements. + +## Providers + +No providers. + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [kms](#module\_kms) | ../../../../modules/kms | n/a | + +## Resources + +No resources. + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [aws\_region](#input\_aws\_region) | The AWS region this is hosted in. | `string` | n/a | yes | + +## Outputs + +No outputs. + diff --git a/aws/environments/production/_bootstrap/primary-kms-key/main.tf b/aws/environments/production/_bootstrap/primary-kms-key/main.tf new file mode 100644 index 0000000..cff198d --- /dev/null +++ b/aws/environments/production/_bootstrap/primary-kms-key/main.tf @@ -0,0 +1,10 @@ +provider "aws" { + region = var.aws_region +} + +module "kms" { + source = "../../../../modules/kms" + + alias = "primary" + description = "The primary KMS key with the default KMS policy." +} diff --git a/aws/environments/production/_bootstrap/primary-kms-key/terragrunt.hcl b/aws/environments/production/_bootstrap/primary-kms-key/terragrunt.hcl new file mode 100644 index 0000000..3e1f65a --- /dev/null +++ b/aws/environments/production/_bootstrap/primary-kms-key/terragrunt.hcl @@ -0,0 +1,3 @@ +include { + path = find_in_parent_folders() +} diff --git a/aws/environments/production/_bootstrap/primary-kms-key/variables.tf b/aws/environments/production/_bootstrap/primary-kms-key/variables.tf new file mode 100644 index 0000000..a84add7 --- /dev/null +++ b/aws/environments/production/_bootstrap/primary-kms-key/variables.tf @@ -0,0 +1,4 @@ +variable "aws_region" { + type = string + description = "The AWS region this is hosted in." +} diff --git a/aws/modules/kms/README.md b/aws/modules/kms/README.md new file mode 100644 index 0000000..f23eb3c --- /dev/null +++ b/aws/modules/kms/README.md @@ -0,0 +1,54 @@ +# Key Management Service + +Creates a basic kms encryption key. + +## Deployment + +```bash +terragrunt init +terragrunt apply +``` + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | <= 1.5.5 | +| [aws](#requirement\_aws) | ~> 4.0 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | ~> 4.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_kms_alias.primary](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | +| [aws_kms_key.primary](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [alias](#input\_alias) | The name of the KMS key alias. | `string` | n/a | yes | +| [auto\_rotate](#input\_auto\_rotate) | Whether to enable automatic KMS key rotation. Defaults to true. | `bool` | `true` | no | +| [deletion\_window\_in\_days](#input\_deletion\_window\_in\_days) | Duration (in days) to wait before deleting a key that is scheduled for deletion. Defaults to 10 days. | `number` | `10` | no | +| [description](#input\_description) | The KMS key description. | `string` | `""` | no | +| [policy](#input\_policy) | A valid policy JSON document to attach to the key. | `string` | `null` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [alias](#output\_alias) | n/a | +| [arn](#output\_arn) | n/a | +| [key\_id](#output\_key\_id) | n/a | + diff --git a/aws/modules/kms/main.tf b/aws/modules/kms/main.tf new file mode 100644 index 0000000..0828f6a --- /dev/null +++ b/aws/modules/kms/main.tf @@ -0,0 +1,12 @@ +resource "aws_kms_key" "main" { + description = var.description + enable_key_rotation = var.auto_rotate + deletion_window_in_days = var.deletion_window_in_days + + policy = var.policy +} + +resource "aws_kms_alias" "main" { + name = "alias/${var.alias}" + target_key_id = aws_kms_key.main.id +} diff --git a/aws/modules/kms/outputs.tf b/aws/modules/kms/outputs.tf new file mode 100644 index 0000000..d8bd45a --- /dev/null +++ b/aws/modules/kms/outputs.tf @@ -0,0 +1,11 @@ +output "arn" { + value = aws_kms_key.main.arn +} + +output "key_id" { + value = aws_kms_key.main.arn +} + +output "alias" { + value = aws_kms_alias.main.name +} diff --git a/aws/modules/kms/providers.tf b/aws/modules/kms/providers.tf new file mode 100644 index 0000000..f9ae2f2 --- /dev/null +++ b/aws/modules/kms/providers.tf @@ -0,0 +1,11 @@ +terraform { + required_version = "<= 1.5.5" + + required_providers { + # Docs: https://registry.terraform.io/providers/hashicorp/aws/latest/docs + aws = { + source = "hashicorp/aws" + version = "~> 4.0" + } + } +} diff --git a/aws/modules/kms/variables.tf b/aws/modules/kms/variables.tf new file mode 100644 index 0000000..58650d5 --- /dev/null +++ b/aws/modules/kms/variables.tf @@ -0,0 +1,34 @@ +variable "alias" { + type = string + description = "The name of the KMS key alias." +} + +variable "description" { + type = string + default = "" + description = "The KMS key description." +} + +variable "auto_rotate" { + type = bool + default = true + description = "Whether to enable automatic KMS key rotation. Defaults to true." +} + +variable "deletion_window_in_days" { + type = number + default = 10 + description = "Duration (in days) to wait before deleting a key that is scheduled for deletion. Defaults to 10 days." +} + +// Note: +// All KMS keys must have a key policy. If a key policy is not specified, AWS gives the KMS key a default key policy +// that gives all principals in the owning account unlimited access to all KMS operations for the key. This default +// key policy effectively delegates all access control to IAM policies and KMS grants. +// - Link: https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key#argument-reference +// - Link: https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html#key-policy-default +variable "policy" { + type = string + default = null + description = "A valid policy JSON document to attach to the key." +}