マネージドサービスを活用したより安全かつ効率的なDify on AWSの構築

記事タイトルとURLをコピーする

はじめに

こんにちは、久保です。

先日、Dify on AWSのシンプル構成をHTTPSアクセス可能な構成にする方法についての記事を書きました。

blog.serverworks.co.jp

こちらの記事で紹介しているDify on AWSの構成は、AWSにおいてEC2 1台でDifyを動かすシンプルな構成となっています。

AWSではGitHubのaws-samplesに、より本番を想定したセキュリティ、可用性を考慮したデプロイを行うサンプルが提供されています。

github.com

本記事では、こちらのサンプルを参考に、DifyをAWSのECS上にデプロイする手順について3パターンの例を紹介します。

  • (A) デフォルトの設定で最短・シンプルにデプロイする方法 (CloudShell利用)
  • (B) カスタマイズ例1: コストの最小化設定
  • (C) カスタマイズ例2: SESによるメール送信有効化、独自ドメインの利用、IPアドレス制限

対象読者

  • Difyをまず検証したいが、EC2単体より本番寄り(例:VPC/ALB/RDS/ECS)の構成を手早く用意したい方
  • AWSサンプルのCDKの利用方法が知りたい方

構成について

出典: https://github.com/aws-samples/dify-self-hosted-on-aws

すべてフルマネージドサービスで構成されるようになっており、以下のようなサービスが利用されています。

構成要素 サービス 備考
CDN Amazon CloudFront SSL/TLS終端、WAF連携
ロードバランサー Application Load Balancer Fargateタスクへのルーティング
コンテナオーケストレーション Amazon ECS on Fargate Webアプリ用とAPI用の2種類のタスクで構成
データベース Amazon Aurora Serverless v2 (PostgreSQL) サーバーレスなデータベース
キャッシュ Amazon ElastiCache for Valkey Redis互換のValkeyノード
WAF AWS WAF IP制限の設定がある場合に構成しCloudFrontにアタッチ
証明書 AWS Certificate Manager CloudFront or ALBにアタッチするSSL/TLS証明書

設定方法

AWS CDK用のbinファイル内で設定が可能です。

https://github.com/aws-samples/dify-self-hosted-on-aws/blob/main/bin/cdk.ts

デフォルトでは以下のような内容になっており、そのまま利用可能になっています。

...略...
export const props: EnvironmentProps = {
  awsRegion: 'us-west-2',
  awsAccount: process.env.CDK_DEFAULT_ACCOUNT!,
  // Set Dify version
  difyImageTag: '1.11.1',
  // Set plugin-daemon version to stable release
  difyPluginDaemonImageTag: '0.5.1-local',

  // uncomment the below options for less expensive configuration:
  // isRedisMultiAz: false,
  // useNatInstance: true,
  // enableAuroraScalesToZero: true,
  // useFargateSpot: true,

  // Please see EnvironmentProps in lib/environment-props.ts for all the available properties
};
...略...

コメントに記載のあるとおり、すべての設定可能項目は lib/environment-props.ts を参照することで確認可能です。

デプロイ方法

AWS CDKで簡単にデプロイできるようになっており、さらにCloudShellでデプロイする場合は、CodeBuildを利用してAWS CDKによるデプロイもできるようになっています。

本記事では、より簡単な、CloudShellを利用したデプロイ方法を紹介します。

(A) デフォルトの設定で最短・シンプルにデプロイする方法 (CloudShell利用)

構成

デフォルト設定でデプロイを行うと以下のような構成が作成されます。

手順

AWSマネジメントコンソールで任意のリージョンを選択した状態で、CloudShellのアイコンをクリックして起動します。

git cloneコマンドでリポジトリをクローンします。

git clone https://github.com/aws-samples/dify-self-hosted-on-aws.git

クローンしたディレクトリに移動します。

cd dify-self-hosted-on-aws

もしデプロイするリージョンを変更したい場合は、bin/cdk.ts内のawsRegionの値を変更します。(デフォルトではus-west-2になっています。)

vim bin/cdk.ts
 ...略...
  8 export const props: EnvironmentProps = {
  9   awsRegion: 'us-west-2',
 10   awsAccount: process.env.CDK_DEFAULT_ACCOUNT!,
 11   // Set Dify version
 12   difyImageTag: '1.11.1',
 13   // Set plugin-daemon version to stable release
 14   difyPluginDaemonImageTag: '0.5.1-local',
 15 
 16   // uncomment the below options for less expensive configuration:
 17   // isRedisMultiAz: false,
 18   // useNatInstance: true,
 19   // enableAuroraScalesToZero: true,
 20   // useFargateSpot: true,
 21 
 22   // Please see EnvironmentProps in lib/environment-props.ts for all the available properties
 23 };
 ...略...

デプロイを行います。

./simple-deploy.sh

CloudShellで直接npx cdk deploy --allを実行することも可能ですが、CloudShellでは利用可能なストレージ容量に限りがあるため、simple-deploy.shスクリプトを利用することが推奨されます。 こちらのスクリプトではCodeBuildを利用してデプロイを行うため、CloudShellのストレージ容量を気にせずにデプロイが可能です。

DifySimpleDeployStackというCloudFormationスタックが作成され、当該スタックによりCodeBuild環境が構築されます。
しばらくすると以下のようにデプロイしてよいかの確認状態となりますので、yesと入力してEnterキーを押下します。

Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - DifySimpleDeployStack
Found S3 bucket: difysimpledeploystack-sourcebucketddd2130a-lhxdtof1yvf8, CodeBuild project: ProjectC78D97AD-i5e0E95q9AC6

Preparation completed. Now proceed to deploy Dify on AWS.
yes
Are you sure you want to deploy? Please check the configuration parameters in bin/cdk.ts.
If you are ready, type 'yes': yes

構築されたCodeBuild内でAWS CDKによるDify環境のデプロイが実行されます。
※20分ほどかかります(RedisとAuroraの起動に特に時間がかかります)※

もし途中でCloudShellのセッションが途切れてしまってもデプロイはCodeBuildにて行われていますので、CodeBuildのコンソールから進捗を確認することが可能です。

デプロイが完了するとログにアクセス用のURLが出力されます。DifyOnAwsStack.DifyUrlの箇所です。

Outputs:
DifyOnAwsStack.ConsoleConnectToTaskCommand = aws ecs execute-command --region us-west-2 --cluster DifyOnAwsStack-Clusterxxxxxxxx-xxxxxxxxxx --container Main --interactive --command "bash" --task $(aws ecs list-tasks --region us-west-2 --cluster DifyOnAwsStack-Clusterxxxxxxxx-xxxxxxxxxx --service-name DifyOnAwsStack-ApiServiceFargateServiceE4EA9E4E-lKTY5hInWJfU --desired-status RUNNING --query 'taskArns[0]' --output text)
DifyOnAwsStack.DifyUrl = https://1234abcd567890.cloudfront.net

DifyOnAwsStack.DifyUrlにブラウザでアクセスし、Difyの初期セットアップ画面が表示されればデプロイ成功です。

(B) カスタマイズ例1: コストの最小化設定

設定を変更することで、よりコストを抑えた構成でデプロイすることが可能です。

  • ElastiCache for ValkeyのMulti-AZ構成を無効化
    • デフォルトではMulti-AZ構成が有効化されていますが、無効化することでコストを削減可能です。
  • NATインスタンスの利用設定
    • デフォルトではマルチAZでNAT Gatewayが利用されますが、シングル構成のNATインスタンスを利用することでコストを削減可能です。
  • Aurora Serverless v2の最小スケール数を0に設定
    • デフォルトではAurora Serverless v2の最小スケール数が0.5に設定されていますが、0に設定することで利用していない時間帯のコストを削減可能です。
  • Fargate Spotの利用設定
    • AWSの余剰リソースを利用するFargate Spotを利用することで、Fargateのコストを削減可能です。
    • 突然停止する可能性があるため、ご利用には注意が必要です。

構成

NAT Gatewayがシングル構成のNAT Instanceとなり、構成図では表していませんがサーバーレスの最小値やFargate Spotの利用等が有効になります。

手順

デプロイ手順は (A) と同様にCloudShellを利用して行います。

設定ファイルにコスト削減のための設定を追加します。

vim bin/cdk.ts

uncomment the below optionsと記載のある箇所のコメントアウトを外して有効化します。

 ...略...
  8 export const props: EnvironmentProps = {
  9   awsRegion: 'us-west-2',
 10   awsAccount: process.env.CDK_DEFAULT_ACCOUNT!,
 11   // Set Dify version
 12   difyImageTag: '1.11.1',
 13   // Set plugin-daemon version to stable release
 14   difyPluginDaemonImageTag: '0.5.1-local',
 15 
 16   // uncomment the below options for less expensive configuration:
 17   isRedisMultiAz: false,
 18   useNatInstance: true,
 19   enableAuroraScalesToZero: true,
 20   useFargateSpot: true,
 21 
 22   // Please see EnvironmentProps in lib/environment-props.ts for all the available properties
 23 };
 ...略...

変更した設定ファイルでデプロイを行います。

./simple-deploy.sh

これで、コスト削減設定でDify環境がデプロイされます。

(C) カスタマイズ例2: SESによるメール送信有効化、独自ドメインの利用、IPアドレス制限

フルセットの設定例です。

独自ドメインで、Difyにアクセスできるようにします。
また、SESを利用したDifyからのメール送信も有効化することが可能です。
AWS WAFによるアクセス元のIPアドレス制限も行います。

※独自ドメイン利用とメール送信を有効化するには、あらかじめRoute53で独自ドメインのパブリックホストゾーンを作成しておく必要があります。(ドメインを所有している必要があります)

Difyでメール送信ができるようにすることで、以下のメリットがあります。

  • ユーザ自身がパスワードリセットを行えるようになる
  • チームメンバー招待時に招待メールが送信されるようになる
    • デフォルトでは招待メールは送信できないため、手動でメールやチャットで招待URLを共有する必要があります

