GitHub Actionsを使ってAmazon Bedrock経由でClaudeを定期実行するワークフローを構築してみた
リテールアプリ共創部のるおんです。
Claude Code を使った自動化が便利になってきて、「人が叩かなくても、決まった時間に勝手に Claude を動かしたい」という場面が出てきました。たとえば「毎晩リポジトリを走査して要約を作る」「定期的にドキュメントを更新する」といったタスクです。
これは GitHub Actions の cron + Claude Code(CLI) でシンプルに実現できます。 その際、通常 Anthropic の API キーを使うのが一般的ですが、今回は API キーを使わず、Amazon Bedrock 経由 + OIDC で動かす構成にしました。
なお、@claude メンションや PR レビューといった「GitHub イベントに反応する」用途向けに作られている Claude Code Action は あえて使わず 、シンプルに GitHub Actions のワークフローの中で(CLI を直接叩いて)Bedrock を呼び出す ことにしています。
本記事では、その構成を CDK での IAM 準備からワークフロー作成、モデル有効化と動作確認まで 一通りまとめます。
先に結論
- GitHub Actions で Claude を定期実行するには、
schedule(cron)トリガーで Claude Code CLI をヘッドレス実行(claude -p) する - Bedrock + GitHub OIDC を採用し、長期シークレット(APIキー)を一切持たない 構成にした
- 必要な GitHub OIDC プロバイダ + IAM ロール(
bedrock:InvokeModelだけ許可) を AWS CDK で管理。 - InvokeModel でモデルアクセスを手元から有効化
GitHub Actions (cron)
│ OIDCトークン
▼
IAMロール(AssumeRoleWithWebIdentity / bedrock:InvokeModel のみ)
│
▼
Amazon Bedrock ── Claude(例: Opus / Sonnet)
構成の全体像
今回作る仕組みの全体像です。
ポイントは、GitHub に AWS の長期クレデンシャルを置かない ことです。OIDC を使うと、GitHub Actions が実行のたびに短命のトークンを発行し、それを使って IAM ロールを一時的に引き受けます。アクセスキーを Secrets に保存する必要がなく、ローテーションも不要になります。
Bedrock 経由での Claude 実行を選んだ理由
Claude の CLI を利用するには、通常 Anthropic の API キーを使うのが一般的です。ですが今回は、API キーを使わずに Amazon Bedrock 経由で呼び出す ことにしました。理由は次の通りです。
- API キーの発行・管理をしたくない:Bedrock なら OIDC で完結し、長期シークレットを持たずに済む
- 課金を AWS に寄せたい:Claude の利用料を AWS の請求にまとめることが可能
また、Claude Code には routines(定期実行機能)という機能がありますが、routines は 個人の claude.ai アカウントに属し 、実行は個人のサブスク使用量を消費します。コミットや PR も その人の GitHub ユーザー名義 になります。
今回は1つのチームで使用するリポジトリに対して実行をしたいので、チームで無人運用する仕組みとしては 特定個人のサブスクに紐づく のは運用・ガバナンスの両面で避けたいところです。その人が抜けたり設定を無効化したら止まってしまいます。GitHub Actions + OIDC ロールなら、リポジトリと AWS アカウントに属する ので属人化しません。
やってみる
① CDK で OIDC プロバイダと IAM ロールを用意
必要な AWS リソースは GitHub OIDC プロバイダ と IAM ロール の2つだけです。これを CDK(TypeScript)で書きます。
import * as cdk from "aws-cdk-lib";
import * as iam from "aws-cdk-lib/aws-iam";
import { Construct } from "constructs";
export class GithubBedrockOidcStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const githubOwner = "<your-org>";
const githubRepo = "<your-repo>"; // ワークフローが動くリポジトリ
const githubDomain = "token.actions.githubusercontent.com";
// ① GitHub OIDC プロバイダ
const oidcProvider = new iam.OpenIdConnectProvider(this, "GitHubOidcProvider", {
url: `https://${githubDomain}`,
clientIds: ["sts.amazonaws.com"],
});
// ② GitHub Actions が引き受けるロール(信頼条件で対象リポジトリに限定)
const role = new iam.Role(this, "BedrockInvokeRole", {
roleName: "github-actions-bedrock-invoke",
// description は ASCII のみ
description: "Role for GitHub Actions (OIDC) to invoke Claude models on Amazon Bedrock",
maxSessionDuration: cdk.Duration.hours(1),
assumedBy: new iam.OpenIdConnectPrincipal(oidcProvider, {
StringEquals: {
[`${githubDomain}:aud`]: "sts.amazonaws.com",
},
StringLike: {
// 対象リポジトリの全ブランチ/イベントを許可。main限定なら ref:refs/heads/main
[`${githubDomain}:sub`]: `repo:${githubOwner}/${githubRepo}:*`,
},
}),
});
// ③ Claude への InvokeModel だけを許可(最小権限)
role.addToPolicy(
new iam.PolicyStatement({
sid: "InvokeClaudeModels",
effect: iam.Effect.ALLOW,
actions: ["bedrock:InvokeModel", "bedrock:InvokeModelWithResponseStream"],
resources: [
// 基盤モデル(クロスリージョン推論の経路先も含めて全リージョン)
"arn:aws:bedrock:*::foundation-model/anthropic.claude-*",
// 推論プロファイル(us. / apac. / jp. など)
`arn:aws:bedrock:*:${this.account}:inference-profile/*anthropic.claude-*`,
],
}),
);
new cdk.CfnOutput(this, "RoleArn", { value: role.roleArn });
}
}
ポイントを整理します。
- 信頼条件で
subを絞る:repo:<org>/<repo>:*とすることで、このリポジトリの GitHub Actions だけ がこのロールを引き受けられます。他人のリポジトリから勝手に Assume されないための肝です - 権限は
bedrock:InvokeModel系のみ:Claude のモデル ARN にスコープした最小権限にしています。クロスリージョン推論プロファイルを使うので、foundation-modelはリージョンをワイルドカードにしています
デプロイは通常の CDK と同じです。
cdk deploy
デプロイ後に出力される RoleArn を控えておきます。これを後で GitHub の Secret に登録します。
デプロイがうまくいくと、マネジメントコンソールで以下の2つができているはずです。
まず IAM → IDプロバイダ に、GitHub の OIDC プロバイダ(token.actions.githubusercontent.com / タイプ: OpenID Connect)が作成されています。

