This document is a guide to how to deploy the entire Reference Architecture, or one of the environments in the
Reference Architecture (e.g., stage or prod), from scratch. This is useful if you want to know how to quickly set up
and tear down environments.
If you are deploying the entire Reference Architecture from scratch, then you should be aware of the various
dependencies that exist between the accounts. In order to ensure that all the dependent resources exist, we recommend
deploying the accounts in the following order:
security
shared-services
dev, stage, and prod. These can be done in parallel.
Build AMIs
All the EC2 Instances in the Reference Architecture (e.g., the ECS Cluster instances, the OpenVPN server, etc) run
Amazon Machine Images (AMIs) that are defined as code
using Packer. You will find the Packer templates (.json files) in the
infrastructure-modules-multi-account-acme repo. You will also find that the corresponding Terraform modules (e.g, the ecs-cluster
module) expect an ami_id parameter to be set in terragrunt.hcl.
Prerequisite: Deploy Packer Build VPC
All the AMIs are built using an EC2 instance that is temporarily deployed into a VPC of the account and region
that owns the AMI. This selection of the VPC and Subnet is done using the tags gruntwork.io/allow-packer=true. You
need to ensure a VPC with a Public Subnet, created with the tag exists in the target region of the AMI account owner.
The easiest way to do this would be to deploy a VPC using the networking/vpc-mgmt infrastructure module in the target
region. This module will properly tag the public subnets and the VPC for use with packer.
Run packer build <PATH-TO-TEMPLATE>. E.g., packer build infrastructure-modules-multi-account-acme/services/ecs-cluster/packer/ecs-node.json.
At the end of the build, Packer will output the new AMI ID. You can use this in the ami_id parameter of
terragrunt.hcl files.
AMIs and AWS regions
Note that AMIs live in a specific AWS region, so if you're deploying to multiple regions, you will have to build AMIs
for each region separately. If this is a common task, you can specify multiple builders in the Packer template, one
for each region, and the builds will run in parallel.
Sharing AMIs across AWS accounts
You can share AMIs across AWS accounts to avoid having to rebuild the same AMI over and over again. For example, you
could build the ECS AMI once in the shared-services account and deploy that same AMI in dev, stage, and prod. To enable
this, set the ami_users parameter to the IDs of the accounts that should have access to the AMI. For example, to
give accounts 11111111111 and 22222222222 access to an AMI:
If you want to encrypt the root volume of your EC2 Instances (e.g., for end-to-end encryption and compliance purposes),
you will need to set the encrypt_boot parameter to true in the Packer template:
The Reference Architecture include several sample Lambda functions under
infrastructure-modules-multi-account-acme/lambda. These show examples of how to use Lambda to perform various tasks without having to
manage any servers.
One of the Lambda functions in infrastructure-modules-multi-account-acme/lambda requires an extra build step to create its
deployment package before you can deploy it:
At the end of that script, it will output the path of the resulting deployment package, plus instructions on how to use
this path, which will tell you to set an environment variable. Make sure to follow those instructions!
Create EC2 Key Pairs
The Reference Architecture installs ssh-grunt
on every EC2 Instance so that each developer can use their own username and key to SSH to servers
(see SSH and VPN). However, we still recommend associating an EC2 Key
Pair with your EC2 Instances as an emergency
backup, in case their is some sort of issue with ssh-grunt.
We typically recommend creating at least 2 Key Pairs:
Save the Key Pair to disk. Do NOT share this Key Pair with anyone else; it's only for emergency backup!
Add a passphrase to the Key Pair: ssh-keygen -p -f <KEY_PAIR_PATH>.
Change permissions on the Key Pair: chmod 400 <KEY_PAIR_PATH>.
Pass the Key Pair name to the appropriate parameter in terragrunt.hcl in infrastructure-live-multi-account-acme; typically, this
parameter will be called ssh_key_name, keypair_name, or cluster_instance_keypair_name. Ensure you only use
the OpenVPN keypair for the OpenVPN server.
Configure Terraform backends
The Reference Architecture uses an S3 backend to store
Terraform State. We also use DynamoDB for locking. We recommend storing the
Terraform State for each AWS account in a separate S3 bucket and DynamoDB table. You will need to fill in the name and
region of the S3 bucket and DynamoDB table in two places in the top-level folder for that account in
infrastructure-live-multi-account-acme:
terragrunt.hcl
When you run Terragrunt, if the S3 bucket or DynamoDB table don't already exist, they will be created automatically.
Configure the VPN server
The Reference Architecture includes an OpenVPN server. The very first time you deploy the
server, it will create the Public Key Infrastructure (PKI) it will
use to sign certificates. This process is very CPU intensive and, on t2.micro EC2 Instances, it can take hours, as
it seems to exceed the burst balance almost immediately.
To avoid this, we recommend initially deploying the OpenVPN server with a larger instance (t2.medium can generate the
PKI in 1-2 minutes). Once the PKI has been generated, you can downgrade to a smaller instance again to save money.
Create data store passwords
Some of the data stores used in the Reference Architecture, such as RDS databases,
require that you set a password in the Terraform code. We do NOT recommend putting that password, in plaintext,
directly in the code. Instead, we recommend:
Create a long, strong, random password. Preferably 30+ characters.
Store the password in a secure secrets manager.
Every time you go to deploy the data store, set the password as an environment variable that Terraform can find
(see Terraform environment variables).
For example, for RDS DBs, you typically set the TF_VAR_master_password environment variable:
export TF_VAR_master_password=(...)
Import Route 53 hosted zones
The Reference Architecture configures DNS entries using Route 53. Each domain name
will live in a Public Hosted Zone
that is either created automatically if you bought a domain name through Route 53, or manually if you are using Route
53 to manage DNS for a domain name bought externally.
If the Public Hosted Zone already exists, you will need to use the import
command to put it under Terraform control. Go to the route53-public
module in infrastructure-live-multi-account-acme for the account you're deploying and run:
Where HOSTED_ZONE_ID is the primary ID of your Hosted Zone, which you can find in the AWS Console (it typically looks
something like Z1AB1Z2CDE3FG4).
Create an IAM User for KMS
The Reference Architecture uses KMS to encrypt and decrypt secrets. When you create a
new Customer Master Key (CMK) in KMS, you must
assign at least one IAM User as an "administrator" for the CMK. If there are no admins, then the CMK—and any secrets
encrypted with it—may become completely inaccessible!
Therefore, you will need to create an IAM User, either in the same AWS account (for single-account deploymens) or in
the security account (for multi-account deployments), and provide that IAM Users ARN to the
cmk_administrator_iam_arns parameter of the kms-master-key module.
Create TLS certs
Public-facing TLS certs
The Reference Architecture will automatically use TLS certs from the AWS Certificate Manager
(ACM) with each of your public load balancers (networking/alb-public in
infrastructure-live-multi-account-acme) and CloudFront distributions (services/static-website in infrastructure-live-multi-account-acme). If you are
deploying with totally new domain names, you will need to:
Request a certificate from ACM for the
AWS region(s) you are deploying to. The Terraform modules in the Reference Architecture typically look for a
wildcard certificate of the format *.<your-domain-name> (e.g., *.acme.com), so make sure to request a wildcard
certificate. If you don't want to use wild card certs, update the code in infrastructure-live-multi-account-acme and
infrastructure-modules-multi-account-acme accordingly.
If you are using CloudFront, you must also request a certificate for us-east-1, no matter what region you are
deploying too. See the cloudfront module
for more info.
Self-signed TLS certs for your apps
If you want to use end-to-end encryption, you will need to generate self-signed TLS certs for your apps so that other
apps or the load balancer can send traffic to them over TLS. If you are unfamiliar with how TLS certificates work,
start with the Background
documentation.
There are many ways to generate a certificate and use it with your apps, but the easiest option is:
Use the create-tls-cert.sh script provided in infrastructure-modules-multi-account-acme.
This script will automatically create a CA cert and a TLS cert signed by that CA, and encrypt the private key using
gruntkms with the KMS master key for the appropriate environment.
Package the public and encrypted private key of the TLS cert with the app (e.g., update your Dockerfile or Packer
template to package the TLS cert). You can take a look at sample-app-backend-multi-account-acme
for an example of how to package the certificates.
Use gruntkms to decrypt the private key just before the app boots (the run-app.sh script already does this).
During boot, configure your app to load the public and private key of the TLS cert and listen for TLS connections.
How you do this is app-specific.
If you have other apps that are going to talk to your app directly (e.g., via service discovery), distribute the
public key of the CA to those apps so they can validate your app's cert.
Self-signed TLS certs for your internal load balancers
If you want to use end-to-end encryption, you will need to generate self-signed TLS certs for your internal load
balancers so that your apps can send requests to those load balancers over TLS. If you are unfamiliar with how TLS
certificates work, start with the Background
documentation.
There are many ways to generate a certificate and use it with a load balancer, but the easiest option is:
Use the private-tls-cert module
to generate the certificates. Configure the TLS cert with a domain name you are going to be using for your load
balancer (see the next steps for how this domain name will work). This should give you back a public and private key
for the TLS certificate and a public key for the CA.
Create an internal domain name (e.g., acme-multi-account.internal) using Route 53 Private
Hosted Zones. This domain name
should match the one in the TLS certificate you created. See networking/route53-private in
infrastructure-live-multi-account-acme.
Import your certificate into the AWS Certificate Manager (ACM). One way to do this is with the aws CLI
import-certificate command, passing
it the public key of the certificate using the --certificate argument, the private key via the --private-key
argument, and the CA's public key using the --certificate-chain argument:
You'll need to do this in each region where you're going to deploy a load balancer. Once you've imported the
certificate everywhere, you may want to delete the private key so no one else can access it. If you're going to keep
the private key around, then make sure to use gruntkms to encrypt it
with KMS.
Create your load balancer with an HTTPS listener and set the certificate ARN to the ARN of the certificate you just
imported into ACM. You can find the ARN automatically using the aws_acm_certificate data
source.
Create a Route 53 A Record that points at your load balancer with the domain name and Private Hosted Zone you
created in step 2. You can use the aws_route53_record
resource to create the record and find the
Hosted Zone ID of your Private Hosted Zone automatically using the aws_route53_zone data
source.
You'll want to distribute the public key of the CA to any app that is going to talk to your load balancer so that it
can use it to validate the TLS certificate.
Self-signed TLS certs for java based apps
If you want to use end-to-end encryption, you will need to generate self-signed TLS certs for Java based apps. Java uses
a special format for managing their TLS certificates (KeyStores and TrustStores) and requires an extra step to encode
the generated certificates. If you are unfamiliar with how TLS certificates work, start with the Background
documentation.
Use the generate-trust-stores.sh script provided in infrastructure-modules-multi-account-acme.
This script will automatically create a CA cert and a TLS cert signed by that CA, and encode them into a Key Store
and Trust Store. The Key Store will be locked with a password that is generaated by the script and stored in AWS
Secrets Manager for use. The script will also encrypt the Key Store password using
gruntkms with the KMS master key for the appropriate environment and
output the KMS encrypted cipher text.
Package the Key Store and Trust Store into the AMI for use with the Java app. You can take a look at
the kafka module
for an example of how to package the certificates, including specific parameters to use for generating the Key Store
and Trust Store.
Run Terragrunt
Now that you have all the prerequisites out of the way, you can finally use Terragrunt to deploy everything!
Authenticate
If you're creating a totally new AWS account, the easiest way to do the initial deployment is to create a temporary IAM
User in that account with admin access. Create
Access Keys for that IAM User and
set them as environment variables:
export AWS_ACCESS_KEY_ID=(your access key for this account)
export AWS_SECRET_ACCESS_KEY=(your secret key for this account)
Once everything is deployed, you can delete this IAM user, and access the account via IAM roles (see the
cross-account-iam-access module
for details).
If you're using an AWS account that already exists and has already been configured with cross-account IAM roles as part
of the multi-account Reference Architecture setup, you should set environment variables for the security account:
export AWS_ACCESS_KEY_ID=(your access key for the security account)
export AWS_SECRET_ACCESS_KEY=(your secret key for the security account)
You should then set the TERRAGRUNT_IAM_ROLE to the ARN of an IAM role in the account you're deploying to that will
give you administrative access. Typically, you'll want the allow-full-access-from-other-accounts IAM role:
If you want to deploy code from your local checkout of infrastructure-modules-multi-account-acme, rather than a versioned release, use
the --terragrunt-source parameter:
If you want to deploy just a single module at a time, just use terragrunt apply:
cd infrastructure-live-multi-account-acme/stage/us-east-1/stage/services/ecs-cluster
terragrunt apply
Deployment order
Note that, in general, there are no dependencies between different AWS accounts, so you can deploy them in any order.
The only exception to this is the security account in the multi-account setup. This account defines all IAM Users,
Groups, and the S3 bucket used for CloudTrail audit logs, so it must always be deployed first.
Within an AWS account, there are many deployment dependencies (e.g., almost everything depends on the VPC being
deployed first), all of which should be defined in the dependencies blocks of terragrunt.hcl files. Terragrunt
takes these dependencies into account automatically and should deploy everything in the right order.
Expected errors
Due to bugs in Terraform, you will most likely hit some of the following (harmless) errors:
TLS handshake timeouts downloading Terraform providers or remote state. See
https://github.com/hashicorp/terraform/issues/15817.
"A separate request to update this alarm is in progress". See
https://github.com/terraform-providers/terraform-provider-aws/issues/422.
"Error loading modules: module xxx: not found, may need to run 'terraform init'". This typically happens if you
run apply-all, change the version of a module you're using, and run apply-all again. Unfortunately, Terragrunt
is not yet smart enough to automatically download the updated module (see
https://github.com/gruntwork-io/terragrunt/issues/388). Easiest workaround for now is to set
TERRAGRUNT_SOURCE_UPDATE=true to force Terragrunt to redownload everything:
{"treedata":{"name":"root","toggled":true,"children":[{"name":".gitignore","path":".gitignore","sha":"1c27fc6013cba46cd301a7c8bf951694670153a3"},{"name":"CODEOWNERS","path":"CODEOWNERS","sha":"6bddb3ff6e1b3dfaba7cf180e56bca12c245be56"},{"name":"README.md","path":"README.md","sha":"45d75f99aefaa9a2d008b223da04bc26453ef651"},{"name":"_docs","children":[{"name":"01-architecture-overview.md","path":"_docs/01-architecture-overview.md","sha":"115a05d08f3a431a19e5aa2596c079619ae66dab"},{"name":"02-whats-deployed.md","path":"_docs/02-whats-deployed.md","sha":"9dc8a401caf24896ce00a8087bfe32c7af99d2d2"},{"name":"03-security-compliance-compatibility.md","path":"_docs/03-security-compliance-compatibility.md","sha":"9342617f42adb28e440cc2161f3fee56205c150e"},{"name":"04-how-code-is-organized.md","path":"_docs/04-how-code-is-organized.md","sha":"3b340de506525633e1f7333a1e9ac9a5565a88e3"},{"name":"05-dev-environment.md","path":"_docs/05-dev-environment.md","sha":"c8b494aed802b623f7891047b6cba633d8ab5fa7"},{"name":"06-ci-cd.md","path":"_docs/06-ci-cd.md","sha":"b6c2a7d7cde7471fb08bff5dcf68c40156db68d5"},{"name":"07-monitoring-alerting-logging.md","path":"_docs/07-monitoring-alerting-logging.md","sha":"619c810c6e60418b3a46fa3d903bc76dc6d48e41"},{"name":"08-ssh-vpn.md","path":"_docs/08-ssh-vpn.md","sha":"9fe83afbd3d6116a4f3faff8923a81cd37ff91c7"},{"name":"09-accounts-and-auth.md","path":"_docs/09-accounts-and-auth.md","sha":"6b0472241644ffc79556e60d582ff1edb80f0554"},{"name":"10-gruntwork-tools.md","path":"_docs/10-gruntwork-tools.md","sha":"d08b1fe7cfbb9ad91155bfff9e3a05525c39c127"},{"name":"11-deploying-a-docker-service.md","path":"_docs/11-deploying-a-docker-service.md","sha":"c735be4ee94e76cc55b48a21039dfec44e6a5d51"},{"name":"12-migration.md","path":"_docs/12-migration.md","sha":"464cadf6e05d5ffd44e569c0d866b5c2cf5f42e9"},{"name":"13-deploying-the-reference-architecture-from-scratch.md","path":"_docs/13-deploying-the-reference-architecture-from-scratch.md","sha":"fa362071f460f7df7331645d6e5052e8cd20c30b","toggled":true},{"name":"14-undeploying-the-reference-architecture.md","path":"_docs/14-undeploying-the-reference-architecture.md","sha":"c6dcaae7266ead56d539b1816a5cfe2988412fe1"},{"name":"15-adding-new-environments-regions-and-accounts.md","path":"_docs/15-adding-new-environments-regions-and-accounts.md","sha":"c01188a1539e93ed2773a1b799b3b0f8e7b2045e"},{"name":"README.md","path":"_docs/README.md","sha":"ddb9fe83eb2fcad91e82771ad276dd0bdba40cb2"},{"name":"_images","children":[{"name":"cw-logs-1.png","path":"_docs/_images/cw-logs-1.png","sha":"84c86f014751844fbd777b5139ed61f749b5ed32"},{"name":"cw-logs-2.png","path":"_docs/_images/cw-logs-2.png","sha":"9a0a80b20490fdc1b9014040cc0bbc87c9cf6f68"},{"name":"cw-logs-3.png","path":"_docs/_images/cw-logs-3.png","sha":"bda49dc4e947658e0ceb9ba592b4e314d9db61e9"},{"name":"cw-logs-4.png","path":"_docs/_images/cw-logs-4.png","sha":"54bcc44c4b0701620b7f20c4e6fc0a9fd8f38049"},{"name":"ecs-console-1.png","path":"_docs/_images/ecs-console-1.png","sha":"afe452278d5f107e6ec225a235c587de7cb53510"},{"name":"ecs-console-2.png","path":"_docs/_images/ecs-console-2.png","sha":"40609b98015d781b9e1de801c131fadc323337ae"},{"name":"ecs-console-3.png","path":"_docs/_images/ecs-console-3.png","sha":"87ad40d291b7e9e6f6caa0389b846392bdb93ee0"},{"name":"ref-arch-full.png","path":"_docs/_images/ref-arch-full.png","sha":"8c17eef52be06757553a1f3ee4e387e6dc820016"},{"name":"ref-arch-icon.png","path":"_docs/_images/ref-arch-icon.png","sha":"05876962e6877df911674237ca1b793d9f4f04b3"},{"name":"terraform-code-provenance.png","path":"_docs/_images/terraform-code-provenance.png","sha":"e2a9d6bfbd8b963b057d4341dd0ec93e3823d834"}]}],"toggled":true},{"name":"dev","children":[{"name":"_global","children":[{"name":"README.md","path":"dev/_global/README.md","sha":"d1b8a96c00211751f079fa13cac1b3417d29bf09"},{"name":"cloudtrail","children":[{"name":"README.md","path":"dev/_global/cloudtrail/README.md","sha":"65aac5742b3dc183d11a7d83a31ae69afe5df2e5"},{"name":"terragrunt.hcl","path":"dev/_global/cloudtrail/terragrunt.hcl","sha":"fb19b4438de2ba919d17f3e4a6ccb3c9f2517f26"}]},{"name":"iam-cross-account","children":[{"name":"README.md","path":"dev/_global/iam-cross-account/README.md","sha":"6bf06985be74cf68085a78728c41cf88fc354141"},{"name":"terragrunt.hcl","path":"dev/_global/iam-cross-account/terragrunt.hcl","sha":"96f6b058d3db5871b45cd9e9c05d2387f7fa8340"}]},{"name":"iam-user-password-policy","children":[{"name":"README.md","path":"dev/_global/iam-user-password-policy/README.md","sha":"d3240490ed6005924706f6dd8a1718747ebcd8d9"},{"name":"terragrunt.hcl","path":"dev/_global/iam-user-password-policy/terragrunt.hcl","sha":"47b669ba52099812a6d52ed4fcdad48c5e32e91e"}]},{"name":"region.yaml","path":"dev/_global/region.yaml","sha":"18b7823ed017b97431d58da7bcb9a4e31299272a"},{"name":"route53-public","children":[{"name":"README.md","path":"dev/_global/route53-public/README.md","sha":"69a24d1bb0eff2a66ca9be44c0dfc864f7086960"},{"name":"terragrunt.hcl","path":"dev/_global/route53-public/terragrunt.hcl","sha":"68ed9958a62546160f9007660857c5baa95ce12b"}]}]},{"name":"empty.yaml","path":"dev/empty.yaml","sha":"5aa66daa40faeaef37eccb7b4b0fcc792233cd7b"},{"name":"terragrunt.hcl","path":"dev/terragrunt.hcl","sha":"a63152bc683cf06815f93c001fc4e96d498db325"},{"name":"us-east-1","children":[{"name":"_global","children":[{"name":"README.md","path":"dev/us-east-1/_global/README.md","sha":"37b828b038945a50e2e571ef1e755c4f9170e7cf"},{"name":"kms-master-key","children":[{"name":"README.md","path":"dev/us-east-1/_global/kms-master-key/README.md","sha":"9f97f59f9d03bc3cef6ecb0e97af8ffdfd7c0334"},{"name":"terragrunt.hcl","path":"dev/us-east-1/_global/kms-master-key/terragrunt.hcl","sha":"d5c556e7eb743da62e0191243a2d4ee9ec2cf828"}]},{"name":"sns-topics","children":[{"name":"README.md","path":"dev/us-east-1/_global/sns-topics/README.md","sha":"7926797c3094f0e708bd761d297589bd94be873e"},{"name":"terragrunt.hcl","path":"dev/us-east-1/_global/sns-topics/terragrunt.hcl","sha":"225cf4b3fe49af57c85a1e25b7942c72cf9e6853"}]}]},{"name":"dev","children":[{"name":"README.md","path":"dev/us-east-1/dev/README.md","sha":"30eef7620895f3ad23174f5f2c8772ab7f8880a8"},{"name":"cloudwatch-dashboard","children":[{"name":"README.md","path":"dev/us-east-1/dev/cloudwatch-dashboard/README.md","sha":"01e60cd5e9f63892e09b1d7edfa7bea8fd7d0a3d"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/cloudwatch-dashboard/terragrunt.hcl","sha":"f3533abbe42145ab1b29f235701892621c9d63d3"}]},{"name":"data-stores","children":[{"name":"elk-single-cluster","children":[{"name":"README.md","path":"dev/us-east-1/dev/data-stores/elk-single-cluster/README.md","sha":"a90283b9240f67c38dd1bd77755a8162fa6f3999"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/data-stores/elk-single-cluster/terragrunt.hcl","sha":"97fc6b6c810137e559da50b3684a5f6383c77c72"}]},{"name":"kafka","children":[{"name":"README.md","path":"dev/us-east-1/dev/data-stores/kafka/README.md","sha":"72582bdb047da4f8820f45716977d5b962c17028"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/data-stores/kafka/terragrunt.hcl","sha":"1c40ceaf50ae178033dda665553598a3f7548cd1"}]},{"name":"mysql","children":[{"name":"README.md","path":"dev/us-east-1/dev/data-stores/mysql/README.md","sha":"625773572c620dcddf722d0d0d206576f57f4af7"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/data-stores/mysql/terragrunt.hcl","sha":"40313bc9ada285fe59d77067728f6cf208b04668"}]},{"name":"redis","children":[{"name":"README.md","path":"dev/us-east-1/dev/data-stores/redis/README.md","sha":"5d82990da39b55e6ac7b3bbb442d4209e62dba1f"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/data-stores/redis/terragrunt.hcl","sha":"bfa22ef95f443e06ccf0624c414d6f9f6bde5b88"}]},{"name":"zookeeper","children":[{"name":"README.md","path":"dev/us-east-1/dev/data-stores/zookeeper/README.md","sha":"87b4dda769ae63cffa851b6ccf2086b617bf989d"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/data-stores/zookeeper/terragrunt.hcl","sha":"76af3451b7a52fd7d59cd8744ff3836da3c1826d"}]}]},{"name":"env.yaml","path":"dev/us-east-1/dev/env.yaml","sha":"c38dd83256fc4206be3afc24972cd7f3b6712b19"},{"name":"lambda","children":[{"name":"long-running-scheduled","children":[{"name":"README.md","path":"dev/us-east-1/dev/lambda/long-running-scheduled/README.md","sha":"274c405a65d60c6a253ca2cf24863e1025402874"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/lambda/long-running-scheduled/terragrunt.hcl","sha":"72518b7089bd107c05c281372f3cccd6d7a6a628"}]},{"name":"s3-image-processing","children":[{"name":"README.md","path":"dev/us-east-1/dev/lambda/s3-image-processing/README.md","sha":"d7e48256e90edb0896769e4bd537c22e34c42f22"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/lambda/s3-image-processing/terragrunt.hcl","sha":"9be5024cab87f495dd8ac275b9807d086b971da5"}]}]},{"name":"networking","children":[{"name":"alb-internal","children":[{"name":"README.md","path":"dev/us-east-1/dev/networking/alb-internal/README.md","sha":"6d7b1a62e65dab5e908d2fd2ba291a98bc639a1d"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/networking/alb-internal/terragrunt.hcl","sha":"3226f2f8cc966d88abe6ffe7b1d912735a638b80"}]},{"name":"alb-public","children":[{"name":"README.md","path":"dev/us-east-1/dev/networking/alb-public/README.md","sha":"6d7b1a62e65dab5e908d2fd2ba291a98bc639a1d"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/networking/alb-public/terragrunt.hcl","sha":"039a02514db5e62d5ec21d3131579c821dcb6283"}]},{"name":"route53-private","children":[{"name":"README.md","path":"dev/us-east-1/dev/networking/route53-private/README.md","sha":"c93f222ed15cae75ec411a4b005ad4da32548c42"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/networking/route53-private/terragrunt.hcl","sha":"f7e7c4b437c11b0340c682314deb9b08aca3a854"}]}]},{"name":"services","children":[{"name":"ecs-cluster","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/ecs-cluster/README.md","sha":"775dc4b2d530ce3ef27d0e9ad22e282a52bcffd3"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/ecs-cluster/terragrunt.hcl","sha":"64c60f67c5ce0a965a2e636015dcb9ff4e22344a"}]},{"name":"eks-cluster","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/eks-cluster/README.md","sha":"8666da2d140182a504efdfedb45554623de0f642"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/eks-cluster/terragrunt.hcl","sha":"791a66ce8376fbec9a019d0cab0ac0ead3aac1ac"}]},{"name":"eks-core-services","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/eks-core-services/README.md","sha":"4c2ea353f337fa34827a56b6a2230f6c8c690deb"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/eks-core-services/terragrunt.hcl","sha":"b9a002b3992e384e57015587693b3e7fe8eddc48"}]},{"name":"k8s-applications-namespace","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/k8s-applications-namespace/README.md","sha":"4475bc76ebcba0b26acff53ccaf827375d74bf7c"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/k8s-applications-namespace/terragrunt.hcl","sha":"dd0fbec59f588fe88fc6c7f59382c0ab6d20ff9c"}]},{"name":"k8s-sample-app-backend-multi-account-acme","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/k8s-sample-app-backend-multi-account-acme/README.md","sha":"62e7efec668cc4effc669c4070dcb968fa0bdc1d"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/k8s-sample-app-backend-multi-account-acme/terragrunt.hcl","sha":"953bef0317447c080e801343e586b0d1b3cbfbfa"}]},{"name":"k8s-sample-app-frontend-multi-account-acme","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/k8s-sample-app-frontend-multi-account-acme/README.md","sha":"63c1026d7c1e936b30a82f90fae754cde0cc6897"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/k8s-sample-app-frontend-multi-account-acme/terragrunt.hcl","sha":"40060b5d96f21608eb30d259cef65289f6169a6f"}]},{"name":"sample-app-backend-multi-account-acme-asg","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/sample-app-backend-multi-account-acme-asg/README.md","sha":"211044e0160f812cc6a5c984ea2dc71d769eece7"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/sample-app-backend-multi-account-acme-asg/terragrunt.hcl","sha":"cf84fcfa70c6d966803b70e29f549f3bd057f206"}]},{"name":"sample-app-backend-multi-account-acme","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/sample-app-backend-multi-account-acme/README.md","sha":"caa8ba67485807d6d463fd7573aa8b9808f7e20b"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/sample-app-backend-multi-account-acme/terragrunt.hcl","sha":"c88b0d61edddbf9337c414cfae2d970735be2b6f"}]},{"name":"sample-app-beanstalk","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/sample-app-beanstalk/README.md","sha":"2cd92b79c23a86d7759b8074de2158ab762ab01d"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/sample-app-beanstalk/terragrunt.hcl","sha":"77ac87dca4c64fbf5108231a6faf807fca3d1fee"}]},{"name":"sample-app-frontend-multi-account-acme-asg","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/sample-app-frontend-multi-account-acme-asg/README.md","sha":"fcd0809e1c9a0a824ed30aca8746a383838b5745"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/sample-app-frontend-multi-account-acme-asg/terragrunt.hcl","sha":"17d10295d106fbde6b0de3bf6c5d3badc97c0ecd"}]},{"name":"sample-app-frontend-multi-account-acme","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/sample-app-frontend-multi-account-acme/README.md","sha":"70cacba00f9ed9f2b11ef2615fd9d27ef24558e6"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/sample-app-frontend-multi-account-acme/terragrunt.hcl","sha":"c423cc7a2fe3630db7c75a72ef212ba186ab3739"}]},{"name":"static-website","children":[{"name":"README.md","path":"dev/us-east-1/dev/services/static-website/README.md","sha":"c39ed7c607eb4d1313ea3892768bad09e7f39fd9"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/services/static-website/terragrunt.hcl","sha":"3329db273624fe437ef031ee4e42583aa13c2312"}]}]},{"name":"vpc","children":[{"name":"README.md","path":"dev/us-east-1/dev/vpc/README.md","sha":"9f2704ce60e42e8f3a603a376abb15135183d887"},{"name":"terragrunt.hcl","path":"dev/us-east-1/dev/vpc/terragrunt.hcl","sha":"aea95690d1f2f5d37e6781f718f4b132c7f509b1"}]}]},{"name":"mgmt","children":[{"name":"README.md","path":"dev/us-east-1/mgmt/README.md","sha":"8a131a11632b97fec18a5e344d5c721fce24b652"},{"name":"env.yaml","path":"dev/us-east-1/mgmt/env.yaml","sha":"b514ab3187ebfb5bf467c632f27a21f5a9611bfc"},{"name":"openvpn-server","children":[{"name":"README.md","path":"dev/us-east-1/mgmt/openvpn-server/README.md","sha":"aa6f4262ab6e2e98c4cc2bb76e0f53953dbefc86"},{"name":"terragrunt.hcl","path":"dev/us-east-1/mgmt/openvpn-server/terragrunt.hcl","sha":"c9373ed801250a4a3f727b77bb7ef026738226ac"}]},{"name":"vpc","children":[{"name":"README.md","path":"dev/us-east-1/mgmt/vpc/README.md","sha":"758f74748caa3cabf6230c214784445e0c1f7c97"},{"name":"terragrunt.hcl","path":"dev/us-east-1/mgmt/vpc/terragrunt.hcl","sha":"20f97f225446751b79f2283837d0d9d225ea3833"}]}]},{"name":"region.yaml","path":"dev/us-east-1/region.yaml","sha":"d56afa3d82e6cea0d792e84748de56dafb0bad70"}]}]},{"name":"master","children":[{"name":"_global","children":[{"name":"README.md","path":"master/_global/README.md","sha":"d1b8a96c00211751f079fa13cac1b3417d29bf09"},{"name":"cloudtrail","children":[{"name":"README.md","path":"master/_global/cloudtrail/README.md","sha":"65aac5742b3dc183d11a7d83a31ae69afe5df2e5"},{"name":"terragrunt.hcl","path":"master/_global/cloudtrail/terragrunt.hcl","sha":"fb19b4438de2ba919d17f3e4a6ccb3c9f2517f26"}]},{"name":"iam-cross-account","children":[{"name":"README.md","path":"master/_global/iam-cross-account/README.md","sha":"6bf06985be74cf68085a78728c41cf88fc354141"},{"name":"terragrunt.hcl","path":"master/_global/iam-cross-account/terragrunt.hcl","sha":"0f540eaa0fa2fddb3c7afdead9cd4d4b71e77b11"}]},{"name":"iam-user-password-policy","children":[{"name":"README.md","path":"master/_global/iam-user-password-policy/README.md","sha":"d3240490ed6005924706f6dd8a1718747ebcd8d9"},{"name":"terragrunt.hcl","path":"master/_global/iam-user-password-policy/terragrunt.hcl","sha":"47b669ba52099812a6d52ed4fcdad48c5e32e91e"}]},{"name":"region.yaml","path":"master/_global/region.yaml","sha":"18b7823ed017b97431d58da7bcb9a4e31299272a"}]},{"name":"empty.yaml","path":"master/empty.yaml","sha":"5aa66daa40faeaef37eccb7b4b0fcc792233cd7b"},{"name":"terragrunt.hcl","path":"master/terragrunt.hcl","sha":"5d9ca2068ff75ac0532e01f3ec52b4051e419053"},{"name":"us-east-1","children":[{"name":"_global","children":[{"name":"README.md","path":"master/us-east-1/_global/README.md","sha":"37b828b038945a50e2e571ef1e755c4f9170e7cf"}]},{"name":"region.yaml","path":"master/us-east-1/region.yaml","sha":"d56afa3d82e6cea0d792e84748de56dafb0bad70"}]}]},{"name":"prod","children":[{"name":"_global","children":[{"name":"README.md","path":"prod/_global/README.md","sha":"d1b8a96c00211751f079fa13cac1b3417d29bf09"},{"name":"cloudtrail","children":[{"name":"README.md","path":"prod/_global/cloudtrail/README.md","sha":"65aac5742b3dc183d11a7d83a31ae69afe5df2e5"},{"name":"terragrunt.hcl","path":"prod/_global/cloudtrail/terragrunt.hcl","sha":"fb19b4438de2ba919d17f3e4a6ccb3c9f2517f26"}]},{"name":"iam-cross-account","children":[{"name":"README.md","path":"prod/_global/iam-cross-account/README.md","sha":"6bf06985be74cf68085a78728c41cf88fc354141"},{"name":"terragrunt.hcl","path":"prod/_global/iam-cross-account/terragrunt.hcl","sha":"96f6b058d3db5871b45cd9e9c05d2387f7fa8340"}]},{"name":"iam-user-password-policy","children":[{"name":"README.md","path":"prod/_global/iam-user-password-policy/README.md","sha":"d3240490ed6005924706f6dd8a1718747ebcd8d9"},{"name":"terragrunt.hcl","path":"prod/_global/iam-user-password-policy/terragrunt.hcl","sha":"47b669ba52099812a6d52ed4fcdad48c5e32e91e"}]},{"name":"region.yaml","path":"prod/_global/region.yaml","sha":"18b7823ed017b97431d58da7bcb9a4e31299272a"},{"name":"route53-public","children":[{"name":"README.md","path":"prod/_global/route53-public/README.md","sha":"69a24d1bb0eff2a66ca9be44c0dfc864f7086960"},{"name":"terragrunt.hcl","path":"prod/_global/route53-public/terragrunt.hcl","sha":"68ed9958a62546160f9007660857c5baa95ce12b"}]}]},{"name":"empty.yaml","path":"prod/empty.yaml","sha":"5aa66daa40faeaef37eccb7b4b0fcc792233cd7b"},{"name":"terragrunt.hcl","path":"prod/terragrunt.hcl","sha":"ba18847c5969b30159af5c87a05655d3e7dc7eb8"},{"name":"us-east-1","children":[{"name":"_global","children":[{"name":"README.md","path":"prod/us-east-1/_global/README.md","sha":"37b828b038945a50e2e571ef1e755c4f9170e7cf"},{"name":"kms-master-key","children":[{"name":"README.md","path":"prod/us-east-1/_global/kms-master-key/README.md","sha":"2de4ac69670b2bf16a3da13f4bff76b5b85891b7"},{"name":"terragrunt.hcl","path":"prod/us-east-1/_global/kms-master-key/terragrunt.hcl","sha":"5e19caaa42e506f2797048979d773f2fac5bce8a"}]},{"name":"sns-topics","children":[{"name":"README.md","path":"prod/us-east-1/_global/sns-topics/README.md","sha":"7926797c3094f0e708bd761d297589bd94be873e"},{"name":"terragrunt.hcl","path":"prod/us-east-1/_global/sns-topics/terragrunt.hcl","sha":"225cf4b3fe49af57c85a1e25b7942c72cf9e6853"}]}]},{"name":"mgmt","children":[{"name":"README.md","path":"prod/us-east-1/mgmt/README.md","sha":"8a131a11632b97fec18a5e344d5c721fce24b652"},{"name":"env.yaml","path":"prod/us-east-1/mgmt/env.yaml","sha":"b514ab3187ebfb5bf467c632f27a21f5a9611bfc"},{"name":"openvpn-server","children":[{"name":"README.md","path":"prod/us-east-1/mgmt/openvpn-server/README.md","sha":"271cbe2b6f59de9ce438ed4516393fd01d64b072"},{"name":"terragrunt.hcl","path":"prod/us-east-1/mgmt/openvpn-server/terragrunt.hcl","sha":"00af46905196d2216ca0e7d7e2767a86900514ea"}]},{"name":"vpc","children":[{"name":"README.md","path":"prod/us-east-1/mgmt/vpc/README.md","sha":"758f74748caa3cabf6230c214784445e0c1f7c97"},{"name":"terragrunt.hcl","path":"prod/us-east-1/mgmt/vpc/terragrunt.hcl","sha":"a3dbfb5bb3b55e6fcf452338c69e2fdab5aa6204"}]}]},{"name":"prod","children":[{"name":"README.md","path":"prod/us-east-1/prod/README.md","sha":"f15da18661ef3624d5f63deb288bad072e93df57"},{"name":"cloudwatch-dashboard","children":[{"name":"README.md","path":"prod/us-east-1/prod/cloudwatch-dashboard/README.md","sha":"01e60cd5e9f63892e09b1d7edfa7bea8fd7d0a3d"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/cloudwatch-dashboard/terragrunt.hcl","sha":"fe0a59a0885dd19898acfd6b65b290e5b6bf279c"}]},{"name":"data-stores","children":[{"name":"elk-multi-cluster","children":[{"name":"README.md","path":"prod/us-east-1/prod/data-stores/elk-multi-cluster/README.md","sha":"b59860709b8ef7bc7746c0bd9e9a1a21d02142c8"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/data-stores/elk-multi-cluster/terragrunt.hcl","sha":"ad3c96134476a81696c73807021c875283c3dfd1"}]},{"name":"kafka","children":[{"name":"README.md","path":"prod/us-east-1/prod/data-stores/kafka/README.md","sha":"72582bdb047da4f8820f45716977d5b962c17028"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/data-stores/kafka/terragrunt.hcl","sha":"c9e85c9678126c48a4cd6fc16cc55d523194b4d8"}]},{"name":"mysql","children":[{"name":"README.md","path":"prod/us-east-1/prod/data-stores/mysql/README.md","sha":"625773572c620dcddf722d0d0d206576f57f4af7"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/data-stores/mysql/terragrunt.hcl","sha":"e88eea81774f2ff43c6ba0f4929593b2adf80e20"}]},{"name":"redis","children":[{"name":"README.md","path":"prod/us-east-1/prod/data-stores/redis/README.md","sha":"5d82990da39b55e6ac7b3bbb442d4209e62dba1f"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/data-stores/redis/terragrunt.hcl","sha":"2ab5abad0edb89d10ffebb7c279a94b5e344bce6"}]},{"name":"zookeeper","children":[{"name":"README.md","path":"prod/us-east-1/prod/data-stores/zookeeper/README.md","sha":"87b4dda769ae63cffa851b6ccf2086b617bf989d"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/data-stores/zookeeper/terragrunt.hcl","sha":"e04f530614ac4913a702c2a18e38b4fa5a1f7848"}]}]},{"name":"env.yaml","path":"prod/us-east-1/prod/env.yaml","sha":"90e2d18e481b6e35ddc57391f752874ffc0058cf"},{"name":"lambda","children":[{"name":"long-running-scheduled","children":[{"name":"README.md","path":"prod/us-east-1/prod/lambda/long-running-scheduled/README.md","sha":"274c405a65d60c6a253ca2cf24863e1025402874"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/lambda/long-running-scheduled/terragrunt.hcl","sha":"72518b7089bd107c05c281372f3cccd6d7a6a628"}]},{"name":"s3-image-processing","children":[{"name":"README.md","path":"prod/us-east-1/prod/lambda/s3-image-processing/README.md","sha":"d7e48256e90edb0896769e4bd537c22e34c42f22"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/lambda/s3-image-processing/terragrunt.hcl","sha":"87d070e374ab2b7a6860167650e26c0fc73b486a"}]}]},{"name":"networking","children":[{"name":"alb-internal","children":[{"name":"README.md","path":"prod/us-east-1/prod/networking/alb-internal/README.md","sha":"21e850d1bbe25ca3b16114b8f58d08086a687916"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/networking/alb-internal/terragrunt.hcl","sha":"cc5feacf99eebd2cd695507d9169037599c763e5"}]},{"name":"alb-public","children":[{"name":"README.md","path":"prod/us-east-1/prod/networking/alb-public/README.md","sha":"21e850d1bbe25ca3b16114b8f58d08086a687916"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/networking/alb-public/terragrunt.hcl","sha":"03af1d8d3f8a860dc443addbf610f5934f7869eb"}]},{"name":"route53-private","children":[{"name":"README.md","path":"prod/us-east-1/prod/networking/route53-private/README.md","sha":"c93f222ed15cae75ec411a4b005ad4da32548c42"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/networking/route53-private/terragrunt.hcl","sha":"f7e7c4b437c11b0340c682314deb9b08aca3a854"}]}]},{"name":"services","children":[{"name":"ecs-cluster","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/ecs-cluster/README.md","sha":"d9e015edbbcd8f9e200fb00a5dde7fc7f466cd3c"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/ecs-cluster/terragrunt.hcl","sha":"b0eef93fabce97dfe098d6e18677fd3b1839d009"}]},{"name":"eks-cluster","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/eks-cluster/README.md","sha":"239bc9a333f256845a90c786c00cd6789000bd9d"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/eks-cluster/terragrunt.hcl","sha":"6cd702f65352efa6710f63842666cd214b9e4109"}]},{"name":"eks-core-services","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/eks-core-services/README.md","sha":"66fbf40d9982d63707eb1e7c60d78bc4aa659a0b"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/eks-core-services/terragrunt.hcl","sha":"3ba3473cbb4c7cd83fb23f3fa18ca624bc9de5aa"}]},{"name":"k8s-applications-namespace","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/k8s-applications-namespace/README.md","sha":"39887806598180d75b0b0b0a46ea4418d75af8f1"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/k8s-applications-namespace/terragrunt.hcl","sha":"c9d638ac7e6367e974db2dbdf2ffc8f17473fb91"}]},{"name":"k8s-sample-app-backend-multi-account-acme","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/k8s-sample-app-backend-multi-account-acme/README.md","sha":"b7524c6453a2e3bf441c953de7236ab6273e2c0f"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/k8s-sample-app-backend-multi-account-acme/terragrunt.hcl","sha":"e8b8df48ed310a08be55d5d3d07af9dc20fe7c12"}]},{"name":"k8s-sample-app-frontend-multi-account-acme","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/k8s-sample-app-frontend-multi-account-acme/README.md","sha":"17ee9c75e9fdea8d4295ad45f2fb8a46d9241e47"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/k8s-sample-app-frontend-multi-account-acme/terragrunt.hcl","sha":"cab54c75aa28d2d0a1df465e3e4272fc7a154adb"}]},{"name":"sample-app-backend-multi-account-acme-asg","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/sample-app-backend-multi-account-acme-asg/README.md","sha":"b848e55fea0f16a9b7ccf9c1366c6b56c9966a7a"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/sample-app-backend-multi-account-acme-asg/terragrunt.hcl","sha":"3bc70a7302b813667b0d9b9a19d888ce7a53e711"}]},{"name":"sample-app-backend-multi-account-acme","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/sample-app-backend-multi-account-acme/README.md","sha":"f0910e01d79209f26d65fdb1e6de428fa26f9eb6"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/sample-app-backend-multi-account-acme/terragrunt.hcl","sha":"f6f9ecf019df9635b4a68f42816d37f1ef4722c3"}]},{"name":"sample-app-beanstalk","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/sample-app-beanstalk/README.md","sha":"a6f2e03ce14753bb39e48fbf350c4aeb3aa3e6c9"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/sample-app-beanstalk/terragrunt.hcl","sha":"aa974300d961214d4a76f729b87e3d6d1dc90107"}]},{"name":"sample-app-frontend-multi-account-acme-asg","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/sample-app-frontend-multi-account-acme-asg/README.md","sha":"a5291ba90a48e7087a2fa7e24f41f1e4f4d43a79"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/sample-app-frontend-multi-account-acme-asg/terragrunt.hcl","sha":"c7cdbcf4cc8effe73a0130cf07a7f5da8cca0f23"}]},{"name":"sample-app-frontend-multi-account-acme","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/sample-app-frontend-multi-account-acme/README.md","sha":"691ef675dbcdb807391b0e2b8547c9f260cc12c6"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/sample-app-frontend-multi-account-acme/terragrunt.hcl","sha":"f0137a766733b3575863a74230dfc92ec0c94cd0"}]},{"name":"static-website","children":[{"name":"README.md","path":"prod/us-east-1/prod/services/static-website/README.md","sha":"c39ed7c607eb4d1313ea3892768bad09e7f39fd9"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/services/static-website/terragrunt.hcl","sha":"d5879453a53db71287dad837ed32e7d9b59d120e"}]}]},{"name":"vpc","children":[{"name":"README.md","path":"prod/us-east-1/prod/vpc/README.md","sha":"934095e18b4fcdb217ba8a0192c2c65e6fafb989"},{"name":"terragrunt.hcl","path":"prod/us-east-1/prod/vpc/terragrunt.hcl","sha":"521968dd6fb563a01f26d8b4662fbf4624cd21a0"}]}]},{"name":"region.yaml","path":"prod/us-east-1/region.yaml","sha":"d56afa3d82e6cea0d792e84748de56dafb0bad70"}]}]},{"name":"security","children":[{"name":"_global","children":[{"name":"README.md","path":"security/_global/README.md","sha":"d1b8a96c00211751f079fa13cac1b3417d29bf09"},{"name":"cloudtrail","children":[{"name":"README.md","path":"security/_global/cloudtrail/README.md","sha":"65aac5742b3dc183d11a7d83a31ae69afe5df2e5"},{"name":"terragrunt.hcl","path":"security/_global/cloudtrail/terragrunt.hcl","sha":"880d875fa813a2ec594b9a8ef15eb431bf540fa4"}]},{"name":"iam-cross-account","children":[{"name":"README.md","path":"security/_global/iam-cross-account/README.md","sha":"6bf06985be74cf68085a78728c41cf88fc354141"},{"name":"terragrunt.hcl","path":"security/_global/iam-cross-account/terragrunt.hcl","sha":"fef1fc1992f71bf1e0707301a038457d70ec918c"}]},{"name":"iam-groups","children":[{"name":"README.md","path":"security/_global/iam-groups/README.md","sha":"93a0e35d82a328def8047539ce7d987ab062d292"},{"name":"terragrunt.hcl","path":"security/_global/iam-groups/terragrunt.hcl","sha":"d1398a63fe6180c591186343e390e4ca1ab45085"}]},{"name":"iam-user-password-policy","children":[{"name":"README.md","path":"security/_global/iam-user-password-policy/README.md","sha":"d3240490ed6005924706f6dd8a1718747ebcd8d9"},{"name":"terragrunt.hcl","path":"security/_global/iam-user-password-policy/terragrunt.hcl","sha":"47b669ba52099812a6d52ed4fcdad48c5e32e91e"}]},{"name":"region.yaml","path":"security/_global/region.yaml","sha":"18b7823ed017b97431d58da7bcb9a4e31299272a"}]},{"name":"empty.yaml","path":"security/empty.yaml","sha":"5aa66daa40faeaef37eccb7b4b0fcc792233cd7b"},{"name":"terragrunt.hcl","path":"security/terragrunt.hcl","sha":"6cb54cf9410ee6cec86c946669e5cbe8348e7e5b"}]},{"name":"shared-services","children":[{"name":"_global","children":[{"name":"README.md","path":"shared-services/_global/README.md","sha":"d1b8a96c00211751f079fa13cac1b3417d29bf09"},{"name":"cloudtrail","children":[{"name":"README.md","path":"shared-services/_global/cloudtrail/README.md","sha":"65aac5742b3dc183d11a7d83a31ae69afe5df2e5"},{"name":"terragrunt.hcl","path":"shared-services/_global/cloudtrail/terragrunt.hcl","sha":"fb19b4438de2ba919d17f3e4a6ccb3c9f2517f26"}]},{"name":"iam-cross-account","children":[{"name":"README.md","path":"shared-services/_global/iam-cross-account/README.md","sha":"6bf06985be74cf68085a78728c41cf88fc354141"},{"name":"terragrunt.hcl","path":"shared-services/_global/iam-cross-account/terragrunt.hcl","sha":"0f540eaa0fa2fddb3c7afdead9cd4d4b71e77b11"}]},{"name":"iam-user-password-policy","children":[{"name":"README.md","path":"shared-services/_global/iam-user-password-policy/README.md","sha":"d3240490ed6005924706f6dd8a1718747ebcd8d9"},{"name":"terragrunt.hcl","path":"shared-services/_global/iam-user-password-policy/terragrunt.hcl","sha":"47b669ba52099812a6d52ed4fcdad48c5e32e91e"}]},{"name":"region.yaml","path":"shared-services/_global/region.yaml","sha":"18b7823ed017b97431d58da7bcb9a4e31299272a"},{"name":"route53-public","children":[{"name":"README.md","path":"shared-services/_global/route53-public/README.md","sha":"69a24d1bb0eff2a66ca9be44c0dfc864f7086960"},{"name":"terragrunt.hcl","path":"shared-services/_global/route53-public/terragrunt.hcl","sha":"68ed9958a62546160f9007660857c5baa95ce12b"}]}]},{"name":"empty.yaml","path":"shared-services/empty.yaml","sha":"5aa66daa40faeaef37eccb7b4b0fcc792233cd7b"},{"name":"terragrunt.hcl","path":"shared-services/terragrunt.hcl","sha":"69470dec0813da115863dbffed34fe6f1ecc3c8e"},{"name":"us-east-1","children":[{"name":"_global","children":[{"name":"README.md","path":"shared-services/us-east-1/_global/README.md","sha":"37b828b038945a50e2e571ef1e755c4f9170e7cf"},{"name":"ecr-repos","children":[{"name":"README.md","path":"shared-services/us-east-1/_global/ecr-repos/README.md","sha":"050f270033456c0a3285056f41a4427ec4ca1db1"},{"name":"terragrunt.hcl","path":"shared-services/us-east-1/_global/ecr-repos/terragrunt.hcl","sha":"0aebd1fe76c536af522f7af783dae529637f5a2b"}]},{"name":"kms-master-key","children":[{"name":"README.md","path":"shared-services/us-east-1/_global/kms-master-key/README.md","sha":"8923e2581297b44e53b3a50b23505b7e0bf85f9e"},{"name":"terragrunt.hcl","path":"shared-services/us-east-1/_global/kms-master-key/terragrunt.hcl","sha":"e3d3456c830e33007018dfa0444e1bb20950e327"}]},{"name":"sns-topics","children":[{"name":"README.md","path":"shared-services/us-east-1/_global/sns-topics/README.md","sha":"7926797c3094f0e708bd761d297589bd94be873e"},{"name":"terragrunt.hcl","path":"shared-services/us-east-1/_global/sns-topics/terragrunt.hcl","sha":"225cf4b3fe49af57c85a1e25b7942c72cf9e6853"}]}]},{"name":"mgmt","children":[{"name":"README.md","path":"shared-services/us-east-1/mgmt/README.md","sha":"8a131a11632b97fec18a5e344d5c721fce24b652"},{"name":"env.yaml","path":"shared-services/us-east-1/mgmt/env.yaml","sha":"b514ab3187ebfb5bf467c632f27a21f5a9611bfc"},{"name":"jenkins","children":[{"name":"README.md","path":"shared-services/us-east-1/mgmt/jenkins/README.md","sha":"c67253232ed9a8a685ca1659c887ae60416f2998"},{"name":"terragrunt.hcl","path":"shared-services/us-east-1/mgmt/jenkins/terragrunt.hcl","sha":"f75d4c6b36c07a20f69863e69e41b2902658fd47"}]},{"name":"openvpn-server","children":[{"name":"README.md","path":"shared-services/us-east-1/mgmt/openvpn-server/README.md","sha":"523ded2b928a312657e689db78730315ad66633b"},{"name":"terragrunt.hcl","path":"shared-services/us-east-1/mgmt/openvpn-server/terragrunt.hcl","sha":"c4f4e0a9021527bf53fe18a62814ca30ce726649"}]},{"name":"vpc","children":[{"name":"README.md","path":"shared-services/us-east-1/mgmt/vpc/README.md","sha":"758f74748caa3cabf6230c214784445e0c1f7c97"},{"name":"terragrunt.hcl","path":"shared-services/us-east-1/mgmt/vpc/terragrunt.hcl","sha":"29ff68537a532e119786f868bb2a709839792e90"}]}]},{"name":"region.yaml","path":"shared-services/us-east-1/region.yaml","sha":"d56afa3d82e6cea0d792e84748de56dafb0bad70"}]}]},{"name":"stage","children":[{"name":"_global","children":[{"name":"README.md","path":"stage/_global/README.md","sha":"d1b8a96c00211751f079fa13cac1b3417d29bf09"},{"name":"cloudtrail","children":[{"name":"README.md","path":"stage/_global/cloudtrail/README.md","sha":"65aac5742b3dc183d11a7d83a31ae69afe5df2e5"},{"name":"terragrunt.hcl","path":"stage/_global/cloudtrail/terragrunt.hcl","sha":"fb19b4438de2ba919d17f3e4a6ccb3c9f2517f26"}]},{"name":"iam-cross-account","children":[{"name":"README.md","path":"stage/_global/iam-cross-account/README.md","sha":"6bf06985be74cf68085a78728c41cf88fc354141"},{"name":"terragrunt.hcl","path":"stage/_global/iam-cross-account/terragrunt.hcl","sha":"96f6b058d3db5871b45cd9e9c05d2387f7fa8340"}]},{"name":"iam-user-password-policy","children":[{"name":"README.md","path":"stage/_global/iam-user-password-policy/README.md","sha":"d3240490ed6005924706f6dd8a1718747ebcd8d9"},{"name":"terragrunt.hcl","path":"stage/_global/iam-user-password-policy/terragrunt.hcl","sha":"47b669ba52099812a6d52ed4fcdad48c5e32e91e"}]},{"name":"region.yaml","path":"stage/_global/region.yaml","sha":"18b7823ed017b97431d58da7bcb9a4e31299272a"},{"name":"route53-public","children":[{"name":"README.md","path":"stage/_global/route53-public/README.md","sha":"69a24d1bb0eff2a66ca9be44c0dfc864f7086960"},{"name":"terragrunt.hcl","path":"stage/_global/route53-public/terragrunt.hcl","sha":"68ed9958a62546160f9007660857c5baa95ce12b"}]}]},{"name":"empty.yaml","path":"stage/empty.yaml","sha":"5aa66daa40faeaef37eccb7b4b0fcc792233cd7b"},{"name":"terragrunt.hcl","path":"stage/terragrunt.hcl","sha":"e2506d916b6362dfc1aa0192b71f388a72e79568"},{"name":"us-east-1","children":[{"name":"_global","children":[{"name":"README.md","path":"stage/us-east-1/_global/README.md","sha":"37b828b038945a50e2e571ef1e755c4f9170e7cf"},{"name":"kms-master-key","children":[{"name":"README.md","path":"stage/us-east-1/_global/kms-master-key/README.md","sha":"2ce8a7cdc4864091ba55cc930ad4e6f8dc29d535"},{"name":"terragrunt.hcl","path":"stage/us-east-1/_global/kms-master-key/terragrunt.hcl","sha":"c0c2f65c3cf60fc59e6646347d4458001a116e6b"}]},{"name":"sns-topics","children":[{"name":"README.md","path":"stage/us-east-1/_global/sns-topics/README.md","sha":"7926797c3094f0e708bd761d297589bd94be873e"},{"name":"terragrunt.hcl","path":"stage/us-east-1/_global/sns-topics/terragrunt.hcl","sha":"225cf4b3fe49af57c85a1e25b7942c72cf9e6853"}]}]},{"name":"mgmt","children":[{"name":"README.md","path":"stage/us-east-1/mgmt/README.md","sha":"8a131a11632b97fec18a5e344d5c721fce24b652"},{"name":"env.yaml","path":"stage/us-east-1/mgmt/env.yaml","sha":"b514ab3187ebfb5bf467c632f27a21f5a9611bfc"},{"name":"openvpn-server","children":[{"name":"README.md","path":"stage/us-east-1/mgmt/openvpn-server/README.md","sha":"5dcede127b26b8cfc2ed78cd1450ec7dd7d66d18"},{"name":"terragrunt.hcl","path":"stage/us-east-1/mgmt/openvpn-server/terragrunt.hcl","sha":"af54f724d3ee040688035af9ae0f41154a7dbc1c"}]},{"name":"vpc","children":[{"name":"README.md","path":"stage/us-east-1/mgmt/vpc/README.md","sha":"758f74748caa3cabf6230c214784445e0c1f7c97"},{"name":"terragrunt.hcl","path":"stage/us-east-1/mgmt/vpc/terragrunt.hcl","sha":"b2016650621679f7b9f99b93806cc0b8efb149ac"}]}]},{"name":"region.yaml","path":"stage/us-east-1/region.yaml","sha":"d56afa3d82e6cea0d792e84748de56dafb0bad70"},{"name":"stage","children":[{"name":"README.md","path":"stage/us-east-1/stage/README.md","sha":"b24ba21bf01baf19ff84a2de457697a757d905c5"},{"name":"cloudwatch-dashboard","children":[{"name":"README.md","path":"stage/us-east-1/stage/cloudwatch-dashboard/README.md","sha":"01e60cd5e9f63892e09b1d7edfa7bea8fd7d0a3d"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/cloudwatch-dashboard/terragrunt.hcl","sha":"01ed95b4b404eda346293dbe5eb78b9a74f2f5bb"}]},{"name":"data-stores","children":[{"name":"elk-single-cluster","children":[{"name":"README.md","path":"stage/us-east-1/stage/data-stores/elk-single-cluster/README.md","sha":"a90283b9240f67c38dd1bd77755a8162fa6f3999"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/data-stores/elk-single-cluster/terragrunt.hcl","sha":"7818782091e335360279369b391a3401703ddedd"}]},{"name":"kafka","children":[{"name":"README.md","path":"stage/us-east-1/stage/data-stores/kafka/README.md","sha":"72582bdb047da4f8820f45716977d5b962c17028"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/data-stores/kafka/terragrunt.hcl","sha":"26d778dddca07ead27d37e481a897659d7cec7d2"}]},{"name":"mysql","children":[{"name":"README.md","path":"stage/us-east-1/stage/data-stores/mysql/README.md","sha":"625773572c620dcddf722d0d0d206576f57f4af7"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/data-stores/mysql/terragrunt.hcl","sha":"35991621a16fb4cc8443fdf2695c23d3e658c5ac"}]},{"name":"redis","children":[{"name":"README.md","path":"stage/us-east-1/stage/data-stores/redis/README.md","sha":"5d82990da39b55e6ac7b3bbb442d4209e62dba1f"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/data-stores/redis/terragrunt.hcl","sha":"79ef1e07fde2d0dcb9673d653089da8fb3fa449a"}]},{"name":"zookeeper","children":[{"name":"README.md","path":"stage/us-east-1/stage/data-stores/zookeeper/README.md","sha":"87b4dda769ae63cffa851b6ccf2086b617bf989d"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/data-stores/zookeeper/terragrunt.hcl","sha":"045e1d8802b8b1dc93070a80d98da5b917dec655"}]}]},{"name":"env.yaml","path":"stage/us-east-1/stage/env.yaml","sha":"5767506e27e978f52524dadbbd8fb9f8ad115599"},{"name":"lambda","children":[{"name":"long-running-scheduled","children":[{"name":"README.md","path":"stage/us-east-1/stage/lambda/long-running-scheduled/README.md","sha":"274c405a65d60c6a253ca2cf24863e1025402874"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/lambda/long-running-scheduled/terragrunt.hcl","sha":"72518b7089bd107c05c281372f3cccd6d7a6a628"}]},{"name":"s3-image-processing","children":[{"name":"README.md","path":"stage/us-east-1/stage/lambda/s3-image-processing/README.md","sha":"d7e48256e90edb0896769e4bd537c22e34c42f22"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/lambda/s3-image-processing/terragrunt.hcl","sha":"02a23cc6f220d8301d40f7616d1e17f9e17448a5"}]}]},{"name":"networking","children":[{"name":"alb-internal","children":[{"name":"README.md","path":"stage/us-east-1/stage/networking/alb-internal/README.md","sha":"9ee564202c79754713107e2c3644c9cb3815922e"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/networking/alb-internal/terragrunt.hcl","sha":"9537dc7cb6dc7c9eb929a0b97a6f89025e042e57"}]},{"name":"alb-public","children":[{"name":"README.md","path":"stage/us-east-1/stage/networking/alb-public/README.md","sha":"9ee564202c79754713107e2c3644c9cb3815922e"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/networking/alb-public/terragrunt.hcl","sha":"8ea93d9b8dafad1fc2044a677dd9d0db8d768a55"}]},{"name":"route53-private","children":[{"name":"README.md","path":"stage/us-east-1/stage/networking/route53-private/README.md","sha":"c93f222ed15cae75ec411a4b005ad4da32548c42"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/networking/route53-private/terragrunt.hcl","sha":"f7e7c4b437c11b0340c682314deb9b08aca3a854"}]}]},{"name":"services","children":[{"name":"ecs-cluster","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/ecs-cluster/README.md","sha":"a4970def6876c873e8f722cbb4ff168d5b95d97d"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/ecs-cluster/terragrunt.hcl","sha":"a42cc57f67f8a9ee2bf5bfce1fb58ea96f5e48f5"}]},{"name":"eks-cluster","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/eks-cluster/README.md","sha":"3c63107a058eeb5b3118b4c569ee867c366c2762"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/eks-cluster/terragrunt.hcl","sha":"ec2a56580f4fbe9d5ea53b4a7bc0768a7ae90029"}]},{"name":"eks-core-services","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/eks-core-services/README.md","sha":"bdfb014e5d96aff7bfcb36d6b07bd20a30ddccf1"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/eks-core-services/terragrunt.hcl","sha":"4c1aecc3ec52837b98978ec6fc1cd8d5564763ae"}]},{"name":"k8s-applications-namespace","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/k8s-applications-namespace/README.md","sha":"41a7a39dea2f5278e9cc05d7c52eb0144fac15d1"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/k8s-applications-namespace/terragrunt.hcl","sha":"3665bac8be17e73ab034e2f32017c69ef209b2af"}]},{"name":"k8s-sample-app-backend-multi-account-acme","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/k8s-sample-app-backend-multi-account-acme/README.md","sha":"184f8a011d291db3558dbdbb0f9d8f0f12d5d888"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/k8s-sample-app-backend-multi-account-acme/terragrunt.hcl","sha":"9ea86835ea625bbc341b4d8cbfbcd9b954c4feb5"}]},{"name":"k8s-sample-app-frontend-multi-account-acme","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/k8s-sample-app-frontend-multi-account-acme/README.md","sha":"bf4f271d1b7d4e933a0919ee373289b03c9380fb"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/k8s-sample-app-frontend-multi-account-acme/terragrunt.hcl","sha":"b53766ca7b1cf18f27c115d086e3aebf697ee5f3"}]},{"name":"sample-app-backend-multi-account-acme-asg","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/sample-app-backend-multi-account-acme-asg/README.md","sha":"3b3779fb30149fb17d27b9d07ff46890645744b1"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/sample-app-backend-multi-account-acme-asg/terragrunt.hcl","sha":"2b1ddfe35699ecff6ee4e8c164ad4c9e00d224da"}]},{"name":"sample-app-backend-multi-account-acme","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/sample-app-backend-multi-account-acme/README.md","sha":"bc6fda688883bd02ec06de1dbf3abd0d7537970b"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/sample-app-backend-multi-account-acme/terragrunt.hcl","sha":"1dd22075941f49b593bc9bfb03f616ac8004a06d"}]},{"name":"sample-app-beanstalk","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/sample-app-beanstalk/README.md","sha":"ca960ca9cf3f71d783b3fd4478503e3bdbdb5690"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/sample-app-beanstalk/terragrunt.hcl","sha":"4360debb24de5f877a88782858260326f9d72dbd"}]},{"name":"sample-app-frontend-multi-account-acme-asg","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/sample-app-frontend-multi-account-acme-asg/README.md","sha":"ebd62ba824756666250d5a5c062c21a01a6a30cb"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/sample-app-frontend-multi-account-acme-asg/terragrunt.hcl","sha":"e0efa40fe276041d8bea4a543144a5591cfcead5"}]},{"name":"sample-app-frontend-multi-account-acme","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/sample-app-frontend-multi-account-acme/README.md","sha":"0ce40b08cc42cacd1d1b5652d7a98c07e3a17172"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/sample-app-frontend-multi-account-acme/terragrunt.hcl","sha":"2507d6e2e44be9e18a120c45b083b901f98a4cf9"}]},{"name":"static-website","children":[{"name":"README.md","path":"stage/us-east-1/stage/services/static-website/README.md","sha":"c39ed7c607eb4d1313ea3892768bad09e7f39fd9"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/services/static-website/terragrunt.hcl","sha":"5dcb8cc0d74456bfa9756c29cbc70118b7c894ed"}]}]},{"name":"vpc","children":[{"name":"README.md","path":"stage/us-east-1/stage/vpc/README.md","sha":"e037370db683520d7d593adddc2125ef3798d801"},{"name":"terragrunt.hcl","path":"stage/us-east-1/stage/vpc/terragrunt.hcl","sha":"96c7ebd950aea8d3e7d6767609e9419ef407db4f"}]}]}]}]}]},"detailsContent":"<h1 class=\"preview__body--title\" id=\"deploying-the-reference-architecture-from-scratch\">Deploying the Reference Architecture from scratch</h1><div class=\"preview__body--border\"></div><p>This document is a guide to how to deploy the entire Reference Architecture, or one of the environments in the\nReference Architecture (e.g., stage or prod), from scratch. This is useful if you want to know how to quickly set up\nand tear down environments.</p>\n<ol>\n<li><a href=\"#deployment-order\" class=\"preview__body--description--blue\">Deployment Order</a></li>\n<li><a href=\"#build-amis\" class=\"preview__body--description--blue\">Build AMIs</a></li>\n<li><a href=\"#build-docker-images\" class=\"preview__body--description--blue\">Build Docker images</a></li>\n<li><a href=\"#build-lambda-functions\" class=\"preview__body--description--blue\">Build lambda functions</a></li>\n<li><a href=\"#create-ec2-key-pairs\" class=\"preview__body--description--blue\">Create EC2 Key Pairs</a></li>\n<li><a href=\"#configure-terraform-backends\" class=\"preview__body--description--blue\">Configure Terraform backends</a></li>\n<li><a href=\"#configure-the-vpn-server\" class=\"preview__body--description--blue\">Configure the VPN server</a></li>\n<li><a href=\"#create-data-store-passwords\" class=\"preview__body--description--blue\">Create data store passwords</a></li>\n<li><a href=\"#import-route-53-hosted-zones\" class=\"preview__body--description--blue\">Import Route 53 hosted zones</a></li>\n<li><a href=\"#create-tls-certs\" class=\"preview__body--description--blue\">Create TLS certs</a></li>\n<li><a href=\"#create-an-iam-user-for-kms\" class=\"preview__body--description--blue\">Create an IAM User for KMS</a></li>\n<li><a href=\"#run-terragrunt\" class=\"preview__body--description--blue\">Run Terragrunt</a></li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"deployment-order\">Deployment Order</h2>\n<p>If you are deploying the entire Reference Architecture from scratch, then you should be aware of the various\ndependencies that exist between the accounts. In order to ensure that all the dependent resources exist, we recommend\ndeploying the accounts in the following order:</p>\n<ol>\n<li><code>security</code></li>\n<li><code>shared-services</code></li>\n<li><code>dev</code>, <code>stage</code>, and <code>prod</code>. These can be done in parallel.</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"build-am-is\">Build AMIs</h2>\n<p>All the EC2 Instances in the Reference Architecture (e.g., the ECS Cluster instances, the OpenVPN server, etc) run\n<a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html\" class=\"preview__body--description--blue\" target=\"_blank\">Amazon Machine Images (AMIs)</a> that are defined as code\nusing <a href=\"https://www.packer.io/\" class=\"preview__body--description--blue\" target=\"_blank\">Packer</a>. You will find the Packer templates (<code>.json</code> files) in the\n<code>infrastructure-modules-multi-account-acme</code> repo. You will also find that the corresponding Terraform modules (e.g, the <code>ecs-cluster</code>\nmodule) expect an <code>ami_id</code> parameter to be set in <code>terragrunt.hcl</code>.</p>\n<h2 class=\"preview__body--subtitle\" id=\"prerequisite-deploy-packer-build-vpc\">Prerequisite: Deploy Packer Build VPC</h2>\n<p>All the AMIs are built using an EC2 instance that is temporarily deployed into a VPC of the account and region\nthat owns the AMI. This selection of the VPC and Subnet is done using the tags <code>gruntwork.io/allow-packer=true</code>. You\nneed to ensure a VPC with a Public Subnet, created with the tag exists in the target region of the AMI account owner.</p>\n<p>The easiest way to do this would be to deploy a VPC using the <code>networking/vpc-mgmt</code> infrastructure module in the target\nregion. This module will properly tag the public subnets and the VPC for use with packer.</p>\n<h3 class=\"preview__body--subtitle\" id=\"running-packer\">Running Packer</h3>\n<ol>\n<li>Authenticate to the AWS account. See <a href=\"/repos/v0.0.1-01172020/infrastructure-live-multi-account-acme/_docs/09-accounts-and-auth.md\" class=\"preview__body--description--blue\">Accounts and Auth</a>.</li>\n<li>Run <code>packer build <PATH-TO-TEMPLATE></code>. E.g., <code>packer build infrastructure-modules-multi-account-acme/services/ecs-cluster/packer/ecs-node.json</code>.</li>\n<li>At the end of the build, Packer will output the new AMI ID. You can use this in the <code>ami_id</code> parameter of\n<code>terragrunt.hcl</code> files.</li>\n</ol>\n<h3 class=\"preview__body--subtitle\" id=\"am-is-and-aws-regions\">AMIs and AWS regions</h3>\n<p>Note that AMIs live in a specific AWS region, so if you're deploying to multiple regions, you will have to build AMIs\nfor each region separately. If this is a common task, you can specify multiple <code>builders</code> in the Packer template, one\nfor each region, and the builds will run in parallel.</p>\n<h3 class=\"preview__body--subtitle\" id=\"sharing-am-is-across-aws-accounts\">Sharing AMIs across AWS accounts</h3>\n<p>You can share AMIs across AWS accounts to avoid having to rebuild the same AMI over and over again. For example, you\ncould build the ECS AMI once in the shared-services account and deploy that same AMI in dev, stage, and prod. To enable\nthis, set the <code>ami_users</code> parameter to the IDs of the accounts that should have access to the AMI. For example, to\ngive accounts <code>11111111111</code> and <code>22222222222</code> access to an AMI:</p>\n<pre>{\n <span class=\"hljs-attr\">\"builders\"</span>: [{\n <span class=\"hljs-attr\">\"type\"</span>: <span class=\"hljs-string\">\"amazon_ebs\"</span>,\n <span class=\"hljs-attr\">\"ami_users\"</span>: [<span class=\"hljs-string\">\"11111111111\"</span>, <span class=\"hljs-string\">\"22222222222\"</span>]\n }]\n}\n</pre>\n<h3 class=\"preview__body--subtitle\" id=\"am-is-and-encryption\">AMIs and encryption</h3>\n<p>If you want to encrypt the root volume of your EC2 Instances (e.g., for end-to-end encryption and compliance purposes),\nyou will need to set the <code>encrypt_boot</code> parameter to true in the Packer template:</p>\n<pre>{\n <span class=\"hljs-attr\">\"builders\"</span>: [{\n <span class=\"hljs-attr\">\"type\"</span>: <span class=\"hljs-string\">\"amazon_ebs\"</span>,\n <span class=\"hljs-attr\">\"encrypt_boot\"</span>: <span class=\"hljs-literal\">true</span>\n }]\n}\n</pre>\n<p>Note that encrypted AMIs may <strong>NOT</strong> be shared with other AWS accounts!</p>\n<h2 class=\"preview__body--subtitle\" id=\"build-docker-images\">Build Docker images</h2>\n<p>If you're using Docker, the sample apps in the Reference Architecture will try to deploy Docker images. You will need\nto:</p>\n<ol>\n<li>Build the Docker images</li>\n<li>Tag them with a version number of some sort</li>\n<li>Push the images to your Docker Registry (typically <a href=\"https://aws.amazon.com/ecr/\" class=\"preview__body--description--blue\" target=\"_blank\">ECR</a>)</li>\n<li>Fill in the Docker image name and version number in the <code>terragrunt.hcl</code> files in <code>infrastructure-live-multi-account-acme</code></li>\n</ol>\n<p>The instructions for building, tagging, and pushing the Docker images are in the READMEs of the\n<a href=\"/repos/sample-app-frontend-multi-account-acme\" class=\"preview__body--description--blue\">sample-app-frontend-multi-account-acme</a> and\n<a href=\"/repos/sample-app-backend-multi-account-acme\" class=\"preview__body--description--blue\">sample-app-backend-multi-account-acme</a> repos.</p>\n<h2 class=\"preview__body--subtitle\" id=\"build-lambda-functions\">Build lambda functions</h2>\n<p>The Reference Architecture include several sample <a href=\"https://aws.amazon.com/lambda/\" class=\"preview__body--description--blue\" target=\"_blank\">Lambda functions</a> under\n<code>infrastructure-modules-multi-account-acme/lambda</code>. These show examples of how to use Lambda to perform various tasks without having to\nmanage any servers.</p>\n<p>One of the Lambda functions in <code>infrastructure-modules-multi-account-acme/lambda</code> requires an extra build step to create its\n<a href=\"https://docs.aws.amazon.com/lambda/latest/dg/deployment-package-v2.html\" class=\"preview__body--description--blue\" target=\"_blank\">deployment package</a> before you can deploy it:</p>\n<pre>./infrastructure-modules-multi-account-acme/lambda/<span class=\"hljs-keyword\">long</span>-<span class=\"hljs-built_in\">running</span>-scheduled/src/build.sh\n</pre>\n<p>At the end of that script, it will output the path of the resulting deployment package, plus instructions on how to use\nthis path, which will tell you to set an environment variable. Make sure to follow those instructions!</p>\n<h2 class=\"preview__body--subtitle\" id=\"create-ec-2-key-pairs\">Create EC2 Key Pairs</h2>\n<p>The Reference Architecture installs <a href=\"/repos/module-security/modules/ssh-grunt\" class=\"preview__body--description--blue\">ssh-grunt</a>\non every EC2 Instance so that each developer can use their own username and key to SSH to servers\n(see <a href=\"/repos/v0.0.1-01172020/infrastructure-live-multi-account-acme/_docs/08-ssh-vpn.md\" class=\"preview__body--description--blue\">SSH and VPN</a>). However, we still recommend associating an <a href=\"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-key-pairs.html\" class=\"preview__body--description--blue\" target=\"_blank\">EC2 Key\nPair</a> with your EC2 Instances as an emergency\nbackup, in case their is some sort of issue with <code>ssh-grunt</code>.</p>\n<p>We typically recommend creating at least 2 Key Pairs:</p>\n<ol>\n<li>For the OpenVPN server.</li>\n<li>For all other services.</li>\n</ol>\n<p>To create an EC2 Key Pair:</p>\n<ol>\n<li>Go to the <a href=\"https://console.aws.amazon.com/ec2/v2/home#KeyPairs:sort=keyName\" class=\"preview__body--description--blue\" target=\"_blank\">Key Pair section</a> of the EC2 Console.</li>\n<li>Click "Create Key Pair."</li>\n<li>Enter a name for the Key Pair.</li>\n<li>Save the Key Pair to disk. Do NOT share this Key Pair with anyone else; it's only for emergency backup!</li>\n<li>Add a passphrase to the Key Pair: <code>ssh-keygen -p -f <KEY_PAIR_PATH></code>.</li>\n<li>Change permissions on the Key Pair: <code>chmod 400 <KEY_PAIR_PATH></code>.</li>\n<li>Pass the Key Pair name to the appropriate parameter in <code>terragrunt.hcl</code> in <code>infrastructure-live-multi-account-acme</code>; typically, this\nparameter will be called <code>ssh_key_name</code>, <code>keypair_name</code>, or <code>cluster_instance_keypair_name</code>. Ensure you only use\nthe OpenVPN keypair for the OpenVPN server.</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"configure-terraform-backends\">Configure Terraform backends</h2>\n<p>The Reference Architecture uses an <a href=\"https://www.terraform.io/docs/backends/types/s3.html\" class=\"preview__body--description--blue\" target=\"_blank\">S3 backend</a> to store\n<a href=\"https://www.terraform.io/docs/state/\" class=\"preview__body--description--blue\" target=\"_blank\">Terraform State</a>. We also use DynamoDB for locking. We recommend storing the\nTerraform State for each AWS account in a separate S3 bucket and DynamoDB table. You will need to fill in the name and\nregion of the S3 bucket and DynamoDB table in two places in the top-level folder for that account in\n<code>infrastructure-live-multi-account-acme</code>:</p>\n<ol>\n<li><code>terragrunt.hcl</code></li>\n</ol>\n<p>When you run Terragrunt, if the S3 bucket or DynamoDB table don't already exist, they will be created automatically.</p>\n<h2 class=\"preview__body--subtitle\" id=\"configure-the-vpn-server\">Configure the VPN server</h2>\n<p>The Reference Architecture includes an <a href=\"https://openvpn.net/\" class=\"preview__body--description--blue\" target=\"_blank\">OpenVPN server</a>. The very first time you deploy the\nserver, it will create the <a href=\"https://en.wikipedia.org/wiki/Public_key_infrastructure\" class=\"preview__body--description--blue\" target=\"_blank\">Public Key Infrastructure (PKI)</a> it will\nuse to sign certificates. This process is very CPU intensive and, on <code>t2.micro</code> EC2 Instances, it can take <em>hours</em>, as\nit seems to exceed the burst balance almost immediately.</p>\n<p>To avoid this, we recommend initially deploying the OpenVPN server with a larger instance (<code>t2.medium</code> can generate the\nPKI in 1-2 minutes). Once the PKI has been generated, you can downgrade to a smaller instance again to save money.</p>\n<h2 class=\"preview__body--subtitle\" id=\"create-data-store-passwords\">Create data store passwords</h2>\n<p>Some of the data stores used in the Reference Architecture, such as <a href=\"https://aws.amazon.com/rds/\" class=\"preview__body--description--blue\" target=\"_blank\">RDS databases</a>,\nrequire that you set a password in the Terraform code. We do NOT recommend putting that password, in plaintext,\ndirectly in the code. Instead, we recommend:</p>\n<ol>\n<li>\n<p>Create a long, strong, random password. Preferably 30+ characters.</p>\n</li>\n<li>\n<p>Store the password in a secure secrets manager.</p>\n</li>\n<li>\n<p>Every time you go to deploy the data store, set the password as an environment variable that Terraform can find\n(see <a href=\"https://www.terraform.io/docs/configuration/variables.html#environment-variables\" class=\"preview__body--description--blue\" target=\"_blank\">Terraform environment variables</a>).\nFor example, for RDS DBs, you typically set the <code>TF_VAR_master_password</code> environment variable:</p>\n<pre><span class=\"hljs-builtin-name\">export</span> TF_VAR_master_password=(<span class=\"hljs-built_in\">..</span>.)\n</pre>\n</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"import-route-53-hosted-zones\">Import Route 53 hosted zones</h2>\n<p>The Reference Architecture configures DNS entries using <a href=\"https://aws.amazon.com/route53/\" class=\"preview__body--description--blue\" target=\"_blank\">Route 53</a>. Each domain name\nwill live in a <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/AboutHZWorkingWith.html\" class=\"preview__body--description--blue\" target=\"_blank\">Public Hosted Zone</a>\nthat is either created automatically if you bought a domain name through Route 53, or manually if you are using Route\n53 to manage DNS for a domain name bought externally.</p>\n<p>If the Public Hosted Zone already exists, you will need to use the <a href=\"https://www.terraform.io/docs/import/index.html\" class=\"preview__body--description--blue\" target=\"_blank\">import\ncommand</a> to put it under Terraform control. Go to the <code>route53-public</code>\nmodule in <code>infrastructure-live-multi-account-acme</code> for the account you're deploying and run:</p>\n<pre><span class=\"hljs-title\">terragrunt</span> <span class=\"hljs-keyword\">import</span> aws_route53_zone.primary_domain <HOSTED_ZONE_ID>\n</pre>\n<p>Where <code>HOSTED_ZONE_ID</code> is the primary ID of your Hosted Zone, which you can find in the AWS Console (it typically looks\nsomething like <code>Z1AB1Z2CDE3FG4</code>).</p>\n<h2 class=\"preview__body--subtitle\" id=\"create-an-iam-user-for-kms\">Create an IAM User for KMS</h2>\n<p>The Reference Architecture uses <a href=\"https://aws.amazon.com/kms/\" class=\"preview__body--description--blue\" target=\"_blank\">KMS</a> to encrypt and decrypt secrets. When you create a\nnew <a href=\"https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html\" class=\"preview__body--description--blue\" target=\"_blank\">Customer Master Key (CMK)</a> in KMS, you must\nassign at least one IAM User as an "administrator" for the CMK. If there are no admins, then the CMK—and any secrets\nencrypted with it—may become completely inaccessible!</p>\n<p>Therefore, you will need to create an IAM User, either in the same AWS account (for single-account deploymens) or in\nthe security account (for multi-account deployments), and provide that IAM Users ARN to the\n<code>cmk_administrator_iam_arns</code> parameter of the <code>kms-master-key</code> module.</p>\n<h2 class=\"preview__body--subtitle\" id=\"create-tls-certs\">Create TLS certs</h2>\n<h3 class=\"preview__body--subtitle\" id=\"public-facing-tls-certs\">Public-facing TLS certs</h3>\n<p>The Reference Architecture will automatically use TLS certs from the <a href=\"https://aws.amazon.com/certificate-manager/\" class=\"preview__body--description--blue\" target=\"_blank\">AWS Certificate Manager\n(ACM)</a> with each of your public load balancers (<code>networking/alb-public</code> in\n<code>infrastructure-live-multi-account-acme</code>) and CloudFront distributions (<code>services/static-website</code> in <code>infrastructure-live-multi-account-acme</code>). If you are\ndeploying with totally new domain names, you will need to:</p>\n<ol>\n<li><a href=\"https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html\" class=\"preview__body--description--blue\" target=\"_blank\">Request a certificate from ACM</a> for the\nAWS region(s) you are deploying to. The Terraform modules in the Reference Architecture typically look for a\nwildcard certificate of the format <code>*.<your-domain-name></code> (e.g., <code>*.acme.com</code>), so make sure to request a wildcard\ncertificate. If you don't want to use wild card certs, update the code in <code>infrastructure-live-multi-account-acme</code> and\n<code>infrastructure-modules-multi-account-acme</code> accordingly.</li>\n<li>If this is a certificate for a domain name managed in Route 53, we recommend <a href=\"https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-validate-dns.html\" class=\"preview__body--description--blue\" target=\"_blank\">using DNS to validate domain\nownership</a>, as it only takes a couple\nclicks.</li>\n<li>If you are using CloudFront, you <strong>must</strong> also request a certificate for <code>us-east-1</code>, no matter what region you are\ndeploying too. See the <a href=\"/repos/package-static-assets/modules/s3-cloudfront\" class=\"preview__body--description--blue\">cloudfront module</a>\nfor more info.</li>\n</ol>\n<h3 class=\"preview__body--subtitle\" id=\"self-signed-tls-certs-for-your-apps\">Self-signed TLS certs for your apps</h3>\n<p>If you want to use end-to-end encryption, you will need to generate self-signed TLS certs for your apps so that other\napps or the load balancer can send traffic to them over TLS. If you are unfamiliar with how TLS certificates work,\nstart with the <a href=\"/repos/module-security/modules/tls-cert-private#background\" class=\"preview__body--description--blue\">Background\ndocumentation</a>.</p>\n<p>There are many ways to generate a certificate and use it with your apps, but the easiest option is:</p>\n<ol>\n<li>\n<p>Use the <code>create-tls-cert.sh</code> script provided in <a href=\"/repos/infrastructure-modules-multi-account-acme/tls-scripts/create-tls-cert.sh\" class=\"preview__body--description--blue\">infrastructure-modules-multi-account-acme</a>.\nThis script will automatically create a CA cert and a TLS cert signed by that CA, and encrypt the private key using\n<a href=\"/repos/gruntkms\" class=\"preview__body--description--blue\">gruntkms</a> with the KMS master key for the appropriate environment.</p>\n</li>\n<li>\n<p>Package the public and encrypted private key of the TLS cert with the app (e.g., update your <code>Dockerfile</code> or Packer\ntemplate to package the TLS cert). You can take a look at <a href=\"/repos/sample-app-backend-multi-account-acme\" class=\"preview__body--description--blue\">sample-app-backend-multi-account-acme</a>\nfor an example of how to package the certificates.</p>\n</li>\n<li>\n<p>Use <code>gruntkms</code> to decrypt the private key just before the app boots (the <code>run-app.sh</code> script already does this).</p>\n</li>\n<li>\n<p>During boot, configure your app to load the public and private key of the TLS cert and listen for TLS connections.\nHow you do this is app-specific.</p>\n</li>\n<li>\n<p>If you have other apps that are going to talk to your app directly (e.g., via service discovery), distribute the\npublic key of the CA to those apps so they can validate your app's cert.</p>\n</li>\n</ol>\n<h3 class=\"preview__body--subtitle\" id=\"self-signed-tls-certs-for-your-internal-load-balancers\">Self-signed TLS certs for your internal load balancers</h3>\n<p>If you want to use end-to-end encryption, you will need to generate self-signed TLS certs for your internal load\nbalancers so that your apps can send requests to those load balancers over TLS. If you are unfamiliar with how TLS\ncertificates work, start with the <a href=\"/repos/module-security/modules/tls-cert-private#background\" class=\"preview__body--description--blue\">Background\ndocumentation</a>.</p>\n<p>There are many ways to generate a certificate and use it with a load balancer, but the easiest option is:</p>\n<ol>\n<li>\n<p>Use the <a href=\"/repos/terraform-aws-vault/modules/private-tls-cert\" class=\"preview__body--description--blue\">private-tls-cert module</a>\nto generate the certificates. Configure the TLS cert with a domain name you are going to be using for your load\nbalancer (see the next steps for how this domain name will work). This should give you back a public and private key\nfor the TLS certificate and a public key for the CA.</p>\n</li>\n<li>\n<p>Create an internal domain name (e.g., <code>acme-multi-account.internal</code>) using <a href=\"https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-private.html\" class=\"preview__body--description--blue\" target=\"_blank\">Route 53 Private\nHosted Zones</a>. This domain name\nshould match the one in the TLS certificate you created. See <code>networking/route53-private</code> in\n<code>infrastructure-live-multi-account-acme</code>.</p>\n</li>\n<li>\n<p>Import your certificate into the AWS Certificate Manager (ACM). One way to do this is with the <code>aws</code> CLI\n<a href=\"https://docs.aws.amazon.com/cli/latest/reference/acm/import-certificate.html\" class=\"preview__body--description--blue\" target=\"_blank\">import-certificate command</a>, passing\nit the public key of the certificate using the <code>--certificate</code> argument, the private key via the <code>--private-key</code>\nargument, and the CA's public key using the <code>--certificate-chain</code> argument:</p>\n<pre>aws acm <span class=\"hljs-keyword\">import</span>-certificate \\\n --region us-east-<span class=\"hljs-number\">1</span> \\\n --certificate <span class=\"hljs-keyword\">file</span>:<span class=\"hljs-comment\">//cert.pem \\</span>\n --<span class=\"hljs-keyword\">private</span>-key <span class=\"hljs-keyword\">file</span>:<span class=\"hljs-comment\">//cert.key \\</span>\n --certificate-chain <span class=\"hljs-keyword\">file</span>:<span class=\"hljs-comment\">//ca.pem</span>\n</pre>\n<p>You'll need to do this in each region where you're going to deploy a load balancer. Once you've imported the\ncertificate everywhere, you may want to delete the private key so no one else can access it. If you're going to keep\nthe private key around, then make sure to use <a href=\"/repos/gruntkms\" class=\"preview__body--description--blue\">gruntkms</a> to encrypt it\nwith KMS.</p>\n</li>\n<li>\n<p>Create your load balancer with an HTTPS listener and set the certificate ARN to the ARN of the certificate you just\nimported into ACM. You can find the ARN automatically using the <a href=\"https://www.terraform.io/docs/providers/aws/d/acm_certificate.html\" class=\"preview__body--description--blue\" target=\"_blank\">aws_acm_certificate data\nsource</a>.</p>\n</li>\n<li>\n<p>Create a Route 53 A Record that points at your load balancer with the domain name and Private Hosted Zone you\ncreated in step 2. You can use the <a href=\"https://www.terraform.io/docs/providers/aws/r/route53_record.html\" class=\"preview__body--description--blue\" target=\"_blank\">aws_route53_record\nresource</a> to create the record and find the\nHosted Zone ID of your Private Hosted Zone automatically using the <a href=\"https://www.terraform.io/docs/providers/aws/d/route53_zone.html\" class=\"preview__body--description--blue\" target=\"_blank\">aws_route53_zone data\nsource</a>.</p>\n</li>\n<li>\n<p>You'll want to distribute the public key of the CA to any app that is going to talk to your load balancer so that it\ncan use it to validate the TLS certificate.</p>\n</li>\n</ol>\n<h3 class=\"preview__body--subtitle\" id=\"self-signed-tls-certs-for-java-based-apps\">Self-signed TLS certs for java based apps</h3>\n<p>If you want to use end-to-end encryption, you will need to generate self-signed TLS certs for Java based apps. Java uses\na special format for managing their TLS certificates (KeyStores and TrustStores) and requires an extra step to encode\nthe generated certificates. If you are unfamiliar with how TLS certificates work, start with the <a href=\"/repos/module-security/modules/tls-cert-private#background\" class=\"preview__body--description--blue\">Background\ndocumentation</a>.</p>\n<ol>\n<li>\n<p>Use the <code>generate-trust-stores.sh</code> script provided in <a href=\"/repos/infrastructure-modules-multi-account-acme/tls-scripts/generate-trust-stores.sh\" class=\"preview__body--description--blue\">infrastructure-modules-multi-account-acme</a>.\nThis script will automatically create a CA cert and a TLS cert signed by that CA, and encode them into a Key Store\nand Trust Store. The Key Store will be locked with a password that is generaated by the script and stored in AWS\nSecrets Manager for use. The script will also encrypt the Key Store password using\n<a href=\"/repos/gruntkms\" class=\"preview__body--description--blue\">gruntkms</a> with the KMS master key for the appropriate environment and\noutput the KMS encrypted cipher text.</p>\n</li>\n<li>\n<p>Package the Key Store and Trust Store into the AMI for use with the Java app. You can take a look at\n<a href=\"/repos/infrastructure-modules-multi-account-acme/data-stores/kafka\" class=\"preview__body--description--blue\">the kafka module</a>\nfor an example of how to package the certificates, including specific parameters to use for generating the Key Store\nand Trust Store.</p>\n</li>\n</ol>\n<h2 class=\"preview__body--subtitle\" id=\"run-terragrunt\">Run Terragrunt</h2>\n<p>Now that you have all the prerequisites out of the way, you can finally use Terragrunt to deploy everything!</p>\n<h3 class=\"preview__body--subtitle\" id=\"authenticate\">Authenticate</h3>\n<p>If you're creating a totally new AWS account, the easiest way to do the initial deployment is to <a href=\"https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html\" class=\"preview__body--description--blue\" target=\"_blank\">create a temporary IAM\nUser</a> in that account with admin access. Create\n<a href=\"https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html\" class=\"preview__body--description--blue\" target=\"_blank\">Access Keys</a> for that IAM User and\nset them as environment variables:</p>\n<pre><span class=\"hljs-builtin-name\">export</span> AWS_ACCESS_KEY_ID=(your access key <span class=\"hljs-keyword\">for</span> this account)\n<span class=\"hljs-builtin-name\">export</span> AWS_SECRET_ACCESS_KEY=(your<span class=\"hljs-built_in\"> secret </span>key <span class=\"hljs-keyword\">for</span> this account)\n</pre>\n<p>Once everything is deployed, you can delete this IAM user, and access the account via IAM roles (see the\n<a href=\"/repos/module-security/modules/cross-account-iam-roles\" class=\"preview__body--description--blue\">cross-account-iam-access module</a>\nfor details).</p>\n<p>If you're using an AWS account that already exists and has already been configured with cross-account IAM roles as part\nof the multi-account Reference Architecture setup, you should set environment variables for the <strong>security</strong> account:</p>\n<pre><span class=\"hljs-builtin-name\">export</span> AWS_ACCESS_KEY_ID=(your access key <span class=\"hljs-keyword\">for</span> the security account)\n<span class=\"hljs-builtin-name\">export</span> AWS_SECRET_ACCESS_KEY=(your<span class=\"hljs-built_in\"> secret </span>key <span class=\"hljs-keyword\">for</span> the security account)\n</pre>\n<p>You should then set the <code>TERRAGRUNT_IAM_ROLE</code> to the ARN of an IAM role in the account you're deploying to that will\ngive you administrative access. Typically, you'll want the <code>allow-full-access-from-other-accounts</code> IAM role:</p>\n<pre><span class=\"hljs-builtin-name\">export</span> <span class=\"hljs-attribute\">TERRAGRUNT_IAM_ROLE</span>=<span class=\"hljs-string\">\"arn:aws:iam::<ACCOUNT_ID>:role/allow-full-access-from-other-accounts\"</span>\n</pre>\n<h3 class=\"preview__body--subtitle\" id=\"run-apply-all\">Run apply-all</h3>\n<p>To deploy the entire account in a single command, you can use <code>apply-all</code>. For example, to deploy the stage account:</p>\n<pre>cd infrastructure-live-<span class=\"hljs-keyword\">multi</span>-account-acme/stage\nterragrunt apply-<span class=\"hljs-built_in\">all</span>\n</pre>\n<p>You may want to run Terragrunt with the <code>--terragrunt-non-interactive</code> flag to avoid any interactive prompts:</p>\n<pre>terragrunt apply-<span class=\"hljs-keyword\">all</span> \\\n <span class=\"hljs-comment\">--terragrunt-non-interactive</span>\n</pre>\n<p>If you want to deploy code from your local checkout of <code>infrastructure-modules-multi-account-acme</code>, rather than a versioned release, use\nthe <code>--terragrunt-source</code> parameter:</p>\n<pre>terragrunt apply-<span class=\"hljs-keyword\">all</span> \\\n <span class=\"hljs-comment\">--terragrunt-non-interactive \\</span>\n <span class=\"hljs-comment\">--terragrunt-source ../../infrastructure-modules-multi-account-acme</span>\n</pre>\n<p>If you want to deploy just a single module at a time, just use <code>terragrunt apply</code>:</p>\n<pre><span class=\"hljs-keyword\">cd</span> infrastructure-live-multi-account-acme/stage/<span class=\"hljs-keyword\">us</span>-east-1/stage/services/ecs-<span class=\"hljs-keyword\">cluster</span>\nterragrunt apply\n</pre>\n<h3 class=\"preview__body--subtitle\" id=\"deployment-order\">Deployment order</h3>\n<p>Note that, in general, there are no dependencies between different AWS accounts, so you can deploy them in any order.\nThe only exception to this is the <code>security</code> account in the multi-account setup. This account defines all IAM Users,\nGroups, and the S3 bucket used for CloudTrail audit logs, so it must always be deployed first.</p>\n<p>Within an AWS account, there are many deployment dependencies (e.g., almost everything depends on the VPC being\ndeployed first), all of which should be defined in the <code>dependencies</code> blocks of <code>terragrunt.hcl</code> files. Terragrunt\ntakes these dependencies into account automatically and should deploy everything in the right order.</p>\n<h3 class=\"preview__body--subtitle\" id=\"expected-errors\">Expected errors</h3>\n<p>Due to bugs in Terraform, you will most likely hit some of the following (harmless) errors:</p>\n<ol>\n<li>\n<p>TLS handshake timeouts downloading Terraform providers or remote state. See\nhttps://github.com/hashicorp/terraform/issues/15817.</p>\n</li>\n<li>\n<p>"A separate request to update this alarm is in progress". See\nhttps://github.com/terraform-providers/terraform-provider-aws/issues/422.</p>\n</li>\n<li>\n<p>"Error loading modules: module xxx: not found, may need to run 'terraform init'". This typically happens if you\nrun <code>apply-all</code>, change the version of a module you're using, and run <code>apply-all</code> again. Unfortunately, Terragrunt\nis not yet smart enough to automatically download the updated module (see\nhttps://github.com/gruntwork-io/terragrunt/issues/388). Easiest workaround for now is to set\n<code>TERRAGRUNT_SOURCE_UPDATE=true</code> to force Terragrunt to redownload everything:</p>\n<pre><span class=\"hljs-attr\">TERRAGRUNT_SOURCE_UPDATE</span>=<span class=\"hljs-literal\">true</span> terragrunt apply-all\n</pre>\n</li>\n</ol>\n<p>If you hit any of these issues—and you'll almost certainly hit one of the first two—simply re-run <code>apply-all</code> and they\nshould go away.</p>\n<h2 class=\"preview__body--subtitle\" id=\"next-steps\">Next steps</h2>\n<p>Now that you know how to deploy the Reference Architecture, the next thing to learn is <a href=\"/repos/v0.0.1-01172020/infrastructure-live-multi-account-acme/_docs/14-undeploying-the-reference-architecture.md\" class=\"preview__body--description--blue\">how to undeploy the\nReference Architecture</a>.</p>\n","repoName":"infrastructure-live-multi-account-acme","repoRef":"v0.0.1-01172020","serviceDescriptor":{"serviceName":"Multi-account Reference Architecture","serviceRepoName":"infrastructure-live-multi-account-acme","serviceRepoOrg":"gruntwork-io","cloudProviders":["aws"],"description":"End-to-end tech stack designed to deploy into multiple AWS accounts. Includes VPCs, EKS, ALBs, CI / CD, monitoring, alerting, VPN, DNS, and more.","imageUrl":"grunt.png","licenseType":"subscriber","technologies":["Terraform","Go","Bash","Python"],"compliance":[],"tags":[""]},"serviceCategoryName":"Reference Architecture","fileName":"13-deploying-the-reference-architecture-from-scratch.md","filePath":"/_docs/13-deploying-the-reference-architecture-from-scratch.md","title":"Repo Browser: Multi-account Reference Architecture","description":"Browse the repos in the Gruntwork Infrastructure as Code Library."}