最近Goを使って小さいアプリケーションを書いていますが、そろそろLambdaにデプロイして動かしてみることにしました。
ちょうど最近AWSからLambdaにデプロイするactionが公開されたようなので、それを使ってみることにしました。
https://dev.classmethod.jp/articles/aws-github-action-support-lambda-deploy/
実際の記述を元に記事用の調整をしているので、そのまま利用した場合に動かない可能性があります。ご容赦ください。
Lambdaの環境構築
簡単にLambdaを構築するための環境を作ります。
Terraformでこんな感じ。
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 = "go-lambda-execution-role"
assume_role_policy = data.aws_iam_policy_document.assume_role.json
}
resource "aws_iam_role_policy_attachment" "lambda_logs" {
role = aws_iam_role.lambda_execution_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}
# Package the Go binary into a zip file
data "archive_file" "lambda_zip" {
type = "zip"
source_file = "build/bootstrap"
output_path = "function.zip"
}
# Lambda function
resource "aws_lambda_function" "go_lambda" {
filename = data.archive_file.lambda_zip.output_path
function_name = "go-lambda-function"
role = aws_iam_role.lambda_execution_role.arn
handler = "bootstrap"
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
runtime = "provided.al2023"
}
まだアプリケーションが小さいので、S3は経由せずzipファイルをあげる方式を取っています。
アプリケーションのビルド時に build/bootstrap
を出力先にしておくのがポイントです。
GitHub Actions OIDC認証の設定
Github ActionsからAWSにデプロイする際、OIDC認証が必要になるためOIDC認証の設定を追加します。
OIDC プロバイダーの作成
まず、AWSでGitHub Actions用のOIDCプロバイダーを作成します。
# terraform-bootstrap/oidc.tf
resource "aws_iam_openid_connect_provider" "github_actions" {
url = "https://token.actions.githubusercontent.com"
client_id_list = [
"sts.amazonaws.com"
]
# GitHubのOIDC証明書のサムプリント(2024年時点)
# 最新の値は GitHub公式ドキュメントで確認してください
thumbprint_list = [
"6938fd4d98bab03faadb97b34396831e3780aea1",
"1c58a3a8518e8759bf075b76b750d4f2df264fcd"
]
}
サムプリント値は時間の経過とともに変更される可能性があります。実装時は必ずGitHub公式ドキュメントで最新の値を確認してください。
IAMロールとAssumeRoleポリシーの設定
特定のリポジトリとブランチからのみアクセスを許可するポリシーを作成:
data "aws_iam_policy_document" "github_actions_assume_role_policy" {
statement {
effect = "Allow"
principals {
type = "Federated"
identifiers = [aws_iam_openid_connect_provider.github_actions.arn]
}
actions = ["sts:AssumeRoleWithWebIdentity"]
condition {
test = "StringEquals"
variable = "token.actions.githubusercontent.com:aud"
values = ["sts.amazonaws.com"]
}
condition {
test = "StringLike"
variable = "token.actions.githubusercontent.com:sub"
values = [
"repo:${var.github_org}/${var.github_repo}:*",
"repo:${var.github_org}/${var.github_repo}:ref:refs/heads/${var.github_branch}"
]
}
}
}
Lambda デプロイ用の権限設定
data "aws_iam_policy_document" "github_actions_lambda_deploy" {
# Lambda関数の操作権限
statement {
effect = "Allow"
actions = [
"lambda:GetFunctionConfiguration",
"lambda:CreateFunction",
"lambda:UpdateFunctionCode",
"lambda:UpdateFunctionConfiguration",
"lambda:PublishVersion"
]
resources = [
"arn:aws:lambda:${var.aws_region}:${var.aws_account_id}:function:go-lambda-function"
]
}
# Lambda実行ロールへのPassRole権限
statement {
effect = "Allow"
actions = [
"iam:PassRole"
]
resources = [
"arn:aws:iam::${var.aws_account_id}:role/*lambda*"
]
}
}
GitHub Actions ワークフローの実装
さて、これまでの情報を使ってGithub Actionsのワークフローを用意します。
基本的なワークフロー構成
# .github/workflows/deploy.yml
name: Deploy Lambda Function
on:
push:
branches: [ "main" ]
workflow_dispatch:
env:
AWS_REGION: us-west-2
permissions:
id-token: write # OIDC認証に必要
contents: read
jobs:
deploy:
name: Deploy Lambda Function
runs-on: ubuntu-latest
steps:
# 中略
- name: Download dependencies
run: go mod download
- name: Build Lambda function
env:
GOOS: linux
GOARCH: amd64
CGO_ENABLED: 0
run: |
mkdir -p build
go build -o build/bootstrap cmd/api/main.go
- name: Check binary exists
run: |
if [ -f build/bootstrap ]; then
echo "✅ Bootstrap binary built successfully"
ls -lh build/bootstrap
else
echo "❌ Bootstrap binary not found"
exit 1
fi
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4.0.2
with:
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
aws-region: ${{ env.AWS_REGION }}
- name: Deploy Lambda Function
uses: aws-actions/aws-lambda-deploy@v1.0.1
with:
function-name: go-lambda-function
code-artifacts-dir: ./build
handler: bootstrap
runtime: provided.al2023
事前にGoの環境の用意、ビルドを行い、AWSの認証を通したうえでLambdaのデプロイを行うという流れです。
まとめ
今回はOIDC認証を使って、GoアプリケーションをLambdaにデプロイする仕組みを構築しました。
小さなGoアプリケーションからスタートして、必要に応じてS3デプロイやマルチ環境対応なども検討していきたいと思います。
今回の実装が、同じような環境を構築する方の参考になれば幸いです。