Last active
May 3, 2021 18:58
-
-
Save sheeley/1ca20c16706c58710bf0fe3fb9ce4e2a to your computer and use it in GitHub Desktop.
Terraform API Gateway Lambda setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env bash | |
GOOS=linux GOARCH=amd64 go build -o main main.go | |
zip main.zip main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"context" | |
"github.com/aws/aws-lambda-go/events" | |
"github.com/aws/aws-lambda-go/lambda" | |
) | |
func Handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { | |
return events.APIGatewayProxyResponse{ | |
StatusCode: 200, | |
Body: "hello", | |
}, nil | |
} | |
func main() { | |
// Make the handler available for Remote Procedure Call by AWS Lambda | |
lambda.Start(Handler) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# To use a custom domain name you must first register that domain | |
variable "domain" { | |
default = "api.example.com" | |
} | |
variable "lambda_zipfile" { | |
default = "main.zip" | |
} | |
resource "aws_acm_certificate" "api-example-com" { | |
domain_name = "${var.domain}" | |
validation_method = "DNS" | |
} | |
resource "aws_route53_record" "api-example-com-cert-validation" { | |
name = "${aws_acm_certificate.api-example-com.domain_validation_options.0.resource_record_name}" | |
type = "${aws_acm_certificate.api-example-com.domain_validation_options.0.resource_record_type}" | |
zone_id = "${aws_route53_zone.aigee-org.zone_id}" | |
records = ["${aws_acm_certificate.api-example-com.domain_validation_options.0.resource_record_value}"] | |
ttl = 60 | |
} | |
resource "aws_acm_certificate_validation" "cert" { | |
certificate_arn = "${aws_acm_certificate.api-example-com.arn}" | |
validation_record_fqdns = ["${aws_route53_record.api-example-com-cert-validation.fqdn}"] | |
} | |
resource "aws_route53_record" "api-example-com" { | |
zone_id = "${aws_route53_zone.aigee-org.zone_id}" | |
name = "${var.domain}" | |
name = "${aws_api_gateway_domain_name.api-example-com.domain_name}" | |
type = "A" | |
alias { | |
name = "${aws_api_gateway_domain_name.api-example-com.cloudfront_domain_name}" | |
zone_id = "${aws_api_gateway_domain_name.api-example-com.cloudfront_zone_id}" | |
evaluate_target_health = true | |
} | |
} | |
resource "aws_api_gateway_rest_api" "api-example-com" { | |
name = "${var.domain} API" | |
} | |
resource "aws_api_gateway_resource" "api-example-com-proxy" { | |
rest_api_id = "${aws_api_gateway_rest_api.api-example-com.id}" | |
parent_id = "${aws_api_gateway_rest_api.api-example-com.root_resource_id}" | |
path_part = "{proxy+}" | |
} | |
resource "aws_api_gateway_method" "api-example-com-proxy" { | |
rest_api_id = "${aws_api_gateway_rest_api.api-example-com.id}" | |
resource_id = "${aws_api_gateway_resource.api-example-com-proxy.id}" | |
http_method = "ANY" | |
authorization = "NONE" | |
} | |
resource "aws_api_gateway_domain_name" "api-example-com" { | |
domain_name = "${var.domain}" | |
certificate_arn = "${aws_acm_certificate.api-example-com.id}" | |
} | |
resource "aws_api_gateway_deployment" "api-example-com" { | |
rest_api_id = "${aws_api_gateway_rest_api.api-example-com.id}" | |
stage_name = "live" | |
depends_on = [ | |
"aws_api_gateway_integration.api-example-com-lambda", | |
] | |
} | |
resource "aws_api_gateway_method_settings" "api-example-com" { | |
rest_api_id = "${aws_api_gateway_rest_api.api-example-com.id}" | |
stage_name = "${aws_api_gateway_deployment.api-example-com.stage_name}" | |
method_path = "*/*" | |
settings { | |
metrics_enabled = true | |
logging_level = "INFO" | |
} | |
depends_on = ["aws_api_gateway_account.global-settings"] | |
} | |
resource "aws_api_gateway_account" "global-settings" { | |
cloudwatch_role_arn = "${aws_iam_role.global-api-gateway-cloudwatch.arn}" | |
} | |
resource "aws_iam_role" "global-api-gateway-cloudwatch" { | |
name = "api_gateway_cloudwatch_global" | |
assume_role_policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Sid": "", | |
"Effect": "Allow", | |
"Principal": { | |
"Service": "apigateway.amazonaws.com" | |
}, | |
"Action": "sts:AssumeRole" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_iam_role_policy" "global-api-gateway-cloudwatch" { | |
name = "default" | |
role = "${aws_iam_role.global-api-gateway-cloudwatch.id}" | |
policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Effect": "Allow", | |
"Action": [ | |
"logs:CreateLogGroup", | |
"logs:CreateLogStream", | |
"logs:DescribeLogGroups", | |
"logs:DescribeLogStreams", | |
"logs:PutLogEvents", | |
"logs:GetLogEvents", | |
"logs:FilterLogEvents" | |
], | |
"Resource": "*" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_lambda_function" "api-example-com" { | |
function_name = "${replace("${var.domain}", ".", "-")}-handler" | |
filename = "${var.lambda_zipfile}" | |
source_code_hash = "${base64sha256(file("${var.lambda_zipfile}"))}" | |
handler = "main" | |
runtime = "go1.x" | |
role = "${aws_iam_role.api-example-com-lambda-exec.arn}" | |
} | |
resource "aws_lambda_permission" "allow-api-gateway" { | |
function_name = "${aws_lambda_function.api-example-com.function_name}" | |
statement_id = "AllowExecutionFromApiGateway" | |
action = "lambda:InvokeFunction" | |
principal = "apigateway.amazonaws.com" | |
source_arn = "${aws_api_gateway_rest_api.api-example-com.execution_arn}/${aws_api_gateway_deployment.api-example-com.stage_name}/*/*" | |
depends_on = ["aws_api_gateway_rest_api.api-example-com", "aws_api_gateway_resource.api-example-com-proxy"] | |
} | |
resource "aws_lambda_permission" "allow-api-gateway-base" { | |
function_name = "${aws_lambda_function.api-example-com.function_name}" | |
statement_id = "AllowExecutionFromApiGatewayBase" | |
action = "lambda:InvokeFunction" | |
principal = "apigateway.amazonaws.com" | |
source_arn = "${aws_api_gateway_rest_api.api-example-com.execution_arn}/${aws_api_gateway_deployment.api-example-com.stage_name}" | |
depends_on = ["aws_api_gateway_rest_api.api-example-com", "aws_api_gateway_resource.api-example-com-proxy"] | |
} | |
# IAM role which dictates what other AWS services the Lambda function | |
# may access. | |
resource "aws_iam_role" "api-example-com-lambda-exec" { | |
name = "${var.domain}-lamdba" | |
assume_role_policy = <<EOF | |
{ | |
"Version": "2012-10-17", | |
"Statement": [ | |
{ | |
"Action": "sts:AssumeRole", | |
"Principal": { | |
"Service": "lambda.amazonaws.com" | |
}, | |
"Effect": "Allow", | |
"Sid": "" | |
} | |
] | |
} | |
EOF | |
} | |
resource "aws_api_gateway_integration" "api-example-com-lambda" { | |
rest_api_id = "${aws_api_gateway_rest_api.api-example-com.id}" | |
resource_id = "${aws_api_gateway_method.api-example-com-proxy.resource_id}" | |
http_method = "${aws_api_gateway_method.api-example-com-proxy.http_method}" | |
integration_http_method = "POST" | |
type = "AWS_PROXY" | |
uri = "${aws_lambda_function.api-example-com.invoke_arn}" | |
} | |
resource "aws_api_gateway_base_path_mapping" "api-example-com" { | |
api_id = "${aws_api_gateway_rest_api.api-example-com.id}" | |
stage_name = "${aws_api_gateway_deployment.api-example-com.stage_name}" | |
domain_name = "${aws_api_gateway_domain_name.api-example-com.domain_name}" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment