SAMをGithub Actionsでデプロイし、Slackへ通知しよう
目次
1.はじめに
お疲れ様です。
クワハラです。
以前、弊社ブログ内でServerless framework V4からの有償化に伴いCloudFormationからAWS SAMへLambda関数を移行する方法の記事が書かれておりますが、それを元に別案件でもSAMへの移行を行いました。
そして今回はGithub ActionsでSAMのCI/CDを組んでみましたので、記事にしてみました。

2.対象読者
下記に該当する方を対象読者としています。
- GithubおよびGithub Actionsの基本的な知識がある方
- SAMおよびSAM CLIの基本的な知識がある方
- SAMを使った開発に興味がある方
3.前提条件
本記事では下記を前提条件としているため、詳細については割愛させていただきます。
また、Mac OSにて本記事の内容を検証していますので、Windows OSを使用されている方は適宜コマンドを読み替えてください。
3-1.必要な前提知識
- AWSのマネジメントコンソールの基本操作
- IAMの基本概念・基本操作
- SAMの基本概念
- Git、Github、 Github Actionsの基本操作・基本概念
- コマンドライン操作の基礎知識
3-2.必要なツール
- Gitがインストール済みであること
- Githubのアカウントがあること
4.手順
4-1.ローカル環境構築
ローカル端末にて作業用ディレクトリを作成します。
mkdir hands-on-sam-github-actions
mkdir -p hands-on-sam-github-actions/sam/lambda
Lambda関数内で実行するソースコードを作成します。今回はPython3.13を使用します。
touch hands-on-sam-github-actions/sam/lambda/lambda_function.py
下記ソースコードをhands-on-sam-github-actions/sam/lambda/lambda_function.pyへコピー&ペーストします。
ハンズオンのためシンプルな処理内容としています。
import json
import logging
import os
from datetime import datetime
# ログ設定
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
"""
基本的なLambda関数のハンドラー
"""
try:
# 環境変数の取得
environment = os.environ.get('ENVIRONMENT', 'unknown')
function_name = context.function_name
# リクエスト情報のログ出力
logger.info(f"Function: {function_name}, Environment: {environment}")
logger.info(f"Event received: {json.dumps(event)}")
# レスポンスデータの作成
response_data = {
'message': 'Hello from Lambda!',
'timestamp': datetime.now().isoformat(),
'environment': environment,
'function_name': function_name,
'request_id': context.aws_request_id,
'event_data': event
}
# 成功ログ
logger.info(f"Response: {json.dumps(response_data)}")
return response_data
except Exception as e:
# エラーログ
logger.error(f"Error occurred: {str(e)}")
error_response = {
'error': 'Internal server error',
'message': str(e),
'timestamp': datetime.now().isoformat()
}
return error_response
次に、SAMテンプレートを作成しましょう。
touch hands-on-sam-github-actions/sam/template.yaml
下記ソースコードをhands-on-sam-github-actions/sam/template.yamlにコピー&ペーストします。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'SAM template for basic Lambda function - converted from CloudFormation'
Resources:
# Lambda実行用のIAMロール
SamLambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
RoleName: 'sam-basic-lambda-function-execution-role'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: CloudWatchLogsPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/sam-basic-lambda-function*'
# Lambda関数定義
SamBasicLambdaFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: 'sam-basic-lambda-function'
Description: 'Basic Lambda function for SAM import tutorial'
CodeUri: lambda/
Handler: lambda_function.lambda_handler
Runtime: python3.13
Timeout: 30
MemorySize: 128
Role: !GetAtt SamLambdaExecutionRole.Arn
Environment:
Variables:
ENVIRONMENT: 'test'
LOG_LEVEL: 'INFO'
# CloudWatch Logs グループ
SamLambdaLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: '/aws/lambda/sam-basic-lambda-function'
RetentionInDays: 14
現時点では下記のようなディレクトリ構成になっていると思います。
hands-on-sam-github-actions/
└── sam/
├── template.yaml
└── lambda/
└── lambda_function.py
4-2.Github Actions用のIAMロール作成
AWSクレデンシャルを設定するActionsとしてaws-actions/configure-aws-credentials@v4を使用します。
そこではOIDCの利用を推奨しているため、今回はそれらを用いてAWS環境へデプロイするようにします。
GitHub – aws-actions/configure-aws-credentials: Configure AWS credential environment variables for use in other GitHub Actions.
まずはIDプロバイダの設定を行います。
以下のGithubの公式ドキュメントに則って対応します。
アマゾン ウェブ サービスでの OpenID Connect の構成 – GitHub ドキュメント
マネジメントコンソールからIAM > IDプロバイダ > プロバイダ作成ボタンを押下します。

