AWS Lambda Function URLsをTerraformで実装してみる

AWS

2022.4.25

Topics

はじめに

2022/04/06 に話題となった Lambda の機能アップデート です。

アップロード内容としては、Lambda に簡単にアクセスできる HTTPS のエンドポイントが追加できる機能です。

AWS Lambda の新しい機能である Lambda 関数 URL の提供開始をお知らせします。この新機能は、AWS Lambda サービスの組み込み機能として、HTTPS エンドポイントを介して関数を簡単に呼び出せるようにします。コンソールで 1 回クリックするか、AWS CloudFormation または AWS Serverless Application Model を使用して数行で、関数 URL を新規および既存の関数に追加できます。関数 URL は、Lambda でのウェブサービスの構築を開始する場合や、ウェブフックの構築などの一般的なタスクに最適です。
AWS Lambda Function URLs: Lambda 関数用の組み込み HTTPS エンドポイント

Terraform Provider for AWS v4.9.0 アップデート

AWS の発表から数日後にTerraform でも Function URLsが作成できるアップデートがリリースされていました。

Release v4.9.0 · hashicorp/terraform-provider-aws · GitHub

Lambda Function URLs が作成できる、新しいデータソースaws_lambda_function_urlです。

リソース:aws_lambda_function_url
Lambda 関数の URL リソースを提供します。関数 URL は、Lambda 関数専用の HTTP(S)エンドポイントです。
aws_lambda_function_url | リソース| hashicorp / aws | Terraform レジストリ > リリース v4.9.0・hashicorp / terraform-provider-aws・GitHub

やってみた

注意点

terraform-provider-aws v4.9.0で追加された機能ですので、プロバイダーのバージョンにご注意してください。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.9.0"
    }
  }
}

下記の環境で構築を行います。

C:\Users>terraform -version
Terraform v1.1.6
on windows_amd64
+ provider registry.terraform.io/hashicorp/aws v4.9.0

なお、Terraform のディレクトリ構成は下記のとおりです。

C:.
│   main.tf
└───contents
        lambda.zip
        lambda_function.py

まずは Lambda Function を作成

Function URLsは、Lambda Functionとは別リソースとして定義されています。
そのため、Lambda Functionを先に作成してあとでFunction URLsと連携させます。

Lambdaのプログラムは、archive_fileを使ってzip形式にしてアップロードしています。
あとは、念のためCloudWatchでログを収集できるように権限を付与しています。

data "archive_file" "sample_function" {
  type        = "zip"
  source_file = "${path.module}${var.lambda_file_name}"
  output_path = "${path.module}${var.lambda_file_zip_name}"
}

