The goal of this project is to design and implement a secure, scalable, and automated multi-tenant SaaS environment using AWS and Terraform. Each tenant will have isolated resources, strict IAM policies, and network segmentation to ensure security and compliance.
provider "aws" {
region = "us-east-1"
}
Each tenant will have an isolated VPC (strong isolation) or a shared VPC with separate subnets (cost-effective).
module "vpc" {
source = "terraform-aws-modules/vpc/aws"
name = "tenant-vpc"
cidr = "10.0.0.0/16"
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnets = ["10.0.3.0/24", "10.0.4.0/24"]
enable_dns_support = true
enable_dns_hostnames = true
}
resource "aws_iam_role" "tenant_role" {
name = "tenant-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Service = "ec2.amazonaws.com" }
Action = "sts:AssumeRole"
}]
})
}
We can use:
resource "aws_db_instance" "tenant_db" {
identifier = "tenant-db"
engine = "postgres"
instance_class = "db.t3.micro"
allocated_storage = 20
username = "admin"
password = "supersecurepassword"
publicly_accessible = false
vpc_security_group_ids = [aws_security_group.tenant_db_sg.id]
}
Each tenant will have a separate S3 bucket or a shared bucket with IAM-based folder access.
resource "aws_s3_bucket" "tenant_bucket" {
bucket = "tenant-${var.tenant_id}-data"
}
resource "aws_iam_policy" "tenant_s3_policy" {
name = "TenantS3Policy"
description = "Allows access to a specific tenant's S3 folder"
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = ["s3:ListBucket"]
Resource = ["arn:aws:s3:::tenant-${var.tenant_id}-data"]
},
{
Effect = "Allow"
Action = ["s3:GetObject", "s3:PutObject"]
Resource = ["arn:aws:s3:::tenant-${var.tenant_id}-data/*"]
}]
})
}
resource "aws_ecs_cluster" "tenant_cluster" {
name = "tenant-cluster"
}
name: Terraform Deployment
on:
push:
branches:
- main
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v2
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 1.3.5
- name: Terraform Init
run: terraform init
- name: Terraform Apply
run: terraform apply -auto-approve
resource "aws_cloudwatch_log_group" "tenant_logs" {
name = "/aws/ecs/tenant-app"
retention_in_days = 30
}