以下の内容はhttps://kakakakakku.hatenablog.com/entry/2026/01/07/095312より取得しました。


Terraform と lambroll で LocalStack に Lambda 関数をデプロイする

lambroll を使って AWS Lambda 関数をデプロイしてる環境で動作確認のために LocalStack にもデプロイしたいという相談があって,検証環境を作る機会があった.結果的に問題なくデプロイできた👌個人環境で検証したことをまとめておく.

github.com

今回の構成としては AWS リソースを Terraform でデプロイしつつ,AWS Lambda 関数のコードは GitHub Actions + lambroll でデプロイする.LocalStack に関しては同じく Terraform でデプロイしつつ,AWS Lambda 関数のコードはローカル環境から lambroll deploy コマンドを実行する.

1. Terraform

👾 main.tf

まず,Terraform では IAM Role・AWS Lambda 関数(空っぽ)・Amazon SQS キューをデプロイしておく.AWS Lambda 関数のコードは lambroll でデプロイするため archive_file データソースを使ってダミーコードを設定しておく.

resource "aws_iam_role" "sandbox" {
  name = "sandbox-role"

  assume_role_policy = jsonencode(
    {
      Version = "2012-10-17"
      Statement = [
        {
          Action = "sts:AssumeRole"
          Effect = "Allow"
          Principal = {
            Service = "lambda.amazonaws.com"
          }
        }
      ]
    }
  )
}

resource "aws_iam_role_policy_attachment" "sqs" {
  role       = aws_iam_role.sandbox.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonSQSFullAccess"
}

data "archive_file" "dummy" {
  type = "zip"
  source {
    content  = "dummy"
    filename = "app.py"
  }
  output_path = "${path.module}/dummy.zip"
}

resource "aws_lambda_function" "sandbox" {
  function_name    = "sandbox-function"
  role             = aws_iam_role.sandbox.arn
  handler          = "app.lambda_handler"
  runtime          = "python3.13"
  filename         = data.archive_file.dummy.output_path
  source_code_hash = data.archive_file.dummy.output_base64sha256

  lifecycle {
    ignore_changes = [
      timeout,
      environment
    ]
  }
}

resource "aws_sqs_queue" "sandbox" {
  name = "sandbox-queue"
}

👾 backend.tf

tfstate は S3 Backend を使って Amazon S3 バケットで管理する.

terraform {
  backend "s3" {
    region       = "ap-northeast-1"
    bucket       = "xxxxx"
    key          = "terraform.tfstate"
    use_lockfile = true
  }
}

デプロイ確認

IAM Role・AWS Lambda 関数(空っぽ)・Amazon SQS キューをデプロイできた.

2. lambroll

👾 functions/app.py

今回はサンプルとして AWS Lambda 関数から Amazon SQS キューにメッセージを送信するシンプルな実装にした.

import json
import os
import uuid

import boto3

sqs = boto3.client('sqs')


def lambda_handler(event, context):
    sqs.send_message(
        QueueUrl=os.environ['QUEUE_URL'],
        MessageBody=json.dumps(
            {
                'id': str(uuid.uuid4()),
            },
        ),
    )

👾 functions/function.json

lambroll の function.json では tfstate 記法を使って tfstate から値を取得するようにしている🐑

{
  "Architectures": [
    "x86_64"
  ],
  "Environment": {
    "Variables": {
      "QUEUE_URL": "{{ tfstate `aws_sqs_queue.sandbox.url` }}"
    }
  },
  "EphemeralStorage": {
    "Size": 512
  },
  "FunctionName": "sandbox-function",
  "Handler": "app.lambda_handler",
  "MemorySize": 128,
  "Role": "{{ tfstate `aws_iam_role.sandbox.arn` }}",
  "Runtime": "python3.13",
  "Timeout": 30
}

👾 .github/workflows/deploy.yml

最後に GitHub Actions + lambroll で AWS Lambda 関数のコードをデプロイする.

name: Deploy Lambda function

on:
  push:
    branches:
      - main
    paths:
      - ".github/workflows/deploy.yml"
      - "functions/**"
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-slim
    permissions:
      contents: read
      id-token: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v5
        with:
          role-to-assume: arn:aws:iam::000000000000:role/xxxxx
          aws-region: ap-northeast-1

      - name: Install lambroll
        uses: fujiwara/lambroll@v1
        with:
          version: v1.4.1

      - name: Deploy Lambda
        run: lambroll deploy --tfstate s3://xxxxx/terraform.tfstate
        working-directory: functions

デプロイ確認

GitHub Actions 経由で AWS Lambda 関数のコードをデプロイできた.

動作確認

AWS Lambda 関数を実行すると Amazon SQS キューにメッセージを送信できていた👌

$ aws lambda invoke --function-name sandbox-function response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

3. LocalStack

デプロイ

AWS アカウントで動作確認ができたため今度は LocalStack にデプロイする.まずは localstack start -d コマンドで LocalStack を起動しておく.

$ localstack start -d

次に LocalStack Terraform CLI(tflocal コマンド)を使って LocalStack に plan / apply を実行すると問題なくデプロイできる.

$ tflocal plan
$ tflocal apply
Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

github.com

IAM Role・AWS Lambda 関数(空っぽ)・Amazon SQS キューをデプロイできた.

次に lambroll で AWS Lambda 関数のコードを LocalStack にデプロイする.lambroll は --endpoint オプションをサポートしているため LocalStack を指定している👌

しかしこのままだと --tfstate オプションで指定した S3 Backend を参照できず error:failed to read tfstate from s3://xxxxx/terraform.tfstate: operation error S3: GetObject, https response error StatusCode: 403 というエラーが出てしまう🔥今回は lambroll が内部的に依存している tfstate-lookup でサポートされている環境変数 AWS_ENDPOINT_URL_S3 に LocalStack の S3 エンドポイントを指定することで解消した.他の選択肢ある!?

github.com

$ export AWS_ENDPOINT_URL_S3=http://s3.localhost.localstack.cloud:4566
$ lambroll deploy --endpoint http://localhost:4566 --tfstate s3://xxxxx/terraform.tfstate

最後は動作確認をする.LocalStack AWS CLI(awslocal コマンド)で AWS Lambda 関数を実行すると Amazon SQS キューにメッセージを送信できていた👌

github.com

$ awslocal lambda invoke --function-name sandbox-function response.json
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}




以上の内容はhttps://kakakakakku.hatenablog.com/entry/2026/01/07/095312より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14