1
0
Files
2026-02-13 15:44:24 +08:00

170 lines
5.0 KiB
Terraform

/**
* # ApigwAuthSample
* A working example which deploys HTTP api, Lambda functions, and necessary permissions.
*
*
* ## Testing the API
* To test this in postman, put in the following settings:
*
* URL: https://<api-id>.execute-api.ap-east-1.amazonaws.com/?inputValue=TestMessage123
* Authorization: api key, key = Authorizations, value = sha256 hash, add to = Header
*
*/
# IAM role for Lambda execution
data "aws_iam_policy_document" "lambda_role" {
statement {
effect = "Allow"
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
actions = ["sts:AssumeRole"]
}
}
resource "aws_iam_role" "role" {
name = "ApiFunctionRole"
assume_role_policy = data.aws_iam_policy_document.lambda_role.json
}
resource "aws_iam_role_policy_attachment" "role" {
role = aws_iam_role.role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
data "archive_file" "EchoFunction" {
type = "zip"
source_file = "${path.module}/EchoFunction.py"
output_path = "${path.module}/EchoFunction.zip"
}
resource "aws_lambda_function" "EchoFunction" {
filename = data.archive_file.EchoFunction.output_path
function_name = "EchoFunction"
description = "Function that echo query parameter inputValue"
role = aws_iam_role.role.arn
handler = "EchoFunction.lambda_handler"
source_code_hash = data.archive_file.EchoFunction.output_base64sha256
architectures = ["arm64"]
runtime = "python3.13"
}
resource "aws_lambda_permission" "EchoFunction" {
statement_id = "AllowExecutionFromApi"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.EchoFunction.function_name
principal = "apigateway.amazonaws.com"
source_arn = "arn:aws:execute-api:${var.aws-region}:${data.aws_caller_identity.this.account_id}:${aws_apigatewayv2_api.SampleHttpApi.id}/*/*"
}
data "archive_file" "SampleAuthorizer" {
type = "zip"
source_file = "${path.module}/SampleAuthorizer.py"
output_path = "${path.module}/SampleAuthorizer.zip"
}
/* Test function with this input
{
"routeArn": "arn:aws:execute-api:ap-east-1:040216112220:wxzvfmiyd2/$default/GET/"
"headers": {
"authorization": "value of pw_hash"
}
}
*/
resource "random_password" "pw" {
length = 20
min_upper = 2
min_lower = 2
min_numeric = 2
min_special = 2
}
resource "aws_lambda_function" "SampleAuthorizer" {
filename = data.archive_file.SampleAuthorizer.output_path
function_name = "SampleAuthorizer"
description = "API authorizer"
role = aws_iam_role.role.arn
handler = "SampleAuthorizer.lambda_handler"
source_code_hash = data.archive_file.SampleAuthorizer.output_base64sha256
architectures = ["arm64"]
runtime = "python3.13"
environment {
variables = {
region = var.aws-region
account_id = data.aws_caller_identity.this.account_id
api_id = aws_apigatewayv2_api.SampleHttpApi.id
pw_hash = sha256(random_password.pw.result)
}
}
}
resource "aws_lambda_permission" "SampleAuthorizer" {
statement_id = "AllowExecutionFromApi"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.SampleAuthorizer.function_name
principal = "apigateway.amazonaws.com"
source_arn = "arn:aws:execute-api:${var.aws-region}:${data.aws_caller_identity.this.account_id}:${aws_apigatewayv2_api.SampleHttpApi.id}/*/*"
}
resource "aws_cloudwatch_log_group" "loggroups" {
for_each = toset(["SampleAuthorizer", "EchoFunction"])
name = "/aws/lambda/${each.value}"
retention_in_days = 1
}
# api
resource "aws_apigatewayv2_api" "SampleHttpApi" {
name = "SampleHttpApi"
protocol_type = "HTTP"
description = "Sample http api which uses Lambda integration"
ip_address_type = "ipv4"
body = file("api_body.json")
}
resource "aws_cloudwatch_log_group" "api_logging" {
name = "/aws/api/SampleHttpApi"
retention_in_days = 1
}
resource "aws_apigatewayv2_stage" "stage1" {
api_id = aws_apigatewayv2_api.SampleHttpApi.id
name = "$default"
description = "Default environment"
deployment_id = aws_apigatewayv2_deployment.deployment.id
access_log_settings {
destination_arn = aws_cloudwatch_log_group.api_logging.arn
format = jsonencode(
{
"requestId" : "$context.requestId",
"ip" : "$context.identity.sourceIp",
"requestTime" : "$context.requestTime",
"httpMethod" : "$context.httpMethod",
"routeKey" : "$context.routeKey",
"status" : "$context.status",
"protocol" : "$context.protocol",
"responseLength" : "$context.responseLength",
"AuthorizerError" : "$context.authorizer.error"
}
)
}
}
resource "aws_apigatewayv2_deployment" "deployment" {
api_id = aws_apigatewayv2_api.SampleHttpApi.id
description = "Triggered by terraform"
triggers = {
redeployment = timestamp()
}
lifecycle {
create_before_destroy = true
}
}