AWS 応用コース / 第2章 Lesson 05

Slack Metrics API用のLambdaの
周辺リソースを作成する

Lambda 本体を作る前に、コンテナイメージの置き場、実行時の権限、RDS への通信経路の役割を分けて準備する。

この Lesson の完了条件(提出不要)

  1. slack-metrics-lambda-stg の ECR と、そこへ push した Docker イメージがある。
  2. cp-slack-metrics-lambda-stg の IAM ロールと Security Group がある。
  3. DB の Security Group が Lambda の Security Group からの TCP 5432 を許可している。

01作るのは Lambda 本体ではなく、その土台

教材の順序は ECR → イメージ push → IAM ロール → Security Group → 次の Lesson で Lambda 作成。ここで関数を先に作らないことに意味がある。

ECR、Lambda実行ロール、VPC内Lambda、RDSの4要素の関係図
ECR はイメージ、IAM ロールは権限を Lambda に渡す。Lambda から RDS への通信は SG で許可する。破線の Lambda 本体は次の課題で作る。

ECR

コンテナイメージの保管場所。push する主体の AWS 認証情報が必要になる。

IAM ロール

Lambda が実行中に AWS API を呼ぶための権限。開発端末の権限ではない。

Security Group

VPC 内の通信を許可する境界。RDS に届く送信元を Lambda 用 SG として表す。

次の Lesson 06 では、これらの ARN・Security Group ID・ECR イメージを指定して Lambda 関数を手動作成し、テストしてから Terraform import する。Lesson 05 では Lambda モジュールがまだ無くても正常である。

02ECR は「実行場所」ではなくイメージの届け先

ECR リポジトリ名は slack-metrics-lambda-stg。Terraform の内部識別子 ecr_slack_metrics_lambda と、AWS コンソールに表示される名前は役割が違う。前者はコード上の参照名、後者は AWS リソース名である。

local → stg:教材では backend ディレクトリを起点に実行する。

cd services/slack-metrics-lambda
ENV=stg make release-image

このコマンドで ECR へ push するのは、ローカルの Docker であり、その時点で有効な AWS 認証情報を使う。Lambda 実行ロールを作っても push 権限にはならない。push には呼び出し元に ECR の認証・アップロード権限が必要で、実行ロールは Lambda サービスの VPC 準備と、起動したアプリケーションの AWS API 操作に使われる。

当時の質問で確認した点:Docker の接続先が、停止中の Colima を指していたため release-image に失敗したことがある。これは Terraform の作成失敗ではない。当時は aws.mk の既定アカウントが自分のアカウントと異なる問題もあった。アカウント設定はその後修正したが、OrbStack を使う場合も Docker を動かす本体が起動済みか確認する。次の Lambda は x86_64 を想定するため、イメージは linux/amd64 で build する。

push の失敗は、止まった段階で切り分ける

自分の環境を明示する実行例。アカウントIDは実行前に置き換える。

AWS_PROFILE=cp-terraform-stg \
AWS_ACCOUNT_ID='<自分のAWSアカウントID>' \
ENV=stg make release-image

03実行ロールは Lambda の準備と実行に使う

ロール名は cp-slack-metrics-lambda-stg。既存の ECS 用 cp-slack-metrics-backend-stg は使い回さない。誰がロールを使えるかを決める信頼ポリシーで lambda.amazonaws.com を指定し、必要なアクセスも ECS タスクとは異なるからである。

必要なこと権限の意味今回の実装例
Parameter Store を読む起動時に共有設定を取得するAmazonSSMReadOnlyAccess
VPC 内で起動するLambda サービスが ENI を管理するための API 操作を許可するAWSLambdaVPCAccessExecutionRole
ログを出すCloudWatch Logs へ実行ログを送るCloudWatchFullAccessV2
SQS を扱う後続の用途も見越したキュー操作既存の sqs_read_write ポリシー

ENI は Lambda が VPC へ接続するために管理する仮想ネットワークカードであり、呼び出しごとに「専用 ENI が 1 枚」作られるものではない。ロールはその管理 API を許可し、Security Group は実際のネットワーク通信を制御する。両者は代替関係ではない。

Supplement:AmazonSSMManagedInstanceCore は EC2 などを Systems Manager の管理対象にするためのポリシーであり、Lambda が Parameter Store を狭く読む用途には適さない。今回採用した CloudWatchFullAccessV2 は VPC 実行ロールに含まれるログ系権限と重なる範囲がある。実務では必要な操作と対象に権限を絞る。教材では SES との連携を省くため、SES の送信権限は今回付けない。

04DB への許可は Lambda SG を送信元にする

Lambda 用 Security Group cp-slack-metrics-lambda-stg を作り、DB のインバウンドに TCP 5432、送信元としてその SG を追加する。これは「Lambda の SG を DB に付ける」設定ではない。このルールが、この SG を持つネットワークインターフェースからの PostgreSQL 接続を許可するという意味であり、既存の踏み台サーバーなどからの接続許可は維持される。

LambdaがENIでVPCにつながり、ENIのLambda用SGとDB用SGで通信を許可する図
ENIはVPCへの接続口。Lambda用SGで送信を許可し、DB用SGでは送信元をLambda用SGとしてTCP 5432を許可する。IAMはこの通信経路上の装置ではなく、LambdaサービスによるENI操作を許可する。
境界決めることこの構成での指定
Lambda 側 SG送信元から外へ出る通信Lambda の VPC 設定で SG を選ぶ(Lesson 06)
DB 側 SG受信側が誰から PostgreSQL を受けるか送信元 slack_metrics_lambda、TCP 5432
IAMAWS API の操作可否ENI 作成・SSM 読み取り・ログ送信など

Lambda 側では外向きの通信、DB 側では入ってくる通信の両方を許可する。Lambda 側の送信許可だけでは DB 側の受信許可を代わりに満たせない。SG が通っても、ネットワーク経路と PostgreSQL のユーザー認証は別に必要になる。

Security Group は関数名そのものを識別するものではない。複数の Lambda が同じ SG を使えば、DB から見える許可単位もその SG になる。関数単位のネットワーク境界が必要になった時点で SG を分ける。

05Terraform は出力を渡して、次のモジュールにつなぐ

IAM / Security Group / ECR の各モジュールがロール ARN、Security Group ID、リポジトリ URL を出力し、stg/aws.tf の親モジュールが将来の Lambda module に渡す。これらの output は AWS リソースでもコスト発生要因でもなく、モジュール間で値を受け渡す名前付きの出口である。まだ Lambda module が無いことは欠落ではなく、Lesson 05 が周辺資源だけを作る段階だからである。

IAMとSGの各モジュールのoutputからstg/aws.tfを経由し、次の課題のLambdaモジュールへ値を渡す図
outputは値を持つ側に置く。stg/aws.tfがその値を受け取り、Lambda側の入力変数につなぐ。output自体はAWSリソースを作らない。

output は、値を持っているモジュールに置く

IAM の ARN は iam_role/outputs.tf、SG の ID は security_group/outputs.tf に書く。別のモジュールにあるリソースを、lambda/outputs.tf から直接参照することはできない。

# modules/aws/iam_role/outputs.tf
output "role_arn_cp_slack_metrics_lambda" {
  value = aws_iam_role.cp_slack_metrics_lambda.arn
}

# modules/aws/security_group/outputs.tf
output "id_slack_metrics_lambda" {
  value = aws_security_group.slack_metrics_lambda.id
}

親の stg/aws.tf からは module.iam_role.role_arn_cp_slack_metrics_lambda のように参照できる。次の課題で Lambda を Terraform 化する際、受け取る側の変数につなぐ。

ECRの実体を保ったまま、Terraformの名前を揃える

旧名slack_metrics_lambdaと新名ecr_slack_metrics_lambdaが、同じECR slack-metrics-lambda-stgを指す図
図の旧名・新名はmodule.ecr.module.に続くTerraform内部のラベル。state mvはstate内の対応先を移す操作で、AWS上のECRを複製・再作成しない。

AWS 上の名前を変えなくても、Terraform 内部の module 名だけ変えると、state との対応が外れる。state mv は AWS の実体を作り直さず、その対応先の住所を移す操作である。2026-09-06 時点では、旧 slack_metrics_lambdaecr_slack_metrics_lambda へ state mv した後、対象を絞った plan は No changes だった。これは当時の状態移行の記録であり、現在の環境を保証するものではない。terraform state mv の公式ドキュメントも参照する。

Supplement:前セッションの疑問 — 部分 apply と state 移動

部分 apply は実務でも使う?

通常の terraform apply は、同じ親モジュール / state にある差分を一度に適用するので、すべてを再作成する操作ではない。-target は依存関係を含む限定的な復旧・調査向けであり、日常の apply の代わりにはしない。詳しくは HashiCorp の resource targeting ガイドを参照する。

過去の plan を現在の保証にしない

DB の for_each に ECS 用 SG も含まれていたため、Lambda だけのつもりでも、2026-09-06 の復旧作業では 11 件追加の計画になった。Recommended alternative:今回は削除済みの ECS 系を戻さないため、Lambda から DB への受信ルールを独立したリソースに分ける案を出した。通常の講座環境では既存 SG が揃っており、従来の map への追加で進められる。

同日の全体 plan には 109 件追加と表示されたが、評価エラーで完走していない。削除済みの AWS 環境に対して撤去前のコードを使っていたため、大量の復元候補が出た。これは Lambda を追加するたびに起きる通常動作ではない。ALB を無効にしても ECS / CloudFront まで自動で対象外にはならない。同じ定義から複数のリソースを作る countfor_each では、作成数や各リソースを識別するキーを plan 時点で決められる必要がある。作成後に決まる ARN などを、その判断に使わない。import の成功も、空の状態からの再構築成功を保証しない。

06この Lesson の確認と、次のチェックポイント

  1. ECR コンソールで slack-metrics-lambda-stg に対象のイメージが存在する。
  2. IAM で cp-slack-metrics-lambda-stg が Lambda を信頼し、必要なポリシーを持つ。
  3. Security Group で Lambda 用 SG があり、DB のインバウンド TCP 5432 がその SG を送信元としている。

次の Lesson 06 は、これらを選んで API 用 Lambda を手動作成し、テストタブで API Gateway 形式のイベントを実行する段階である。アプリケーションは ENV により共有の slack-metrics-${ENV} Parameter Store を読み、MODE は API / batch / SQS で直接指定して起動処理を選ぶ。

VPC 内 Lambda と ENI の詳細は AWS Lambda の VPC 設定ドキュメント、Security Group のルールは AWS の Security Group ルールドキュメントで確認できる。

結論

  1. ECR push は開発端末側の認証情報、AWS API 呼び出しは Lambda 実行ロールという別経路である。
  2. IAM は AWS API 操作、Security Group は通信許可を担当し、DB 側には Lambda 用 SG から TCP 5432 への受信許可を追加する。
  3. Lesson 05 は土台を Terraform 化する段階。Lambda 本体の作成・テスト・import は次の Lesson 06 で行う。