次に、作成された IAM ロール には、Claude への InvokeModel だけを許可する インラインポリシー がアタッチされています。

この 「IDプロバイダ」+「最小権限のインラインポリシーを持つ IAM ロール」 の2つができていれば、① は成功です。
② GitHub Actions ワークフロー実装
本題のワークフローです。schedule(cron)で定期実行し、Claude Code CLI をヘッドレス実行 して Bedrock 経由で Claude を動かします。
name: Claude定期実行
on:
schedule:
# 毎日 22:00 JST(UTC 13:00)
- cron: "0 13 * * *"
workflow_dispatch: # 手動実行も可能
# 同時実行を防ぐ
concurrency:
group: claude-scheduled
cancel-in-progress: false
permissions:
contents: write
id-token: write # ← OIDC に必須
jobs:
run:
runs-on: ubuntu-latest
timeout-minutes: 20
env:
AWS_REGION: ap-northeast-1 # Claude を使うリージョン
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: AWS認証(OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
aws-region: ${{ env.AWS_REGION }}
- name: Claude Code をインストール
run: npm i -g @anthropic-ai/claude-code
- name: Claudeを実行(Bedrock)
env:
CLAUDE_CODE_USE_BEDROCK: "1" # APIキーの代わりに Bedrock を使う
ANTHROPIC_MODEL: jp.anthropic.claude-opus-4-8 # 接頭辞付きの推論プロファイルID
run: |
claude -p "ここに Claude にやらせたいタスクを書く" \
--max-turns 30 \
--dangerously-skip-permissions
GitHub 側の設定は、リポジトリの Settings → Secrets and variables → Actions で以下を登録するだけです。
| Secret | 値 |
|---|---|
AWS_ROLE_TO_ASSUME |
CDK 出力の RoleArn |
③ Bedrock のモデルアクセスを有効化
ワークフローを動かす前に、Bedrock 側で Claude の モデルアクセスを有効化 しておく必要があります。これを忘れると、実行時に403 エラーで落ちます。
手元の環境から有効化しておきます。
aws bedrock-runtime invoke-model \
--region ap-northeast-1 \
--model-id jp.anthropic.claude-opus-4-8 \
--body '{"anthropic_version":"bedrock-2023-05-31","max_tokens":16,"messages":[{"role":"user","content":"ping"}]}' \
--cli-binary-format raw-in-base64-out \
/tmp/out.json && cat /tmp/out.json
"text":"Pong!..." のような応答が返れば有効化完了です。以降は、最小権限の GitHub Actions ロール(bedrock:InvokeModel だけ)でも呼び出せるようになります。
動作確認
ワークフローを push したら、cron を待たずに 手動実行(workflow_dispatch) で確認します。Actions タブから「Run workflow」、または CLI から実行できます。
gh workflow run claude-scheduled.yml --ref main
gh run watch "$(gh run list --workflow=claude-scheduled.yml --limit 1 --json databaseId --jq '.[0].databaseId')"
ジョブのログで、
- AWS認証(OIDC) ステップが成功(ロールの引き受けOK)
- Claudeを実行(Bedrock) ステップが成功(Bedrock 経由で Claude が応答)
となっていれば、定期実行の仕組みは完成です。あとは cron の時刻に自動で走ります。
おわりに
GitHub Actions の cron + Claude Code CLI で、API キーを一切持たずに、Bedrock 経由で Claude を定期実行する 仕組みを作りました。要点を振り返ります。
| 要素 | 役割 |
|---|---|
| GitHub OIDC プロバイダ + IAMロール | 長期シークレットなしで AWS を引き受ける(CDKで管理) |
| 最小権限 | bedrock:InvokeModel を Claude モデルにスコープ |
| configure-aws-credentials | OIDC でロールを引き受け、一時クレデンシャルを払い出す |
Claude Code CLI(CLAUDE_CODE_USE_BEDROCK=1) |
Bedrock 経由で claude -p を実行 |
| schedule(cron) | 定期実行のトリガー |
「Claude を人手で叩くのをやめて、定期実行に乗せたい」と思ったときに、API キーを増やさずに済む Bedrock + OIDC 構成はかなり扱いやすいので、ぜひ試してみてください。
以上、どなたかの参考になれば幸いです。
お知らせ
クラスメソッドのリテールアプリ共創部 ビルドチーム ではエンジニアを募集しています。
Claude Code や Cursor などの AI エージェントを業務に組み込み、プロジェクトの立ち上げから本番開発までを高速に回しているチームです。AI 駆動開発・プリセールス・顧客折衝・要件定義までフルスタックに踏み込んでみたい方は、ぜひ以下をご覧ください。
参考







