DifyをEC2に立ててAmazon Bedrockのモデルを使う構成は、2024年前後の解説どおりに進めると設定画面が一致しません。Dify 1.0でモデルプロバイダーがプラグインへ分離され、Bedrock側も認証方式が増えたためです。本記事はDify 1.16.1(2026-07-28)とBedrockプラグイン0.0.79(2026-08-18)の実装を読み、構築からIAMロール接続、つながらないときの切り分けまでを現行仕様で整理します。
まとめ
- Dify 1.16.1のDocker Compose構成はコア7サービス+依存8コンポーネント+初期化タスク1本です。公式の最小要件(CPU 2コア/RAM 4GiB)は下限で、実運用の入口は8GiB級になります。
- Bedrockプラグイン0.0.79は認証方式を
auth_methodで3択(IAMロール/アクセスキー/Bedrock APIキー)し、既定はIAMロールです。「アクセスキー欄を空欄にするとIAMロールになる」という旧手順は、現行スキーマでは必須項目のため通りません。 - プラグインはコンテナ内で動くため、IMDSのホップ数が既定の1のままではIMDSv2のトークン取得が返らず、インスタンスプロファイルの資格情報を取得できません。
http-put-response-hop-limitを2にします。 - プロバイダー設定の保存時、IAMロール方式では実接続の検証が行われません(コード上その場でreturnします)。保存できたことは疎通の証拠になりません。
- 日本国内にデータを留めるなら、Geographicではなく
japan(jp.推論プロファイル)を選びます。東京のGeographicはapac.に解決され、国内保管の要件を満たしません。
EC2にDifyを構築する前提と1.16.1の構成
インスタンス選定と最小要件の読み方
1.16.1のdocker compose up -dが起動するのは、コア7サービス(api、api_websocket、worker、worker_beat、web、plugin_daemon、agent_backend)と依存8コンポーネント(weaviate、db_postgres、redis、nginx、ssrf_proxy、agent_ssrf_proxy、sandbox、local_sandbox)、加えて権限設定用に一度だけ動いて終了するinit_permissionsです。ベクトルDBもPostgreSQLも同居するため、公式の最小要件であるRAM 4GiBは検証用の下限と考え、実運用の入口では8GiB級を選びます。プラグイン実行環境とアップロードファイル、ベクトルデータも同じEBSに載るので、容量とバックアップを分けたい場合はDifyのストレージをAmazon S3に切り替える設定を先に決めておくと移行作業が減ります。
Docker Composeでの構築手順
Amazon Linux 2023やUbuntuでDocker EngineとCompose v2を入れたあと、最新リリースのタグを指定してcloneします。
git clone --branch "$(curl -s https://api.github.com/repos/langgenius/dify/releases/latest | jq -r .tag_name)" https://github.com/langgenius/dify.git
cd dify/docker
cp .env.example .env
docker compose up -d
docker compose ps
全コンテナがUpまたはhealthyになったら、http://<パブリックIP>/installで管理者アカウントを作成します。注意すべきは.envの既定値です。1.16.1の.env.exampleではSECRET_KEYが空欄で、コメントに「空のままにするとストレージディレクトリに永続的な鍵を自動生成する」と明記されており、openssl rand -base64 42で自分で生成する旧手順は必須ではなくなりました。一方DB_PASSWORDはdifyai123456のまま、NGINX_HTTPS_ENABLEDはfalse、EXPOSE_NGINX_PORTは80です。パブリックIPで/installが開けるということは第三者も開けるということなので、セキュリティグループの80番は自社IPに絞ってから初期セットアップを行ってください。
コンテナランタイムをDockerに固定できない環境ではDifyをPodmanのrootlessで動かす手順、複数ノードで冗長化する段階に入るならAWS EKSへのDify導入が選択肢になります。
AWS Marketplace版(Dify Premium)との使い分け
Dify PremiumはAWS Marketplaceで提供されるAMIで、VPCへワンクリック配置できます。自前構築との違いは、管理者初期化パスワードがEC2のインスタンスIDであること、既定でHTTPの80番を使うこと、設定ファイルが/dify/.envと/dify/envs/配下に分かれることです。検証環境を最短で用意したいならMarketplace版、composeとバージョン更新を自分で握りたいなら自前構築を選びます。
Bedrock接続の認証方式3種と、EC2でIAMロールを選ぶ理由
Dify 1.0以降、Bedrockは組み込みのモデルプロバイダーではなくプラグインです。マーケットプレイスからlanggenius/bedrock(2026年8月19日時点で最新0.0.79、更新2026-08-18、インストール数98,863)を入れ、プラグイン設定を開くと最初に現れるのが認証方式のセレクトボックスで、既定値はIAM Roleです。署名検証やパッケージ容量でインストール自体が失敗する場合は、Difyのプラグインがインストールできない原因と対処法を先に確認してください。
IAMロール方式(EC2では第一選択)
認証方式にIAM Roleを選ぶと、アクセスキーの入力欄そのものが消え、必須項目はAWSリージョンだけになります。プラグインのクライアント生成コードは、この方式のときだけboto3.Session()を毎回新規生成。既定セッションが資格情報をプロセス内にキャッシュすると、期限切れのExpiredTokenExceptionがプラグイン再起動まで残り続けるためで、コメントにもその意図が書かれています。結果として、EC2にアタッチしたインスタンスプロファイルの一時資格情報が自動更新されても追随します。
設定画面にロールARNの入力欄はありません。プラグインはAssumeRoleを自分で実行せず、boto3の既定資格情報チェーン(環境変数、共有クレデンシャル、インスタンスメタデータ)に委ねる設計です。別アカウントのBedrockを使いたい場合は、Dify側ではなくEC2にアタッチするロール側でクロスアカウントの信頼関係を組みます。
Bedrock APIキー方式の制約
BedrockにはAWS資格情報の代わりにベアラートークンを使うAPIキーがあります。短期キーは最大12時間(またはセッション期間)で失効しAWSは本番向けと位置づけ、長期キーは有効期限を指定できるものの実体はIAMユーザーの作成で「探索用途向け」と明記されています。
Difyのプラグインはこの方式を選ぶと、受け取ったキーをAWS_BEARER_TOKEN_BEDROCK環境変数に設定します。短期キーを貼れば12時間以内に必ず切れ、長期キーを貼れば静的な資格情報をアプリ内に抱えることになります。EC2で動かす前提なら、インスタンスプロファイルのほうが運用も監査も軽く済みます。APIキー方式が向くのは、IAMロールを付けられない場所で短期間だけ検証する場合に限られます。なおこのキーはBedrockとBedrock Runtimeのアクション専用で、Agents系やData Automation系のAPIには使えません。
アクセスキー方式と「欄を空欄にする」旧手順
2024年前後の解説記事の多くは、Bedrock設定でAccess KeyとSecret Access Keyを空欄にしたまま保存すればEC2のIAMロールが使われる、と説明しています。これは0.x時代の挙動で、現行スキーマではaws_access_key_idとaws_secret_access_keyがいずれもrequired: trueです(認証方式にAccess-Secret Keyを選んだときだけ表示されます)。空欄のまま保存できないため、旧手順をなぞるとここで止まります。IAMロールを使いたいなら、空欄にするのではなく認証方式のセレクトでIAM Roleを選ぶ、というのが現行の答えです。
コンテナからIMDSに届かない問題(ホップ数の設定)
IAMロールを選んだのに資格情報が取れない、という詰まり方の典型がここです。Difyのモデルプラグインはplugin_daemonコンテナの中で動きます。AWSのドキュメントは「コンテナへ入ることは追加のネットワークホップとみなされる」「コンテナ環境ではホップ数1が問題を起こしうる」と明記し、IMDSv2を必須とするSDKではレスポンスがまったく返らない可能性がある、と説明しています。既定のホップ数は1なので、ブリッジネットワーク上のコンテナではトークン取得(PUT)の応答が返らず、フォールバックを持つSDKでも起動が遅延します。
aws ec2 modify-instance-metadata-options \
--instance-id i-0123456789abcdef0 \
--http-endpoint enabled \
--http-put-response-hop-limit 2
ホップ数を指定するときは--http-endpoint enabledも同時に渡す必要があります(AWS CLIとSDKのみ対応、コンソールからは変更できません)。設定後は次のコマンドで実値を確認します。
aws ec2 describe-instances --instance-ids i-0123456789abcdef0 \
--query "Reservations[].Instances[].MetadataOptions" --output json
アカウントレベルの既定値が1のリージョンでは、AMI側がImdsSupport: v2.0でホップ数2を意図していてもアカウント設定が優先されるため、起動時に明示指定するのが確実です。なお、ワークフローのHTTPリクエストノードからVPC内部やメタデータを叩けないのは別問題で、ssrf_proxy(squid)がhttp_access deny to_private_networksでプライベート宛てを落としているためです。plugin_daemonにはプロキシ環境変数が無く、Bedrockへは直接通信します。
IAMポリシーとモデルアクセスの現行仕様
プラグインが実際に呼ぶAPIは、推論がconverse/converse_streamとinvoke_model/invoke_model_with_response_stream、モデル一覧の取得がlist_foundation_modelsです。ConverseにIAMの専用アクションは無く、bedrock:InvokeModel権限で動きます。AmazonBedrockFullAccessを貼れば動きますが、最小権限に寄せるなら次の形が起点になります。一覧系はリソースレベルの権限に対応していないため、ARNで絞るステートメントとは分ける必要があります。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "BedrockList",
"Effect": "Allow",
"Action": [
"bedrock:ListFoundationModels",
"bedrock:ListInferenceProfiles"
],
"Resource": "*"
},
{
"Sid": "BedrockInvoke",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream",
"bedrock:GetInferenceProfile"
],
"Resource": [
"arn:aws:bedrock:*::foundation-model/*",
"arn:aws:bedrock:*:*:inference-profile/*"
]
},
{
"Sid": "MarketplaceSubscribe",
"Effect": "Allow",
"Action": [
"aws-marketplace:Subscribe",
"aws-marketplace:Unsubscribe",
"aws-marketplace:ViewSubscriptions"
],
"Resource": "*"
}
]
}
bedrock:ListFoundationModelsとbedrock:ListInferenceProfilesはAWSのサービスリファレンス上でリソースを取らないアクションなので、ARNでスコープすると許可されません(Resourceは*にします)。また推論プロファイルをResourceに書くときは、AWSのドキュメントが「そのプロファイルに紐づく各リージョンの基盤モデルも併せて指定しなければならない」と警告しています。プロファイルのARNだけに絞ると、ルーティング先リージョンの呼び出しで拒否されます。
モデルアクセスの扱いも2024年当時とは違います。現在は「適切なAWS Marketplace権限があれば、すべての基盤モデルへのアクセスが既定で有効」で、コンソールから1つずつリクエストする作業は不要です。代わりに前提が3つあります。上のポリシーに含めたMarketplaceの3アクション、Anthropicモデルの用途申告フォーム(アカウントで1回。オプトインリージョンでは再提出が必要)、そしてMarketplace購入に使える支払い方法です。初回呼び出し時はバックグラウンドでサブスクリプション処理が走るため、確定まで最大15分、権限付与の直後も最大2分はAccessDeniedExceptionが返りえます。モデル追加の直後だけ失敗するなら、この待ち時間を疑ってください。
東京リージョンでのモデル選択とクロスリージョン推論
プラグインのリージョン選択にはap-northeast-1(東京)が含まれますが、新しい世代のモデルほど直接呼び出しではなく推論プロファイル経由が前提になります。切り替えはプロバイダーの資格情報側ではなく、アプリのモデル設定パネルにあるCross-Region Inferenceパラメータで行います。Claude系の選択肢はdisabled/geographic/japan/globalの4つで、既定はglobalです。
踏みやすいのが、データ所在の要件をGeographicで満たそうとする誤りです。プラグインのhelpは「Geographicは自分の地理圏に限定される(東京はapac.に解決される)、Japanは日本国内(東京・大阪)でのみ処理する」と明記しています。東京からGeographicを選ぶと処理先にAPACの他国が入り、国内保管の要件は満たせません。
| 設定 | 処理リージョン | 料金 | SCPの前提 |
|---|---|---|---|
| japan | 東京・大阪のみ | 標準 | 日本の2リージョン許可 |
| geographic | apac.(東京の場合) | 標準 | プロファイルの全宛先を許可 |
| global | 商用リージョン全体 | 約10%安い | aws:RequestedRegionにunspecified許可 |
国内保管が要件ならjapan一択です。ただしjp.プロファイルを持つのはSonnet 4.6、Sonnet 4.5、Haiku 4.5、Opus 4.7、Opus 4.8、Nova 2 Liteの6モデルに限られます。Claude 5系は選択肢がglobalとgeographicの2つだけで、geoプロファイルもus./eu./au.(Fable 5はus.のみ)とAPAC向けが存在しません。東京からClaude 5を使うなら越境を許容してGlobalを選ぶことになり、国内保管が譲れない案件では世代を落としてSonnet 4.6などをjapanで使う判断になります。
Organizationsでリージョン制限のSCPを敷いている場合は、Globalを選ぶ前にaws:RequestedRegionでunspecifiedを許可しているか確認してください。AWSの比較表がGlobalの前提に挙げている条件で、見落とすとポリシー側で弾かれます。なお推論プロファイルIDを直接指定するinference_profile_id欄は、プロバイダー設定ではなくモデル追加側(カスタムモデル)にあります。
接続確認と切り分け(保存できた=つながったではない)
設定は保存できたのにチャットで応答が返らない、という詰まり方には実装上の理由があります。プロバイダー設定を保存するとき、プラグインのvalidate_credentialsは認証方式がIAM Roleなら何も検証せずその場でreturnします(アクセスキー方式は値の有無、APIキー方式はキーの有無を見るだけです)。検証用モデル名の欄があり既定値はamazon.nova-pro-v1:0ですが、IAMロール方式ではその呼び出しに到達しません。保存の成功は「入力形式が正しい」以上の意味を持たないと考えてください。例外はカスタムモデルとして推論プロファイルIDを登録する経路で、こちらはGetInferenceProfileを実際に呼び、状態がACTIVEでなければ保存に失敗します。
実際の疎通は、EC2上から次のコマンドで確認するのが最短です。プラグインが使うのと同じListFoundationModelsを、インスタンスプロファイルの権限で叩きます。
aws bedrock list-foundation-models --region ap-northeast-1 \
--query "modelSummaries[?contains(modelId, 'nova')].modelId" --output text
ここが通ってDify側だけ失敗するなら原因はホップ数かプラグインの設定、ここで既に失敗するならIAMロールの権限かモデルアクセスの前提条件です。順序を逆にすると、権限の問題をDifyの不具合と誤認します。
設定項目由来のつまずきも押さえます。カスタムエンドポイントURLとプロキシURLは排他で、両方に値を入れるとCannot use both bedrock_endpoint_url and bedrock_proxy_url at the same timeで弾かれます。エンドポイントURLが効くのはbedrock-runtimeへの接続だけで、モデル一覧の取得には適用されません。ドメインやIPを付け替えた直後の401はBedrockと無関係で、CONSOLE_API_URLなど7つのURL・CORS変数の更新漏れです。
疎通が取れたら、モデルを使う側の設計に進みます。ノードの組み方はDifyワークフローの作り方と使い方にまとめています。
よくある質問
DifyをEC2で動かすのに必要なスペックは?
公式の最小要件はCPU 2コア以上、RAM 4GiB以上、Docker 19.03以上、Docker Compose 2.24.0以上です。1.16.1のcomposeは16本のコンテナを同一ホストで起動するため、4GiBは検証用の下限と考えてください。見落としやすいのがComposeのバージョンで、公式も「Difyは2.24.0以降を必要とする。docker compose versionで確認せよ」と注記しています。ディストリビューション同梱のdocker-compose v1が残っている環境では、起動前にv2へ入れ替えます。
AWS MarketplaceのAMIと自前構築はどちらを選ぶべきですか?
最短で立ち上げたい、Powered by Difyの表示を変えたい場合はDify Premium(Marketplace AMI)が適します。管理者初期化パスワードはEC2のインスタンスIDです。設定は/dify/.envと/dify/envs/配下のテンプレートに分かれ、前者が優先されます。さらにdocker-compose.override.yamlのサービス直下に書いたenvironmentはenvファイルより優先されるため、値が効かないときはこの優先順位を先に確認してください。自分で.envとcomposeを管理し、更新時期を握りたい場合は自前構築です。
Bedrockの設定でアクセスキーを空欄にできません。IAMロールはどう指定しますか?
現行のプラグインではaws_access_key_idとaws_secret_access_keyがどちらも必須項目のため、空欄で保存する旧手順は使えません。認証方式のセレクトでIAM Roleを選ぶと、これらの入力欄は表示条件(show_on)から外れて消え、必須項目はAWSリージョンだけになります。資格情報はEC2にアタッチしたインスタンスプロファイルから、boto3の既定チェーン経由で取得されます。
IAMロールを選んだのにモデル呼び出しが失敗します。何を確認すべきですか?
まずインスタンスのメタデータオプションでホップ数が2以上かを確認します。既定の1ではコンテナからIMDSv2のトークンを取得できません。次にEC2上でaws bedrock list-foundation-modelsが通るかを見て、失敗するならIAMポリシーとAWS Marketplace権限、Anthropicモデルの用途申告フォームを疑います。なお、プラグインの導入自体が進まない場合は権限ではなく署名検証(FORCE_VERIFYING_SIGNATUREが既定でtrue)やパッケージ容量の問題なので、切り分けの入口が変わります。
東京リージョンからClaude 5系は使えますか?
使えますが推論プロファイル経由に限られ、選択肢はglobalとgeographicだけです。GeographicのgeoプロファイルはOpus 5とSonnet 5がus./eu./au.、Fable 5はus.のみでAPAC向けが無いため、東京からの実用解はGlobalになります。Globalは標準料金より約10%安い一方、処理リージョンが世界全体に広がります。国内保管が要件の案件では、Claude 5をあきらめてjp.プロファイルを持つSonnet 4.6やHaiku 4.5をjapanで使う判断になります。