はじめに
Claude Code ActionにBedrockを組み合わせて使ってみた話について書きたいと思います。
経緯
本題とあまり関係ありませんが、書いておきます
あるプロジェクトにおいて、CDKで crossRegionReferences を利用していました。この機能では、リージョンを跨いで値をやり取りするためのLambda関数が作成されますが、そこでNode.js 18が利用されていました。
LambdaランタイムのNode.js 18は2025/9/1に廃止日を迎えました(非推奨のランタイム)。
※関数を更新できなくなるのは2026/3/9ですが、廃止日以降はセキュリティパッチが適用されなくなるので、まだの方はなるべく早めの更新をお勧めいたします。
対処方法としては、CDK動作に必要なLambda関数なので、CDKパッケージを最新化することでランタイムバージョンを上げることができます。単純にパッケージの最新化だけであれば対処は容易ですが、他にも変更が必要なポイントが見つかり、まとめて対応することになりました。例えば、該当のCDKアプリで利用されていたCloudFrontの S3Origin クラスが非推奨になっており、代わりに S3BucketOrigin を利用するよう修正する必要がありました。
ということで、当初想定よりレビューの確認ポイントが多いことがわかりました。
ここでふと Amazon Q Developer for GitHub を使いたいと思ったけれどまだ使えていなかったことに思い当たりました
まだプレビューだけど使ってみるか~と考えていたときに以下の記事を拝見しました。
調べてみると、Claude Code Actionは8/27にGA(一般提供開始) となっており、であればまずは Claude Code Actionを使ってみよう と思いました。
builders.flash は参考になる記事が多く、とても勉強になります
Claude Code Actionとは
ドキュメント から引用します。
Claude Code GitHub ActionsはAIを活用した自動化をGitHubワークフローにもたらします。PRやissueで簡単に@claudeとメンションするだけで、Claudeがコードを分析し、プルリクエストを作成し、機能を実装し、バグを修正します - すべてプロジェクトの標準に従って行います。
2025/5/23に ベータ版がリリース され、先述のとおり2025/8/27にGAとなりました。
なお、名称としては、Claudeドキュメントでは「Claude Code GitHub Actions」、GitHubリポジトリでは「Claude Code Action」となっており、複数あるようですが同じものを指していると思われます。
セットアップ
こちらに従って進めていきました
セットアップの流れ
- GitHubアプリ作成
- GitHubアプリをリポジトリにインストール
- リポジトリのシークレットにGitHubアプリ情報をセット
- GitHub Actions連携用IAMロールの作成
- ワークフロー作成
1. GitHubアプリ作成
GitHubアプリ名を付けます。
Homepage URLは適当なもので大丈夫です。
Webhookはチェックを外して無効にします。
Repository permissionsに下記3つの権限を付与します。
-
Contents
: Read & Write -
Issues
: Read & Write -
Pull requests
: Read & Write
Only on this account
(デフォルト)を選択したままの状態で、アプリを作成します。
作成後に割り当てられるApp ID
をメモします。
秘密鍵を生成するとローカルにPEMファイルがダウンロードされます。
2. GitHubアプリをリポジトリにインストール
作成したアプリをインストールします。
インストール先は選べますが、ここでは特定のリポジトリを指定してインストールします。
3. リポジトリのシークレットにGitHubアプリ情報をセット
リポジトリのActionシークレットに追加します。
-
APP_ID
: GitHubアプリのID -
APP_PRIVATE_KEY
: 秘密鍵(.pem)の内容
シークレットへの保存が済んだら、ローカル上に保存された秘密鍵ファイル(xxx.private-key.pem)は安全のため完全削除してしまうことをお勧めします。もしシークレットを削除してしまうなどして秘密鍵がわからなくなってしまった場合は再作成すれば良いので、シークレット以外の場所に残らないようにするのが良いと思います。
4. GitHub Actions連携用IAMロールの作成
GitHub Actionsのワークフロー内からBedrockを利用するためのIAMロールを作成します。
わたしはCloudFormationで作成してみました。
テンプレートYAML
AWSTemplateFormatVersion: 2010-09-09
Description: Creates an IAM Role for GitHub Actions with permissions to invoke Amazon Bedrock models for Claude Code.
Parameters:
GitHubOrg:
Type: String
Description: GitHub Organization name
RepositoryName:
Type: String
Description: GitHub repository name
OIDCProviderArn:
Description: Arn for the GitHub OIDC Provider.
Default: ''
Type: String
Conditions:
CreateOIDCProvider: !Equals
- !Ref OIDCProviderArn
- ''
Resources:
GithubOidc:
Type: AWS::IAM::OIDCProvider
Condition: CreateOIDCProvider
Properties:
Url: https://token.actions.githubusercontent.com
ClientIdList:
- sts.amazonaws.com
ThumbprintList:
- ffffffffffffffffffffffffffffffffffffffff
Role:
Type: AWS::IAM::Role
Properties:
RoleName: github-actions-claude-code-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Action: sts:AssumeRoleWithWebIdentity
Principal:
Federated: !If
- CreateOIDCProvider
- !Ref GithubOidc
- !Ref OIDCProviderArn
Condition:
StringEquals:
token.actions.githubusercontent.com:aud:
- sts.amazonaws.com
StringLike:
token.actions.githubusercontent.com:sub:
- !Sub repo:${GitHubOrg}/${RepositoryName}:*
Policies:
- PolicyName: bedrock-claude
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: InvokeBedrockModels
Effect: Allow
Action:
- bedrock:InvokeModel
- bedrock:InvokeModelWithResponseStream
Resource:
- !Sub arn:${AWS::Partition}:bedrock:*::foundation-model/anthropic.claude-*
- !Sub arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:inference-profile/*.anthropic.claude-*
Outputs:
ClaudeCodeRoleArn:
Value: !GetAtt Role.Arn
ドキュメントにはAmazonBedrockFullAccess
ポリシーを付与すると記載されていますが、最小限の権限付与とするため下記のようにアクションをしぼりました。
Policies:
- PolicyName: bedrock-claude
PolicyDocument:
Version: 2012-10-17
Statement:
- Sid: InvokeBedrockModels
Effect: Allow
Action:
- bedrock:InvokeModel
- bedrock:InvokeModelWithResponseStream
Resource:
- !Sub arn:${AWS::Partition}:bedrock:*::foundation-model/anthropic.claude-*
- !Sub arn:${AWS::Partition}:bedrock:*:${AWS::AccountId}:inference-profile/*.anthropic.claude-*
IAMロールを作成したら、ロールのARNをシークレットに保存します。ここではCLAUDE_CODE_ACTION_ROLE
という名称としました。
5. ワークフロー作成
ドキュメントのサンプルを元に下記のようなワークフローファイルを作成しました。
name: Claude PR Action
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
jobs:
claude-pr:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'issues' && contains(github.event.issue.body, '@claude'))
runs-on: ubuntu-latest
env:
AWS_REGION: ap-northeast-1
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate session name
id: session
run: |
repo="${GITHUB_REPOSITORY#${GITHUB_REPOSITORY_OWNER}/}"
echo "name=${repo}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "${GITHUB_OUTPUT}"
- name: Configure AWS Credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
role-to-assume: ${{ secrets.CLAUDE_CODE_ACTION_ROLE }}
role-session-name: ${{ steps.session.outputs.name }}
aws-region: ap-northeast-1
- uses: anthropics/claude-code-action@v1
with:
github_token: ${{ steps.app-token.outputs.token }}
use_bedrock: 'true'
claude_args: |
--model jp.anthropic.claude-sonnet-4-5-20250929-v1:0
--max-turns 10
サンプルから変更したところを2点解説します。
① permissionsにactions: read
を追加
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read
Claude Codeドキュメントには記載がなかったため、actions: read
を付与せずClaudeアクションを実行したところ、下記の警告メッセージが出力されました。
Warning: The github_ci MCP server requires 'actions: read' permission. Please ensure your GitHub token has this permission. See: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
これについては こちら のドキュメントに記載がありました。このPermissionを付与することで、Claudeアクションがgithub_ci
MCPサーバー経由でワークフロー情報にアクセス可能となり、CI/CDの障害分析やワークフローの問題のデバッグに役立つようです。
② トレーサビリティ向上
こちらはClaude Code Actionに限った話ではありませんが、上記の記事を参考にさせていただき、下記のステップを入れました。
ロールセッション名にリポジトリ名などを付与することで、CloudTrailでトレースし易くなります。
- name: Generate session name
id: session
run: |
repo="${GITHUB_REPOSITORY#${GITHUB_REPOSITORY_OWNER}/}"
echo "name=${repo}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "${GITHUB_OUTPUT}"
- name: Configure AWS Credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
role-to-assume: ${{ secrets.CLAUDE_CODE_ACTION_ROLE }}
role-session-name: ${{ steps.session.outputs.name }}
aws-region: ap-northeast-1
実行してみた
適当なCloudFormationテンプレートファイルを追加するプルリクエストを作り、コメント欄でレビューをお願いしてみました。
少し待っていると・・・レビュー結果がコメント欄に書き込まれました
とてもいい感じです!
Issue comment
トリガーでワークフローが起動し、所要時間は1分ほどでした。
アクションのサマリー画面にClaude Codeの実行結果がサマリーとして書き込まれています。
使ったツールと実行結果も確認することができます。
サマリーの最下部で、レビューにかかったコストも確認することができます。
GitHubアプリはAnthropic公式と独自のどちらを利用するか
先述のセットアップ手順では特に説明なく独自のGitHubアプリを作成しましたが、Anthropicから公式のGitHubアプリ(Claude)が提供されています。
公式アプリを利用する方が準備は楽ですが、Claudeドキュメントには以下の記述があります。
(翻訳)
Vertex AI や Bedrock などの 3P プロバイダーを使用する場合は、最適な制御とセキュリティを確保するために、独自の GitHub アプリを作成することをお勧めします。
「最適な制御とセキュリティを確保する」とはどういうことか、考えてみたいと思います。
下記はClaudeドキュメント記載のワークフローサンプル抜粋で、独自GitHubアプリを使う場合のワークフロー定義になっています。
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
~省略~
- uses: anthropics/claude-code-action@v1
with:
github_token: ${{ steps.app-token.outputs.token }}
use_bedrock: "true"
claude_args: '--model us.anthropic.claude-sonnet-4-5-20250929-v1:0 --max-turns 10'
Generate GitHub App token
で、シークレットに保管した秘密鍵を使って一時的な認証情報(トークン)を生成し、anthropics/claude-code-action
アクションにgithub_token
パラメータでトークンを渡すことにより、リポジトリに対する操作権限をワークフロー実行中のみ一時的に付与しています。
一方、Anthropic公式のGitHubアプリを利用する場合は、Generate GitHub App token
ステップは不要になり、anthropics/claude-code-action
アクションにトークンを渡す必要もなく、下記のようなワークフローの記述になります。
- uses: anthropics/claude-code-action@v1
with:
use_bedrock: "true"
claude_args: '--model us.anthropic.claude-sonnet-4-5-20250929-v1:0 --max-turns 10'
つまり、GitHubアプリを独自に作ることで、秘密鍵の管理を自分で行う&トークンの生成も自分で行う(=サードパーティアプリに秘密鍵の操作を任せない)ことになり、(秘密鍵を自身で厳密に管理することが前提ですが)よりセキュアな構成になります。
※GitHubアプリに付与する権限を自身でコントロールできるという利点もあります。
その他やってみたこと
日本語で回答するよう指示してみた
日本語で問いかけても結果が日本語だったり英語だったりしたため、--system-prompt
で、日本語で回答するよう指示してみました。
- uses: anthropics/claude-code-action@v1
with:
github_token: ${{ steps.app-token.outputs.token }}
use_bedrock: 'true'
claude_args: |
--model jp.anthropic.claude-sonnet-4-5-20250929-v1:0
--max-turns 10
--system-prompt "Please respond in Japanese."
英語での問いかけであっても日本語で回答してくれるようになりました!
上記を試した後に--append-system-prompt
というパラメータの存在を知りました。ドキュメント によると、このパラメータはシステムプロンプトを書き換えるのではなく、任意の指示文を追加できるようです。
- uses: anthropics/claude-code-action@v1
with:
github_token: ${{ steps.app-token.outputs.token }}
use_bedrock: 'true'
claude_args: |
--model jp.anthropic.claude-sonnet-4-5-20250929-v1:0
--max-turns 10
--append-system-prompt "Please respond in Japanese."
試したところ同様の効果が得られました。
具体的な動作の違いを確認することはできていませんが、日本語で回答してほしいだけなのであれば、こちらを使った方が良さそうです。
モデルをNovaにしてみた
下記エラーが発生し、使えませんでした・・・
API Error: 400 Malformed input request: #: extraneous key [metadata] is not permitted, please reformat your input and try again.
MCPサーバーを追加してみた
こちら を参考に設定してみました。
MCPサーバーの定義はJSONファイルに切り出し、 AWS Documentation MCP Server を設定しました。
{
"mcpServers": {
"awslabs.aws-documentation-mcp-server": {
"command": "uvx",
"args": ["awslabs.aws-documentation-mcp-server@latest"],
"env": {
"FASTMCP_LOG_LEVEL": "ERROR",
"AWS_DOCUMENTATION_PARTITION": "aws"
},
"disabled": false,
"autoApprove": []
}
}
}
ワークフローは下記のように修正しました。uvをインストールし、claude-code-actionにパラメータ--mcp-config
と--allowedTools
を追加しました。
- name: Install uv
uses: astral-sh/setup-uv@v6
- uses: anthropics/claude-code-action@v1
with:
github_token: ${{ steps.app-token.outputs.token }}
use_bedrock: 'true'
claude_args: |
--model jp.anthropic.claude-sonnet-4-5-20250929-v1:0
--max-turns 10
--append-system-prompt "Please respond in Japanese."
--mcp-config mcp-config.json
--allowedTools awslabs.aws-documentation-mcp-server__read_documentation,awslabs.aws-documentation-mcp-server__search_documentation,awslabs.aws-documentation-mcp-server__recommend
こんな感じで聞いてみました。
するとこんな感じで返ってきました。使えるそうです!
・・・本当でしょうか?
GitHub Actionsのログを見てみると、利用できるツールとMCPサーバーが出力されていました。
こちらはツールです。
"tools": [
"Task",
"Bash",
"Glob",
"Grep",
"ExitPlanMode",
"Read",
"Edit",
"Write",
"NotebookEdit",
"WebFetch",
"TodoWrite",
"BashOutput",
"KillShell",
"SlashCommand",
"mcp__github_ci__get_ci_status",
"mcp__github_ci__get_workflow_run_details",
"mcp__github_ci__download_job_log",
"mcp__github_comment__update_claude_comment",
"mcp__awslabs_aws-documentation-mcp-server__read_documentation",
"mcp__awslabs_aws-documentation-mcp-server__search_documentation",
"mcp__awslabs_aws-documentation-mcp-server__recommend",
"ListMcpResourcesTool",
"ReadMcpResourceTool"
]
こちらがMCPサーバーです。「connected」となっているのでおそらく本当なようです。
"mcp_servers": [
{
"name": "github_ci",
"status": "connected"
},
{
"name": "github_comment",
"status": "connected"
},
{
"name": "awslabs.aws-documentation-mcp-server",
"status": "connected"
}
]
今度はMCPサーバーを使うようにお願いしてみました。
するとエラーが・・・使えていませんでした 「connected」ってなに?
どうしたものか・・・
上記のメッセージを良く見ると、ツールの名前が「mcp__awslabs_aws-documentation-mcp-server__search_documentation」になっており、--allowedTools
で指定した名称と異なることに気づきました。
そこで下記のようにフォーマットを変更して試してみることにしました。
【変更前】awslabs.aws-documentation-mcp-server__search_documentation
【変更後】mcp__awslabs_aws-documentation-mcp-server__search_documentation
--allowedTools
部分は下記のようになりました。
--allowedTools mcp__awslabs_aws-documentation-mcp-server__read_documentation,mcp__awslabs_aws-documentation-mcp-server__search_documentation,mcp__awslabs_aws-documentation-mcp-server__recommend
すると、ついにMCPサーバーを使ってくれました
でもちょっとサマリー出力のフォーマットがうまくいっていない部分がありました。ここは今後の改善に期待したいと思います。
なお、上記で試したときはMAXのターン数に到達して最終的にはエラーになり、最終回答がプルリクエストのコメント欄に書き込まれず終わってしまいました。
"type": "result",
"subtype": "error_max_turns",
"duration_ms": 102013,
"duration_api_ms": 94697,
"is_error": false,
"num_turns": 10,
--max-turns
のデフォルト値は10になっています。デフォルトからMCPサーバーを追加するとターン数はおそらく増える傾向になると思われるため、コストとのバランスを考慮のうえ調整していく部分になりそうです。
さいごに
今回はじめて使ってみて、とても便利なツールであると感じました。
今後継続的に利用していくことを考えると、精度やコストが気になるところです。
いろいろ試しながらワークフローに変更を加えてきたので、最終系をこちらに改めて記載しておきます。
ワークフロー最終系
name: Claude PR Action
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
actions: read
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
jobs:
claude-pr:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'issues' && contains(github.event.issue.body, '@claude'))
runs-on: ubuntu-latest
env:
AWS_REGION: ap-northeast-1
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Generate session name
id: session
run: |
repo="${GITHUB_REPOSITORY#${GITHUB_REPOSITORY_OWNER}/}"
echo "name=${repo}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" >> "${GITHUB_OUTPUT}"
- name: Configure AWS Credentials (OIDC)
uses: aws-actions/configure-aws-credentials@v5.0.0
with:
role-to-assume: ${{ secrets.CLAUDE_CODE_ACTION_ROLE }}
role-session-name: ${{ steps.session.outputs.name }}
aws-region: ap-northeast-1
- name: Install uv
uses: astral-sh/setup-uv@v6
- uses: anthropics/claude-code-action@v1
with:
github_token: ${{ steps.app-token.outputs.token }}
use_bedrock: 'true'
claude_args: |
--model jp.anthropic.claude-sonnet-4-5-20250929-v1:0
--max-turns 10
--append-system-prompt "Please respond in Japanese."
--mcp-config mcp-config.json
--allowedTools mcp__awslabs_aws-documentation-mcp-server__read_documentation,mcp__awslabs_aws-documentation-mcp-server__search_documentation,mcp__awslabs_aws-documentation-mcp-server__recommend
弊社では一緒に働く仲間を募集中です!
現在、様々な職種を募集しております。
カジュアル面談も可能ですので、ご連絡お待ちしております!
募集内容等詳細は、是非採用サイトをご確認ください。