Skip to content

Instantly share code, notes, and snippets.

@vslala
Created June 18, 2023 14:54
Show Gist options
  • Save vslala/2497fcf12dd8dd9cef65861d91969f13 to your computer and use it in GitHub Desktop.
Save vslala/2497fcf12dd8dd9cef65861d91969f13 to your computer and use it in GitHub Desktop.
Terraform deploy lambda with API Gateway
variable "aws_profile" {
description = "AWS Profile For Deployment"
}
variable "aws_region" {
description = "AWS Region For Deployment"
}
variable "project" {
type = string
description = "name of the project"
}
variable "account_id" {
type = string
}
variable "lambda_policy_arn" {
type = string
}
variable "stage" {
type = string
}
provider "aws" {
profile = var.aws_profile
region = var.aws_region
}
################################################################################
# Create an AWS IAM role for Lambda execution #
################################################################################
resource "aws_iam_role" "lambda_exec" {
name = "${var.project}-lambda-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = ""
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
}
################################################################################
# Attach an IAM policy to the Lambda execution role #
################################################################################
resource "aws_iam_role_policy_attachment" "lambda_policy" {
role = aws_iam_role.lambda_exec.id
policy_arn = var.lambda_policy_arn
}
################################################################################
# Create an AWS Lambda function #
################################################################################
resource "aws_lambda_function" "lambda_demo" {
function_name = "${var.project}-lambda_demo"
role = aws_iam_role.lambda_exec.arn
architectures = ["arm64"]
runtime = "python3.10"
handler = "LambdaDemo.handler"
source_code_hash = data.archive_file.lambda-demo.output_base64sha256
# Use the base64-encoded SHA-256 hash of the function code to determine if it has changed
s3_bucket = aws_s3_bucket.lambda_bucket.id
s3_key = aws_s3_object.lambda_demo.id
}
################################################################################
# Create a ZIP archive of the function code #
################################################################################
data "archive_file" "lambda-demo" {
type = "zip"
source_dir = "../python"
output_path = "../lambda-demo.zip"
}
################################################################################
# Create an S3 bucket to store the Lambda function code #
################################################################################
resource "aws_s3_bucket" "lambda_bucket" {
bucket = "${var.project}-lambda-demo"
}
################################################################################
# Upload the Lambda function code to S3 #
################################################################################
resource "aws_s3_object" "lambda_demo" {
bucket = aws_s3_bucket.lambda_bucket.id
key = "lambda-demo"
source = data.archive_file.lambda-demo.output_path
# Calculate the ETag of the ZIP archive using the MD5 hash of its contents
etag = filemd5(data.archive_file.lambda-demo.output_path)
}
###########################################################
# Create an AWS API Gateway REST API #
###########################################################
resource "aws_api_gateway_rest_api" "lambda_demo" {
name = "${var.project}-lambda-demo-api"
endpoint_configuration {
types = ["REGIONAL"]
}
}
###########################################################
# Create a resource for the Lambda function in the API #
# Gateway REST API #
###########################################################
resource "aws_api_gateway_resource" "lambda_demo" {
parent_id = aws_api_gateway_rest_api.lambda_demo.root_resource_id
path_part = "lambda-demo"
rest_api_id = aws_api_gateway_rest_api.lambda_demo.id
}
###########################################################
# Create a method for the HTTP verb on the Lambda #
# function resource #
###########################################################
resource "aws_api_gateway_method" "lambda_demo_get_method" {
authorization = "NONE"
http_method = "GET"
resource_id = aws_api_gateway_resource.lambda_demo.id
rest_api_id = aws_api_gateway_rest_api.lambda_demo.id
}
resource "aws_api_gateway_method" "lambda_demo_post_method" {
authorization = "NONE"
http_method = "POST"
resource_id = aws_api_gateway_resource.lambda_demo.id
rest_api_id = aws_api_gateway_rest_api.lambda_demo.id
}
###########################################################
# Create an integration for the Lambda function in the API #
# Gateway REST API #
###########################################################
resource "aws_api_gateway_integration" "lambda_demo_get_method_integration" {
http_method = aws_api_gateway_method.lambda_demo_get_method.http_method
resource_id = aws_api_gateway_resource.lambda_demo.id
rest_api_id = aws_api_gateway_rest_api.lambda_demo.id
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.lambda_demo.invoke_arn
}
resource "aws_api_gateway_integration" "lambda_demo_post_method_integration" {
http_method = aws_api_gateway_method.lambda_demo_post_method.http_method
resource_id = aws_api_gateway_resource.lambda_demo.id
rest_api_id = aws_api_gateway_rest_api.lambda_demo.id
integration_http_method = "POST"
type = "AWS_PROXY"
uri = aws_lambda_function.lambda_demo.invoke_arn
}
###########################################################
# Deploy the API Gateway REST API #
###########################################################
resource "aws_api_gateway_deployment" "lambda_demo" {
depends_on = [
aws_api_gateway_integration.lambda_demo_get_method_integration,
aws_api_gateway_integration.lambda_demo_post_method_integration
]
rest_api_id = aws_api_gateway_rest_api.lambda_demo.id
lifecycle {
create_before_destroy = true
}
triggers = {
redeployment = sha1(jsonencode([
jsonencode(aws_api_gateway_integration.lambda_demo_get_method_integration),
jsonencode(aws_api_gateway_integration.lambda_demo_post_method_integration)
]))
}
}
###########################################################
# Create a stage for the API Gateway REST API deployment #
###########################################################
resource "aws_api_gateway_stage" "lambda_demo" {
deployment_id = aws_api_gateway_deployment.lambda_demo.id
rest_api_id = aws_api_gateway_rest_api.lambda_demo.id
stage_name = var.stage
}
#################################################################################
# APIGATEWAY PERMISSION FOR LAMBDA INVOKE #
#################################################################################
resource "aws_lambda_permission" "lambda_demo_get_method_permission" {
statement_id = "AllowExecutionFromAPIGateway"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.lambda_demo.function_name
principal = "apigateway.amazonaws.com"
# More: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-control-access-using-iam-policies-to-invoke-api.html
source_arn = "arn:aws:execute-api:${var.aws_region}:${var.account_id}:${aws_api_gateway_rest_api.lambda_demo.id}/*/${aws_api_gateway_method.lambda_demo_get_method.http_method}${aws_api_gateway_resource.lambda_demo.path}"
# source_arn = aws_api_gateway_rest_api.lambda_demo.execution_arn
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment