1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Code Action with Bedrockに入門しました

Posted at

はじめに

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 を使いたいと思ったけれどまだ使えていなかったことに思い当たりました :bulb:

まだプレビューだけど使ってみるか~と考えていたときに以下の記事を拝見しました。

調べてみると、Claude Code Actionは8/27にGA(一般提供開始) となっており、であればまずは Claude Code Actionを使ってみよう:exclamation: と思いました。

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」となっており、複数あるようですが同じものを指していると思われます。

セットアップ

こちらに従って進めていきました

セットアップの流れ

  1. GitHubアプリ作成
  2. GitHubアプリをリポジトリにインストール
  3. リポジトリのシークレットにGitHubアプリ情報をセット
  4. GitHub Actions連携用IAMロールの作成
  5. ワークフロー作成

1. GitHubアプリ作成

GitHubアプリ名を付けます。

image.png

Homepage URLは適当なもので大丈夫です。

image.png

Webhookはチェックを外して無効にします。

image.png

Repository permissionsに下記3つの権限を付与します。

  • Contents: Read & Write
  • Issues: Read & Write
  • Pull requests: Read & Write

image.png

Only on this account(デフォルト)を選択したままの状態で、アプリを作成します。

image.png

作成後に割り当てられるApp IDをメモします。

image.png

秘密鍵を生成するとローカルにPEMファイルがダウンロードされます。

image.png

2. GitHubアプリをリポジトリにインストール

作成したアプリをインストールします。

image.png

インストール先は選べますが、ここでは特定のリポジトリを指定してインストールします。

image.png

3. リポジトリのシークレットにGitHubアプリ情報をセット

リポジトリのActionシークレットに追加します。

  • APP_ID: GitHubアプリのID
  • APP_PRIVATE_KEY: 秘密鍵(.pem)の内容

image.png

シークレットへの保存が済んだら、ローカル上に保存された秘密鍵ファイル(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という名称としました。

image.png

5. ワークフロー作成

ドキュメントのサンプルを元に下記のようなワークフローファイルを作成しました。

claude-code.yml
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テンプレートファイルを追加するプルリクエストを作り、コメント欄でレビューをお願いしてみました。

image.png

少し待っていると・・・レビュー結果がコメント欄に書き込まれました :smiley:
とてもいい感じです!

image.png

Issue commentトリガーでワークフローが起動し、所要時間は1分ほどでした。

image.png

アクションのサマリー画面にClaude Codeの実行結果がサマリーとして書き込まれています。

image.png

使ったツールと実行結果も確認することができます。

image.png

サマリーの最下部で、レビューにかかったコストも確認することができます。

image.png

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."

英語での問いかけであっても日本語で回答してくれるようになりました!

image.png

上記を試した後に--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 を設定しました。

./mcp-config.json
{
  "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

こんな感じで聞いてみました。

image.png

するとこんな感じで返ってきました。使えるそうです!

image.png

・・・本当でしょうか?
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サーバーを使うようにお願いしてみました。

image.png

するとエラーが・・・使えていませんでした :cry: 「connected」ってなに?

image.png

どうしたものか・・・

上記のメッセージを良く見ると、ツールの名前が「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サーバーを使ってくれました :tada:

image.png

でもちょっとサマリー出力のフォーマットがうまくいっていない部分がありました。ここは今後の改善に期待したいと思います。

image.png

なお、上記で試したときはMAXのターン数に到達して最終的にはエラーになり、最終回答がプルリクエストのコメント欄に書き込まれず終わってしまいました。

  "type": "result",
  "subtype": "error_max_turns",
  "duration_ms": 102013,
  "duration_api_ms": 94697,
  "is_error": false,
  "num_turns": 10,

--max-turnsのデフォルト値は10になっています。デフォルトからMCPサーバーを追加するとターン数はおそらく増える傾向になると思われるため、コストとのバランスを考慮のうえ調整していく部分になりそうです。

さいごに

今回はじめて使ってみて、とても便利なツールであると感じました。
今後継続的に利用していくことを考えると、精度やコストが気になるところです。
いろいろ試しながらワークフローに変更を加えてきたので、最終系をこちらに改めて記載しておきます。

ワークフロー最終系
claude-code.yml
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

弊社では一緒に働く仲間を募集中です!

現在、様々な職種を募集しております。
カジュアル面談も可能ですので、ご連絡お待ちしております!

募集内容等詳細は、是非採用サイトをご確認ください。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?