以下を設定し、プロバイダ追加ボタンを押下します。
- プロバイダのタイプ: OpenID Connect
- プロバイダの URL:
https://token.actions.githubusercontent.com - 対象者:
sts.amazonaws.com

続いて任意の名前でポリシーを作成します。

{{AWS_ACCOUNT_ID}}を適宜ご自身のAWSアカウントIDに置き換えて、以下のJSONをポリシーエディタにコピー&ペーストします。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudFormationDeployOnly",
"Effect": "Allow",
"Action": [
"cloudformation:CreateStack",
"cloudformation:UpdateStack",
"cloudformation:CreateChangeSet",
"cloudformation:ExecuteChangeSet",
"cloudformation:DeleteChangeSet",
"cloudformation:DescribeStacks",
"cloudformation:DescribeStackEvents",
"cloudformation:DescribeChangeSet",
"cloudformation:GetTemplateSummary",
"cloudformation:ListStackResources"
],
"Resource": "*"
},
{
"Sid": "S3ForSamArtifacts",
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:PutObject",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::hands-on-sam-github-actions-deploy-bucket",
"arn:aws:s3:::hands-on-sam-github-actions-deploy-bucket/*"
]
},
{
"Sid": "IamForExecutionRoleDeployOnly",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:GetRole",
"iam:AttachRolePolicy",
"iam:PutRolePolicy",
"iam:TagRole"
],
"Resource": "arn:aws:iam::{{AWS_ACCOUNT_ID}}:role/sam-basic-lambda-function-execution-role"
},
{
"Sid": "PassRoleToLambdaOnly",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::{{AWS_ACCOUNT_ID}}:role/sam-basic-lambda-function-execution-role",
"Condition": {
"StringEquals": {
"iam:PassedToService": "lambda.amazonaws.com"
}
}
},
{
"Sid": "LambdaDeployOnly",
"Effect": "Allow",
"Action": [
"lambda:CreateFunction",
"lambda:UpdateFunctionCode",
"lambda:UpdateFunctionConfiguration",
"lambda:GetFunction",
"lambda:TagResource",
"lambda:UntagResource"
],
"Resource": "arn:aws:lambda:ap-northeast-1:{{AWS_ACCOUNT_ID}}:function:sam-basic-lambda-function"
},
{
"Sid": "LogsDeployOnly",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:PutRetentionPolicy",
"logs:DescribeLogGroups",
"logs:TagResource",
"logs:UntagResource"
],
"Resource": [
"arn:aws:logs:ap-northeast-1:{{AWS_ACCOUNT_ID}}:log-group:/aws/lambda/sam-basic-lambda-function",
"arn:aws:logs:ap-northeast-1:{{AWS_ACCOUNT_ID}}:log-group:/aws/lambda/sam-basic-lambda-function:*"
]
},
{
"Sid": "CallerIdentity",
"Effect": "Allow",
"Action": "sts:GetCallerIdentity",
"Resource": "*"
}
]
}

確認し問題なければポリシーを作成します。

続いてIAMロールの作成を行います。

以下を選択し、次へ。
- 信頼されたエンティティタイプ:
ウェブアイデンティティ - アイデンティティプロバイダー:
token.actions.githubusercontent.com - Audience:
sts.amazonaws.com - GitHub organization: ご自身の組織名
- GitHub repository:
hands-on-sam-deploy-with-github-actions - GitHub branch:
main

作成したインラインポリシーを選択します。

確認し問題なければ、ロール名を任意の名前で作成します。

作成したIAMロールのARNをコピーします。

これでdeploy用のOIDCを使用したIAMロールが作成できました。
4-3.デプロイ用のS3バケットを作成
マネジメントコンソールからS3 > 汎用バケット > バケットを作成ボタンを押下します。

任意のS3バケット名で作成し、後はデフォルトのまま作成します。
なおS3バケット名はグローバルで一意になるようにしてください。また、S3バケット名は小文字、数字、ハイフンのみ使用可能です。

4-4.Slackのwebhook URLを取得
弊社では主にSlackを用いてコミュニケーションを取っております。
今回はGithubActionで簡易的に通知できるようにslackのwebhook urlを取得し、そちらへ通知するようにします。
組織のSlackのMarketPlaceからIncoming Webhookを検索し、該当のSlackアプリをクリックします

Slackに追加を押下し、対象のチャネルを選択。
その後、Incoming Webhook インテグレーションの追加ボタンを押下。


するとWebhook URLが表示されますので、コピーします。
(対象のチャネルにはインテグレーションが追加されます。)


