Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Serverless Infrastructure

Production-grade, modular, scalable Terraform codebase deploying a serverless processing pipeline across isolated AWS Accounts (dev, uat, prod).


1. Architectural Overview

                           +-------------------------------------------------------------+
                           |                     Target AWS Account                      |
                           |                                                             |
                           |   +-----------------------------------------------------+   |
                           |   |                      VPC                            |   |
                           |   |                                                     |   |
                           |   |  +------------------------+  +-------------------+  |   |
                           |   |  | Private Subnet A & B   |  |   Public Subnet   |  |   |
                           |   |  |                        |  |                   |  |   |
                           |   |  |   +----------------+   |  |  +-------------+  |  |   |
                           |   |  |   | Lambda Function|---|--|->| NAT Gateway |--|--|--> External APIs
                           |   |  |   +----------------+   |  |  +-------------+  |  |    (HTTPS / Port 443)
                           |   |  |        |          |    |  +-------------------+  |   |
                           |   |  |        |          +--------------------------+   |   |
                           |   |  |        | Port 3306                           |   |   |
                           |   |  |        v                                     v   |   |
                           |   |  |   +----------------+                +-------------+  |
                           |   |  |   | Existing MySQL |                |  SNS Topic  |  |
                           |   |  |   |   Database     |                |   (Events)  |  |
                           |   |  |   +----------------+                +-------------+  |
                           |   |  +------------------------+                     ^       |   |
                           |   +-------------------------------------------------|-------+   |
                           |                                                     |           |
                           |   +-------------------------+                       |           |
                           |   | AWS Secrets Manager     |                       |           |
                           |   | (MySQL Credentials)     |<----------------------+           |
                           |   +-------------------------+                                   |
                           +-----------------------------------------------------------------+

Components & Responsibilities

  • AWS Lambda:
    • Attached to existing VPC private subnets.
    • Egress rules: Port 443 to 0.0.0.0/0 (via existing NAT Gateway for outbound API communication) and Port 3306 to the existing MySQL Database Security Group.
    • Automated ingress rule injection on existing DB security group to accept traffic from Lambda SG.
    • Least-privilege IAM execution role (AWSLambdaVPCAccessExecutionRole, scoped CloudWatch logs, scoped Secrets Manager read, scoped SNS publish).
  • AWS SNS Topic:
    • Encrypted topic (AWS KMS) for publishing service events.
    • Resource policy restricting sns:Publish to the Lambda execution role.
  • Existing Resources (Inputs):
    • VPC ID, Private Subnets, existing DB Security Group, Secrets Manager Secret ARN.

2. Directory Structure

 serverless-infrastructure/
├── environment/
│   ├── dev/
│   │   ├── backend.hcl
│   │   ├── env.conf
│   │   ├── parameters.tfvars
│   │   └── terraform.tfvars
│   ├── uat/
│   │   ├── backend.hcl
│   │   ├── env.conf
│   │   ├── parameters.tfvars
│   │   └── terraform.tfvars
│   └── prod/
│       ├── backend.hcl
│       ├── env.conf
│       ├── parameters.tfvars
│       └── terraform.tfvars
├── modules/
│   ├── compute/lambda/
│   ├── events/{eventbridge,sns}/
│   └── storage/{s3,ssm-parameter-store}/
├── policies/iam/
└── scripts/terraform.sh

3. Multi-Account Deployment Strategy

Each environment (dev, uat, prod) is completely segregated into its own folder. This guarantees:

  1. Isolated State: Dev operations can never corrupt UAT or Production state.
  2. Distinct IAM & Permissions: Deployments target distinct AWS Account IDs with separate AWS profiles or assumed roles.
  3. Environment Parity: All environments leverage identical modules (modules/sns, modules/lambda) while tuning sizing parameters (memory, timeout, retention) via .tfvars.

Before a first deployment, replace every REPLACE_WITH_* value in the selected environment's terraform.tfvars and env.conf. The VPC, private subnet, database security-group, and account ID are deliberately not inferred or committed.


4. How to Plan and Apply

Container Image Deployment

The Lambda is deployed as a Node.js 24 container image, not a ZIP archive. CI/CD must publish an image before the first Terraform apply:

# Build and publish image from service application repository:
cd ../service
scripts/build-and-push-image.sh latest

# Subsequent CI/CD release: push and update the existing Lambda
scripts/build-and-push-image.sh "$GIT_SHA" service

The script builds a Lambda-compatible container image from the application repository and pushes it to the ECR repository. If passed a function name, it also updates that Lambda to the pushed image. For release deployments, use an immutable tag (for example, a Git commit SHA) and update the environment's image_uri accordingly before the initial Terraform creation.

Step 1: Set AWS Credentials / Profile

Authenticate to the target AWS account before running commands:

# For Dev Account
export AWS_PROFILE=<environment-profile>
# Or specify temporary credentials:
# export AWS_ACCESS_KEY_ID=...
# export AWS_SECRET_ACCESS_KEY=...
# export AWS_SESSION_TOKEN=...

Step 2: Configure Remote State (Production / Team Setup)

Configure the S3 backend in each environment's backend.hcl file:

terraform {
  backend "s3" {
    bucket         = "terraform-state-<env>-<account-id>"
    key            = "serverless-infrastructure/<env>/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-state-lock-<env>"
    encrypt        = true
  }
}

Step 3: Run Deployment Per Environment

Option A: Using make (Recommended)

# Formats code across modules
make fmt

# Dev
make init ENV=dev
make dev-plan     # or make plan ENV=dev
make dev-apply    # or make apply ENV=dev

# UAT
make init ENV=uat
make uat-plan
make uat-apply

# Prod
make init ENV=prod
make prod-plan
make prod-apply

Option B: Direct Terraform CLI

terraform init -backend-config=environment/dev/backend.hcl
terraform plan \
  -var-file=environment/dev/terraform.tfvars \
  -var-file=environment/dev/parameters.tfvars
terraform apply \
  -var-file=environment/dev/terraform.tfvars \
  -var-file=environment/dev/parameters.tfvars

5. Security & Best Practices Implemented

  • Network Isolation: Lambda placed strictly in private subnets with no public IP.
  • Strict Egress:
    • Port 443 outbound to 0.0.0.0/0 routed through existing NAT Gateway.
    • Port 3306 outbound targeted only to existing DB SG.
  • Least-Privilege IAM:
    • No wildcard * permissions on sensitive actions.
    • Secrets Manager read scoped strictly to DB secret ARN.
    • SNS publish scoped strictly to created topic ARN.
    • CloudWatch logs scoped to the specific function log group.
  • SNS Encryption: Server-side encryption enabled via AWS KMS.
  • Resource Tagging: Default provider tags ensure cost tracking and auditing across all created resources.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages