Documentation Index Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
Use this file to discover all available pages before exploring further.
In this walkthrough, you’ll use Terragrunt to provision a multi-account, multi-region AWS infrastructure. You’ll configure remote state, set up environments (dev, stage, prod), and deploy core modules (VPC, Key Pair, Security Group, EC2).
Keep your AWS credentials handy. Run the following at any time to fetch them:
Prerequisites
Before you begin, confirm you have the following tools installed:
terraform version
terragrunt --version
aws --version
Project Setup
Clone or navigate to your Terragrunt root.
Create a working demo directory:
cd terragrunt-stack
mkdir -p demo
ls -1
# demo
Step 1: Account Configuration
Create terragrunt-stack/demo/account.hcl to define account-level locals:
locals {
account = basename ( get_terragrunt_dir ())
account_name = "labs"
}
In your root terragrunt.hcl, add remote state and provider generation:
locals {
account_vars = read_terragrunt_config ( find_in_parent_folders ( "account.hcl" ))
}
remote_state {
config = {
bucket = "kk-state- ${ local . account_vars . locals . account_name } "
region = "us-east-1"
dynamodb_table = "terraform-locks"
}
generate = {
path = "backend.tf"
if_exists = "overwrite_terragrunt"
}
}
generate "provider" {
path = "providers.tf"
if_exists = "overwrite_terragrunt"
contents = << EOF
provider "aws" {
region = " ${ local . region_vars . locals . aws_region } "
}
EOF
}
Step 2: Region Configuration
Create terragrunt-stack/demo/us-east-1/region.hcl:
locals {
aws_region = basename ( get_terragrunt_dir ())
}
Update root terragrunt.hcl:
locals {
region_vars = read_terragrunt_config ( find_in_parent_folders ( "region.hcl" ))
}
Step 3: Environment Configuration (Dev)
Create terragrunt-stack/demo/us-east-1/dev/env.hcl:
locals {
env = basename ( get_terragrunt_dir ())
}
Add to root terragrunt.hcl:
locals {
env_vars = read_terragrunt_config ( find_in_parent_folders ( "env.hcl" ))
}
Step 4: VPC Module
File: terragrunt-stack/demo/us-east-1/dev/vpc/terragrunt.hcl
terraform {
source = "tfr://terraform-aws-modules/vpc/aws//?version=5.8.1"
}
include "root" {
path = find_in_parent_folders ()
expose = true
}
inputs = {
name = "KodeKloud- ${ include . root . locals . account_vars . locals . account_name } - ${ include . root . locals . region_vars . locals . aws_region } - ${ include . root . locals . env_vars . locals . env } .vpc"
cidr = "10.64.0.0/16"
azs = [ " ${ include . root . locals . region_vars . locals . aws_region } a" , " ${ include . root . locals . region_vars . locals . aws_region } b" ]
private_subnets = [ "10.64.0.0/24" , "10.64.1.0/24" ]
public_subnets = [ "10.64.2.0/24" , "10.64.3.0/24" ]
}
Initialize and apply:
cd terragrunt-stack/demo/us-east-1/dev/vpc
terragrunt init
terragrunt apply
Verify in the AWS VPC Dashboard.
Step 5: Key Pair & Security Group Modules
Key Pair
terragrunt-stack/demo/us-east-1/dev/key-pair/terragrunt.hcl:
terraform {
source = "tfr://terraform-aws-modules/key-pair/aws//?version=0.2.8"
}
include "root" {
path = find_in_parent_folders ()
expose = true
}
inputs = {
key_name = "KodeKloud- ${ include . root . locals . account_vars . locals . account_name } - ${ include . root . locals . region_vars . locals . aws_region } - ${ include . root . locals . env_vars . locals . env } -key-pair"
create_private_key = true
}
Security Group
terragrunt-stack/demo/us-east-1/dev/security-group/terragrunt.hcl:
terraform {
source = "tfr://terraform-aws-modules/security-group/aws//?version=5.1.2"
}
include "root" {
path = find_in_parent_folders ()
expose = true
}
dependency "vpc" {
config_path = "../vpc"
}
inputs = {
name = "KodeKloud- ${ include . root . locals . account_vars . locals . account_name } - ${ include . root . locals . region_vars . locals . aws_region } - ${ include . root . locals . env_vars . locals . env } -security-group"
vpc_id = dependency.vpc.outputs.vpc_id
}
Step 6: EC2 Module
Ensure modules/ec2/main.tf contains:
resource "aws_instance" "ec2_instance" {
ami = var . ami
key_name = var . key_name
subnet_id = var . subnet_id
security_groups = var . security_groups
instance_type = "t2.micro"
tags = {
Name = var.name
}
}
Create terragrunt-stack/demo/us-east-1/dev/ec2/terragrunt.hcl:
terraform {
source = " ${ find_in_parent_folders ("modules") } /ec2"
}
include "root" {
path = find_in_parent_folders ()
expose = true
}
dependency "key_pair" {
config_path = "../key-pair"
}
dependency "vpc" {
config_path = "../vpc"
}
dependency "security_group" {
config_path = "../security-group"
}
inputs = {
name = "KodeKloud- ${ include . root . locals . account_vars . locals . account_name } - ${ include . root . locals . region_vars . locals . aws_region } - ${ include . root . locals . env_vars . locals . env } "
ami = "ami-0f21b3c242fe285"
key_name = dependency.key_pair.outputs.key_pair_name
subnet_id = dependency.vpc.outputs.public_subnets[ 0 ]
security_groups = [dependency.security_group.outputs.security_group_id]
}
Step 7: Apply the Dev Environment
Run all modules in order from terragrunt-stack/demo/us-east-1:
terragrunt run-all init
terragrunt run-all apply
Terragrunt processes dependencies in this sequence:
Key Pair
VPC
Security Group
EC2
Step 8: Stage Environment
Duplicate the dev folder to stage and apply:
cp -r dev stage
cd stage
terragrunt run-all apply
Check that the stage directory mirrors dev in your editor.
Step 9: Production in us-west-2
Copy us-east-1 → us-west-2, remove dev, rename stage → prod.
In prod/ec2/terragrunt.hcl, update:
inputs = {
ami = "ami-02f378d2e4ac266a"
# other inputs unchanged
}
Apply prod:
cd terragrunt-stack/demo/us-west-2
terragrunt run-all apply
Step 10: Review Remote State Files
List state files in your S3 bucket:
BUCKET_NAME = $( aws s3 ls | grep -oE "kk-state-.*" )
aws s3 ls s3:// $BUCKET_NAME --recursive
Example output:
2024-06-23 08:23:05 5210 demo/us-east-1/dev/ec2/terraform.tfstate
2024-06-23 08:23:06 24327 demo/us-east-1/dev/key-pair/terraform.tfstate
2024-06-23 08:23:06 2331 demo/us-east-1/dev/security-group/terraform.tfstate
2024-06-23 08:24:55 334400 demo/us-east-1/vpc/terraform.tfstate
2024-06-23 08:26:17 5116 demo/us-east-1/stage/key-pair/terraform.tfstate
2024-06-23 08:26:17 32265 demo/us-east-1/stage/security-group/terraform.tfstate
2024-06-23 08:26:37 5277 demo-us-west-2/prod/ec2/terraform.tfstate
2024-06-23 08:29:58 242840 demo-us-west-2/prod/security-group/terraform.tfstate
2024-06-23 08:29:58 32840 demo-us-west-2/prod/vpc/terraform.tfstate
Each module maintains its own state, promoting isolation and reducing the blast radius.
Congratulations! You’ve successfully built a modular, scalable AWS infrastructure with Terragrunt.
References & Further Reading