-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
we are doing infra as code ladies and gents
- Loading branch information
Showing
11 changed files
with
409 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
# ALB | ||
resource "aws_security_group" "alb" { | ||
name = "${var.app_name}-alb-sg" | ||
vpc_id = var.vpc_id | ||
egress { | ||
from_port = 0 | ||
to_port = 0 | ||
protocol = "-1" | ||
cidr_blocks = ["0.0.0.0/0"] | ||
} | ||
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"] | ||
} | ||
} | ||
resource "aws_lb" "this" { | ||
name = "${var.app_name}-alb" | ||
load_balancer_type = "application" | ||
security_groups = [aws_security_group.alb.id] | ||
subnets = var.public_subnet_ids | ||
} | ||
resource "aws_lb_target_group" "this" { | ||
name = "${var.app_name}-lb-tg" | ||
vpc_id = var.vpc_id | ||
port = 80 | ||
protocol = "HTTP" | ||
target_type = "ip" | ||
health_check { | ||
port = 80 | ||
path = "/docs" | ||
interval = 30 | ||
protocol = "HTTP" | ||
timeout = 5 | ||
unhealthy_threshold = 2 | ||
matcher = 200 | ||
} | ||
} | ||
resource "aws_lb_listener" "http" { | ||
port = "80" | ||
protocol = "HTTP" | ||
load_balancer_arn = aws_lb.this.arn | ||
default_action { | ||
target_group_arn = aws_lb_target_group.this.arn | ||
type = "forward" | ||
} | ||
depends_on = [aws_lb_target_group.this] | ||
} | ||
resource "aws_lb_listener_rule" "this" { | ||
listener_arn = aws_lb_listener.http.arn | ||
action { | ||
type = "forward" | ||
target_group_arn = aws_lb_target_group.this.arn | ||
} | ||
condition { | ||
path_pattern { | ||
values = ["*"] | ||
} | ||
} | ||
} | ||
|
||
# IAM | ||
data "aws_iam_policy_document" "ecs_assume_policy" { | ||
statement { | ||
actions = ["sts:AssumeRole"] | ||
principals { | ||
type = "Service" | ||
identifiers = ["ecs-tasks.amazonaws.com"] | ||
} | ||
} | ||
} | ||
resource "aws_iam_role" "ecs_execution_role" { | ||
name = "${var.app_name}-execution-role" | ||
assume_role_policy = data.aws_iam_policy_document.ecs_assume_policy.json | ||
} | ||
resource "aws_iam_policy" "ecs_execution_policy" { | ||
name = "${var.app_name}-ecs-execution-role-policy" | ||
policy = jsonencode({ | ||
Version = "2012-10-17" | ||
Statement = [ | ||
{ | ||
Effect : "Allow", | ||
Action : [ | ||
"ecr:*", | ||
"ecs:*", | ||
"elasticloadbalancing:*", | ||
"cloudwatch:*", | ||
"logs:*" | ||
], | ||
Resource : "*" | ||
} | ||
] | ||
}) | ||
} | ||
resource "aws_iam_role_policy_attachment" "ecs_execution_role_policy_attach" { | ||
role = aws_iam_role.ecs_execution_role.name | ||
policy_arn = aws_iam_policy.ecs_execution_policy.arn | ||
} | ||
|
||
# ECS | ||
resource "aws_cloudwatch_log_group" "ecs" { | ||
name = "/aws/ecs/${var.app_name}/cluster" | ||
} | ||
resource "aws_ecs_task_definition" "api" { | ||
family = "${var.app_name}-api-task" | ||
requires_compatibilities = ["FARGATE"] | ||
network_mode = "awsvpc" | ||
execution_role_arn = aws_iam_role.ecs_execution_role.arn | ||
task_role_arn = aws_iam_role.ecs_execution_role.arn | ||
cpu = 256 | ||
memory = 512 | ||
container_definitions = jsonencode([ | ||
{ | ||
name = "${var.app_name}-api-container" | ||
image = "${var.image}" | ||
command = ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "80"] | ||
portMappings = [ | ||
{ | ||
hostPort = 80 | ||
containerPort = 80 | ||
protocol = "tcp" | ||
} | ||
], | ||
logConfiguration = { | ||
logDriver = "awslogs" | ||
options = { | ||
awslogs-group = aws_cloudwatch_log_group.ecs.name | ||
awslogs-stream-prefix = "ecs" | ||
awslogs-region = var.region | ||
} | ||
} | ||
environment = [ | ||
{ | ||
name = "SUPABASE_URL", | ||
value = var.supabase_url | ||
}, | ||
{ | ||
name = "SUPABASE_KEY", | ||
value = var.supabase_key | ||
} | ||
] | ||
} | ||
]) | ||
} | ||
|
||
# Cluster | ||
resource "aws_ecs_cluster" "this" { | ||
name = "${var.app_name}-cluster" | ||
setting { | ||
name = "containerInsights" | ||
value = "enabled" | ||
} | ||
} | ||
|
||
# Security Group and Service | ||
resource "aws_security_group" "ecs" { | ||
name = "${var.app_name}-ecs-sg" | ||
vpc_id = var.vpc_id | ||
egress { | ||
from_port = 0 | ||
to_port = 0 | ||
protocol = "-1" | ||
cidr_blocks = ["0.0.0.0/0"] | ||
} | ||
ingress { | ||
from_port = 80 | ||
to_port = 80 | ||
protocol = "tcp" | ||
security_groups = [aws_security_group.alb.id] | ||
} | ||
} | ||
resource "aws_ecs_service" "api" { | ||
name = "${var.app_name}-ecs-service" | ||
cluster = aws_ecs_cluster.this.name | ||
launch_type = "FARGATE" | ||
desired_count = length(var.private_subnet_ids) | ||
task_definition = aws_ecs_task_definition.api.arn | ||
network_configuration { | ||
subnets = var.private_subnet_ids | ||
security_groups = [aws_security_group.ecs.id] | ||
} | ||
load_balancer { | ||
target_group_arn = aws_lb_target_group.this.arn | ||
container_name = "${var.app_name}-api-container" | ||
container_port = "80" | ||
} | ||
lifecycle { | ||
ignore_changes = [ | ||
desired_count, | ||
] | ||
} | ||
depends_on = [aws_lb_listener_rule.this] | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
output "alb_dns_name" { | ||
value = aws_lb.this.dns_name | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
variable "app_name" { | ||
description = "Name of the app." | ||
type = string | ||
} | ||
variable "region" { | ||
description = "AWS region to deploy the network to." | ||
type = string | ||
} | ||
variable "image" { | ||
description = "Image used to start the container. Should be in repository-url/image:tag format." | ||
type = string | ||
} | ||
variable "vpc_id" { | ||
description = "ID of the VPC where the ECS will be hosted." | ||
type = string | ||
} | ||
variable "public_subnet_ids" { | ||
description = "IDs of public subnets where the ALB will be attached to." | ||
type = list(string) | ||
} | ||
variable "private_subnet_ids" { | ||
description = "IDs of private subnets where the ECS service will be deployed to." | ||
type = list(string) | ||
} | ||
variable "supabase_url" { | ||
type = string | ||
description = "Supabase URL for the application" | ||
sensitive = true | ||
} | ||
variable "supabase_key" { | ||
type = string | ||
description = "Supabase API key" | ||
sensitive = true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
provider "aws" { | ||
region = var.region | ||
default_tags { | ||
tags = { | ||
app = var.app_name | ||
} | ||
} | ||
} | ||
|
||
module "network" { | ||
source = "./network" | ||
app_name = var.app_name | ||
region = var.region | ||
} | ||
|
||
module "ecs" { | ||
source = "./ecs" | ||
app_name = var.app_name | ||
region = var.region | ||
image = var.image | ||
supabase_url = var.supabase_url | ||
supabase_key = var.supabase_key | ||
vpc_id = module.network.vpc.id | ||
public_subnet_ids = [for s in module.network.public_subnets : s.id] | ||
private_subnet_ids = [for s in module.network.private_subnets : s.id] | ||
depends_on = [module.network] | ||
} | ||
|
||
|
||
# Outputs | ||
output "alb_dns_name" { | ||
value = module.ecs.alb_dns_name | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# Define provider | ||
provider "aws" { | ||
region = var.region | ||
default_tags { | ||
tags = { | ||
app = var.app_name | ||
} | ||
} | ||
} | ||
|
||
# Create VPC and IGW | ||
resource "aws_vpc" "this" { | ||
cidr_block = var.vpc_cidr_block | ||
} | ||
resource "aws_internet_gateway" "this" { | ||
vpc_id = aws_vpc.this.id | ||
} | ||
|
||
# Create public subnets | ||
resource "aws_subnet" "public_subnets" { | ||
count = length(var.availability_zones) | ||
vpc_id = aws_vpc.this.id | ||
cidr_block = var.public_cidr_blocks[count.index] | ||
availability_zone = var.availability_zones[count.index] | ||
} | ||
|
||
# Create routing tables for public subnets | ||
resource "aws_route_table" "public" { | ||
vpc_id = aws_vpc.this.id | ||
route { | ||
cidr_block = "0.0.0.0/0" | ||
gateway_id = aws_internet_gateway.this.id | ||
} | ||
} | ||
resource "aws_route_table_association" "publics" { | ||
count = length(var.availability_zones) | ||
subnet_id = element(aws_subnet.public_subnets.*.id, count.index) | ||
route_table_id = aws_route_table.public.id | ||
} | ||
|
||
|
||
# Create Elastic IPs and NAT Gateways | ||
resource "aws_eip" "eips" { | ||
count = length(var.availability_zones) | ||
domain = "vpc" | ||
} | ||
resource "aws_nat_gateway" "this" { | ||
count = length(var.availability_zones) | ||
subnet_id = element(aws_subnet.public_subnets.*.id, count.index) | ||
allocation_id = element(aws_eip.eips.*.id, count.index) | ||
} | ||
|
||
# Create private subnets | ||
resource "aws_subnet" "private_subnets" { | ||
count = length(var.availability_zones) | ||
vpc_id = aws_vpc.this.id | ||
cidr_block = var.private_cidr_blocks[count.index] | ||
availability_zone = var.availability_zones[count.index] | ||
} | ||
|
||
# Create routing tables for private subnets | ||
resource "aws_route_table" "private" { | ||
count = length(var.availability_zones) | ||
vpc_id = aws_vpc.this.id | ||
route { | ||
cidr_block = "0.0.0.0/0" | ||
nat_gateway_id = element(aws_nat_gateway.this.*.id, count.index) | ||
} | ||
} | ||
resource "aws_route_table_association" "privates" { | ||
count = length(var.availability_zones) | ||
subnet_id = element(aws_subnet.private_subnets.*.id, count.index) | ||
route_table_id = element(aws_route_table.private.*.id, count.index) | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
output "vpc" { | ||
value = aws_vpc.this | ||
} | ||
output "public_subnets" { | ||
value = aws_subnet.public_subnets | ||
} | ||
output "private_subnets" { | ||
value = aws_subnet.private_subnets | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
variable "app_name" { | ||
type = string | ||
} | ||
variable "region" { | ||
type = string | ||
} | ||
variable "vpc_cidr_block" { | ||
type = string | ||
default = "10.0.0.0/16" | ||
} | ||
variable "availability_zones" { | ||
type = list(string) | ||
default = ["us-east-1a", "us-east-1f"] | ||
} | ||
variable "public_cidr_blocks" { | ||
type = list(string) | ||
default = ["10.0.1.0/24", "10.0.2.0/24"] | ||
} | ||
variable "private_cidr_blocks" { | ||
type = list(string) | ||
default = ["10.0.11.0/24", "10.0.12.0/24"] | ||
} |
Oops, something went wrong.