Terragrunt Structure Reference¶
Before You Read¶
This page is a reference. For context on why Terragrunt is used see Terraform & Terragrunt. For making changes see Change Management.
Directory Layout¶
infrastructure-management/
│
├── modules/ ← Reusable Terraform modules (see Terraform Modules Reference)
│ ├── k8s/
│ ├── network/
│ ├── datastore/
│ ├── redis/
│ ├── artifacts/
│ ├── secretmanager/
│ ├── secretmanager-version/
│ ├── service-accounts/
│ ├── helm/
│ │ └── AppsIngress/ ← Gateway + VirtualService templates
│ ├── dns/
│ ├── buckets/
│ ├── users-access/
│ ├── cert-monitor/
│ │ └── scripts/
│ │ ├── monitor.py
│ │ └── Dockerfile
│ ├── kms/
│ ├── cloudsql-root-password/
│ └── cloudsql-microservice-credentials/
│
└── projects/
├── orofi-dev/ ← Development environment
│ ├── local.tf ← Backend config + local variables
│ ├── network.tf ← VPC, subnets, firewall, static IP
│ ├── k8s.tf ← GKE cluster
│ ├── sql.tf ← Cloud SQL instance + root password
│ ├── redis.tf ← Cloud Memorystore Redis
│ ├── artifacts.tf ← Artifact Registry (docker + maven)
│ ├── service-accounts.tf ← All microservice + platform service accounts
│ ├── secrets.tf ← All Secret Manager secrets
│ ├── dns.tf ← Cloud DNS records
│ ├── buckets.tf ← GCS buckets
│ ├── kms.tf ← KMS key ring for identity service
│ ├── helm.tf ← Istio + cert-manager + ArgoCD
│ └── users-access.tf ← Engineer IAM bindings
│
├── orofi-staging/ ← Staging environment (same file structure)
│ ├── local.tf
│ ├── network.tf
│ ├── k8s.tf
│ ├── sql.tf
│ ├── redis.tf
│ ├── service-accounts.tf
│ ├── secrets.tf
│ ├── dns.tf
│ └── ...
│
└── orofi-prod/ ← Production (sparse — some resources managed manually)
└── local.tf
Variable Inheritance¶
Unlike pure Terragrunt (which uses terragrunt.hcl inheritance), this repo uses standard Terraform with local.tf files that define environment-specific locals. There is no Terragrunt parent/child hierarchy — each project is self-contained.
local.tf Pattern¶
# infrastructure-management/projects/orofi-staging/local.tf
terraform {
backend "gcs" {
bucket = "oro-infra-stag"
prefix = "terraform/automation/staging"
}
}
provider "google" {
project = "orofi-stage-cloud"
region = "us-central1"
}
locals {
project_id = "orofi-stage-cloud"
env = "stage"
region = "us-central1"
zone = "us-central1-a"
domain = "*.stage.orofi.xyz"
network_cidr = "11.0.0.0/16"
}
All module calls in the same directory reference these locals:
# infrastructure-management/projects/orofi-staging/k8s.tf
module "k8s" {
source = "../../modules/k8s"
project_id = local.project_id # → "orofi-stage-cloud"
env = local.env # → "stage"
region = local.region # → "us-central1"
zone = local.zone # → "us-central1-a"
}
Adding a New Resource¶
To add a new GCP resource to an environment:
- If a module exists: add a module call to the appropriate
.tffile inprojects/orofi-{env}/ - If no module exists: create a new module in
modules/following the existing patterns - Run
terraform planto validate, thenterraform apply
Example: Adding a new secret to staging
# infrastructure-management/projects/orofi-staging/secrets.tf
module "new_feature_secret" {
source = "../../modules/secretmanager"
project_id = local.project_id
secret_id = "${local.env}-new-feature-secret"
}
Then add the secret ID to the appropriate service account's secret_ids list in service-accounts.tf.
Adding a New Environment¶
To create a new environment (e.g., a qa environment):
- Create
infrastructure-management/projects/orofi-qa/ - Copy
local.tffrom an existing environment and update all values - Copy each
.tfresource file, adjusting module inputs as needed - Create a new GCS bucket for Terraform state
- Create a Terraform service account in the new GCP project
- Run
terraform initthenterraform apply
State Management¶
Each project maintains its own state:
| Environment | Bucket | Prefix |
|---|---|---|
| Dev | oro-dev-infra |
terraform/oro/dev |
| Staging | oro-infra-stag |
terraform/automation/staging |
| Production | oro-infra-production |
terraform/automation/production |
State buckets themselves are not managed by Terraform (bootstrapping problem) — they were created manually and must not be deleted.
Running Terraform¶
# Initialize (do this once, or after changing backend/providers)
cd infrastructure-management/projects/orofi-dev
terraform init
# Authenticate as the Terraform service account
gcloud auth activate-service-account terraform-mnl@orofi-dev-cloud.iam.gserviceaccount.com \
--key-file=/path/to/key.json
# Or use application default credentials if you have sufficient permissions
gcloud auth application-default login
# Plan
terraform plan
# Apply
terraform apply
# Apply a specific resource (useful during development)
terraform apply -target=module.microservice_identity_sa
See Change Management for the full safe-change process.