4-5.Github Actionsのワークフローファイルを作成
続いてGithub Actionsの実行ファイルを作成していきましょう
mkdir -p hands-on-sam-github-actions/.github/workflows
touch hands-on-sam-github-actions/.github/workflows/sam-deploy-actions.yml
下記ソースコードをhands-on-sam-github-actions/.github/workflows/sam-deploy-actions.ymlにコピー&ペーストします。
今回は一旦mainブランチへpush時に起動するようにしています
なお、envプロパティのDEPLOY_BUCKET_NAMEは先ほど作成したデプロイ先のS3バケットのバケット名を指定してください。
name: Deploy SAM with GitHub Actions
on:
push:
branches:
- main
paths:
- 'sam/**'
- '.github/workflows/sam-deploy-actions.yml'
env:
AWS_REGION: ap-northeast-1
SAM_STACK_NAME: hands-on-sam-github-actions-basic-lambda-stack
DEPLOY_BUCKET_NAME: [S3バケット名] # 【注意】先ほど作成したS3バケット名に置き換えてください。
AWS_ASSUME_ROLE: ${{ secrets.AWS_ASSUME_ROLE }}
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
permissions:
id-token: write
contents: read
jobs:
deploy-sam:
name: Deploy SAM with GitHub Actions
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Notify Slack of Start
uses: lazy-actions/slatify@master # Slack通知用アクション
if: always()
with:
type: ${{ job.status }}
job_name: ':rocket: *sam-cicd デプロイ開始*'
url: ${{ env.SLACK_WEBHOOK }}
# PythonのLambdaを使用するためのセットアップ
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- uses: aws-actions/setup-sam@v2 # SAM CLIのインストール
with:
use-installer: true # installを高速化
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ env.AWS_ASSUME_ROLE }}
aws-region: ${{ env.AWS_REGION }}
role-session-name: GitHubActionsSamDeploySession
- name: SAM Build
run: sam build
working-directory: sam
- name: SAM Deploy
run: |
sam deploy \
--stack-name "${SAM_STACK_NAME}" \
--region "${AWS_REGION}" \
--s3-bucket "${DEPLOY_BUCKET_NAME}" \
--capabilities CAPABILITY_NAMED_IAM \
--no-confirm-changeset \
--no-fail-on-empty-changeset
working-directory: sam
- name: Notify Slack of Results
uses: lazy-actions/slatify@master
if: always()
with:
type: ${{ job.status }}
job_name: ':rocket: *sam-cicd デプロイ結果*'
url: ${{ env.SLACK_WEBHOOK }}
最終的に下記のようなディレクトリ構成になっていると思います。
hands-on-sam-github-actions/
├── .github/workflows/
│ └── sam-deploy-actions.yml
└── sam/
├── template.yaml
└── lambda/
└── lambda_function.py
ここで一旦Gitのコミットを作成しましょう。
以下のコマンドを実行し、Gitのコミットを作成します。
cd hands-on-sam-github-actions
git init
git add .github/workflows/sam-deploy-actions.yml sam/lambda/lambda_function.py sam/template.yaml
git commit -m "init SAM deploy with GitHub Actions"
4-6.GitHubリポジトリを作成
Githubで新規リポジトリを作成します。
なお、今回はhands-on-sam-deploy-with-github-actionsという名前でリポジトリを作成します。

GitHubリポジトリでSecrets Keyを作成します
Settings > Secrets and variables > Actionsをクリックし、New repository secretボタンを押下します。

そして、以下のSecrets情報を入力し、Add secretボタンを押下します。
- AWS_ASSUME_ROLE:
先ほど取得したIAMロールのARN - SLACK_WEBHOOK:
先ほど取得したSlackのWebhook URL


設定が完了すると以下の状態になっているかと思います。

これでGithub Actionsを利用する準備が整いました。
4-7.Git push→デプロイ
それでは実際にgit pushしてGithub Actionsを動かしてみましょう。{{YourOrg}}をご自身が所属するGithubの組織名あるいは個人名に置き換えて、下記を実行します。
git remote add origin https://github.com/{{YourOrg}}/hands-on-sam-deploy-with-github-actions.git
git branch -M main
git push -u origin main
Github Actionsが起動するので完了まで待ち、StatusがSuccessとなれば成功です。

その際に、Slackの通知も届いているはずです。

※なお失敗時は以下のような通知です。

AWSマネジメントコンソールからも無事にデプロイが成功していることが確認できています。

念の為、AWSマネジメントコンソールでLambda関数、IAM RoleおよびCloudWatch Logsのリソースが存在していることを確認しましょう。



各種リソースが存在していることを確認できました。
これで、Github ActionsでAWS SAMへのデプロイができました。
5.まとめ

本記事では、AWS SAMとGithub ActionsによるCI/CD化について解説させていただきました。
思っていたより簡単に作成できたのではないでしょうか。
皆さんの一助になれば幸いです!
