Skip to content

Commit

Permalink
- Simplify lambda functions to a single proxy that handles all reques…
Browse files Browse the repository at this point in the history
…ts routed to BC Gov API

- Enable VPC settings for lambda functions
- Added DARS secrets
  • Loading branch information
Ronaldo Macapobre committed Feb 7, 2025
1 parent 0aac51f commit 3863aa1
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 244 deletions.
28 changes: 6 additions & 22 deletions infrastructure/cloud/environments/dev/webapp.tf
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module "iam" {
account_id = data.aws_caller_identity.current.account_id
kms_key_id = module.initial.kms_key_arn
region = var.region
vpc_id = data.aws_vpc.vpc.id
}

# Parse Subnets
Expand Down Expand Up @@ -129,28 +130,11 @@ module "lambda" {
lambda_role_arn = module.iam.lambda_role_arn
apigw_execution_arn = module.apigw.apigw_execution_arn
lambda_ecr_repo_url = module.initial.lambda_ecr.ecr_repo_url
mtls_secret_name = module.secrets_manager.mtls_secret_name
lambda_memory_size = var.lambda_memory_size
functions = {
"authorizer" = {
http_method = "*"
resource_path = ""
env_variables = {
VERIFY_SECRET_NAME = module.secrets_manager.api_authorizer_secret.name
}
},
"rotate-key" = {
http_method = "POST"
resource_path = "/*"
statement_id_prefix = "AllowSecretsManagerInvoke"
source_arn = module.secrets_manager.api_authorizer_secret.arn
principal = "secretsmanager.amazonaws.com"
env_variables = {
VERIFY_SECRET_NAME = module.secrets_manager.api_authorizer_secret.name
CLUSTER_NAME = module.ecs_cluster.ecs_cluster.name
}
}
}
subnet_ids = module.subnets.all_subnet_ids
sg_ids = [data.aws_security_group.web_sg.id, data.aws_security_group.data_sg.id, data.aws_security_group.app_sg.id]
lambda_secrets = module.secrets_manager.lambda_secrets
ecs_cluster_name = module.ecs_cluster.ecs_cluster.name
}

# Create Cloudwatch LogGroups
Expand Down Expand Up @@ -234,7 +218,7 @@ module "ecs_api_td" {
},
{
name = "AWS_API_GATEWAY_URL"
value = module.apigw.apigw_invoke_url
value = "${module.apigw.apigw_invoke_url}${var.environment}"
}
]
secret_env_variables = module.secrets_manager.api_secrets
Expand Down
28 changes: 6 additions & 22 deletions infrastructure/cloud/environments/prod/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module "iam" {
account_id = data.aws_caller_identity.current.account_id
kms_key_id = module.initial.kms_key_arn
region = var.region
vpc_id = data.aws_vpc.vpc.id
}

# Parse Subnets
Expand Down Expand Up @@ -129,28 +130,11 @@ module "lambda" {
lambda_role_arn = module.iam.lambda_role_arn
apigw_execution_arn = module.apigw.apigw_execution_arn
lambda_ecr_repo_url = module.initial.lambda_ecr.ecr_repo_url
mtls_secret_name = module.secrets_manager.mtls_secret_name
lambda_memory_size = var.lambda_memory_size
functions = {
"authorizer" = {
http_method = "*"
resource_path = ""
env_variables = {
VERIFY_SECRET_NAME = module.secrets_manager.api_authorizer_secret.name
}
},
"rotate-key" = {
http_method = "POST"
resource_path = "/*"
statement_id_prefix = "AllowSecretsManagerInvoke"
source_arn = module.secrets_manager.api_authorizer_secret.arn
principal = "secretsmanager.amazonaws.com"
env_variables = {
VERIFY_SECRET_NAME = module.secrets_manager.api_authorizer_secret.name
CLUSTER_NAME = module.ecs_cluster.ecs_cluster.name
}
}
}
subnet_ids = module.subnets.all_subnet_ids
sg_ids = [data.aws_security_group.web_sg.id, data.aws_security_group.data_sg.id, data.aws_security_group.app_sg.id]
lambda_secrets = module.secrets_manager.lambda_secrets
ecs_cluster_name = module.ecs_cluster.ecs_cluster.name
}

# Create Cloudwatch LogGroups
Expand Down Expand Up @@ -234,7 +218,7 @@ module "ecs_api_td" {
},
{
name = "AWS_API_GATEWAY_URL"
value = module.apigw.apigw_invoke_url
value = "${module.apigw.apigw_invoke_url}${var.environment}"
}
]
secret_env_variables = module.secrets_manager.api_secrets
Expand Down
28 changes: 6 additions & 22 deletions infrastructure/cloud/environments/test/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ module "iam" {
account_id = data.aws_caller_identity.current.account_id
kms_key_id = module.initial.kms_key_arn
region = var.region
vpc_id = data.aws_vpc.vpc.id
}

# Parse Subnets
Expand Down Expand Up @@ -129,28 +130,11 @@ module "lambda" {
lambda_role_arn = module.iam.lambda_role_arn
apigw_execution_arn = module.apigw.apigw_execution_arn
lambda_ecr_repo_url = module.initial.lambda_ecr.ecr_repo_url
mtls_secret_name = module.secrets_manager.mtls_secret_name
lambda_memory_size = var.lambda_memory_size
functions = {
"authorizer" = {
http_method = "*"
resource_path = ""
env_variables = {
VERIFY_SECRET_NAME = module.secrets_manager.api_authorizer_secret.name
}
},
"rotate-key" = {
http_method = "POST"
resource_path = "/*"
statement_id_prefix = "AllowSecretsManagerInvoke"
source_arn = module.secrets_manager.api_authorizer_secret.arn
principal = "secretsmanager.amazonaws.com"
env_variables = {
VERIFY_SECRET_NAME = module.secrets_manager.api_authorizer_secret.name
CLUSTER_NAME = module.ecs_cluster.ecs_cluster.name
}
}
}
subnet_ids = module.subnets.all_subnet_ids
sg_ids = [data.aws_security_group.web_sg.id, data.aws_security_group.data_sg.id, data.aws_security_group.app_sg.id]
lambda_secrets = module.secrets_manager.lambda_secrets
ecs_cluster_name = module.ecs_cluster.ecs_cluster.name
}

# Create Cloudwatch LogGroups
Expand Down Expand Up @@ -234,7 +218,7 @@ module "ecs_api_td" {
},
{
name = "AWS_API_GATEWAY_URL"
value = module.apigw.apigw_invoke_url
value = "${module.apigw.apigw_invoke_url}${var.environment}"
}
]
secret_env_variables = module.secrets_manager.api_secrets
Expand Down
128 changes: 11 additions & 117 deletions infrastructure/cloud/modules/APIGateway/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ resource "aws_api_gateway_rest_api" "apigw" {

resource "aws_api_gateway_deployment" "apigw_deployment" {
depends_on = [
# Add new integration here so that it registers in API Gateway
aws_api_gateway_integration.get_locations_integration,
aws_api_gateway_integration.get_locations_rooms_integration,
aws_api_gateway_integration.get_files_civil_integration,
aws_api_gateway_integration.get_files_criminal_integration,
aws_api_gateway_integration.lambda_integration,
]
rest_api_id = aws_api_gateway_rest_api.apigw.id

Expand Down Expand Up @@ -111,89 +107,17 @@ resource "aws_api_gateway_authorizer" "authorizer" {
identity_source = "method.request.header.x-origin-verify"
}

#
# /locations Resource
#
resource "aws_api_gateway_resource" "locations_resource" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
parent_id = aws_api_gateway_rest_api.apigw.root_resource_id
path_part = "locations"
}

# GET /locations
resource "aws_api_gateway_method" "get_locations_method" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
resource_id = aws_api_gateway_resource.locations_resource.id
http_method = var.lambda_functions["get-locations"].http_method
authorization = "CUSTOM"
authorizer_id = aws_api_gateway_authorizer.authorizer.id
api_key_required = true

request_parameters = {
"method.request.header.x-origin-verify" = true
}
}

resource "aws_api_gateway_integration" "get_locations_integration" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
resource_id = aws_api_gateway_resource.locations_resource.id
http_method = aws_api_gateway_method.get_locations_method.http_method
type = "AWS_PROXY"
integration_http_method = "POST"
uri = var.lambda_functions["get-locations"].invoke_arn
}

# /locations/rooms Resource
resource "aws_api_gateway_resource" "rooms_resource" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
parent_id = aws_api_gateway_resource.locations_resource.id
path_part = "rooms"
}

# GET /locations/rooms
resource "aws_api_gateway_method" "get_locations_rooms_method" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
resource_id = aws_api_gateway_resource.rooms_resource.id
http_method = var.lambda_functions["get-rooms"].http_method
authorization = "CUSTOM"
authorizer_id = aws_api_gateway_authorizer.authorizer.id
api_key_required = true

request_parameters = {
"method.request.header.x-origin-verify" = true
}
}

resource "aws_api_gateway_integration" "get_locations_rooms_integration" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
resource_id = aws_api_gateway_resource.rooms_resource.id
http_method = aws_api_gateway_method.get_locations_rooms_method.http_method
type = "AWS_PROXY"
integration_http_method = "POST"
uri = var.lambda_functions["get-rooms"].invoke_arn
}

#
# /files Resource
#
resource "aws_api_gateway_resource" "files_resource" {
# Root Resource /
resource "aws_api_gateway_resource" "root_resource" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
parent_id = aws_api_gateway_rest_api.apigw.root_resource_id
path_part = "files"
}

# /files/civil Resource
resource "aws_api_gateway_resource" "civil_resource" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
parent_id = aws_api_gateway_resource.files_resource.id
path_part = "civil"
path_part = "{proxy+}"
}

# GET /files/civil
resource "aws_api_gateway_method" "get_files_civil_method" {
resource "aws_api_gateway_method" "root_method" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
resource_id = aws_api_gateway_resource.civil_resource.id
http_method = var.lambda_functions["search-civil-files"].http_method
resource_id = aws_api_gateway_resource.root_resource.id
http_method = "ANY"
authorization = "CUSTOM"
authorizer_id = aws_api_gateway_authorizer.authorizer.id
api_key_required = true
Expand All @@ -203,41 +127,11 @@ resource "aws_api_gateway_method" "get_files_civil_method" {
}
}

resource "aws_api_gateway_integration" "get_files_civil_integration" {
resource "aws_api_gateway_integration" "lambda_integration" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
resource_id = aws_api_gateway_resource.civil_resource.id
http_method = aws_api_gateway_method.get_files_civil_method.http_method
type = "AWS_PROXY"
resource_id = aws_api_gateway_resource.root_resource.id
http_method = aws_api_gateway_method.root_method.http_method
integration_http_method = "POST"
uri = var.lambda_functions["search-civil-files"].invoke_arn
}

# /files/criminal Resource
resource "aws_api_gateway_resource" "criminal_resource" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
parent_id = aws_api_gateway_resource.files_resource.id
path_part = "criminal"
}

# GET /files/criminal
resource "aws_api_gateway_method" "get_files_criminal_method" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
resource_id = aws_api_gateway_resource.criminal_resource.id
http_method = var.lambda_functions["search-criminal-files"].http_method
authorization = "CUSTOM"
authorizer_id = aws_api_gateway_authorizer.authorizer.id
api_key_required = true

request_parameters = {
"method.request.header.x-origin-verify" = true
}
}

resource "aws_api_gateway_integration" "get_files_criminal_integration" {
rest_api_id = aws_api_gateway_rest_api.apigw.id
resource_id = aws_api_gateway_resource.criminal_resource.id
http_method = aws_api_gateway_method.get_files_criminal_method.http_method
type = "AWS_PROXY"
integration_http_method = "POST"
uri = var.lambda_functions["search-criminal-files"].invoke_arn
uri = var.lambda_functions["proxy-request"].invoke_arn
}
11 changes: 6 additions & 5 deletions infrastructure/cloud/modules/ECS/TaskDefinition/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ resource "aws_ecs_task_definition" "ecs_td" {
execution_role_arn = var.ecs_execution_role_arn
task_role_arn = var.ecs_execution_role_arn

lifecycle {
# Since the dummy-image will be replaced when the GHA pipeline runs,
# the whole container_definition edits has been ignored.
ignore_changes = [container_definitions]
}
# This will be uncommented out when the long term solution is implemented (JASPER-291)
# lifecycle {
# # Since the dummy-image will be replaced when the GHA pipeline runs,
# # the whole container_definition edits has been ignored.
# ignore_changes = [container_definitions]
# }

container_definitions = jsonencode([
{
Expand Down
19 changes: 17 additions & 2 deletions infrastructure/cloud/modules/IAM/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -287,8 +287,7 @@ resource "aws_iam_policy" "lambda_role_policy" {
"ecs:ListServices"
],
"Resource" : [
"arn:aws:ecs:${var.region}:${var.account_id}:cluster/${var.app_name}-app-cluster-${var.environment}",
"arn:aws:ecs:${var.region}:${var.account_id}:service/${var.app_name}-app-cluster-${var.environment}/${var.app_name}-*-ecs-service-${var.environment}"
"arn:aws:ecs:${var.region}:${var.account_id}:service/${var.app_name}-app-cluster-${var.environment}/*"
]
},
{
Expand All @@ -301,6 +300,22 @@ resource "aws_iam_policy" "lambda_role_policy" {
"Resource" : [
"arn:aws:ecr:${var.region}:${var.account_id}:repository/${var.app_name}-*-repo-${var.environment}"
]
},
{
"Action" : [
"ec2:CreateNetworkInterface",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface",
"ec2:AttachNetworkInterface",
"ec2:DetachNetworkInterface"
],
"Effect" : "Allow",
"Resource" : "*",
"Condition" : {
"ArnLikeIfExists" : {
"ec2:Vpc" : "arn:aws:ec2:${var.region}:*:vpc/${var.vpc_id}"
}
}
}
]
})
Expand Down
5 changes: 5 additions & 0 deletions infrastructure/cloud/modules/IAM/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,8 @@ variable "region" {
description = "The AWS region"
type = string
}

variable "vpc_id" {
description = "The default VPC Id"
type = string
}
Loading

0 comments on commit 3863aa1

Please sign in to comment.