Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some refactoring for Yakov to review! #12

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
91f44a5
ammending gitignore, setting-up PR
colemandevries May 14, 2022
c24c43d
commenting out trigger for lambda build workflow
colemandevries May 14, 2022
dc84082
tidy lambda variables, reformatting with tf fmt
colemandevries May 14, 2022
2d0f975
Updated Lambda module main.tf and variables.tf
colemandevries May 14, 2022
0680ce2
finished refactoring lambda module, created outputs file
colemandevries May 14, 2022
9cfde4f
Updated lambda module variable descriptions
colemandevries May 14, 2022
92842a8
updated lambda module main.tf tags, reformatted tf
colemandevries May 14, 2022
9e11153
beginning dynamodb module refactoring, created outputs.tf
colemandevries May 14, 2022
936fdc1
making dynamodb more generic in conventions and variable usage
colemandevries May 14, 2022
19af06a
modifying dynamo role and policies with aws_iam_policy_document data …
colemandevries May 14, 2022
f2278bf
Refactored the ddb module IAM role
colemandevries May 14, 2022
faad5e4
Finished dynamodb role refactor
colemandevries May 14, 2022
b2f5af0
Refactoring the apigateway module
colemandevries May 14, 2022
af30b62
parameterizing API Gateway module with variables
colemandevries May 14, 2022
2216bf0
format changes for readability
colemandevries May 14, 2022
a4c842c
reformatting for readability and variable naming consistency
colemandevries May 14, 2022
81acf06
restructuring api-gateway module/file composition
colemandevries May 14, 2022
db18eb1
updated lambda module file structure
colemandevries May 14, 2022
86ef7ef
cleaning up variable names
colemandevries May 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/lambda-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ name: Lambda Build
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the master branch
pull_request:
branches: [ master ]
# pull_request:
# branches: [ master ]


