Skip to content

Commit

Permalink
Deploy vengeful vineyard to AWS Lambda/API Gateway (#662)
Browse files Browse the repository at this point in the history
  • Loading branch information
junlarsen authored Oct 30, 2023
1 parent 8ea6eab commit f1f4c58
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 24 deletions.
23 changes: 23 additions & 0 deletions infra/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion infra/auth.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module "post_signup_trigger_lambda" {
ecr_repository_name = "dispatcher-auth-${terraform.workspace}"
function_name = "dispatcher-auth-${terraform.workspace}"
execution_role_name = "DispatcherAuthExecuteRole${title(terraform.workspace)}"
environment_variables = local.aws_safe_doppler_secrets
environment_variables = local.monoweb_aws_safe_doppler_secrets

tags = {
Project = "monoweb"
Expand Down
26 changes: 24 additions & 2 deletions infra/doppler.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
data "doppler_secrets" "monoweb" {
config = terraform.workspace
project = "monoweb"

provider = doppler.monoweb
}

locals {
aws_safe_doppler_secrets = {
for key, value in data.doppler_secrets.monoweb.map : key => value if !contains(["AWS_REGION", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"], key)
forbidden_aws_lambda_keys = [
"AWS_REGION",
"AWS_DEFAULT_REGION",
"AWS_ACCESS_KEY",
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
"AWS_SESSION_TOKEN"
]

monoweb_aws_safe_doppler_secrets = {
for key, value in data.doppler_secrets.monoweb.map : key => value if !contains(local.forbidden_aws_lambda_keys, key)
}

vengeful_aws_safe_doppler_secrets = {
for key, value in data.doppler_secrets.vengeful.map : key => value if !contains(local.forbidden_aws_lambda_keys, key)
}
}

data "doppler_secrets" "vengeful" {
project = "vengeful-vineyard"
config = terraform.workspace

provider = doppler.vengeful
}
1 change: 1 addition & 0 deletions infra/modules/aws-docker-lambda/lambda.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ resource "aws_lambda_function" "this" {
timeout = var.function_timeout
image_uri = "${aws_ecr_repository.this.repository_url}:latest"
package_type = "Image"
memory_size = var.memory

environment {
variables = var.environment_variables
Expand Down
6 changes: 6 additions & 0 deletions infra/modules/aws-docker-lambda/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ variable "function_timeout" {
default = 60
}

variable "memory" {
description = "How much memory to allocate to lambda in MB"
type = number
default = 128
}

variable "environment_variables" {
description = "Environment variables to attach to the lambda"
type = map(string)
Expand Down
15 changes: 7 additions & 8 deletions infra/modules/aws-s3-public-bucket/cloudfront.tf
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
resource "aws_cloudfront_origin_access_identity" "this" {
comment = "${var.domain_name}/aws-cloudfront-origin-access-identity"
}

resource "aws_cloudfront_distribution" "this" {
origin {
domain_name = aws_s3_bucket.this.bucket_domain_name
domain_name = aws_s3_bucket_website_configuration.this.website_endpoint
origin_id = "s3"

s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.this.cloudfront_access_identity_path
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = ["TLSv1.2"]
}
}

enabled = true
is_ipv6_enabled = true

default_root_object = "_index.html"
default_root_object = "index.html"
aliases = [var.domain_name]
price_class = "PriceClass_100"

Expand Down
8 changes: 3 additions & 5 deletions infra/modules/aws-s3-public-bucket/iam.tf
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
data "aws_iam_policy_document" "cdn" {
version = "2008-10-17"
statement {
sid = "AllowCloudFrontReadOnly"
sid = "AllowPublicRead"
effect = "Allow"
principals {
type = "AWS"
identifiers = [
aws_cloudfront_origin_access_identity.this.iam_arn
]
type = "*"
identifiers = ["*"]
}
actions = ["s3:GetObject"]
resources = [
Expand Down
3 changes: 3 additions & 0 deletions infra/modules/aws-s3-public-bucket/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "domain_name" {
value = aws_cloudfront_distribution.this.domain_name
}
5 changes: 2 additions & 3 deletions infra/modules/aws-s3-public-bucket/s3.tf
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@ resource "aws_s3_bucket_website_configuration" "this" {
resource "aws_s3_bucket_public_access_block" "this" {
bucket = aws_s3_bucket.this.id

block_public_acls = true
block_public_policy = true
ignore_public_acls = true
block_public_acls = false
block_public_policy = false
restrict_public_buckets = false
}

Expand Down
17 changes: 14 additions & 3 deletions infra/providers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,24 @@ provider "vercel" {
team = "dotkom"
}

variable "doppler_token" {
description = "TF Variable for the doppler token"
variable "doppler_token_monoweb" {
description = "TF Variable for the monoweb doppler token"
type = string
}

provider "doppler" {
doppler_token = var.doppler_token
doppler_token = var.doppler_token_monoweb
alias = "monoweb"
}

variable "doppler_token_vengeful" {
description = "TF Variable for the vengeful doppler token"
type = string
}

provider "doppler" {
doppler_token = var.doppler_token_vengeful
alias = "vengeful"
}

provider "neon" {}
131 changes: 129 additions & 2 deletions infra/vengeful-vineyard.tf
Original file line number Diff line number Diff line change
@@ -1,9 +1,136 @@
locals {
vengeful_project_name = "vengeful-vineyard-${terraform.workspace}"
vengeful_project_name = "vengeful-vineyard-${terraform.workspace}"
vengeful_domain_name = "${terraform.workspace}.redwine.online.ntnu.no"
vengeful_cdn_domain_name = "${terraform.workspace}.redwine-static.online.ntnu.no"
}

module "vengeful_database" {
source = "./modules/neon-project"
source = "./modules/neon-project"

project_name = local.vengeful_project_name
role_name = "vengeful"
}

module "vengeful_lambda" {
source = "./modules/aws-docker-lambda"

ecr_repository_name = "vengeful-vineyard-${terraform.workspace}"
function_name = "vengeful-vineyard-${terraform.workspace}"
execution_role_name = "VengefulVineyardExecutionRole${title(terraform.workspace)}"
iam_inline_policies = []
environment_variables = local.vengeful_aws_safe_doppler_secrets
memory = 1024

tags = {
Project = "vengeful-vineyard"
Environment = terraform.workspace
}
}

module "vengeful_gateway_domain_certificate" {
source = "./modules/aws-acm-certificate"

domain = local.vengeful_domain_name
zone_id = local.zone_id

tags = {
Project = "vengeful-vineyard"
Environment = terraform.workspace
}

providers = {
aws.regional = aws.eu-north-1
}
}

module "vengeful_gateway_proxy" {
source = "./modules/aws-api-gateway"

domain = local.vengeful_domain_name
zone_id = local.zone_id
certificate_arn = module.vengeful_gateway_domain_certificate.certificate_arn

tags = {
Project = "vengeful-vineyard"
Environment = terraform.workspace
}
}

# ---------------------------------------------------------------------------------------------------------------------
# Connect backend lambda to API Gateway
# ---------------------------------------------------------------------------------------------------------------------

resource "aws_apigatewayv2_integration" "vengeful_backend_lambda" {
api_id = module.vengeful_gateway_proxy.api_gateway_id
integration_type = "AWS_PROXY"
integration_method = "POST"
integration_uri = module.vengeful_lambda.lambda_invoke_arn
payload_format_version = "1.0"
}

resource "aws_apigatewayv2_route" "vengeful_backend_lambda" {
api_id = module.vengeful_gateway_proxy.api_gateway_id
route_key = "ANY /api/{proxy+}"
target = "integrations/${aws_apigatewayv2_integration.vengeful_backend_lambda.id}"
}

resource "aws_lambda_permission" "vengeful_backend_gateway_lambda" {
statement_id = "APIGatewayExecuteLambda"
action = "lambda:InvokeFunction"
principal = "apigateway.amazonaws.com"
function_name = module.vengeful_lambda.lambda_name
source_arn = "${module.vengeful_gateway_proxy.api_gateway_execution_arn}/*/*"
}

# ---------------------------------------------------------------------------------------------------------------------
# Define static bucket for frontend Vite app
# ---------------------------------------------------------------------------------------------------------------------

module "vengeful_cdn_domain_certificate" {
source = "./modules/aws-acm-certificate"

domain = local.vengeful_cdn_domain_name
zone_id = local.zone_id

tags = {
Project = "vengeful-vineyard"
Environment = terraform.workspace
}

providers = {
aws.regional = aws.us-east-1
}
}

module "vengeful_cdn_bucket" {
source = "./modules/aws-s3-public-bucket"

certificate_arn = module.vengeful_cdn_domain_certificate.certificate_arn
domain_name = local.vengeful_cdn_domain_name
zone_id = local.zone_id

tags = {
Project = "vengeful-vineyard"
Environment = terraform.workspace
}

depends_on = [module.vengeful_cdn_domain_certificate]
}

# ---------------------------------------------------------------------------------------------------------------------
# Connect static bucket CDN to API Gateway
# ---------------------------------------------------------------------------------------------------------------------

resource "aws_apigatewayv2_integration" "vengeful_cdn" {
api_id = module.vengeful_gateway_proxy.api_gateway_id
integration_type = "HTTP_PROXY"
integration_method = "GET"
integration_uri = "https://${module.vengeful_cdn_bucket.domain_name}"
passthrough_behavior = "WHEN_NO_MATCH"
}

resource "aws_apigatewayv2_route" "vengeful_cdn" {
api_id = module.vengeful_gateway_proxy.api_gateway_id
route_key = "$default"
target = "integrations/${aws_apigatewayv2_integration.vengeful_cdn.id}"
}

1 comment on commit f1f4c58

@vercel
Copy link

@vercel vercel bot commented on f1f4c58 Oct 30, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

web – ./apps/web

web-git-main-dotkom.vercel.app
web-pi-umber.vercel.app
dev.web.online.ntnu.no
web-dotkom.vercel.app

Please sign in to comment.