In production, companies usually have multiple Git repositories.
Platform (or Cloud) engineers create shared infrastructure repos, and DevOps or application teams have their own repos that consume those shared resources.
This is industry standard.
π§ Real Production Model (MOST COMMON)
Typical setup:
GitHub Organization
β
βββ terraform-platform-networking (Platform team)
β
βββ terraform-platform-security (Platform team)
β
βββ terraform-app-orders (App / DevOps team)
β
βββ terraform-app-payments (App / DevOps team)
β
βββ terraform-app-analytics (App / DevOps team)
π₯ Who owns what?
π¦ Platform / Cloud Engineering Team
Owns:
- VPC
- Subnets
- Routing
- Shared IAM
- Shared EKS clusters
- Shared logging / monitoring
- Terraform backends (S3 + DynamoDB)
Examples:
terraform-platform-networkingterraform-platform-security
π© DevOps / Application Teams
Own:
- EC2 / ECS / EKS workloads
- RDS / DynamoDB
- App-specific IAM roles
- Autoscaling / ALB
Examples:
terraform-app-ordersterraform-app-payments
They do NOT create VPCs β they consume them.
π How teams collaborate (KEY CONCEPT)
They collaborate via Remote State Data Source:
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "terraform-state-company-prod"
key = "networking/terraform.tfstate"
region = "us-east-1"
}
}
β No hardcoding
β Loose coupling
β Safe separation
β Production-grade
π Why state is centralized
| Component | Owner |
|---|---|
| S3 state bucket | Platform team |
| DynamoDB locking | Platform team |
| Backend config | All teams |
| State files | Isolated per repo |
π« Why NOT one repo in production?
| Reason | Explanation |
|---|---|
| Access control | Not all teams should touch networking |
| Blast radius | Mistake in one repo β break everything |
| Team autonomy | Teams deploy independently |
| CI/CD | Separate pipelines |
| Scaling | Hundreds of services |
Single repo is used for:
- Learning Terraform concepts
- Seeing full picture
- Exam preparation
- Student labs
Multi-repo is used for:
- Real production
- Enterprise environments
- Interviews
π Both are correct depending on context.
π― Interview-Perfect Answer (MEMORIZE)
In production, we typically use multiple Terraform repositories. Platform engineers manage shared infrastructure like networking and backends, while DevOps or application teams have separate repositories for their services. Teams collaborate using remote state stored in S3 with DynamoDB locking.
π§ One-Sentence Summary (VERY STRONG)
Platform teams build the foundation, application teams build on top of it.
β Certificate Alignment (Terraform Associate)
The exam expects you to know:
- Multiple repos exist
- Remote state enables collaboration
- State must be secured
- Teams are isolated
What this project covers
β Git team collaboration
β Why Terraform state must NOT be in Git
β .gitignore
β Terraform backend
β S3 backend
β DynamoDB state locking
β Terraform state management
β Remote state data source
β Cross-project collaboration
β Terraform import
β Interview & certification alignment
Real-World Scenario
A company has multiple teams:
- Networking team β creates VPC
- Application team β creates EC2
- Teams collaborate using remote state
- State is stored securely in S3
- Git is used safely by multiple engineers
High-Level Architecture
GitHub (Code Only)
|
Terraform
|
S3 (State Files)
|
DynamoDB (Locking)
|
Networking Project (VPC)
|
Application Project (EC2)
1οΈβ£ Create ONE parent directory
mkdir terraform-team-collaboration
cd terraform-team-collaboration
FINAL PROJECT STRUCTURE
terraform-team-collaboration/
β
βββ terraform-networking/
β βββ backend.tf
β βββ provider.tf
β βββ vpc.tf
β βββ subnet.tf
β βββ outputs.tf
β
βββ terraform-application/
βββ backend.tf
βββ provider.tf
βββ data.tf
βββ ec2.tf
PART 1 β Networking Project (Platform Team)
terraform-networking/backend.tf
terraform {
backend "s3" {
bucket = "terraform-state-company-prod"
key = "networking/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
terraform-networking/provider.tf
provider "aws" {
region = "us-east-1"
}
terraform-networking/vpc.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "prod-vpc"
}
}
terraform-networking/subnet.tf
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
}
terraform-networking/outputs.tf
output "vpc_id" {
value = aws_vpc.main.id
}
output "subnet_id" {
value = aws_subnet.public.id
}
βΆ Run networking
cd terraform-networking
terraform init
terraform apply
PART 2 β Application Project (DevOps Team)
terraform-application/backend.tf
terraform {
backend "s3" {
bucket = "terraform-state-company-prod"
key = "application/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
terraform-application/provider.tf
provider "aws" {
region = "us-east-1"
}
terraform-application/data.tf
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "terraform-state-company-prod"
key = "networking/terraform.tfstate"
region = "us-east-1"
}
}
terraform-application/ec2.tf
resource "aws_instance" "app" {
ami = "ami-0fc5d935ebf8bc3bc"
instance_type = "t2.micro"
subnet_id = data.terraform_remote_state.network.outputs.subnet_id
tags = {
Name = "app-server"
}
}
βΆ Run application
cd ../terraform-application
terraform init
terraform apply
PART 3 β State Locking (DynamoDB)
- Two engineers run
terraform apply - Second engineer gets state lock error
- Infrastructure is protected
PART 4 β Terraform Import (Overview)
terraform import aws_instance.app i-0abcd1234
terraform plan
β Existing infra now managed
β No recreation
PART 5 β Terraform State Management
terraform state list
terraform state show aws_vpc.main
terraform state rm aws_instance.app
terraform refresh
Top comments (0)