構成

独自ドメイン利用のため、AWS Certificate Manager(ACM)によるSSL証明書の発行が行われます。
CloudFront用のACM証明書や、AWS WAFのWebACLは仕様上米国東部(バージニア北部)リージョン(us-east-1)で作成する必要があるため、これらのリソースはus-east-1リージョンに作成されるようになっています。

手順

デプロイ手順は (A) と同様にCloudShellを利用して行います。

設定ファイルに各種設定を追加します。
※ (B)のコスト最小化設定は行わず適切な可用性を確保した構成とします

vim bin/cdk.ts

domainName, setupEmail, allowedIPv4Cidrsの各プロパティを追加・設定します。

  • domainName: 利用する独自ドメイン名を指定します (例: example.com)
  • setupEmail: trueに設定することでSESによるメール送信が有効化されます
  • allowedIPv4Cidrs: アクセスを許可するIPアドレスまたはCIDRブロックの配列を指定します。空配列の場合はIP制限は行われません。
 ...略...
  8 export const props: EnvironmentProps = {
  9   awsRegion: 'us-west-2',
 10   awsAccount: process.env.CDK_DEFAULT_ACCOUNT!,
 11   // Set Dify version
 12   difyImageTag: '1.11.1',
 13   // Set plugin-daemon version to stable release
 14   difyPluginDaemonImageTag: '0.5.1-local',
 15 
 16   // uncomment the below options for less expensive configuration:
 17   // isRedisMultiAz: false,
 18   // useNatInstance: true,
 19   // enableAuroraScalesToZero: true,
 20   // useFargateSpot: true,
 21 
 22   setupEmail: true,  
 23   domainName: 'sample.com', // <-- ご自身の独自ドメインに置き換えてください
 24   allowedIPv4Cidrs: ['1.2.3.4/32'], // <-- ご自身のIPアドレスに置き換えてください
 25
 26   // Please see EnvironmentProps in lib/environment-props.ts for all the available properties
 27 };
 ...略...

変更した設定ファイルででデプロイを行います。

./simple-deploy.sh

主に以下が行われます。

  • 独自ドメイン用のACM証明書の発行
  • 独自ドメイン用のRoute53レコードの作成 (CloudFrontディストリビューション用): dify.<domainName> になります。
  • SESのセットアップ (ドメイン認証)
  • AWS WAFのセットアップ (IPアドレス制限)

注意事項として、SESはサンドボックスの状態でセットアップされます。
本番利用する場合は、SESのサンドボックス解除申請を行い、承認される必要があります。
サンドボックスの状態の場合、SESで個別に認証したメールアドレスやドメインにのみメール送信が可能です。

デプロイ完了後、Difyにdify.<domainName>でアクセスできれば成功です。
指定したIPアドレスからのみアクセス可能になっていることもご確認ください。

Difyからのメール通知の確認

ECS Taskの環境変数設定を通してDifyにSESの設定が自動的に反映されます。

招待したいメンバーのメールアドレスを指定して「招待を送る」をクリックします。
デフォルトのデプロイではメールは送信されませんが、今回は送信されるはずです。

以下の画面になります。
デフォルトの設定ではメール送信されないため、"招待リンク"をコピーして別途連絡する必要がありました。

今回はSESが有効化されているため、指定したメールアドレスに招待メールが送信されました。
リンクをクリックすることで招待されたユーザが自分でサインアップ可能となります。

招待リンクにアクセスすると以下のようにパスワードの設定が求められ、入力するとサインインが可能となります。

補足

dify-self-hosted-on-aws のサンプルでは他にも、VPCの閉域環境でのデプロイや、CloudFrontを利用しない構成などもサポートされています。
また、Amazon Bedrock Knowledge BasesをDifyから利用するためのAPIサーバコンテナも利用可能など紹介できていないその他機能もあります。

詳しくはGitHubリポジトリのREADMEをご参照ください。

環境の削除方法

AWS CDKでデプロイした環境は、AWS CDKのdestroyコマンドで削除可能です。
(AWS WAF等us-east-1のリソースもデプロイした場合--allオプションを付与する必要があります)

cd dify-self-hosted-on-aws 
npx cdk destroy --all

CloudShellでsimple-deploy.shスクリプトを利用してデプロイした場合は、CodeBuild環境の削除も忘れず行ってください。

aws cloudformation delete-stack --stack-name DifySimpleDeployStack  

おわりに

マネージドサービスを活用したより本番利用に望ましいDify on AWSのデプロイ方法についてAWSのサンプルを元にご紹介しました。

Difyのコミュニティ版は無料で利用可能な一方で、セルフホストで運用するためにはどうしてもある程度複雑なインフラ構成が必要となります。
可能な限りマネージドなサービスを活用することで、運用負荷を抑えつつ、セキュリティも確保した構成が可能となります。

Difyの安全な本番利用に向けて、参考になりましたら幸いです。

久保 賢二(執筆記事の一覧)

猫とAWSが好きです。