This repo, along with the terragrunt-ecs-modules repo, show an example file/folder structure you can use with Terragrunt to keep your Terraform code DRY. For background information, check out the Keep your Terraform code DRY section of the Terragrunt documentation.
This repo shows an example of how to use the modules from the terragrunt-ecs-modules
repo to
deploy an ECS cluster, w/ supporting ALB and VPC across three environments (qa, stage, prod) and two AWS accounts
(non-prod, prod), all without duplicating any of the Terraform code. That's because there is just a single copy of
the Terraform code, defined in the terragrunt-ecs-modules
repo, and in this repo, we solely define
terragrunt.hcl
files that reference that code (at a specific version, too!) and fill in variables specific to each
environment.
Note: This code is solely for demonstration purposes. This is not production-ready code, so use at your own risk. If you are interested in battle-tested, production-ready Terraform code, check out Gruntwork.
- Install Terraform version
0.12.18
or newer and Terragrunt versionv0.23.0
or newer. - Update the
bucket
parameter innon-prod/terragrunt.hcl
andprod/terragrunt.hcl
to unique names. We use S3 as a Terraform backend to store your Terraform state, and S3 bucket names must be globally unique. The names currently in the file are already taken, so you'll have to specify your own. Alternatively, you can set the environment variableTG_BUCKET_PREFIX
to set a custom prefix. - Configure your AWS credentials using one of the supported authentication mechanisms.
cd
into the module's folder (e.g.cd non-prod/us-east-1/qa/vpc
).- Run
terragrunt plan
to see the changes you're about to apply. - If the plan looks good, run
terragrunt apply
.
cd
into the region folder (e.g.cd non-prod/us-east-1
).- Run
terragrunt plan-all
to see all the changes you're about to apply. - If the plan looks good, run
terragrunt apply-all
.
The code in this repo uses the following folder hierarchy:
account
└ _global
└ region
└ _global
└ environment
└ resource
Where:
-
Account: At the top level are each of your AWS accounts, such as
stage-account
,prod-account
,mgmt-account
, etc. If you have everything deployed in a single AWS account, there will just be a single folder at the root (e.g.main-account
). -
Region: Within each account, there will be one or more AWS regions, such as
us-east-1
,eu-west-1
, andap-southeast-2
, where you've deployed resources. There may also be a_global
folder that defines resources that are available across all the AWS regions in this account, such as IAM users, Route 53 hosted zones, and CloudTrail. -
Environment: Within each region, there will be one or more "environments", such as
qa
,stage
, etc. Typically, an environment will correspond to a single AWS Virtual Private Cloud (VPC), which isolates that environment from everything else in that AWS account. There may also be a_global
folder that defines resources that are available across all the environments in this AWS region, such as Route 53 A records, SNS topics, and ECR repos. -
Resource: Within each environment, you deploy all the resources for that environment, such as EC2 Instances, Auto Scaling Groups, ECS Clusters, Databases, Load Balancers, and so on. Note that the Terraform code for most of these resources lives in the terragrunt-infrastructure-modules-example repo.
In the situation where you have multiple AWS accounts or regions, you often have to pass common variables down to each
of your modules. Rather than copy/pasting the same variables into each terragrunt.hcl
file, in every region, and in
every environment, you can inherit them from the inputs
defined in the root terragrunt.hcl
file.