Chapter 04無料公開

AWS Lambda 関数をデプロイしよう

kakakakakku
kakakakakku
2025.02.25に更新

Chapter.4 では、Terraform を使って AWS Lambda 関数をデプロイしてみましょう。

アーキテクチャ図

デプロイするのは、以下のアーキテクチャ図のような構成です。AWS Lambda 関数と IAM Role というシンプルな構成です。

main.tf を読む

Chapter.4 では、今までの Chapter と順番を変えて、最初に Terraform コードを紹介します。

まずは main.tf の最後に定義している aws_lambda_function リソースです。名前の通り、AWS Lambda 関数を定義するリソースです。そして、aws_lambda_function の引数 function_name は関数名、runtime はランタイムを意味していて、ここはイメージしやすいはずです。

なお、引数 role に設定している IAM Role は、別の aws_iam_role リソースで定義しています。

なお、引数 filenamesource_code_hash に関しては、Chapter.4 最後のコード解説にまとめています。

data "aws_iam_policy_document" "assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }

    actions = ["sts:AssumeRole"]
  }
}

resource "aws_iam_role" "lambda_execution_role" {
  name               = "chapter04-role"
  assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

data "archive_file" "chapter04" {
  type        = "zip"
  source_dir  = "${path.module}/function/src"
  output_path = "${path.module}/function/dist/chapter04.zip"
}

resource "aws_lambda_function" "chapter04" {
  function_name    = "chapter04-function"
  handler          = "app.lambda_handler"
  runtime          = "python3.12"
  role             = aws_iam_role.lambda_execution_role.arn
  filename         = "${path.module}/function/dist/chapter04.zip"
  source_code_hash = data.archive_file.chapter04.output_base64sha256
}

Terraform でデプロイする(terraform init

まずは terraform init コマンド(tflocal init コマンド)で初期化をします。

$ cd ${CODESPACE_VSCODE_FOLDER}/chapter04
$ tflocal init

Terraform でデプロイする(terraform plan

そして、terraform plan コマンド(tflocal plan コマンド)を使って実行結果の確認をします。最後の行を確認すると 2 to add とあり、リソースが2つ追加されることを表しています。そして、... will be created という文字列を探すと、IAM Role aws_iam_role.lambda_execution_role と AWS Lambda 関数 aws_lambda_function.chapter04 の2つが追加されることを確認できます。

$ tflocal plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_iam_role.lambda_execution_role will be created
  + resource "aws_iam_role" "lambda_execution_role" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "lambda.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "chapter04-role"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + tags_all              = (known after apply)
      + unique_id             = (known after apply)

      + inline_policy (known after apply)
    }

  # aws_lambda_function.chapter04 will be created
  + resource "aws_lambda_function" "chapter04" {
      + architectures                  = (known after apply)
      + arn                            = (known after apply)
      + code_sha256                    = (known after apply)
      + filename                       = "./function/dist/chapter04.zip"
      + function_name                  = "chapter04-function"
      + handler                        = "app.lambda_handler"
      + id                             = (known after apply)
      + invoke_arn                     = (known after apply)
      + last_modified                  = (known after apply)
      + memory_size                    = 128
      + package_type                   = "Zip"
      + publish                        = false
      + qualified_arn                  = (known after apply)
      + qualified_invoke_arn           = (known after apply)
      + reserved_concurrent_executions = -1
      + role                           = (known after apply)
      + runtime                        = "python3.12"
      + signing_job_arn                = (known after apply)
      + signing_profile_version_arn    = (known after apply)
      + skip_destroy                   = false
      + source_code_hash               = "oG5IjnWwks/rbuIDkaDRQF/2caONc4cAtIex9N0dB4Q="
      + source_code_size               = (known after apply)
      + tags_all                       = (known after apply)
      + timeout                        = 3
      + version                        = (known after apply)

      + ephemeral_storage (known after apply)

      + logging_config (known after apply)

      + tracing_config (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

Terraform でデプロイする(terraform apply

最後は、terraform apply コマンド(tflocal apply コマンド)を使ってデプロイします。

$ tflocal apply

(中略)

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_iam_role.lambda_execution_role: Creating...
aws_iam_role.lambda_execution_role: Creation complete after 0s [id=chapter04-role]
aws_lambda_function.chapter04: Creating...
aws_lambda_function.chapter04: Still creating... [10s elapsed]
aws_lambda_function.chapter04: Still creating... [20s elapsed]
aws_lambda_function.chapter04: Still creating... [30s elapsed]
aws_lambda_function.chapter04: Creation complete after 38s [id=chapter04-function]

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

Apply complete! Resources: 2 added, 0 changed, 0 destroyed. と表示されていれば成功です!

リソース確認

LocalStack Resource Browser を開き、Lambda 画面に遷移し、chapter04-function を確認してみましょう!AWS Lambda 関数がデプロイされているはずです。

Chapter.4 はここまでです✋

コード解説

簡単にコードのポイントを解説します。読み飛ばしても大丈夫です👌

provider.tf

Chapter.2 と同じです。

main.tf

まず、archive_file データソースで、指定したディレクトリを zip 形式にまとめています。zip ファイルは terraform plan コマンド(tflocal plan コマンド)を実行したタイミングで生成されます。

data "archive_file" "chapter04" {
  type        = "zip"
  source_dir  = "${path.module}/function/src"
  output_path = "${path.module}/function/dist/chapter04.zip"
}

そして、AWS Lambda 関数は、コードとライブラリを zip ファイルにまとめてアップロードする仕組みになっています。archive_file データソースで生成した zip ファイルを aws_lambda_function リソースの filename に指定しています。さらに、source_code_hash には、AWS Lambda 関数のコードを更新するかどうかを判定するために、zip ファイルの Base64 エンコードされた SHA-256 ハッシュの値を設定しています。

resource "aws_lambda_function" "chapter04" {
  function_name    = "chapter04-function"
  handler          = "app.lambda_handler"
  runtime          = "python3.12"
  role             = aws_iam_role.lambda_execution_role.arn
  filename         = "${path.module}/function/dist/chapter04.zip"
  source_code_hash = data.archive_file.chapter04.output_base64sha256
}

function/src/app.py

Chapter.4 では AWS Lambda 関数をデプロイすることを目的にしていたため、実際のコードはログを1行出力するだけのシンプルな実装になっています。

def lambda_handler(event, context):
    print('aws-terraform-workshop-using-localstack')

コード解説はここまでです✋