Skip to content

Instantly share code, notes, and snippets.

@yasudacloud
Created October 14, 2022 05:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yasudacloud/dc7bdbd8d1fb4c050fc7fd570e519596 to your computer and use it in GitHub Desktop.
Save yasudacloud/dc7bdbd8d1fb4c050fc7fd570e519596 to your computer and use it in GitHub Desktop.
Link CloudFront and Lambda function URLs
provider "aws" {
region = "ap-northeast-1"
}
locals {
project_name = "example-cf-lambda-url"
# CloudFrontに設定したいドメイン
cf_domain = ""
# ACMのARN(バージニア北部)
cf_domain_acm_arn = ""
# Route53に登録されている独自ドメインのホストゾーンID
route53_host_zone_id = ""
# Lambdaとの紐付け関連
custom_header_key = "x-custom-header"
custom_header_value = "hello"
# Lambda関数URLのidとURL
origins = [
{
domain_name = replace(replace(aws_lambda_function_url.example_lambda1_url.function_url, "https://", ""), "/", ""),
origin_id = aws_lambda_function_url.example_lambda1_url.url_id
}, {
domain_name = replace(replace(aws_lambda_function_url.example_lambda2_url.function_url, "https://", ""), "/", ""),
origin_id = aws_lambda_function_url.example_lambda2_url.url_id
}
]
}
# Lambda Zip(共通)
data "archive_file" "lambda-zip" {
source_dir = "${path.module}/functions"
output_path = "${path.module}/output/code.zip"
type = "zip"
}
# Lambda関数1
resource "aws_lambda_function" "example_lambda1" {
function_name = "${local.project_name}-example-lambda1"
role = aws_iam_role.example-lambda-role.arn
filename = "output/code.zip"
package_type = "Zip"
runtime = "nodejs16.x"
handler = "lambda1.handler"
source_code_hash = filebase64sha256(data.archive_file.lambda-zip.output_path)
}
# Lambda関数1のURL
resource "aws_lambda_function_url" "example_lambda1_url" {
authorization_type = "NONE"
function_name = aws_lambda_function.example_lambda1.function_name
}
# Lambda関数2
resource "aws_lambda_function" "example_lambda2" {
function_name = "${local.project_name}-example-lambda2"
role = aws_iam_role.example-lambda-role.arn
filename = "output/code.zip"
package_type = "Zip"
runtime = "nodejs16.x"
handler = "lambda2.handler"
source_code_hash = filebase64sha256(data.archive_file.lambda-zip.output_path)
}
# Lambda関数2のURL
resource "aws_lambda_function_url" "example_lambda2_url" {
authorization_type = "NONE"
function_name = aws_lambda_function.example_lambda2.function_name
}
# Lambdaロール
resource "aws_iam_role" "example-lambda-role" {
name = "${local.project_name}-lambda-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Sid = "lambda"
Principal = {
Service = "lambda.amazonaws.com"
}
}
]
})
inline_policy {
name = "${local.project_name}-lambda-policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"logs:DescribeLogStreams",
"logs:DescribeLogGroups"
]
Effect = "Allow"
Resource = [
"*"
]
}
]
})
}
}
# CloudFront
resource "aws_cloudfront_distribution" "example-cloudfront" {
enabled = true
comment = "${local.project_name}-${terraform.workspace}"
aliases = [
local.cf_domain
]
default_cache_behavior {
allowed_methods = ["HEAD", "GET"]
cached_methods = ["HEAD", "GET"]
target_origin_id = aws_lambda_function_url.example_lambda1_url.url_id
viewer_protocol_policy = "redirect-to-https"
compress = true
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}
dynamic origin {
for_each = [
for i in local.origins : {
domain_name = i.domain_name
origin_id = i.origin_id
}
]
content {
domain_name = origin.value.domain_name
origin_id = origin.value.origin_id
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols = ["TLSv1.2"]
}
custom_header {
name = local.custom_header_key
value = local.custom_header_value
}
}
}
# 関数が多くなると冗長なのでここもdynamic化すると良い
ordered_cache_behavior {
allowed_methods = ["HEAD", "GET"]
cached_methods = ["HEAD", "GET"]
path_pattern = "/lambda2"
target_origin_id = aws_lambda_function_url.example_lambda2_url.url_id
viewer_protocol_policy = "redirect-to-https"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}
viewer_certificate {
acm_certificate_arn = local.cf_domain_acm_arn
minimum_protocol_version = "TLSv1"
ssl_support_method = "sni-only"
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
}
# CloudFrontに独自ドメイン振る
resource "aws_route53_record" "example-cf-domain" {
name = local.cf_domain
type = "A"
zone_id = local.route53_host_zone_id
depends_on = [
aws_cloudfront_distribution.example-cloudfront
]
alias {
name = aws_cloudfront_distribution.example-cloudfront.domain_name
zone_id = aws_cloudfront_distribution.example-cloudfront.hosted_zone_id
evaluate_target_health = false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment