Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ name: Terraform CI
on:
pull_request:
branches: [ main ]
paths:
- '**/*.tf'
- '**/*.tfvars'
- 'modules/**'

jobs:
validate:
Expand Down
112 changes: 67 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ It creates a Virtual Private Cloud (VPC) with public and private subnets, Intern

## 📘 Overview

Infrastructure Includes
### Infrastructure Includes

- VPC (aws_vpc.csye6225)
- 3 Public subnets and 3 Private subnets, each in a different AZ
Expand All @@ -16,69 +16,97 @@ Infrastructure Includes
- Private Route Table (internal routing only)
- Modular Terraform structure (separate .tf files for each resource type)

Key Features
### Key Features

- Modular, readable configuration
- Supports multiple environments (dev, demo) via separate .tfvars files
- Terraform Workspaces to isolate states
- No hardcoded values — variables and inputs are fully parameterized

---

## 🗂️ Project Structure

.
├── main.tf
├── providers.tf
├── versions.tf
├── variables.tf
├── dev.tfvars # dev environment variables
├── demo.tfvars # demo environment variables
├── vpc.tf
├── subnets.tf
├── igw.tf
├── route_tables.tf
└── outputs.tf

---

⚙️ Prerequisites
## ⚙️ Prerequisites

- Terraform >= 1.6.0
- AWS CLI installed and configured

```shell
aws configure --profile dev
aws configure --profile demo
```
```shell
aws configure --profile dev
aws configure --profile demo
```

- IAM user or profile with permissions to create VPC, subnets, route tables, and IGWs
- Create environment-specific variable files (dev.tfvars or demo.tfvars) with the following structure:

```hcl
region = "us-east-1"
profile = "dev"
vpc_name = "dev"
vpc_cidr = "10.0.0.0/16"
```

---

## 🚀 How to Deploy
## 🚀 How to Deploy (with Terraform Workspaces)

Workspaces let you maintain multiple, isolated sets of infrastructure (states)
using the same code and resource names — ideal for creating multiple VPCs in one account/region.

### Initialize Terraform
### Step 1 - Initialize Terraform

```shell
terraform init
```

### Plan and Apply for Each Environment
### Step 2 - Create and List Workspaces

```shell
terraform workspace new dev
terraform workspace new demo
terraform workspace list
```

You’ll see something like:

```
default
* dev
demo
```

The * indicates your current workspace

### Step 3 - Plan and Apply for Each Environment

- Dev Environment

```shell
terraform plan -var-file="dev.tfvars"
terraform apply -var-file="dev.tfvars"
terraform workspace select dev
terraform plan --var-file="dev.tfvars"
terraform apply --var-file="dev.tfvars"
```

- Demo Environment

```shell
terraform plan -var-file="demo.tfvars"
terraform apply -var-file="demo.tfvars"
terraform workspace select demo
terraform plan --var-file="demo.tfvars"
terraform apply --var-file="demo.tfvars"
```

### ⚠️ Important Notes:
Terraform will automatically create per-workspace state files under:

```
terraform.tfstate.d/
├── dev/
│ └── terraform.tfstate
└── demo/
└── terraform.tfstate
```

### ⚠️ Important Notes

😁 This won't happen if you're using workspace!!

- Each .tfvars represents a separate environment configuration.
- Terraform treats all resources defined in this directory as a single state.
Expand All @@ -90,6 +118,7 @@ terraform init

After deployment, Terraform prints key identifiers:

- current_workspace
- vpc_id
- public_subnets
- private_subnets
Expand All @@ -102,24 +131,17 @@ You can also view them via: `terraform output`

## 🧠 Notes

- Each .tfvars defines values like:

```hcl
region = "us-east-1"
profile = "dev"
vpc_name = "dev"
vpc_cidr = "10.0.0.0/16"
```

- Do not use multiple tfvars with the same workspace — Terraform will treat it as an update, not a new VPC.
- For multiple coexisting VPCs in the same AWS account/region, consider switching to Terraform Workspaces (see next version).
- Keep your CIDR blocks unique across workspaces (10.0.0.0/16, 10.1.0.0/16, etc.)
- Add ${terraform.workspace} in resource tags to easily identify which workspace created which resource in AWS.
- Terraform automatically stores workspace states in: `terraform.tfstate.d/<workspace>/terraform.tfstate`

---

## 🧹 Clean Up

To destroy the infrastructure:
To destroy the specific Workspace's infrastructure, select and destroy only that workspace's env

```shell
terraform destroy -var-file="dev.tfvars"
terraform workspace select demo
terraform destroy -var-file="demo.tfvars"
```
2 changes: 1 addition & 1 deletion igw.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ resource "aws_internet_gateway" "csye6225" {
vpc_id = aws_vpc.csye6225.id

tags = merge(var.tags, {
Name = "igw-csye6225-${var.vpc_name}"
Name = "igw-csye6225-${var.vpc_name}-${terraform.workspace}"
})
}
4 changes: 4 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
output "current_workspace" {
value = terraform.workspace
}

output "vpc_id" {
value = aws_vpc.csye6225.id
}
Expand Down
2 changes: 1 addition & 1 deletion providers.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Configure the AWS Provider
provider "aws" {
region = "us-east-1"
region = var.region
profile = var.profile
}
4 changes: 2 additions & 2 deletions route_tables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ resource "aws_route_table" "public" {
vpc_id = aws_vpc.csye6225.id

tags = merge(var.tags, {
Name = "rt-public-${var.vpc_name}"
Name = "rt-public-${var.vpc_name}-${terraform.workspace}"
})
}

Expand All @@ -12,7 +12,7 @@ resource "aws_route_table" "private" {
vpc_id = aws_vpc.csye6225.id

tags = merge(var.tags, {
Name = "rt-private-${var.vpc_name}"
Name = "rt-private-${var.vpc_name}-${terraform.workspace}"
})
}

Expand Down
4 changes: 2 additions & 2 deletions subnets.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ resource "aws_subnet" "public" {
map_public_ip_on_launch = true

tags = merge(var.tags, {
Name = "subnet-public-${var.vpc_name}-${each.key}",
Name = "subnet-public-${var.vpc_name}-${terraform.workspace}-${each.key}",
Tier = "public"
})
}
Expand All @@ -28,7 +28,7 @@ resource "aws_subnet" "private" {
availability_zone = each.key

tags = merge(var.tags, {
Name = "subnet-private-${var.vpc_name}-${each.key}",
Name = "subnet-private-${var.vpc_name}-${terraform.workspace}-${each.key}",
Tier = "private"
})
}
4 changes: 1 addition & 3 deletions vpc.tf
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
resource "aws_vpc" "csye6225" {
region = var.region
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true

tags = merge(var.tags, {
Name = "csye6225-${var.vpc_name}"
Name = "csye6225-${var.vpc_name}-${terraform.workspace}"
})

}