Skip to content

Commit fac43dd

Browse files
nimisha-gjvjdhama
authored andcommitted
add initial draft of terragrunt blog
1 parent d735a03 commit fac43dd

File tree

2 files changed

+155
-9
lines changed

2 files changed

+155
-9
lines changed

content/blog/terragrunt-environment-management.md

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
---
2+
title: "From Chaos to Clarity: Managing Environments with Terragrunt"
3+
authorId: "nimisha"
4+
date: 2024-09-10
5+
draft: true
6+
featured: true
7+
weight: 1
8+
---
9+
10+
Managing multiple environments was a never-ending headache for me. Like many others in the DevOps world, I was responsible for deploying applications across various environments—production, staging, and development. Each of these environments required the same infrastructure, but I found myself writing the same Terraform code over and over again in different folders. The repetition felt inefficient, and the potential for human error only grew with each tweak I had to make for a specific environment.
11+
12+
## The Repetition Trap
13+
14+
At first, my solution was simple: copy-paste. I created three separate folders: one for production, one for staging, and one for development. In each folder, I had the same Terraform files with minor tweaks like different variables or configurations for each environment. It worked, but I soon found myself dealing with the chaos of managing three sets of nearly identical infrastructure code.
15+
16+
Let’s say I needed to update a configuration for my database service. This meant that I had to open each folder, make the same change in three different places, and run Terraform multiple times for each environment. It was a tedious and error-prone process, and as my infrastructure grew, so did the complexity. I knew there had to be a better way.
17+
18+
> My Initial Setup was like this
19+
20+
```text
21+
.
22+
├── production
23+
│   ├── app.tf
24+
│   ├── database.tf
25+
│   └── redis.tf
26+
├── qa
27+
│   ├── app.tf
28+
│   ├── database.tf
29+
│   └── redis.tf
30+
└── staging
31+
├── app.tf
32+
├── database.tf
33+
└── redis.tf
34+
```
35+
36+
The terraform files are contains same resources in different environment but the only difference was the values of the variables.
37+
That is lot of Repeated Code.
38+
39+
## The Terragrunt Revelation
40+
41+
That’s when I discovered Terragrunt. Terragrunt is a thin wrapper for Terraform that provides extra tools for keeping your Terraform code DRY (Don’t Repeat Yourself). It allows you to manage multiple Terraform modules in a single repository and reuse code across different environments. Terragrunt’s ability to manage remote state, generate configurations, and apply configurations across multiple environments made it the perfect solution for my environment management woes.
42+
43+
How we reduce the repeated code using Terragrunt:
44+
First step was to make a module of the resources with all the changeable variables exposed, Next was to use them in each environment.
45+
46+
> The new setup with Terragrunt
47+
48+
```text
49+
.
50+
├── terragrunt.hcl
51+
├── production
52+
│   ├── app
53+
│   │ └── terragrunt.hcl
54+
│   ├── database
55+
│   │ └── terragrunt.hcl
56+
│   └── redis
57+
│   └── terragrunt.hcl
58+
├── staging
59+
│   ├── app
60+
│   │ └── terragrunt.hcl
61+
│   ├── database
62+
│   │ └── terragrunt.hcl
63+
│   └── redis
64+
│   └── terragrunt.hcl
65+
└── qa
66+
   ├── app
67+
   │ └── terragrunt.hcl
68+
   ├── database
69+
   │ └── terragrunt.hcl
70+
   └── redis
71+
   └── terragrunt.hcl
72+
```
73+
74+
In the `terragrunt.hcl` file, we define the module to use and the
75+
variables to pass to the module.
76+
77+
```hcl
78+
# terragrunt.hcl
79+
terraform {
80+
source = "gittfr:///exampleorg/app/aws?version=5.8.1"
81+
}
82+
inputs = {
83+
app_name = "my-app"
84+
environment = "production"
85+
}
86+
```
87+
88+
Similarly in the other terragrunt files we define the module to use and the variables to pass to the module.
89+
and now for the storing the state file we can use the remote state file.
90+
91+
```hcl
92+
# terragrunt.hcl
93+
generate "backend" {
94+
path = "backend.tf"
95+
if_exists = "overwrite_terragrunt"
96+
contents = <<EOF
97+
terraform {
98+
backend "s3" {
99+
bucket = "my-terraform-state"
100+
key = "${path_relative_to_include()}/terraform.tfstate"
101+
region = "us-east-1"
102+
encrypt = true
103+
dynamodb_table = "my-lock-table"
104+
}
105+
}
106+
EOF
107+
}
108+
```
109+
110+
This tells terragrunt to create a new file `backend.tf` with the contents of the `contents` block, Even if backend.tf already exists it will overwrite the contents because we have specified `overwrite_terragrunt`.
111+
This is like a defining a function, Now we need to call it in the files i.e `terragrunt.hcl` files.
112+
113+
> This would look like this
114+
115+
```hcl
116+
include "root" {
117+
path = find_in_parent_folders()
118+
}
119+
```
120+
121+
here the `find_in_parent_folders` returns the absolute path to the first `terragrunt.hcl` file it finds in the parent folders above the current `terragrunt.hcl` file.
122+
and the include block tells terragrunt to include all the cofigurations from the file with the path returned by the `find_in_parent_folders` function.
123+
124+
## The Terragrunt Workflow
125+
126+
Here is a high-level overview of the terragrunt workflow:
127+
128+
> We run the command `terragrunt run-all plan` in the root directory.
129+
130+
This will run the terragrunt plan in each sub directory it finds, Then it reads the `terragrunt.hcl` file in the current directory and does the following:
131+
132+
1. Terragrunt reads the `terraform` block and downloads the specified Terraform module
133+
2. Terragrunt reads the `inputs` block and passes the variables to the Terraform module
134+
3. Terragrunt reads the `generate` block and creates the `backend.tf` file
135+
4. Terragrunt runs Terraform with the specified configurations
136+
5. Terragrunt stores the Terraform state in the remote state file
137+
6. Terragrunt returns the output of the Terraform run
138+
139+
This workflow allows me to manage multiple environments with ease. I can make changes to my infrastructure code in a single place and apply those changes across all environments with a single command. Terragrunt’s ability to keep my Terraform code DRY has saved me time and effort, and I no longer have to worry about managing multiple sets of nearly identical infrastructure code.
140+
141+
## How Terragrunt worked for me
142+
143+
1. Centralized Modules: I now have a shared repository of modules that are environment-agnostic. The modules are reusable and cover things like VPCs, ECS clusters, RDS instances, and IAM roles. I no longer need to maintain three different sets of Terraform code.
144+
145+
2. Per-Environment Configurations: For each environment, I have a terragrunt.hcl file that passes environment-specific configurations like the number of instances or database types. These configurations override default values in the shared modules, ensuring that each environment gets what it needs without redundant code.
146+
147+
3. Automated Initialization: Running Terraform in multiple environments is now a breeze. Terragrunt automatically handles running terraform init, terraform plan, and terraform apply for each environment. No more manually navigating into each folder and executing commands multiple times. Terragrunt takes care of initializing each environment’s backend configuration (e.g., for state storage in S3 and locking with DynamoDB).
148+
149+
4. Dependency Management: Another Terragrunt superpower is managing dependencies between infrastructure components. For example, my ECS service depends on the VPC and subnets being provisioned first. Terragrunt’s dependencies block ensures that I deploy resources in the correct order, so my ECS service doesn’t attempt to launch before the network is ready.
150+
151+
## Final Thoughts
152+
153+
Terragrunt isn’t just about making Terraform easier to use. It’s about enabling you to manage infrastructure at scale without the chaos. I no longer have to worry about accidentally mismatching configurations between environments or spending hours applying changes manually.
154+
155+
If you’re tired of duplicating Terraform code across environments, I highly recommend giving Terragrunt a try. It’s been a game-changer in my workflow, and it just might bring the clarity you need in your infrastructure management journey.

0 commit comments

Comments
 (0)