mirror of
https://github.com/Sea-Haven-Industries/meal-order-manager.git
synced 2026-09-30 06:33:12 +00:00
fix(infra): give meals its own VPC because prod has none
This commit is contained in:
parent
19cbddd2fc
commit
6573312bb3
5 changed files with 137 additions and 34 deletions
|
|
@ -1,22 +1,6 @@
|
|||
# Always-on meals API: Fargate behind an ALB. GitHub Actions owns the image;
|
||||
# Terraform ignores container_definitions after the bootstrap task definition.
|
||||
|
||||
data "aws_vpc" "default" {
|
||||
default = true
|
||||
}
|
||||
|
||||
data "aws_subnets" "default" {
|
||||
filter {
|
||||
name = "vpc-id"
|
||||
values = [data.aws_vpc.default.id]
|
||||
}
|
||||
|
||||
filter {
|
||||
name = "default-for-az"
|
||||
values = ["true"]
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_ecr_repository" "api" {
|
||||
name = local.project
|
||||
image_tag_mutability = "MUTABLE"
|
||||
|
|
@ -55,7 +39,7 @@ resource "aws_ecr_lifecycle_policy" "api" {
|
|||
resource "aws_security_group" "alb" {
|
||||
name = "${local.project}-alb"
|
||||
description = "Public ALB for meal-order-manager"
|
||||
vpc_id = data.aws_vpc.default.id
|
||||
vpc_id = aws_vpc.this.id
|
||||
|
||||
ingress {
|
||||
# CloudFront prefix lists cannot cover GitHub-hosted weekly-menu HMAC
|
||||
|
|
@ -79,7 +63,7 @@ resource "aws_security_group" "alb" {
|
|||
resource "aws_security_group" "api" {
|
||||
name = "${local.project}-api"
|
||||
description = "Fargate tasks for meal-order-manager"
|
||||
vpc_id = data.aws_vpc.default.id
|
||||
vpc_id = aws_vpc.this.id
|
||||
|
||||
ingress {
|
||||
description = "From ALB"
|
||||
|
|
@ -102,7 +86,7 @@ resource "aws_lb" "api" {
|
|||
load_balancer_type = "application"
|
||||
idle_timeout = 120
|
||||
security_groups = [aws_security_group.alb.id]
|
||||
subnets = data.aws_subnets.default.ids
|
||||
subnets = aws_subnet.public[*].id
|
||||
|
||||
drop_invalid_header_fields = true
|
||||
}
|
||||
|
|
@ -111,7 +95,7 @@ resource "aws_lb_target_group" "api" {
|
|||
name = "${local.project}-api"
|
||||
port = 8080
|
||||
protocol = "HTTP"
|
||||
vpc_id = data.aws_vpc.default.id
|
||||
vpc_id = aws_vpc.this.id
|
||||
target_type = "ip"
|
||||
|
||||
health_check {
|
||||
|
|
@ -218,7 +202,7 @@ resource "aws_ecs_service" "api" {
|
|||
launch_type = "FARGATE"
|
||||
|
||||
network_configuration {
|
||||
subnets = data.aws_subnets.default.ids
|
||||
subnets = aws_subnet.public[*].id
|
||||
security_groups = [aws_security_group.api.id]
|
||||
assign_public_ip = true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -464,23 +464,45 @@ resource "aws_iam_role_policy" "hcptf_apply_services" {
|
|||
},
|
||||
{
|
||||
Action = [
|
||||
"ec2:DescribeVpcs",
|
||||
"ec2:DescribeSubnets",
|
||||
"ec2:DescribeSecurityGroups",
|
||||
"ec2:DescribeNetworkInterfaces",
|
||||
"ec2:DescribeAccountAttributes",
|
||||
"ec2:CreateSecurityGroup",
|
||||
"ec2:DeleteSecurityGroup",
|
||||
"ec2:AuthorizeSecurityGroupIngress",
|
||||
"ec2:AssociateRouteTable",
|
||||
"ec2:AttachInternetGateway",
|
||||
"ec2:AuthorizeSecurityGroupEgress",
|
||||
"ec2:RevokeSecurityGroupIngress",
|
||||
"ec2:RevokeSecurityGroupEgress",
|
||||
"ec2:AuthorizeSecurityGroupIngress",
|
||||
"ec2:CreateInternetGateway",
|
||||
"ec2:CreateRoute",
|
||||
"ec2:CreateRouteTable",
|
||||
"ec2:CreateSecurityGroup",
|
||||
"ec2:CreateSubnet",
|
||||
"ec2:CreateTags",
|
||||
"ec2:CreateVpc",
|
||||
"ec2:DeleteInternetGateway",
|
||||
"ec2:DeleteRoute",
|
||||
"ec2:DeleteRouteTable",
|
||||
"ec2:DeleteSecurityGroup",
|
||||
"ec2:DeleteSubnet",
|
||||
"ec2:DeleteTags",
|
||||
"ec2:DeleteVpc",
|
||||
"ec2:DescribeAccountAttributes",
|
||||
"ec2:DescribeAvailabilityZones",
|
||||
"ec2:DescribeInternetGateways",
|
||||
"ec2:DescribeNetworkInterfaces",
|
||||
"ec2:DescribeRouteTables",
|
||||
"ec2:DescribeSecurityGroupRules",
|
||||
"ec2:DescribeSecurityGroups",
|
||||
"ec2:DescribeSubnets",
|
||||
"ec2:DescribeTags",
|
||||
"ec2:DescribeVpcAttribute",
|
||||
"ec2:DescribeVpcs",
|
||||
"ec2:DetachInternetGateway",
|
||||
"ec2:DisassociateRouteTable",
|
||||
"ec2:ModifySubnetAttribute",
|
||||
"ec2:ModifyVpcAttribute",
|
||||
"ec2:RevokeSecurityGroupEgress",
|
||||
"ec2:RevokeSecurityGroupIngress",
|
||||
]
|
||||
Resource = "*"
|
||||
Effect = "Allow"
|
||||
Sid = "VpcSecurityGroups"
|
||||
Sid = "Ec2VpcManagement"
|
||||
},
|
||||
{
|
||||
Action = [
|
||||
|
|
@ -858,9 +880,17 @@ resource "aws_iam_role_policy" "hcptf_plan_refresh" {
|
|||
},
|
||||
{
|
||||
Action = [
|
||||
"ec2:DescribeVpcs",
|
||||
"ec2:DescribeSubnets",
|
||||
"ec2:DescribeAccountAttributes",
|
||||
"ec2:DescribeAvailabilityZones",
|
||||
"ec2:DescribeInternetGateways",
|
||||
"ec2:DescribeNetworkInterfaces",
|
||||
"ec2:DescribeRouteTables",
|
||||
"ec2:DescribeSecurityGroupRules",
|
||||
"ec2:DescribeSecurityGroups",
|
||||
"ec2:DescribeSubnets",
|
||||
"ec2:DescribeTags",
|
||||
"ec2:DescribeVpcAttribute",
|
||||
"ec2:DescribeVpcs",
|
||||
]
|
||||
Resource = "*"
|
||||
Effect = "Allow"
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ locals {
|
|||
|
||||
github_oidc_provider_arn = "arn:aws:iam::${local.account_id}:oidc-provider/token.actions.githubusercontent.com"
|
||||
|
||||
# Prod has no default VPC. 10.60 is unused in 011934824531
|
||||
# (10.0 proposal-system, 10.20 payments-dashboard, 10.40 syslog, 10.80 apm-wo).
|
||||
vpc_cidr = "10.60.0.0/16"
|
||||
public_subnet_cidrs = ["10.60.0.0/24", "10.60.1.0/24"]
|
||||
|
||||
form_bucket_name = "${local.project}-form-${local.account_id}"
|
||||
reports_bucket_name = "${local.project}-reports-${local.account_id}"
|
||||
|
||||
|
|
|
|||
58
terraform/vpc.tf
Normal file
58
terraform/vpc.tf
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
data "aws_availability_zones" "available" {
|
||||
state = "available"
|
||||
}
|
||||
|
||||
resource "aws_vpc" "this" {
|
||||
cidr_block = local.vpc_cidr
|
||||
enable_dns_support = true
|
||||
enable_dns_hostnames = true
|
||||
|
||||
tags = {
|
||||
Name = "${local.project}-vpc"
|
||||
}
|
||||
|
||||
# First apply updates the live hcptf apply role before CreateVpc.
|
||||
depends_on = [aws_iam_role_policy.hcptf_apply_services]
|
||||
}
|
||||
|
||||
resource "aws_internet_gateway" "this" {
|
||||
vpc_id = aws_vpc.this.id
|
||||
|
||||
tags = {
|
||||
Name = "${local.project}-igw"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_subnet" "public" {
|
||||
count = length(local.public_subnet_cidrs)
|
||||
|
||||
vpc_id = aws_vpc.this.id
|
||||
cidr_block = local.public_subnet_cidrs[count.index]
|
||||
availability_zone = data.aws_availability_zones.available.names[count.index]
|
||||
map_public_ip_on_launch = true
|
||||
|
||||
tags = {
|
||||
Name = "${local.project}-public-${count.index}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table" "public" {
|
||||
vpc_id = aws_vpc.this.id
|
||||
|
||||
tags = {
|
||||
Name = "${local.project}-public"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route" "public_default" {
|
||||
route_table_id = aws_route_table.public.id
|
||||
destination_cidr_block = "0.0.0.0/0"
|
||||
gateway_id = aws_internet_gateway.this.id
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "public" {
|
||||
count = length(local.public_subnet_cidrs)
|
||||
|
||||
subnet_id = aws_subnet.public[count.index].id
|
||||
route_table_id = aws_route_table.public.id
|
||||
}
|
||||
26
tests/test_terraform_vpc.py
Normal file
26
tests/test_terraform_vpc.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
"""Meals owns a dedicated VPC. Prod has no default VPC."""
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
TERRAFORM = ROOT / "terraform"
|
||||
|
||||
|
||||
def _read(name: str) -> str:
|
||||
return (TERRAFORM / name).read_text()
|
||||
|
||||
|
||||
def test_meals_owns_a_vpc_instead_of_looking_up_default():
|
||||
vpc = _read("vpc.tf")
|
||||
ecs = _read("ecs.tf")
|
||||
locals_tf = _read("locals.tf")
|
||||
|
||||
assert 'resource "aws_vpc" "this"' in vpc
|
||||
assert "cidr_block = local.vpc_cidr" in vpc
|
||||
assert 'vpc_cidr = "10.60.0.0/16"' in locals_tf
|
||||
assert 'data "aws_vpc" "default"' not in ecs
|
||||
assert "data.aws_vpc.default" not in ecs
|
||||
assert "data.aws_subnets.default" not in ecs
|
||||
assert "aws_vpc.this.id" in ecs
|
||||
assert "aws_subnet.public[*].id" in ecs
|
||||
assert "ec2:CreateVpc" in _read("hcp_iam.tf")
|
||||
Loading…
Add table
Reference in a new issue