diff --git a/.github/workflows/tf-docs.yml b/.github/workflows/tf-docs.yml
index 750c6cd..2b3b131 100644
--- a/.github/workflows/tf-docs.yml
+++ b/.github/workflows/tf-docs.yml
@@ -24,7 +24,7 @@ jobs:
- name: Render terraform docs inside modules
uses: terraform-docs/gh-actions@v1.0.0
with:
- working-dir: modules/amplify-app,modules/rds,modules/vpc,modules/bastion,live/core
+ working-dir: modules/amplify-app,modules/rds,modules/vpc,modules/bastion,live/prod/us-west-2/app,live/staging/us-west-2/app
output-file: docs/MODULE.md
output-method: replace
git-push: "true"
diff --git a/README.md b/README.md
index 537de6e..ac433aa 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,8 @@ Welcome to the Terraform AWS Starter Kit! This comprehensive and robust starter
The Terraform AWS Starter Kit solves the most challenging aspect of AWS infrastructure building by providing a powerful solution for our clients. Our goal is to simplify the process of setting up a reliable and scalable AWS environment, allowing you to focus on developing and deploying your applications swiftly and confidently.
## Key Features
@@ -60,15 +60,20 @@ We welcome contributions and feedback to improve this starter kit further, makin
## Quick Start
-To get started quickly, navigate to the [`live/core`](./live/core) directory and follow the instructions in the [README](./live/core/README.md). This directory contains the Terraform root module for our core infrastructure, including Terraform variables and backend configuration. Additionally, we provide post-deployment steps in the [README](./live/core/README.md#post-deployment-steps) to help you test the setup and get familiar with the infrastructure.
+Check the [Live Infrastructure](#live-infrastructure) section for more information about existing infrastructure modules and how to use them.
+
+Once you have chosen the infrastructure module you want to use, move to the module directory and follow the instructions in the README file.
## Live Infrastructure
The `live` directory houses our live infrastructure. This is where you'll find our Terraform variables, backend configuration, and Terraform root modules.
-| Module | Description |
-| :------------------------------------------- | :------------------------------------------------- |
-| [Core Infrastructure](./live/core/README.md) | Terraform root module for our core infrastructure. |
+It is recommended to create a separate directory for each environment (e.g., `dev`, `staging`, `prod`) and region (e.g., `us-east-1`, `us-west-2`, `eu-west-1`). This allows you to easily manage and deploy your infrastructure.
+
+| Module | Description |
+| :------------------------------------------------------------------------------- | :---------------------------------------------------- |
+| [Prod App Infrastructure (us-west-2)](./live/prod/us-west-2/app/README.md) | Terraform root module for our prod infrastructure. |
+| [Staging App Infrastructure (us-west-2)](./live/staging/us-west-2/app/README.md) | Terraform root module for our staging infrastructure. |
## Terraform Modules
diff --git a/live/core/configs/prod.us-west-2.tfvars b/live/core/configs/prod.us-west-2.tfvars
deleted file mode 100644
index cc4017d..0000000
--- a/live/core/configs/prod.us-west-2.tfvars
+++ /dev/null
@@ -1,20 +0,0 @@
-# General settings
-
-region = "us-west-2"
-name = "core"
-namespace = "nan"
-environment = "prod"
-tags = {
- "Terraform" = "true"
- "Environment" = "prod"
-}
-
-# AWS settings
-
-vpc_cidr_block = "10.0.0.0/16"
-enable_bastion = false
-
-# RDS Database settings
-
-example_db_name = "example"
-example_db_master_username = "root"
diff --git a/live/core/context.tf b/live/core/context.tf
deleted file mode 100644
index 2be61f9..0000000
--- a/live/core/context.tf
+++ /dev/null
@@ -1,54 +0,0 @@
-variable "name" {
- description = "Name to use for servers, tags, etc"
- type = string
- default = "name"
-}
-
-variable "namespace" {
- description = "Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp'"
- type = string
- default = "development"
-}
-
-variable "environment" {
- description = "Environment, e.g. 'prod', 'staging', 'dev', 'pre-prod', 'UAT'"
- type = string
- default = "development"
-}
-
-variable "stage" {
- description = "Stage, e.g. 'build', 'test', 'deploy', 'release'"
- type = string
- # not required, so no default
- default = null
-}
-
-variable "tags" {
- description = "Any extra tags to assign to objects"
- type = map(any)
- default = {}
-}
-
-data "aws_caller_identity" "aws" {}
-
-locals {
- tf_tags = {
- Terraform = true,
- By = data.aws_caller_identity.aws.arn
- }
-}
-
-// Keep labels, tags consistent
-module "label" {
- source = "cloudposse/label/null"
- version = "0.25.0"
-
- name = var.name
- environment = var.environment
- namespace = var.namespace
- stage = var.stage
-
- delimiter = "-"
- label_order = ["namespace", "environment", "stage", "name", "attributes"]
- tags = merge(var.tags, local.tf_tags)
-}
diff --git a/live/core/variables.tf b/live/core/variables.tf
deleted file mode 100644
index 098424d..0000000
--- a/live/core/variables.tf
+++ /dev/null
@@ -1,5 +0,0 @@
-variable "region" {
- description = "AWS region"
- type = string
- default = "us-west-2"
-}
diff --git a/live/core/.terraform.lock.hcl b/live/prod/us-west-2/app/.terraform.lock.hcl
similarity index 100%
rename from live/core/.terraform.lock.hcl
rename to live/prod/us-west-2/app/.terraform.lock.hcl
diff --git a/live/core/README.md b/live/prod/us-west-2/app/README.md
similarity index 89%
rename from live/core/README.md
rename to live/prod/us-west-2/app/README.md
index 843af34..ac27a78 100644
--- a/live/core/README.md
+++ b/live/prod/us-west-2/app/README.md
@@ -1,4 +1,4 @@
-# Core Infrastructure
+# Prod Infrastructure (us-west-2)
🏢 This directory contains the infrastructure as code for our cloud infrastructure. It provides a ready-to-use Terraform module with various features. Follow the steps below to get started.
@@ -32,21 +32,12 @@ tfswitch
terraform init
```
-2. Switch to a workspace:
-
-```sh
-# Switch to the another workspace or create it if it doesn't exist
-terraform workspace select -or-create prod
-```
-
## Deploy
-🚀 **NOTE:** In this example, we are using the `prod` environment and the `us-west-2` region. Modify these values according to your environment and region.
-
1. Plan the deployment:
```sh
-terraform plan -var-file ./configs/prod.us-west-2.tfvars -out ./prod.tfplan
+terraform plan -out ./prod.tfplan
```
2. Apply the deployment:
@@ -74,12 +65,10 @@ git push
## Destroy
-💣 **NOTE:** In this example, we are using the `prod` environment and the `us-west-2` region. Modify these values according to your environment and region.
-
To destroy the infrastructure, run the following command:
```sh
-terraform destroy -var-file ./configs/prod.us-west-2.tfvars
+terraform destroy
```
## Post Deployment Steps
diff --git a/live/core/backend.tf b/live/prod/us-west-2/app/backend.tf
similarity index 61%
rename from live/core/backend.tf
rename to live/prod/us-west-2/app/backend.tf
index 690d171..0cff6d7 100644
--- a/live/core/backend.tf
+++ b/live/prod/us-west-2/app/backend.tf
@@ -6,16 +6,14 @@ module "terraform_state_backend" {
source = "cloudposse/tfstate-backend/aws"
version = "1.1.1"
- # Avoid creating anything within if we are not in the workspace "default" and "prod".
- enabled = contains(["default", "prod"], terraform.workspace)
-
- name = module.label.name
- namespace = module.label.namespace
- attributes = ["state"]
+ name = module.label.name
+ namespace = module.label.namespace
+ environment = module.label.environment
+ attributes = ["state"]
terraform_backend_config_file_path = "."
terraform_backend_config_file_name = "s3-backend.tf"
- terraform_state_file = "${module.label.namespace}-${module.label.name}.tfstate"
+ terraform_state_file = "${module.label.id}.tfstate"
bucket_enabled = true
dynamodb_enabled = true
diff --git a/live/core/bastion.tf b/live/prod/us-west-2/app/bastion.tf
similarity index 50%
rename from live/core/bastion.tf
rename to live/prod/us-west-2/app/bastion.tf
index 452e18e..2b7ffea 100644
--- a/live/core/bastion.tf
+++ b/live/prod/us-west-2/app/bastion.tf
@@ -1,30 +1,30 @@
-variable "enable_bastion" {
- type = bool
- description = "Enable bastion host"
- default = false
+locals {
+ bastion = {
+ enable = true
+ }
}
module "bastion" {
- count = var.enable_bastion ? 1 : 0
+ count = local.bastion.enable ? 1 : 0
- source = "../../modules/bastion"
+ source = "../../../../modules/bastion"
name = "${module.label.id}-bastion"
vpc_id = module.vpc.vpc_id
subnets = module.vpc.public_subnets
associate_public_ip_address = true
- associate_elastic_ip_address = false
+ associate_elastic_ip_address = true
tags = module.label.tags
}
output "bastion_instance_id" {
- value = var.enable_bastion ? module.bastion[0].instance_id : null
+ value = local.bastion.enable ? module.bastion[0].instance_id : null
}
output "bastion_instance_profile" {
- value = var.enable_bastion ? module.bastion[0].instance_profile : null
+ value = local.bastion.enable ? module.bastion[0].instance_profile : null
}
output "ssm_parameter_bastion_ssh_key" {
description = "name of the ssm parameter for the bastion ssh key"
- value = var.enable_bastion ? module.bastion[0].ssm_parameter_ssh_key : null
+ value = local.bastion.enable ? module.bastion[0].ssm_parameter_ssh_key : null
}
diff --git a/live/prod/us-west-2/app/context.tf b/live/prod/us-west-2/app/context.tf
new file mode 100644
index 0000000..29e3340
--- /dev/null
+++ b/live/prod/us-west-2/app/context.tf
@@ -0,0 +1,34 @@
+locals {
+ context = {
+ name = "app"
+ namespace = "nan"
+ environment = "prod"
+ tags = {
+ "Terraform" = "true"
+ "Environment" = "prod"
+ }
+ }
+}
+
+data "aws_caller_identity" "aws" {}
+
+locals {
+ tf_tags = {
+ Terraform = true,
+ By = data.aws_caller_identity.aws.arn
+ }
+}
+
+// Keep labels, tags consistent
+module "label" {
+ source = "cloudposse/label/null"
+ version = "0.25.0"
+
+ name = local.context.name
+ environment = local.context.environment
+ namespace = local.context.namespace
+
+ delimiter = "-"
+ label_order = ["namespace", "environment", "name", "attributes"]
+ tags = merge(local.context.tags, local.tf_tags)
+}
diff --git a/live/core/docs/MODULE.md b/live/prod/us-west-2/app/docs/MODULE.md
similarity index 66%
rename from live/core/docs/MODULE.md
rename to live/prod/us-west-2/app/docs/MODULE.md
index 94f63be..a5e3ad2 100644
--- a/live/core/docs/MODULE.md
+++ b/live/prod/us-west-2/app/docs/MODULE.md
@@ -16,11 +16,11 @@
| Name | Source | Version |
|------|--------|---------|
-| [bastion](#module\_bastion) | ../../modules/bastion | n/a |
-| [exampledb](#module\_exampledb) | ../../modules/rds | n/a |
+| [bastion](#module\_bastion) | ../../../../modules/bastion | n/a |
+| [exampledb](#module\_exampledb) | ../../../../modules/rds | n/a |
| [label](#module\_label) | cloudposse/label/null | 0.25.0 |
| [terraform\_state\_backend](#module\_terraform\_state\_backend) | cloudposse/tfstate-backend/aws | 1.1.1 |
-| [vpc](#module\_vpc) | ../../modules/vpc | n/a |
+| [vpc](#module\_vpc) | ../../../../modules/vpc | n/a |
## Resources
@@ -30,18 +30,7 @@
## Inputs
-| Name | Description | Type | Default | Required |
-|------|-------------|------|---------|:--------:|
-| [enable\_bastion](#input\_enable\_bastion) | Enable bastion host | `bool` | `false` | no |
-| [environment](#input\_environment) | Environment, e.g. 'prod', 'staging', 'dev', 'pre-prod', 'UAT' | `string` | `"development"` | no |
-| [example\_db\_master\_username](#input\_example\_db\_master\_username) | The username for the master DB user | `string` | `"root"` | no |
-| [example\_db\_name](#input\_example\_db\_name) | The name of the database to create | `string` | `"mydb"` | no |
-| [name](#input\_name) | Name to use for servers, tags, etc | `string` | `"name"` | no |
-| [namespace](#input\_namespace) | Namespace, which could be your organization name or abbreviation, e.g. 'eg' or 'cp' | `string` | `"development"` | no |
-| [region](#input\_region) | AWS region | `string` | `"us-west-2"` | no |
-| [stage](#input\_stage) | Stage, e.g. 'build', 'test', 'deploy', 'release' | `string` | `null` | no |
-| [tags](#input\_tags) | Any extra tags to assign to objects | `map(any)` | `{}` | no |
-| [vpc\_cidr\_block](#input\_vpc\_cidr\_block) | CIDR block for the VPC | `string` | `"10.0.0.0/16"` | no |
+No inputs.
## Outputs
diff --git a/live/core/example-rds-instance.tf b/live/prod/us-west-2/app/example-rds-instance.tf
similarity index 69%
rename from live/core/example-rds-instance.tf
rename to live/prod/us-west-2/app/example-rds-instance.tf
index 7b14a28..46fdade 100644
--- a/live/core/example-rds-instance.tf
+++ b/live/prod/us-west-2/app/example-rds-instance.tf
@@ -1,25 +1,20 @@
-variable "example_db_name" {
- description = "The name of the database to create"
- type = string
- default = "mydb"
-}
-
-variable "example_db_master_username" {
- description = "The username for the master DB user"
- type = string
- default = "root"
+locals {
+ exampledb = {
+ db_name = "mydb"
+ db_master_username = "myuser"
+ }
}
module "exampledb" {
- source = "../../modules/rds"
+ source = "../../../../modules/rds"
name = "${module.label.id}-exampledb"
vpc_id = module.vpc.vpc_id
db_subnet_group = module.vpc.database_subnet_group
- db_name = var.example_db_name
- db_master_username = var.example_db_master_username
+ db_name = local.exampledb.db_name
+ db_master_username = local.exampledb.db_master_username
db_port = 5432
allocated_storage = 20
diff --git a/live/core/main.tf b/live/prod/us-west-2/app/main.tf
similarity index 78%
rename from live/core/main.tf
rename to live/prod/us-west-2/app/main.tf
index 143ee86..fe5e8dc 100644
--- a/live/core/main.tf
+++ b/live/prod/us-west-2/app/main.tf
@@ -1,5 +1,5 @@
provider "aws" {
- region = var.region
+ region = "us-west-2"
default_tags {
tags = {
diff --git a/live/core/outputs.tf b/live/prod/us-west-2/app/outputs.tf
similarity index 100%
rename from live/core/outputs.tf
rename to live/prod/us-west-2/app/outputs.tf
diff --git a/live/core/versions.tf b/live/prod/us-west-2/app/versions.tf
similarity index 100%
rename from live/core/versions.tf
rename to live/prod/us-west-2/app/versions.tf
diff --git a/live/core/vpc.tf b/live/prod/us-west-2/app/vpc.tf
similarity index 84%
rename from live/core/vpc.tf
rename to live/prod/us-west-2/app/vpc.tf
index ae45af9..16a3f0b 100644
--- a/live/core/vpc.tf
+++ b/live/prod/us-west-2/app/vpc.tf
@@ -1,13 +1,7 @@
-variable "vpc_cidr_block" {
- description = "CIDR block for the VPC"
- type = string
- default = "10.0.0.0/16"
-}
-
module "vpc" {
- source = "../../modules/vpc"
+ source = "../../../../modules/vpc"
name = module.label.id
- vpc_cidr_block = var.vpc_cidr_block
+ vpc_cidr_block = "10.0.0.0/16"
tags = module.label.tags
enable_nat_gateway = true
single_nat_gateway = true
diff --git a/live/staging/us-west-2/app/.terraform.lock.hcl b/live/staging/us-west-2/app/.terraform.lock.hcl
new file mode 100644
index 0000000..3f8fe65
--- /dev/null
+++ b/live/staging/us-west-2/app/.terraform.lock.hcl
@@ -0,0 +1,101 @@
+# This file is maintained automatically by "terraform init".
+# Manual edits may be lost in future updates.
+
+provider "registry.terraform.io/hashicorp/aws" {
+ version = "5.6.2"
+ constraints = ">= 3.0.0, >= 3.29.0, >= 3.72.0, >= 3.73.0, >= 4.9.0, >= 5.0.0"
+ hashes = [
+ "h1:ew6CvX7pUxD8I+1Etv25m5Okk1I8Gna/7Uqd+8Z6vxI=",
+ "zh:25322d7e1f0054550357d5a03fe29168cc179421e5dcf44b28c25a99d8d6e4e7",
+ "zh:394aa5bff70003e76d1d33ef4fe37c4826918577cf339d35e56ae84d01e86765",
+ "zh:485b288bf95b5d3014903e386e8ee2d1182e507f746bc988458b9711c7df7171",
+ "zh:48cf69750681337d64df7e402116a6753a40b6702c49fc9232ff6621947d85af",
+ "zh:6ab11d052d681b5157e261b9dd9167482acffe2018fffd1204575e9bf6a08522",
+ "zh:882f22d0e6c16cd5a5f01a0ae817b1e75e928667d21d986b93a4ee74fa62c067",
+ "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
+ "zh:ac3403e3ab5c10869b23626467b919e3f010e7cae6e0acf8515e0cefab0dbff0",
+ "zh:b959a425c9be83838895e8626037656bf5db81397ad0078595d3b72fd1b816bc",
+ "zh:bf390951f21a5fe6b96b206c5496fda4d8b95823bd00d1c03a4a53dd215d882a",
+ "zh:c3534972986cd68a421359f07ab86631ffa8731606936276fce18ec8ae9045f4",
+ "zh:d4cf29d67ead2c5feb999c2882e5365bd4d04c115e98fb1639b747b682507fea",
+ "zh:dea669eea5bca9b57dae2975ec783d577d58a39eec769d1c9bd7fc4d50f241d0",
+ "zh:e7a82063d01eb2be3fd192afbad910150fe8054731db20c1b22c714d9391dbe5",
+ "zh:fdbbf96948e96dfed614ea4daa4f1706859122a3f978c42c37db8727cb55c94f",
+ ]
+}
+
+provider "registry.terraform.io/hashicorp/local" {
+ version = "2.4.0"
+ constraints = ">= 2.0.0"
+ hashes = [
+ "h1:R97FTYETo88sT2VHfMgkPU3lzCsZLunPftjSI5vfKe8=",
+ "zh:53604cd29cb92538668fe09565c739358dc53ca56f9f11312b9d7de81e48fab9",
+ "zh:66a46e9c508716a1c98efbf793092f03d50049fa4a83cd6b2251e9a06aca2acf",
+ "zh:70a6f6a852dd83768d0778ce9817d81d4b3f073fab8fa570bff92dcb0824f732",
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
+ "zh:82a803f2f484c8b766e2e9c32343e9c89b91997b9f8d2697f9f3837f62926b35",
+ "zh:9708a4e40d6cc4b8afd1352e5186e6e1502f6ae599867c120967aebe9d90ed04",
+ "zh:973f65ce0d67c585f4ec250c1e634c9b22d9c4288b484ee2a871d7fa1e317406",
+ "zh:c8fa0f98f9316e4cfef082aa9b785ba16e36ff754d6aba8b456dab9500e671c6",
+ "zh:cfa5342a5f5188b20db246c73ac823918c189468e1382cb3c48a9c0c08fc5bf7",
+ "zh:e0e2b477c7e899c63b06b38cd8684a893d834d6d0b5e9b033cedc06dd7ffe9e2",
+ "zh:f62d7d05ea1ee566f732505200ab38d94315a4add27947a60afa29860822d3fc",
+ "zh:fa7ce69dde358e172bd719014ad637634bbdabc49363104f4fca759b4b73f2ce",
+ ]
+}
+
+provider "registry.terraform.io/hashicorp/random" {
+ version = "3.5.1"
+ constraints = ">= 3.1.0"
+ hashes = [
+ "h1:VSnd9ZIPyfKHOObuQCaKfnjIHRtR7qTw19Rz8tJxm+k=",
+ "zh:04e3fbd610cb52c1017d282531364b9c53ef72b6bc533acb2a90671957324a64",
+ "zh:119197103301ebaf7efb91df8f0b6e0dd31e6ff943d231af35ee1831c599188d",
+ "zh:4d2b219d09abf3b1bb4df93d399ed156cadd61f44ad3baf5cf2954df2fba0831",
+ "zh:6130bdde527587bbe2dcaa7150363e96dbc5250ea20154176d82bc69df5d4ce3",
+ "zh:6cc326cd4000f724d3086ee05587e7710f032f94fc9af35e96a386a1c6f2214f",
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
+ "zh:b6d88e1d28cf2dfa24e9fdcc3efc77adcdc1c3c3b5c7ce503a423efbdd6de57b",
+ "zh:ba74c592622ecbcef9dc2a4d81ed321c4e44cddf7da799faa324da9bf52a22b2",
+ "zh:c7c5cde98fe4ef1143bd1b3ec5dc04baf0d4cc3ca2c5c7d40d17c0e9b2076865",
+ "zh:dac4bad52c940cd0dfc27893507c1e92393846b024c5a9db159a93c534a3da03",
+ "zh:de8febe2a2acd9ac454b844a4106ed295ae9520ef54dc8ed2faf29f12716b602",
+ "zh:eab0d0495e7e711cca367f7d4df6e322e6c562fc52151ec931176115b83ed014",
+ ]
+}
+
+provider "registry.terraform.io/hashicorp/template" {
+ version = "2.2.0"
+ hashes = [
+ "h1:94qn780bi1qjrbC3uQtjJh3Wkfwd5+tTtJHOb7KTg9w=",
+ "zh:01702196f0a0492ec07917db7aaa595843d8f171dc195f4c988d2ffca2a06386",
+ "zh:09aae3da826ba3d7df69efeb25d146a1de0d03e951d35019a0f80e4f58c89b53",
+ "zh:09ba83c0625b6fe0a954da6fbd0c355ac0b7f07f86c91a2a97849140fea49603",
+ "zh:0e3a6c8e16f17f19010accd0844187d524580d9fdb0731f675ffcf4afba03d16",
+ "zh:45f2c594b6f2f34ea663704cc72048b212fe7d16fb4cfd959365fa997228a776",
+ "zh:77ea3e5a0446784d77114b5e851c970a3dde1e08fa6de38210b8385d7605d451",
+ "zh:8a154388f3708e3df5a69122a23bdfaf760a523788a5081976b3d5616f7d30ae",
+ "zh:992843002f2db5a11e626b3fc23dc0c87ad3729b3b3cff08e32ffb3df97edbde",
+ "zh:ad906f4cebd3ec5e43d5cd6dc8f4c5c9cc3b33d2243c89c5fc18f97f7277b51d",
+ "zh:c979425ddb256511137ecd093e23283234da0154b7fa8b21c2687182d9aea8b2",
+ ]
+}
+
+provider "registry.terraform.io/hashicorp/tls" {
+ version = "4.0.4"
+ hashes = [
+ "h1:pe9vq86dZZKCm+8k1RhzARwENslF3SXb9ErHbQfgjXU=",
+ "zh:23671ed83e1fcf79745534841e10291bbf34046b27d6e68a5d0aab77206f4a55",
+ "zh:45292421211ffd9e8e3eb3655677700e3c5047f71d8f7650d2ce30242335f848",
+ "zh:59fedb519f4433c0fdb1d58b27c210b27415fddd0cd73c5312530b4309c088be",
+ "zh:5a8eec2409a9ff7cd0758a9d818c74bcba92a240e6c5e54b99df68fff312bbd5",
+ "zh:5e6a4b39f3171f53292ab88058a59e64825f2b842760a4869e64dc1dc093d1fe",
+ "zh:810547d0bf9311d21c81cc306126d3547e7bd3f194fc295836acf164b9f8424e",
+ "zh:824a5f3617624243bed0259d7dd37d76017097dc3193dac669be342b90b2ab48",
+ "zh:9361ccc7048be5dcbc2fafe2d8216939765b3160bd52734f7a9fd917a39ecbd8",
+ "zh:aa02ea625aaf672e649296bce7580f62d724268189fe9ad7c1b36bb0fa12fa60",
+ "zh:c71b4cd40d6ec7815dfeefd57d88bc592c0c42f5e5858dcc88245d371b4b8b1e",
+ "zh:dabcd52f36b43d250a3d71ad7abfa07b5622c69068d989e60b79b2bb4f220316",
+ "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c",
+ ]
+}
diff --git a/live/staging/us-west-2/app/README.md b/live/staging/us-west-2/app/README.md
new file mode 100644
index 0000000..bf0c60c
--- /dev/null
+++ b/live/staging/us-west-2/app/README.md
@@ -0,0 +1,204 @@
+# Staging Infrastructure (us-west-2)
+
+🏢 This directory contains the infrastructure as code for our cloud infrastructure. It provides a ready-to-use Terraform module with various features. Follow the steps below to get started.
+
+## Features
+
+- ✨ Ready to use Root Terraform module!
+- 🗄️ Store Terraform state in an S3 bucket with a DynamoDB table for locking.
+- 🌐 VPC with public and private subnets (application and database subnets) in three availability zones.
+- 🔒 Security groups for bastion host and database.
+- 🔑 Bastion host to access private resources.
+- 🐘 RDS Postgres instance and other database resources.
+- 🔒 AWS Secrets Manager to store database credentials.
+- 🔧 SSM Parameter Store to store parameters such as VPC ID, Subnet IDs, etc.
+
+## Prerequisites
+
+- [Terraform](https://www.terraform.io/downloads.html)
+- [TFswitch](https://tfswitch.warrensbox.com/)
+
+## Setup
+
+1. Switch to the correct Terraform version
+
+```sh
+tfswitch
+```
+
+2. Initialize the Terraform working directory:
+
+```sh
+terraform init
+```
+
+## Deploy
+
+1. Plan the deployment:
+
+```sh
+terraform plan -out ./staging.tfplan
+```
+
+2. Apply the deployment:
+
+```sh
+terraform apply ./staging.tfplan
+```
+
+### First Time Deployment?
+
+If this is the first time you are deploying, a file called `s3-backend.tf` will be created. This file configures the backend for Terraform, using S3 to store the state of our infrastructure.
+
+Run the following command to copy the state to the S3 bucket:
+
+```sh
+terraform init -force-copy
+```
+
+Push the `s3-backend.tf` file to the repository:
+
+```sh
+git add s3-backend.tf && git commit -m "Add s3-backend.tf file"
+git push
+```
+
+## Destroy
+
+To destroy the infrastructure, run the following command:
+
+```sh
+terraform destroy
+```
+
+## Post Deployment Steps
+
+After successfully deploying the infrastructure, follow these steps to test the deployment and ensure everything is working as expected:
+
+### Accessing the Parameter Store
+
+Retrieve stored values, such as the VPC ID, using the AWS Parameter Store:
+
+```bash
+# Retrieve the parameter value from the AWS Parameter Store
+vpc_id_parameter_name=$(terraform output -json | jq -r '.ssm_parameter_vpc_id.value')
+vpc_id=$(aws ssm get-parameter --name "$vpc_id_parameter_name" --query 'Parameter.Value' --output text)
+
+# Print the value
+echo "VPC ID: $vpc_id"
+```
+
+### Connecting to the Bastion Host
+
+To establish a secure connection with the bastion host, follow these steps:
+
+#### Obtain Required Information
+
+First, you need to gather some essential information:
+
+- Bastion SSH Parameter Name
+- Bastion Instance ID
+
+You can retrieve these values using Terraform:
+
+```bash
+bastion_ssh_parameter_name=$(terraform output -json | jq -r '.ssm_parameter_bastion_ssh_key.value')
+bastion_instance_id=$(terraform output -json | jq -r '.bastion_instance_id.value')
+```
+
+#### Generate .pem file with the ssh key
+
+```bash
+aws ssm get-parameter --name "$bastion_ssh_parameter_name" --with-decryption --query 'Parameter.Value' --output text > /tmp/ssh_key.pem
+chmod 400 /tmp/ssh_key.pem
+```
+
+#### Retrieve bastion's public IP
+
+```bash
+bastion_public_ip=$(aws ec2 describe-instances --instance-ids "$bastion_instance_id" --query 'Reservations[0].Instances[0].PublicIpAddress' --output text | tr '.' '-')
+
+# Print the value
+echo "Bastion IP: $bastion_public_ip"
+```
+
+#### Connect to Bastion Host
+
+```bash
+ssh -i "/tmp/ssh_key.pem" ubuntu@ec2-"$bastion_public_ip".us-west-2.compute.amazonaws.com
+```
+
+Ensure that you can access the database from the bastion host and verify that Docker is functioning correctly.
+
+#### Testing Docker and Internet Access
+
+To verify internet access and Docker functionality, execute the following commands:
+
+```bash
+# Test Internet Access
+ping -c 3 google.com
+
+# Test Docker
+docker run -it --rm hello-world
+```
+
+#### Connecting to the Database
+
+To connect to the database from the bastion host, retrieve the connection information from AWS Secrets Manager. Follow these steps:
+
+- Outside the bastion host:
+
+```bash
+# Retrieve the parameter value from the AWS Parameter Store
+SECRET_ID=$(terraform output -json | jq -r '.example_db_connection_secret_arn.value')
+```
+
+- Inside the bastion host:
+
+```bash
+# Retrieve the connection information from AWS Secrets Manager
+db_secret=$(aws secretsmanager get-secret-value --secret-id "$SECRET_ID" \
+ --query 'SecretString' --output json)
+
+# Parse the connection information to obtain the username, password, host, port, and database name
+db_username=$(echo $db_secret | jq -r '.username')
+db_password=$(echo $db_secret | jq -r '.password')
+db_host=$(echo $db_secret | jq -r '.host')
+db_port=$(echo $db_secret | jq -r '.port')
+db_name=$(echo $db_secret | jq -r '.dbname')
+
+# Connect to the database using Psql with Docker
+docker run -it --rm postgres:14.0-alpine psql -h $db_host -p $db_port -U $db_username -d $db_name
+```
+
+You can now execute SQL commands to test the database setup. For example:
+
+- Retrieve the current date and time:
+
+```sql
+> SELECT NOW();
+```
+
+- Check the database version:
+
+```sql
+> SELECT version();
+```
+
+- List the tables in the database:
+
+```sql
+> SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';
+```
+
+These steps will help you verify the successful setup of the database and ensure that the necessary connections and configurations are in place.
+
+## Module Documentation
+
+The module documentation is generated with [terraform-docs](https://github.com/terraform-docs/terraform-docs) by running the following command from the module directory:
+
+```sh
+terraform-docs md . > ./docs/MODULE.md
+```
+
+You can also view the latest version of the module documentation [here](./docs/MODULE.md).
diff --git a/live/staging/us-west-2/app/backend.tf b/live/staging/us-west-2/app/backend.tf
new file mode 100644
index 0000000..0cff6d7
--- /dev/null
+++ b/live/staging/us-west-2/app/backend.tf
@@ -0,0 +1,22 @@
+# You cannot create a new backend by simply defining this and then
+# immediately proceeding to "terraform apply". The S3 backend must
+# be bootstrapped according to the simple yet essential procedure in
+# https://github.com/cloudposse/terraform-aws-tfstate-backend#usage
+module "terraform_state_backend" {
+ source = "cloudposse/tfstate-backend/aws"
+ version = "1.1.1"
+
+ name = module.label.name
+ namespace = module.label.namespace
+ environment = module.label.environment
+ attributes = ["state"]
+
+ terraform_backend_config_file_path = "."
+ terraform_backend_config_file_name = "s3-backend.tf"
+ terraform_state_file = "${module.label.id}.tfstate"
+
+ bucket_enabled = true
+ dynamodb_enabled = true
+
+ force_destroy = false
+}
diff --git a/live/staging/us-west-2/app/bastion.tf b/live/staging/us-west-2/app/bastion.tf
new file mode 100644
index 0000000..2b7ffea
--- /dev/null
+++ b/live/staging/us-west-2/app/bastion.tf
@@ -0,0 +1,30 @@
+locals {
+ bastion = {
+ enable = true
+ }
+}
+
+module "bastion" {
+ count = local.bastion.enable ? 1 : 0
+
+ source = "../../../../modules/bastion"
+ name = "${module.label.id}-bastion"
+ vpc_id = module.vpc.vpc_id
+ subnets = module.vpc.public_subnets
+ associate_public_ip_address = true
+ associate_elastic_ip_address = true
+ tags = module.label.tags
+}
+
+output "bastion_instance_id" {
+ value = local.bastion.enable ? module.bastion[0].instance_id : null
+}
+
+output "bastion_instance_profile" {
+ value = local.bastion.enable ? module.bastion[0].instance_profile : null
+}
+
+output "ssm_parameter_bastion_ssh_key" {
+ description = "name of the ssm parameter for the bastion ssh key"
+ value = local.bastion.enable ? module.bastion[0].ssm_parameter_ssh_key : null
+}
diff --git a/live/staging/us-west-2/app/context.tf b/live/staging/us-west-2/app/context.tf
new file mode 100644
index 0000000..8090493
--- /dev/null
+++ b/live/staging/us-west-2/app/context.tf
@@ -0,0 +1,34 @@
+locals {
+ context = {
+ name = "app"
+ namespace = "nan"
+ environment = "staging"
+ tags = {
+ "Terraform" = "true"
+ "Environment" = "staging"
+ }
+ }
+}
+
+data "aws_caller_identity" "aws" {}
+
+locals {
+ tf_tags = {
+ Terraform = true,
+ By = data.aws_caller_identity.aws.arn
+ }
+}
+
+// Keep labels, tags consistent
+module "label" {
+ source = "cloudposse/label/null"
+ version = "0.25.0"
+
+ name = local.context.name
+ environment = local.context.environment
+ namespace = local.context.namespace
+
+ delimiter = "-"
+ label_order = ["namespace", "environment", "name", "attributes"]
+ tags = merge(local.context.tags, local.tf_tags)
+}
diff --git a/live/staging/us-west-2/app/docs/MODULE.md b/live/staging/us-west-2/app/docs/MODULE.md
new file mode 100644
index 0000000..a5e3ad2
--- /dev/null
+++ b/live/staging/us-west-2/app/docs/MODULE.md
@@ -0,0 +1,52 @@
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [aws](#requirement\_aws) | >= 5.0.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [aws](#provider\_aws) | 5.6.2 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [bastion](#module\_bastion) | ../../../../modules/bastion | n/a |
+| [exampledb](#module\_exampledb) | ../../../../modules/rds | n/a |
+| [label](#module\_label) | cloudposse/label/null | 0.25.0 |
+| [terraform\_state\_backend](#module\_terraform\_state\_backend) | cloudposse/tfstate-backend/aws | 1.1.1 |
+| [vpc](#module\_vpc) | ../../../../modules/vpc | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [aws_caller_identity.aws](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
+
+## Inputs
+
+No inputs.
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [bastion\_instance\_id](#output\_bastion\_instance\_id) | n/a |
+| [bastion\_instance\_profile](#output\_bastion\_instance\_profile) | n/a |
+| [example\_db\_instance\_address](#output\_example\_db\_instance\_address) | The address of the RDS instance |
+| [example\_db\_instance\_master\_user\_secret\_arn](#output\_example\_db\_instance\_master\_user\_secret\_arn) | The ARN of the secret containing the connection details for the RDS instance |
+| [example\_db\_instance\_name](#output\_example\_db\_instance\_name) | The database name |
+| [example\_db\_instance\_port](#output\_example\_db\_instance\_port) | The database port |
+| [ssm\_parameter\_app\_security\_group](#output\_ssm\_parameter\_app\_security\_group) | name of the ssm parameter for the app security group |
+| [ssm\_parameter\_app\_subnets](#output\_ssm\_parameter\_app\_subnets) | name of the ssm parameter for the app subnets |
+| [ssm\_parameter\_bastion\_ssh\_key](#output\_ssm\_parameter\_bastion\_ssh\_key) | name of the ssm parameter for the bastion ssh key |
+| [ssm\_parameter\_database\_subnets](#output\_ssm\_parameter\_database\_subnets) | name of the ssm parameter for the database subnets |
+| [ssm\_parameter\_private\_subnets](#output\_ssm\_parameter\_private\_subnets) | name of the ssm parameter for the private subnets |
+| [ssm\_parameter\_public\_subnets](#output\_ssm\_parameter\_public\_subnets) | name of the ssm parameter for the public subnets |
+| [ssm\_parameter\_vpc\_id](#output\_ssm\_parameter\_vpc\_id) | name of the ssm parameter for the vpc id |
+
\ No newline at end of file
diff --git a/live/staging/us-west-2/app/example-rds-instance.tf b/live/staging/us-west-2/app/example-rds-instance.tf
new file mode 100644
index 0000000..46fdade
--- /dev/null
+++ b/live/staging/us-west-2/app/example-rds-instance.tf
@@ -0,0 +1,45 @@
+locals {
+ exampledb = {
+ db_name = "mydb"
+ db_master_username = "myuser"
+ }
+}
+
+module "exampledb" {
+ source = "../../../../modules/rds"
+
+ name = "${module.label.id}-exampledb"
+
+ vpc_id = module.vpc.vpc_id
+ db_subnet_group = module.vpc.database_subnet_group
+
+ db_name = local.exampledb.db_name
+ db_master_username = local.exampledb.db_master_username
+ db_port = 5432
+
+ allocated_storage = 20
+
+ manage_master_user_password = true
+
+ tags = module.label.tags
+}
+
+output "example_db_instance_address" {
+ description = "The address of the RDS instance"
+ value = module.exampledb.db_instance_address
+}
+
+output "example_db_instance_port" {
+ description = "The database port"
+ value = module.exampledb.db_instance_port
+}
+
+output "example_db_instance_name" {
+ description = "The database name"
+ value = module.exampledb.db_instance_name
+}
+
+output "example_db_instance_master_user_secret_arn" {
+ description = "The ARN of the secret containing the connection details for the RDS instance"
+ value = module.exampledb.db_instance_master_user_secret_arn
+}
diff --git a/live/staging/us-west-2/app/main.tf b/live/staging/us-west-2/app/main.tf
new file mode 100644
index 0000000..fe5e8dc
--- /dev/null
+++ b/live/staging/us-west-2/app/main.tf
@@ -0,0 +1,9 @@
+provider "aws" {
+ region = "us-west-2"
+
+ default_tags {
+ tags = {
+ Terraform = true
+ }
+ }
+}
diff --git a/live/staging/us-west-2/app/outputs.tf b/live/staging/us-west-2/app/outputs.tf
new file mode 100644
index 0000000..1e4feb0
--- /dev/null
+++ b/live/staging/us-west-2/app/outputs.tf
@@ -0,0 +1 @@
+# common outputs
diff --git a/live/staging/us-west-2/app/versions.tf b/live/staging/us-west-2/app/versions.tf
new file mode 100644
index 0000000..729454b
--- /dev/null
+++ b/live/staging/us-west-2/app/versions.tf
@@ -0,0 +1,10 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ aws = {
+ source = "hashicorp/aws"
+ version = ">= 5.0.0"
+ }
+ }
+}
diff --git a/live/staging/us-west-2/app/vpc.tf b/live/staging/us-west-2/app/vpc.tf
new file mode 100644
index 0000000..1da0966
--- /dev/null
+++ b/live/staging/us-west-2/app/vpc.tf
@@ -0,0 +1,38 @@
+module "vpc" {
+ source = "../../../../modules/vpc"
+ name = module.label.id
+ vpc_cidr_block = "10.1.0.0/16"
+ tags = module.label.tags
+ enable_nat_gateway = true
+ single_nat_gateway = true
+}
+
+output "ssm_parameter_vpc_id" {
+ description = "name of the ssm parameter for the vpc id"
+ value = module.vpc.ssm_parameter_vpc_id
+}
+
+output "ssm_parameter_public_subnets" {
+ description = "name of the ssm parameter for the public subnets"
+ value = module.vpc.ssm_parameter_public_subnets
+}
+
+output "ssm_parameter_private_subnets" {
+ description = "name of the ssm parameter for the private subnets"
+ value = module.vpc.ssm_parameter_private_subnets
+}
+
+output "ssm_parameter_database_subnets" {
+ description = "name of the ssm parameter for the database subnets"
+ value = module.vpc.ssm_parameter_database_subnets
+}
+
+output "ssm_parameter_app_subnets" {
+ description = "name of the ssm parameter for the app subnets"
+ value = module.vpc.ssm_parameter_app_subnets
+}
+
+output "ssm_parameter_app_security_group" {
+ description = "name of the ssm parameter for the app security group"
+ value = module.vpc.ssm_parameter_app_security_group
+}
diff --git a/tools/dac/live_core.py b/tools/dac/live_core.py
index 926d61d..da9f089 100644
--- a/tools/dac/live_core.py
+++ b/tools/dac/live_core.py
@@ -7,7 +7,7 @@
from diagrams.onprem.network import Internet
from diagrams.aws.management import Cloudwatch
-with Diagram("Live Core Infrastructure", show=False):
+with Diagram("Live Prod Infrastructure", show=False):
with Cluster("AWS Region"):
with Cluster("VPC"):
with Cluster("Public Subnet"):
diff --git a/tools/dac/live_core_infrastructure.png b/tools/dac/live_prod_infrastructure.png
similarity index 100%
rename from tools/dac/live_core_infrastructure.png
rename to tools/dac/live_prod_infrastructure.png