Skip to content

Commit

Permalink
Merge pull request #21 from andrewlod/terraform
Browse files Browse the repository at this point in the history
Terraform VPC, RDS and EKS
  • Loading branch information
andrewlod authored Apr 1, 2024
2 parents a2c91dd + 3e4b88c commit a211995
Show file tree
Hide file tree
Showing 4 changed files with 379 additions and 3 deletions.
5 changes: 3 additions & 2 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
node_modules
.github
.vscode
terraform
build
docs
.github
.vscode
.env
*.log
.gitignore
Expand Down
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,11 @@ src/database/schemas/generated
src/docs/swagger_output.json

# TSDoc artifacts
docs
docs

# Terraform files
*.tfvars
*.tfvars.json
*.tfstate
*.tfstate.*
**/.terraform/*
288 changes: 288 additions & 0 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.43.0"
}
}

required_version = ">= 1.7.5"
}

provider "aws" {
access_key = var.aws_access_key_id
secret_key = var.aws_secret_access_key
region = var.aws_region
}

# VPC Resources
resource "aws_vpc" "main_vpc" {
cidr_block = var.vpc_cidr

tags = {
"Environment" = var.infra_env
"Name" = "auth-vpc-${var.infra_env}"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

resource "aws_subnet" "public_subnets" {
for_each = var.public_subnet_map

vpc_id = "${aws_vpc.vpc.id}"
cidr_block = "${each.value}"
availability_zone = "${each.key}"
map_public_ip_on_launch = true

tags = {
"Environment" = var.infra_env
"Name" = "auth-public-subnet"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

locals {
public_subnet_ids = [ for subnet in aws_subnet.public_subnets : subnet.id ]
}

resource "aws_internet_gateway" "igw" {
vpc_id = "${aws_vpc.main_vpc.id}"

tags = {
"Environment" = var.infra_env
"Name" = "auth-vpc-igw"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

resource "aws_route_table" "public_route_table" {
vpc_id = "${aws_vpc.main_vpc.id}"

tags = {
"Environment" = var.infra_env
"Name" = "auth-vpc-public-rt"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

resource "aws_route" "public_internet_gateway" {
route_table_id = aws_route_table.public_route_table.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}

resource "aws_route_table_association" "public_subnets_associations" {
for_each = toset(local.public_subnet_ids)

subnet_id = each.key
route_table_id = aws_route_table.public_route_table.id
}

resource "aws_security_group" "public_sg" {
name = "auth-public-sg"
description = "Security group to allow inbound/outbound from the VPC on application ports"
vpc_id = aws_vpc.main_vpc.id
depends_on = [aws_vpc.main_vpc]

ingress {
from_port = "80"
to_port = "80"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
from_port = "443"
to_port = "443"
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
from_port = "0"
to_port = "0"
protocol = "-1"
self = true
}

egress {
from_port = "0"
to_port = "0"
protocol = "-1"
cidr_blocks = [ "0.0.0.0" ]
}
tags = {
"Environment" = var.infra_env
"Name" = "auth-public-sg"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

resource "aws_security_group" "private_sg" {
name = "auth-private-sg"
description = "Security group for internal VPC traffic"
vpc_id = aws_vpc.main_vpc.id
depends_on = [aws_vpc.main_vpc]

ingress {
from_port = "0"
to_port = "0"
protocol = "-1"
self = true
}

egress {
from_port = "0"
to_port = "0"
protocol = "-1"
cidr_blocks = [ "0.0.0.0" ]
}
tags = {
"Environment" = var.infra_env
"Name" = "auth-public-sg"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

# RDS Resources
resource "aws_db_subnet_group" "authentication_db_sng" {
name = "authdbsng"
subnet_ids = local.public_subnet_ids

tags = {
"Environment" = var.infra_env
"Name" = "authdbsng"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

resource "aws_db_instance" "authentication_db" {
allocated_storage = var.db_storage
db_name = "${var.db_name}-${var.infra_env}"
engine = "postgres"
engine_version = "16.2"
instance_class = var.db_instance_type
username = var.db_username
password = var.db_password
skip_final_snapshot = true
publicly_accessible = true

db_subnet_group_name = aws_db_subnet_group.authentication_db_sng.name

tags = {
"Environment" = var.infra_env
"Name" = "${var.db_name}-${var.infra_env}"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

resource "aws_secretsmanager_secret" "db_secret" {
name = "${var.db_name}-${var.infra_env}-secret"

tags = {
"Environment" = var.infra_env
"Name" = "${var.db_name}-${var.infra_env}-secret"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

resource "aws_secretsmanager_secret_version" "db_secret_values" {
secret_id = aws_secretsmanager_secret.db_secret.id
secret_string = jsonencode({
"DATABASE_URL" = "postgres://${var.db_username}:${var.db_password}@${aws_db_instance.authentication_db.endpoint}/${var.db_schema_name}?schema=public"
"ENDPOINT" = "${aws_db_instance.authentication_db.endpoint}"
})
}

# IAM Resources
resource "aws_iam_role" "eks_fargate_execution_role" {
name = "eks-fargate-execution-role"

assume_role_policy = jsonencode({
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "eks-fargate-pods.amazonaws.com"
}
}]
Version = "2012-10-17"
})
}

resource "aws_iam_role_policy_attachment" "eks_fargate_execution_attachment" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSFargatePodExecutionRolePolicy"
role = aws_iam_role.eks_fargate_execution_role.arn
}

resource "aws_iam_role" "eks_cluster_role" {
name = "eks-cluster-role"
assume_role_policy = jsonencode({
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "eks.amazonaws.com"
}
}]
Version = "2012-10-17"
})
}

resource "aws_iam_role_policy_attachment" "eks_cluster_policy_attachment" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
role = aws_iam_role.eks_cluster_role.name
}

resource "aws_iam_role_policy_attachment" "eks_cluster_vpc_policy_attachment" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSVPCResourceController"
role = aws_iam_role.eks_cluster_role.name
}

# EKS Resources
resource "aws_eks_cluster" "authentication_cluster" {
name = "authentication-cluster-${var.infra_env}"
role_arn = aws_iam_role.eks_cluster_role.arn

vpc_config {
security_group_ids = [aws_security_group.public_sg.id, aws_security_group.private_sg.id]
subnet_ids = local.public_subnet_ids
}

tags = {
"Environment" = var.infra_env
"Name" = "authentication-cluster-${var.infra_env}"
"Project" = "authentication-app"
"ManagedBy" = "terraform"
"Organization" = "andrewlod"
}
}

resource "aws_eks_fargate_profile" "auth_cluster_fargate_profile" {
fargate_profile_name = "authentication-cluster-profile-${var.infra_env}"
cluster_name = aws_eks_cluster.authentication_cluster.name
pod_execution_role_arn = aws_iam_role.eks_fargate_execution_role.arn
subnet_ids = local.public_subnet_ids

selector {
namespace = "default"
}
}
80 changes: 80 additions & 0 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
variable "infra_env" {
type = string
description = "Infrastructure environment (prod/dev/test)"
}

variable "aws_access_key_id" {
type = string
description = "AWS Access Key ID"
sensitive = true
}

variable "aws_secret_access_key" {
type = string
description = "AWS Secret Access Key"
sensitive = true
}

variable "aws_region" {
type = string
description = "AWS primary region to create resources"
default = "us-east-1"
}

variable "vpc_cidr" {
type = string
description = "CIDR of the main VPC"
default = "10.0.0.0/24"
}

variable "public_subnet_map" {
type = map(string)
description = "Mapping between public subnet AZs and CIDRs"
default = {
"us-east-1a" = "10.0.0.0/28"
"us-east-1b" = "10.0.0.16/28"
}
}

variable "private_subnet_map" {
type = map(string)
description = "Mapping between private subnet AZs and CIDRs"
default = {
"us-east-1a" = "10.0.0.32/28"
"us-east-1b" = "10.0.0.48/28"
}
}

variable "db_storage" {
type = number
description = "Amount of storage allocated into the RDS instance, in GB"
default = 10
}

variable "db_name" {
type = string
description = "Name of the RDS instance"
}

variable "db_schema_name" {
type = string
description = "Name of the authentication system schema in the RDS database"
}

variable "db_instance_type" {
type = string
description = "Type of the RDS instance"
default = "db.t3.micro"
}

variable "db_username" {
type = string
description = "RDS database username"
sensitive = true
}

variable "db_password" {
type = string
description = "RDS database password"
sensitive = true
}

0 comments on commit a211995

Please sign in to comment.