data "aws_iam_policy_document" "AWSLambdaTrustPolicy" {
  statement {
    actions = ["sts:AssumeRole"]
    effect  = "Allow"
    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "function_role" {
  name               = "lambdaurl-function_role"
  assume_role_policy = data.aws_iam_policy_document.AWSLambdaTrustPolicy.json
}

resource "aws_iam_role_policy_attachment" "lambda_policy" {
  role       = aws_iam_role.function_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}


resource "aws_lambda_function" "test_lambda" {
  filename         = data.archive_file.sample_function.output_path
  function_name    = "lambdaurl-test"
  role             = aws_iam_role.function_role.arn
  handler          = "lambda_function.lambda_handler"
  publish          = true
  source_code_hash = data.archive_file.sample_function.output_base64sha256
  runtime          = "python3.9"
}

resource "aws_lambda_permission" "allow_cloudwatch" {
  statement_id  = "AllowExecutionFromCloudWatch"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.test_lambda.function_name
  principal     = "events.amazonaws.com"
}

variable "lambda_file_name" {
  default = "/contents/lambda_function.py"
}

variable "lambda_file_zip_name" {
  default = "/contents/lambda.zip"
}

Lambda プログラム

使用するプログラムはHello world!を返すように作成しています。

def lambda_handler(event, context):
    message = 'Hello world!'
    return message

Function URLs作成

認証タイプは下記の2つがあります。

  • AWS_IAM
  • NONE

今回はNONEを選択して構築します。
NONE の場合はパブリック API になるので注意が必要です。

Lambda 関数の URL のセキュリティと認証モデル-AWSLambda

resource "aws_lambda_function_url" "test" {
  function_name      = aws_lambda_function.test_lambda.function_name
  authorization_type = "NONE"
}

apply する

terraform apply

aws_iam_role.function_role: Creating...
aws_iam_role.function_role: Creation complete after 2s [id=lambdaurl-function_role]
aws_iam_role_policy_attachment.lambda_policy: Creating...
aws_lambda_function.test_lambda: Creating...
aws_iam_role_policy_attachment.lambda_policy: Creation complete after 0s [id=lambdaurl-function_role-20220425014505220500000001]
aws_lambda_function.test_lambda: Still creating... [10s elapsed]
aws_lambda_function.test_lambda: Creation complete after 15s [id=lambdaurl-test]
aws_lambda_permission.allow_cloudwatch: Creating...
aws_lambda_function_url.test: Creating...
aws_lambda_permission.allow_cloudwatch: Creation complete after 1s [id=AllowExecutionFromCloudWatch]
aws_lambda_function_url.test: Creation complete after 1s [id=lambdaurl-test]

Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

構築が完了したので、実際に接続してみます。

接続確認

Lambda にアクセスする URL はコンソール画面から簡単に確認できますが、せっかくなので AWS CLI を利用して確認してみます。

AWS CLI のバージョンは 2.5.4 以上だと対応しています。

aws-cli/CHANGELOG.rst at 2.5.4 · aws/aws-cli · GitHub

C:\Users>aws --version
aws-cli/2.5.8 Python/3.9.11 Windows/10 exe/AMD64 prompt/off

使うコマンドは、get-function-url-configです。

Lambda 関数の URL に関する詳細を返します。
get-function-url-config — AWS CLI 2.5.8 Command Reference

<br />C:\Users>aws lambda get-function-url-config --function-name lambdaurl-test
{
    "FunctionUrl": "https://awij7tk363d7rvoupoo6m7fpdm0wsdfh.lambda-url.us-east-1.on.aws/",
    "FunctionArn": "arn:aws:lambda:us-east-1:アカウント:function:lambdaurl-test",
    "AuthType": "NONE",
    "CreationTime": "2022-04-25T01:45:20.593956Z",
    "LastModifiedTime": "2022-04-25T01:45:20.593956Z"
}

実行すると URL が返ってくるのでそのエンドポイントに対して、cURL コマンドを実行します。

C:\Users>curl https://awij7tk363d7rvoupoo6m7fpdm0wsdfh.lambda-url.us-east-1.on.aws/
Hello world!

Lambda で作成したメッセージが返ってきたので成功です。

まとめ

API Gateway を使うより迅速に API を作成できるので開発時とかには有用な機能ですね。
ですが、セキュリティの観点から認識タイプをNONEにする場合は注意が必要です。

参考記事

リリース v4.9.0・hashicorp / terraform-provider-aws・GitHub
aws_lambda_function | リソース| hashicorp / aws | Terraform レジストリ
AWS Lambda Function URLs – Speaker Deck
Announcing AWS Lambda Function URLs: Built-in HTTPS Endpoints for Single-Function Microservices | AWS News Blog
get-function-url-config — AWSCLI2.5.8 コマンドリファレンス
aws-cli/CHANGELOG.rst at 2.5.4 · aws/aws-cli · GitHub

Cold-Airflow

2021年新卒入社。インフラエンジニアです。RDBが三度の飯より好きです。 主にデータベースやAWSのサーバレスについて書く予定です。あと寒いのは苦手です。

Recommends

こちらもおすすめ

Special Topics

注目記事はこちら