# Allows you to run this workflow manually from the Actions tab
Expand Down
12 changes: 11 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,14 @@
notes
pgmSSHKey.pem
*.iml
scratch/
scratch/
**/.terraform/*
*.tfstate
*.tfstate.*
crash.log
override.tf
override.tf.json
*_override.tf
*_override.tf.json
.DS_Store
*.DS_Store*
10 changes: 5 additions & 5 deletions tf/locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ data "template_file" "api_swagger" {
template = file("modules/lambda/tf-swagger-userapi-v3.yaml")

vars = {
lambda_arn = module.lambda.lambda_arn
lambda_arn = module.lambda.lambda_arn
ddb_action_get_item = "arn:aws:apigateway:us-east-1:dynamodb:action/GetItem"
ddb_action_scan = "arn:aws:apigateway:us-east-1:dynamodb:action/Scan"
ddb_action_query = "arn:aws:apigateway:us-east-1:dynamodb:action/Query"
ddb_role_arn = module.ddb-extusers.iam-access-ddb-role-arn
users_table_name = module.ddb-extusers.ddb-extusers-name
ddb_action_scan = "arn:aws:apigateway:us-east-1:dynamodb:action/Scan"
ddb_action_query = "arn:aws:apigateway:us-east-1:dynamodb:action/Query"
ddb_role_arn = module.ddb-extusers.iam-access-ddb-role-arn
users_table_name = module.ddb-extusers.ddb-extusers-name
}
}

36 changes: 19 additions & 17 deletions tf/main.tf
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@


module "ddb-extusers" {
source = "./modules/ddb-extusers"
env = var.env
module "dynamodb" {
source = "./modules/dynamodb"
env = var.env
}

module "lambda" {
depends_on = [module.ddb-extusers]
source = "./modules/lambda"
env = var.env
depends_on = [module.dynamodb]

source = "./modules/lambda"
env = var.env
must-be-role-prefix = var.role-prefix
must-be-policy-arn = var.policy-boundary-arn
ddb-table-name = module.ddb-extusers.ddb-extusers-name
must-be-policy-arn = var.policy-boundary-arn
ddb-table-name = module.dynamodb.dynamodb_table_name
}

module "api-gateway" {
depends_on = [module.ddb-extusers, module.lambda]
source = "./modules/api-gateway"
env = var.env
depends_on = [module.dynamodb, module.lambda]

source = "./modules/api-gateway"
env = var.env
must-be-role-prefix = var.role-prefix
must-be-policy-arn = var.policy-boundary-arn
okta-issuer = lookup(local.OktaMap, var.env).issuer
app-name = "eracommons"
app-description = "Enterprise Data & Integration Services Web Services"
api-swagger = data.template_file.api_swagger.rendered
api-resource-policy = local.resource_policy
must-be-policy-arn = var.policy-boundary-arn
okta-issuer = lookup(local.OktaMap, var.env).issuer
app-name = "eracommons"
app-description = "Enterprise Data & Integration Services Web Services"
api-swagger = data.template_file.api_swagger.rendered
api-resource-policy = local.resource_policy
}
3 changes: 3 additions & 0 deletions tf/modules/api-gateway/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
The api-gateway module creates api gateway based on a given swagger file and includes lambda authorizer for authorization API calls


<!-- BEGIN_TF_DOCS -->
## Requirements

Expand Down
23 changes: 23 additions & 0 deletions tf/modules/api-gateway/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
data "aws_iam_policy_document" "assume_role_lambda_service" {
statement {
sid = ""
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}

data "aws_iam_policy_document" "assume_role_apigateway_service" {
statement {
sid = ""
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["apigateway.amazonaws.com"]
}
}
}
175 changes: 107 additions & 68 deletions tf/modules/api-gateway/main.tf
Original file line number Diff line number Diff line change
@@ -1,101 +1,140 @@
#
# The api-gateway module creates api gateway based on a given swagger file
# and includes lambda authorizer for authorization API calls
#
resource "aws_api_gateway_account" "api_gateway" {
cloudwatch_role_arn = aws_iam_role.api_gateway.arn
}

resource "aws_api_gateway_rest_api" "api_gateway" {
name = "${var.app}-REST-API-${var.env}"
description = "${var.env} - ${var.app-description}"
disable_execute_api_endpoint = var.apigw_disable_execute_api_endpoint
body = [var.api-swagger]

endpoint_configuration {
types = var.apigw_endpoint_config
}

tags = {
app = var.app
}
}

# the policy would ideally be set-up with a datasource (and lifecycle hook for depends on)
# can still use count with a bool variable to indicate whether or not a policy should be applied.
resource "aws_api_gateway_rest_api_policy" "api_gateway" {
count = (var.api-resource-policy != "") ? 1 : 0

rest_api_id = aws_api_gateway_rest_api.api_gateway.id
policy = var.api-resource-policy
}

resource "aws_api_gateway_deployment" "api_gateway" {
rest_api_id = aws_api_gateway_rest_api.api_gateway.id
}

resource "aws_api_gateway_stage" "api_gateway" {
deployment_id = aws_api_gateway_deployment.api_gateway.id
rest_api_id = aws_api_gateway_rest_api.api_gateway.id
stage_name = var.env
cache_cluster_enabled = var.apigw_stage_cache_enabled
cache_cluster_size = var.apigw_stage_cache_size
xray_tracing_enabled = var.apigw_stage_xray_enabled

access_log_settings {
destination_arn = aws_cloudwatch_log_group.api_gateway.arn
format = "{ \"requestTime\": \"$context.requestTime\", \"requestId\": \"$context.requestId\", \"httpMethod\": \"$context.httpMethod\", \"path\": \"$context.path\", \"resourcePath\": \"$context.resourcePath\", \"status\": $context.status, \"responseLatency\": $context.responseLatency, \"xrayTraceId\": \"$context.xrayTraceId\", \"integrationRequestId\": \"$context.integration.requestId\", \"functionResponseStatus\": \"$context.integration.status\", \"integrationLatency\": \"$context.integration.latency\", \"integrationServiceStatus\": \"$context.integration.integrationStatus\", \"authorizeResultStatus\": \"$context.authorize.status\", \"authorizerServiceStatus\": \"$context.authorizer.status\", \"authorizerLatency\": \"$context.authorizer.latency\", \"authorizerRequestId\": \"$context.authorizer.requestId\", \"ip\": \"$context.identity.sourceIp\", \"userAgent\": \"$context.identity.userAgent\", \"principalId\": \"$context.authorizer.principalId\", \"user\": \"$context.identity.user\" }"
}
}

resource "aws_api_gateway_method_settings" "api_gateway" {
method_path = var.apigw_method_path
rest_api_id = aws_api_gateway_rest_api.api_gateway.id
stage_name = aws_api_gateway_stage.api_gateway.stage_name

settings {
metrics_enabled = var.apigw_method_metrics_enabled
logging_level = var.apigw_method_log_level
data_trace_enabled = var.apigw_method_trace_enabled
cache_data_encrypted = var.apigw_method_cache_encryption
cache_ttl_in_seconds = var.apigw_method_cache_ttl
caching_enabled = var.apigw_method_cache_enabled
}
}

# Lambda Authorizer

resource "aws_api_gateway_authorizer" "api_gateway" {
name = "${var.app}-lambda-authorizer-${var.env}"
rest_api_id = aws_api_gateway_rest_api.api_gateway.id
authorizer_uri = aws_lambda_function.auth_lambda.invoke_arn
type = var.authorizer_type
}

resource "aws_lambda_function" "auth_lambda" {
function_name = "lambda-auth-${var.env}"
function_name = "${var.app}-lambda-auth-${var.env}"
role = aws_iam_role.auth_lambda.arn
description = "Lambda function with basic authorization."
handler = "src/lambda.handler"
runtime = "nodejs12.x"
memory_size = 2048
timeout = 30
handler = var.lambda_handler_file
runtime = var.lambda_runtime
memory_size = var.lambda_memory_size
timeout = var.timeout
filename = var.lambda_file_location

tracing_config {
mode = "Active"
mode = var.lambda_tracing_mode
}

environment {
variables = {
"LOG_LEVEL" = "info"
"LOG_LEVEL" = var.lambda_log_level
"AUDIENCE" = var.okta-audience
"ISSUER" = var.okta-issuer
}
}

tags = {
app = var.app-name
app = var.app
}
filename = "../lambda-zip/lambda-auth/lambda-auth.zip"
}

resource "aws_lambda_function_event_invoke_config" "auth_lambda" {
function_name = aws_lambda_function.auth_lambda.function_name
maximum_retry_attempts = 0
}

resource "aws_api_gateway_account" "api_gateway" {
cloudwatch_role_arn = "${aws_iam_role.api_gateway.arn}"
}

resource "aws_api_gateway_rest_api" "api_gateway" {
name = "${var.app-name} - ${var.env}"
description = "${var.env} - ${var.app-description}"
endpoint_configuration {
types = ["REGIONAL"]
}
body = var.api-swagger
function_name = aws_lambda_function.auth_lambda.function_name
maximum_retry_attempts = var.lambda_config_retry_attempts
}

resource "aws_api_gateway_deployment" "api_gateway" {
rest_api_id = "${aws_api_gateway_rest_api.api_gateway.id}"
resource "aws_cloudwatch_log_group" "api_gateway" {
name = "${var.portfolio}-${var.env}-${var.app}-accesslogs"
retention_in_days = var.cloudwatch_log_retention_days
}

resource "aws_api_gateway_authorizer" "api_gateway" {
name = "era-commons-user-api-authorizer"
rest_api_id = "${aws_api_gateway_rest_api.api_gateway.id}"
authorizer_uri = "${aws_lambda_function.auth_lambda.invoke_arn}"
type = "TOKEN"
resource "aws_iam_role" "auth_lambda" {
name = "${var.must-be-role-prefix}-lambda-auth-${var.env}"
assume_role_policy = data.aws_iam_policy_document.assume_role_lambda_service.json
path = "/"
permissions_boundary = var.must-be-policy-arn
}

resource "aws_api_gateway_rest_api_policy" "api_gateway" {
count = (var.api-resource-policy != "") ? 1 : 0
rest_api_id = aws_api_gateway_rest_api.api_gateway.id
policy = var.api-resource-policy
resource "aws_iam_role_policy_attachment" "auth_lambda" {
role = aws_iam_role.auth_lambda.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

resource "aws_cloudwatch_log_group" "api_gateway" {
name = "business_apps-${var.env}-${var.app-name}-accesslogs"
retention_in_days = 90
resource "aws_iam_role_policy_attachment" "auth_lambda" {
role = aws_iam_role.auth_lambda.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
}

resource "aws_api_gateway_stage" "api_gateway" {
deployment_id = "${aws_api_gateway_deployment.api_gateway.id}"
rest_api_id = "${aws_api_gateway_rest_api.api_gateway.id}"
stage_name = "${var.env}"
cache_cluster_enabled = true
cache_cluster_size = "1.6"
access_log_settings {
destination_arn = "${aws_cloudwatch_log_group.api_gateway.arn}"
format = "{ \"requestTime\": \"$context.requestTime\", \"requestId\": \"$context.requestId\", \"httpMethod\": \"$context.httpMethod\", \"path\": \"$context.path\", \"resourcePath\": \"$context.resourcePath\", \"status\": $context.status, \"responseLatency\": $context.responseLatency, \"xrayTraceId\": \"$context.xrayTraceId\", \"integrationRequestId\": \"$context.integration.requestId\", \"functionResponseStatus\": \"$context.integration.status\", \"integrationLatency\": \"$context.integration.latency\", \"integrationServiceStatus\": \"$context.integration.integrationStatus\", \"authorizeResultStatus\": \"$context.authorize.status\", \"authorizerServiceStatus\": \"$context.authorizer.status\", \"authorizerLatency\": \"$context.authorizer.latency\", \"authorizerRequestId\": \"$context.authorizer.requestId\", \"ip\": \"$context.identity.sourceIp\", \"userAgent\": \"$context.identity.userAgent\", \"principalId\": \"$context.authorizer.principalId\", \"user\": \"$context.identity.user\" }"
}
xray_tracing_enabled = true
resource "aws_iam_role_policy_attachment" "auth_lambda" {
role = aws_iam_role.auth_lambda.name
policy_arn = "arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess"
}

resource "aws_api_gateway_method_settings" "api_gateway" {
method_path = "*/*"
rest_api_id = "${aws_api_gateway_rest_api.api_gateway.id}"
stage_name = "${aws_api_gateway_stage.api_gateway.stage_name}"
settings {
metrics_enabled = true
logging_level = "INFO"
data_trace_enabled = true
cache_data_encrypted = true
cache_ttl_in_seconds = 300
caching_enabled = true
}
resource "aws_iam_role" "api_gateway" {
name = "${var.must-be-role-prefix}-api-gateway-${var.app}-${var.env}"
assume_role_policy = data.aws_iam_policy_document.assume_role_apigateway_service
path = "/"
permissions_boundary = var.must-be-policy-arn
}

output "url" {
value = "${aws_api_gateway_deployment.api_gateway.invoke_url}/api"
}
resource "aws_iam_role_policy_attachment" "api_gateway" {
role = aws_iam_role.api_gateway.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs"
}
3 changes: 3 additions & 0 deletions tf/modules/api-gateway/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "url" {
value = "${aws_api_gateway_deployment.api_gateway.invoke_url}/api"
}
50 changes: 0 additions & 50 deletions tf/modules/api-gateway/roles.tf

This file was deleted.

Loading