π Project Structure (Skeleton)
terraform-alias-workspace-import-lab/
β
βββ providers.tf
βββ variables.tf
βββ main.tf
βββ outputs.tf
βββ terraform.tfvars.example
β
βββ backend.tf
β
βββ scripts/
βββ import.sh
1οΈβ£ providers.tf
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# Default provider (primary region)
provider "aws" {
region = var.primary_region
}
# Alias provider (secondary region)
provider "aws" {
alias = "secondary"
region = var.secondary_region
}
2οΈβ£ variables.tf (NO hardcoding)
variable "project_name" {
type = string
}
variable "environment" {
type = string
}
variable "primary_region" {
type = string
}
variable "secondary_region" {
type = string
}
variable "bucket_name" {
type = string
}
variable "common_tags" {
type = map(string)
default = {}
}
3οΈβ£ main.tf
πΉ Uses:
- workspace
- alias provider
- dynamic naming
locals {
env = terraform.workspace
name_prefix = "${var.project_name}-${local.env}"
tags = merge(var.common_tags, {
Project = var.project_name
Environment = local.env
ManagedBy = "Terraform"
})
}
# Primary region bucket
resource "aws_s3_bucket" "primary" {
bucket = "${local.name_prefix}-primary"
tags = local.tags
}
# Secondary region bucket (alias usage)
resource "aws_s3_bucket" "secondary" {
provider = aws.secondary
bucket = "${local.name_prefix}-secondary"
tags = local.tags
}
4οΈβ£ outputs.tf
output "primary_bucket" {
value = aws_s3_bucket.primary.bucket
}
output "secondary_bucket" {
value = aws_s3_bucket.secondary.bucket
}
output "workspace" {
value = terraform.workspace
}
5οΈβ£ terraform.tfvars.example
project_name = "jumptotech"
environment = "dev"
primary_region = "us-east-2"
secondary_region = "us-west-1"
common_tags = {
Owner = "DevOpsTeam"
}
6οΈβ£ backend.tf (Optional but Production Style)
terraform {
backend "s3" {}
}
terraform init \
-backend-config="bucket=YOUR-TF-STATE-BUCKET" \
-backend-config="key=alias-workspace/terraform.tfstate" \
-backend-config="region=us-east-2" \
-backend-config="dynamodb_table=terraform-locks"
7οΈβ£ scripts/import.sh
#!/bin/bash
# Usage:
# ./import.sh <bucket_name>
BUCKET_NAME=$1
if [ -z "$BUCKET_NAME" ]; then
echo "Usage: ./import.sh <bucket_name>"
exit 1
fi
echo "Importing existing S3 bucket..."
terraform import aws_s3_bucket.primary $BUCKET_NAME
π STEP-BY-STEP EXECUTION
Step 1: Initialize
terraform init
Step 2: Create Workspaces
terraform workspace new dev
terraform workspace new stage
terraform workspace new prod
Switch:
terraform workspace select dev
Step 3: Plan & Apply
terraform plan -var-file="terraform.tfvars"
terraform apply -var-file="terraform.tfvars"
Step 4: Verify Workspace Behavior
Switch workspace:
terraform workspace select stage
terraform apply -var-file="terraform.tfvars"
π Creates different buckets automatically
Step 5: IMPORT (IMPORTANT)
π₯ Scenario:
Bucket already exists (created manually)
aws s3 mb s3://jumptotech-dev-primary
Now import:
./scripts/import.sh jumptotech-dev-primary
Step 6: Verify Import
terraform plan
Expected:
No changes. Infrastructure is up-to-date.
π§ KEY CONCEPTS (Explain to Students)
πΉ 1. Alias Provider
provider = aws.secondary
β‘οΈ Allows:
- Multi-region
- Multi-account
πΉ 2. Workspace
terraform.workspace
β‘οΈ Automatically separates:
- dev
- stage
- prod
πΉ 3. Import
terraform import RESOURCE_NAME RESOURCE_ID
β‘οΈ Example:
terraform import aws_s3_bucket.primary my-bucket
πΉ 4. Why Import is Critical
Without import:
- Terraform will try to recreate resource
- Can cause data loss / conflicts
πΉ 5. No Hardcoding
Everything comes from:
- variables.tf
- tfvars
- workspace
π― REAL INTERVIEW QUESTIONS (FROM THIS LAB)
- What is provider alias and when do you use it?
- Difference between workspace and separate state files?
- What happens if you donβt import existing resources?
- Can you import into module?
- How do you manage multi-region deployments?
- What is terraform.workspace used for?
Top comments (0)