
Dagsterとdbt CoreをECS on Fargateで構築する
こんにちは、データ事業本部のキタガワです。
今回はDagsterとdbt Coreの構成をECS on Fargateの構成で動かすサンプルを作っていきたいと思います。
前回Dockerコンテナ上で構築した記事の続きとして、ECS on Fargateの構成で動かすサンプルを作っていきます。
続きとは言っても、この記事を読むだけでECS on FargateでDagsterとdbtを動かすことができるように書いていくつもりです。
(参考)
この記事でもdbtのサンプルプロジェクトとして jaffle_shop
を使います。
また前回同様に実装は公式リポジトリ https://github.com/dagster-io/dagster を参考に進めていきます。
https://github.com/dagster-io/dagster/tree/master/examples/deploy_ecs にECSを使った具体的な例があるんですが、この手順の中で使用されている docker context create ecs
は 2023年11月に廃止 されています。
したがって現在はECS周りのリソースも併せて作成する必要がありました。
そこについてもこの記事で扱っていきます。
今回作りたい構成はこんな感じです。
ポイントとしては
- コンテナの構成は前回と同じ
- Dagster Webserver・Dagster Daemon・Code Server
- それぞれのビルド済みイメージはECRに登録する
- 実行履歴やログの格納にはRDS(PostgreSQL)を使用
- WebserverにはALB経由でインターネットからアクセス
- dbtがビルドするモデルはSnowflakeに保存
- 各種認証情報はSecrets Managerに保存
です!
Snowflakeは事前に設定済みのものを使用します。
もしアカウントのセットアップが必要な場合は以下ページからトライアルアカウントが作成できます。
またdbtとSnowflakeの接続にはキーペア認証を使用します。
キーペア認証については以下ページを参考にしてください。
また前提としてAWS CLIとTerraform、Dockerは使用可能な状態にしておいてください。
プロジェクトの作成
まずはプロジェクトを作成します。
dbtのプロジェクトをDagsterのアセットとして取り込むところまでは前回行ったことと重複するので、手順だけ簡単に記載します。
uv
を使用しているところは適宜お使いのツールに読み替えてください。
# プロジェクトの作成
uv init dagster-dbt-ecs-sample --bare --python 3.12
cd dagster-dbt-ecs-sample
# gitでバージョン管理したいので初期化
git init
git add .
git commit -m "Initial commit"
# dbtのプロジェクトをクローン(ここではgitのサブツリーとして取り込む)
git subtree add --prefix=jaffle_shop https://github.com/dbt-labs/jaffle_shop_duckdb.git duckdb --squash
# 仮想環境にライブラリを追加
uv add dagster-dbt dagster-webserver
# Dagsterのプロジェクトを作成
uv run dagster-dbt project scaffold --project-name dagster_project --dbt-project-dir jaffle_shop
dagster dev
でローカルのDagster Webserverが起動できたら準備OKです。
次に必要なファイルを作成します。
dbtの設定
ここでは jaffle_shop/profiles.yml
という設定ファイルを編集します。
gitからクローンしてきた段階ではDuckDBを使用する設定になっているので、これをSnowflake用のものに変更します。
jaffle_shop:
target: dev
outputs:
dev:
type: snowflake
account: "{{ env_var('DBT_ENV_SECRET_SNOWFLAKE_ACCOUNT', 'dummy') }}"
user: "{{ env_var('DBT_ENV_SECRET_SNOWFLAKE_USER', 'dummy') }}"
private_key: "{{ env_var('DBT_ENV_SECRET_SNOWFLAKE_PRIVATE_KEY', 'dummy') }}"
private_key_passphrase: "{{ env_var('DBT_ENV_SECRET_SNOWFLAKE_PRIVATE_KEY_PASSPHRASE', 'dummy') }}"
role: SYSADMIN
warehouse: X_SMALL_WH
database: KITAGAWA_TEST_DB
schema: DAGSTER_DBT_SAMPLE
threads: 1
client_session_keep_alive: False
query_tag: cm_kitagawa_dagster
ここでは DBT_ENV_SECRET_SNOWFLAKE_ACCOUNT
などの環境変数を使用しています。
これらは後ほどSecrets Managerに保存します。
role
や database
は事前に作成済みのものを使用します。
こういった値もSecrets ManagerやSSMのパラメータストアなどで管理してもいいですが、ここではハードコードしています。
また env_var()
にデフォルト値を設定することで、環境変数を設定せずとも dbt parse
を実行できるようにしています。
これは次の項目で dagster-dbt project prepare-and-package
を実行する際に必要になります。
Dagsterの設定
dbtのパッケージの作成
dagster-dbt project prepare-and-package
コマンドを実行して、dbtのパッケージを作成します。
--file
で project.py
のパスを指定してください。
uv run dagster-dbt project prepare-and-package --file dagster_project/dagster_project/project.py
これで dagster_project/dbt-project
にパッケージが作成されます。
このパッケージはdbtプロジェクトを dbt deps
dbt parse
で最新化した上で丸っとコピーしてきたものです。
今回はこれをコンテナにコピーして使用します。
次に dagster_project/dagster_project/project.py
を編集します。
環境変数 DAGSTER_ENV
を使用して、AWS環境ではパッケージ化されたプロジェクトを使用、開発環境では元のプロジェクトを使用するようにします。
こうすることでDagsterとdbt双方の開発を分離して行えるようになることを期待してこのような実装にしています。
import os
from pathlib import Path
from dagster_dbt import DbtProject
# AWS環境ではパッケージ化されたプロジェクトを使用、開発環境では元のプロジェクトを使用
is_aws = os.getenv("DAGSTER_ENV") == "AWS"
print(f"is_aws: {is_aws}")
if is_aws:
# AWS環境: packaged_project_dirをproject_dirとして使用
project_dir = Path(__file__).joinpath("..", "..", "dbt-project").resolve()
packaged_project_dir = project_dir
else:
# ローカル環境: ローカルではjaffle_shopを使用
project_dir = Path(__file__).joinpath("..", "..", "..", "jaffle_shop").resolve()
packaged_project_dir = Path(__file__).joinpath("..", "..", "dbt-project").resolve()
jaffle_shop_project = DbtProject(
project_dir=project_dir,
packaged_project_dir=packaged_project_dir,
)
jaffle_shop_project.prepare_if_dev()
必要なファイルの作成
以下のファイルを作成していきます。
dagster_project/docker-compose.yml
dagster_project/Dockerfile_dagster
dagster_project/Dockerfile_user_code
dagster_project/dagster.yaml
dagster_project/workspace.yaml
docker-compose.yml
各コンテナをビルドするのに使います。
platform
はECS上で動かすため、linux/amd64
を指定します。
今回はローカルで docker compose up
することはないので、イメージのビルドに必要な最低限の設定のみ記述しています。
services:
dagster_ecs_core:
platform: linux/amd64
build:
context: .
dockerfile: ./Dockerfile_dagster
dagster_ecs_user_code:
platform: linux/amd64
build:
context: .
dockerfile: ./Dockerfile_user_code
Dockerfile_dagster
Dagster WebserverとDagster Daemonを実行するためのイメージです。
必要なライブラリのインストールと、Dagsterの設定ファイルをコピーしています。
# Dagster libraries to run both dagster-webserver and the dagster-daemon. Does not
# need to have access to any pipeline code.
FROM python:3.12-slim
RUN pip install \
dagster \
dagster-graphql \
dagster-webserver \
dagster-postgres \
dagster-aws
# Set $DAGSTER_HOME and copy dagster instance and workspace YAML there
ENV DAGSTER_HOME=/opt/dagster/dagster_home/
RUN mkdir -p $DAGSTER_HOME
COPY dagster.yaml workspace.yaml $DAGSTER_HOME
WORKDIR $DAGSTER_HOME
Dockerfile_user_code
ユーザーコードを実行するためのイメージです。
Dagsterとdbt両方のプロジェクトをコピーする必要があります。
前回の記事では dagster api grpc
を使用していましたが、今回は dagster code-server start
を使用します。
こちらを使用することでDagster全体のシステムを再起動することなく、ユーザーコードの変更を反映できます。
FROM python:3.12-slim
# Install system dependencies
RUN apt-get update && apt-get upgrade -yqq
RUN apt-get install git -y
# Checkout and install dagster libraries needed to run the gRPC server
# exposing your repository to dagster-webserver and dagster-daemon, and to load the DagsterInstance
RUN pip install \
dagster \
dagster-postgres \
dagster-docker \
dagster-dbt \
dbt-snowflake
# Add repository code
WORKDIR /opt/dagster/app
COPY dagster_project/ ./dagster_project/
COPY dbt-project/ ./dbt-project/
# Set environment variable
ENV DAGSTER_ENV=AWS
# Run dagster gRPC server on port 4000
EXPOSE 4000
CMD ["dagster", "code-server", "start", "-h", "0.0.0.0", "-p", "4000", "--module-name", "dagster_project.definitions"]
dagster.yaml
Dagsterの設定ファイルです。
いろいろな設定があるので、詳しくは公式ドキュメントを参照してください。
ここでは examples/deploy_ecs/dagster.yaml を元に、少し修正したものを使います。
scheduler:
module: dagster.core.scheduler
class: DagsterDaemonScheduler
run_coordinator:
module: dagster.core.run_coordinator
class: QueuedRunCoordinator
run_launcher:
module: dagster_aws.ecs
class: EcsRunLauncher
run_storage:
module: dagster_postgres.run_storage
class: PostgresRunStorage
config:
postgres_db:
hostname:
env: DAGSTER_POSTGRES_HOST
username:
env: DAGSTER_POSTGRES_USER
password:
env: DAGSTER_POSTGRES_PASSWORD
db_name:
env: DAGSTER_POSTGRES_DB
port: 5432
schedule_storage:
module: dagster_postgres.schedule_storage
class: PostgresScheduleStorage
config:
postgres_db:
hostname:
env: DAGSTER_POSTGRES_HOST
username:
env: DAGSTER_POSTGRES_USER
password:
env: DAGSTER_POSTGRES_PASSWORD
db_name:
env: DAGSTER_POSTGRES_DB
port: 5432
event_log_storage:
module: dagster_postgres.event_log
class: PostgresEventLogStorage
config:
postgres_db:
hostname:
env: DAGSTER_POSTGRES_HOST
username:
env: DAGSTER_POSTGRES_USER
password:
env: DAGSTER_POSTGRES_PASSWORD
db_name:
env: DAGSTER_POSTGRES_DB
port: 5432
telemetry:
enabled: false
workspace.yaml
コードロケーション用の設定ファイルです。
Dagsterにコードサーバーの読み込み方法を教えてあげるためのファイルです。
ECSでのコンテナ間通信には サービス検出 を使用します。
hostにはサービス名を指定します。
load_from:
- grpc_server:
host: user-code.cm-kitagawa-dagster-ecs.internal
port: 4000
location_name: "dagster-ecs-user-code"
hostは後ほど作成するECSサービスの「サービス検出」から確認することもできます。
もしWebserverやDaemonがコードサーバーを認識できていなかったらここを確認して設定し直すことをお勧めします。
AWSリソースの作成
あとはAWSリソースの作成が必要です。
リソース作成にはTerraformを使用します。
ECRなどの事前作成が必要なリソースを先に作成し、必要な設定を行った後に残りのリソースを作成していきます。
Terraformは事前に作成が必要なリソース(foundation)とアプリケーション用のリソース(application)に分けてテンプレートを作っています。
それぞれの構成は以下の通りです。
-
foundation/ (基盤リソース)
- VPC・ネットワーク: VPC、サブネット、IGW、NAT Gateway、ルートテーブル
- セキュリティグループ: 全てのSG定義
- RDS: PostgreSQLデータベース
- ECR: Dockerレジストリ
- IAM: 全てのロール・ポリシー
- Secrets Manager: DB認証情報、Snowflake認証情報
-
application/ (アプリケーションリソース)
- ALB: ロードバランサー、ターゲットグループ、リスナー
- ECS: クラスター、タスク定義、サービス
- CloudWatch: ログ群
- Service Discovery: Cloud Map設定
代表的なリソースを抜粋して説明を行いますが、ソースコードについてはGitHubを参照してください。
またリソースの設定はあくまで検証用のものであり、本番運用にはセキュリティや可用性を考慮し、適切に設定してください。
terraform/foundation/ - 基盤リソース
まず基盤となるリソースから見ていきます。
ネットワーク構成
# VPC
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_support = true
enable_dns_hostnames = true
}
# Public Subnets
resource "aws_subnet" "public" {
count = length(var.public_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidrs[count.index]
map_public_ip_on_launch = true
availability_zone = data.aws_availability_zones.available.names[count.index]
}
# Private Subnets
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = data.aws_availability_zones.available.names[count.index]
}
VPCは典型的な2AZ構成で、パブリックサブネットとプライベートサブネットを2つずつ作成しています。
パブリックサブネットにはALBを配置し、プライベートサブネットにはECSタスクとRDSを配置します。
セキュリティグループ
# ALB用セキュリティグループ
resource "aws_security_group" "alb" {
name = "${var.prefix}-dagster-ecs-alb-sg"
description = "Allow HTTP/HTTPS traffic to ALB"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
prefix_list_ids = var.prefix_list_ids
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Webserver用セキュリティグループ
resource "aws_security_group" "web" {
name = "${var.prefix}-dagster-ecs-web-sg"
description = "Allow HTTP/HTTPS traffic from ALB"
vpc_id = aws_vpc.main.id
ingress {
from_port = 3000
to_port = 3000
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
セキュリティグループは役割別に分けて作成します。
ALBは特定のIPアドレスからのアクセスを許可し、WebserverはALBからのアクセスのみを許可するように設定しています。
prefix_list_idsは必要な場合 terraform/foundation/variables.tfvars
で指定してください。
RDS
resource "aws_db_instance" "main" {
identifier = "${var.prefix}-dagster-ecs-db"
db_name = var.dagster_postgres_db
engine = "postgres"
engine_version = "17.2"
instance_class = "db.m5.large"
allocated_storage = 20
username = var.dagster_postgres_user
password = var.dagster_postgres_password
port = 5432
db_subnet_group_name = aws_db_subnet_group.main.name
vpc_security_group_ids = [aws_security_group.rds.id]
skip_final_snapshot = true
publicly_accessible = false
multi_az = false
storage_encrypted = true
deletion_protection = false
tags = {
"cm-daily-stop" = "true"
}
}
RDSはPostgreSQL 17.2を使用しています。
検証用なので skip_final_snapshot = true
deletion_protection = false
としていますが、本番運用では適切に設定してください。
またこちらの検証環境用に cm-daily-stop
タグを付けることで、スケジュールによる自動停止の対象にしています。
IAMロール
ECSタスクには2つのロールが必要です。
# タスクロール(実行時に使用)
resource "aws_iam_role" "task" {
name_prefix = "${var.prefix}-dagster-ecs-task-"
description = "Role for Dagster ECS tasks"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {Service = "ecs-tasks.amazonaws.com"},
Action = "sts:AssumeRole"
}
]
})
}
# 実行ロール(コンテナ起動時に使用)
resource "aws_iam_role" "execution" {
name_prefix = "${var.prefix}-dagster-ecs-execution-"
description = "Role for ECS task execution"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "ecs-tasks.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
}
タスクロールはDagsterのEcsRunLauncherがジョブ実行時に新しいタスクを起動するために必要な権限を持ちます。
実行ロールはECRからのイメージ取得やSecrets Managerからの値取得に使用されます。
Secrets Manager
resource "aws_secretsmanager_secret" "dbt_env_secret_snowflake" {
name = "${var.prefix}-dbt_env_secret_snowflake"
}
resource "aws_secretsmanager_secret_version" "dbt_env_secret_snowflake" {
secret_id = aws_secretsmanager_secret.dbt_env_secret_snowflake.id
secret_string = jsonencode({
account = var.dbt_env_secret_snowflake_account
user = var.dbt_env_secret_snowflake_user
private_key = var.dbt_env_secret_snowflake_private_key
private_key_passphrase = var.dbt_env_secret_snowflake_private_key_passphrase
})
}
Snowflakeの認証情報とPostgreSQLの認証情報をそれぞれSecrets Managerで管理します。
これらの値はECSタスクの環境変数として自動的に注入されます。
terraform/application/ - アプリケーションリソース
続いてアプリケーション側のリソースです。
データソース連携
data "terraform_remote_state" "foundation" {
backend = "local"
config = {
path = "../foundation/terraform.tfstate"
}
}
applicationディレクトリではfoundationで作成したリソースの情報を terraform_remote_state
で参照しています。
ALB
resource "aws_lb" "main" {
name = "${var.prefix}-dagster-ecs-alb"
internal = false
load_balancer_type = "application"
security_groups = [data.terraform_remote_state.foundation.outputs.alb_security_group_id]
subnets = data.terraform_remote_state.foundation.outputs.public_subnet_ids
}
resource "aws_lb_target_group" "web" {
name = "${var.prefix}-dagster-ecs-alb-tg"
port = 3000
protocol = "HTTP"
vpc_id = data.terraform_remote_state.foundation.outputs.vpc_id
target_type = "ip"
health_check {
path = "/"
protocol = "HTTP"
matcher = "200-399"
interval = 30
timeout = 5
healthy_threshold = 2
unhealthy_threshold = 2
}
}
ALBはDagster Webserverへの外部アクセスを提供します。
ターゲットタイプは ip
を指定し、Fargateタスクと連携します。
ECSタスク定義
Dagster WebserverとDaemonのタスク定義では、環境変数とシークレットの設定が重要です。
container_definitions = jsonencode([
{
name = "${var.prefix}-dagster-ecs-web"
image = "${data.terraform_remote_state.foundation.outputs.dagster_ecr_repository_url}:latest"
entryPoint = ["dagster-webserver", "-h", "0.0.0.0", "-p", "3000"]
environment = [
{
name = "DAGSTER_POSTGRES_HOST"
value = data.terraform_remote_state.foundation.outputs.rds_endpoint
}
]
secrets = [
{
name = "DAGSTER_POSTGRES_DB"
valueFrom = "${data.terraform_remote_state.foundation.outputs.dagster_postgres_secret_arn}:db_name::"
},
{
name = "DAGSTER_POSTGRES_USER"
valueFrom = "${data.terraform_remote_state.foundation.outputs.dagster_postgres_secret_arn}:username::"
},
{
name = "DAGSTER_POSTGRES_PASSWORD"
valueFrom = "${data.terraform_remote_state.foundation.outputs.dagster_postgres_secret_arn}:password::"
}
]
}
])
PostgreSQLの接続情報は、ホスト名は環境変数で、ユーザー名・パスワード・データベース名はSecrets Managerから自動取得するように設定しています。
Service Discovery
resource "aws_service_discovery_private_dns_namespace" "main" {
name = "${var.prefix}-dagster-ecs.internal"
description = "Dagster Cloud Map Namespace"
vpc = data.terraform_remote_state.foundation.outputs.vpc_id
}
resource "aws_service_discovery_service" "user_code" {
name = "user-code"
dns_config {
namespace_id = aws_service_discovery_private_dns_namespace.main.id
dns_records {
type = "A"
ttl = 10
}
routing_policy = "MULTIVALUE"
}
}
ECSサービス間の通信にはAWS Cloud Mapによるサービスディスカバリを使用します。
これにより、WebserverとDaemonがUser Codeサーバーに user-code.{prefix}-dagster-ecs.internal:4000
でアクセスできるようになります。
実行手順
Terraformの実行は必ず foundation → application の順で行います。
1. AWS認証設定
export AWS_PROFILE=your-profile-name
2. 変数ファイルの準備
# foundation用変数ファイル作成
cp terraform/foundation/terraform.tfvars.example terraform/foundation/terraform.tfvars
# 必要な値を編集
# application用変数ファイル作成
cp terraform/application/terraform.tfvars.example terraform/application/terraform.tfvars
# 必要な値を編集
foundation/で必要な変数:
prefix
: リソース名プレフィックスdagster_postgres_db
: PostgreSQLデータベース名dagster_postgres_user
: PostgreSQLユーザー名dagster_postgres_password
: PostgreSQLパスワードdbt_env_secret_snowflake_account
: Snowflakeアカウントdbt_env_secret_snowflake_user
: Snowflakeサービスユーザーdbt_env_secret_snowflake_private_key
: 秘密鍵dbt_env_secret_snowflake_private_key_passphrase
: 秘密鍵パスフレーズ
application/で必要な変数:
prefix
: リソース名プレフィックス
3. 基盤リソースの作成
Terraformのfoundationディレクトリに移動して以下コマンドを実行してください。
cd terraform/foundation
terraform init
terraform plan
terraform apply
4. コンテナイメージのビルド・プッシュ
Dagsterの設定の項で作成したDockerfileをビルドしてECRにプッシュします。
基盤リソースの作成を行うとoutputからECRのリポジトリURLが取得できるので、それを参考にして以下の手順を修正してください。
dagster_ecr_repository_url
と user_code_ecr_repository_url
が該当します。
Dockerfileのあるdagster_projectディレクトリに移動して以下コマンドを実行してください。
cd ../../dagster_project
# コンテナイメージのビルド
docker compose build
# ECRのURLを環境変数に設定
# <AWS_ACCOUNT_ID> と <AWS_REGION> は適宜変更してください。
export ECR_REGISTRY="<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com"
# ECRにログイン
aws ecr get-login-password | docker login --username AWS --password-stdin ${ECR_REGISTRY}
# Dagsterのコンテナイメージのタグ付けとプッシュ
docker tag dagster_project-dagster_ecs_core:latest ${ECR_REGISTRY}/cm-kitagawa-dagster_ecs_core:latest
docker push ${ECR_REGISTRY}/cm-kitagawa-dagster_ecs_core:latest
# ユーザーコードのコンテナイメージのタグ付けとプッシュ
docker tag dagster_project-dagster_ecs_user_code:latest ${ECR_REGISTRY}/cm-kitagawa-dagster_ecs_user_code:latest
docker push ${ECR_REGISTRY}/cm-kitagawa-dagster_ecs_user_code:latest
5. アプリケーションリソースの作成
Terraformのapplicationディレクトリに移動して以下コマンドを実行してください。
cd ../terraform/application
terraform init
terraform plan
terraform apply
DagsterのWebserverにアクセス
上記までの操作が完了したらECSクラスターにサービスが3つ起動しているはずです。
添付の画像のように3つとも完了表示になっていると成功です。
それではDagsterのUIを開いてみましょう。
Terraformのapplicationディレクトリで以下コマンドを実行してください。
terraform output -raw dagster_url
これでDagsterのURLが取得できるので、それをブラウザで開くとDagsterのWebserverにアクセスできます。
次のような画面が表示されます。
これはDagsterのアセットの一覧が表示されている画面です。
dbtで定義したモデルが表示されていることがわかります。
試しに右上①の Materialize All
ボタンを押して、そのあと表示される②の View
ボタンを押してみましょう。
この画面では実行したジョブの詳細を確認することができます。
すべてのアセットのマテリアライズが完了すると画像のように緑色になり、成功したことがわかります。
また先ほどのアセットの画面に戻ってみましょう。
左上の Assets
タブを押し、右側の View lineage
を押すとアセットのリネージ画面に戻れます。
この画面でもすべてのアセットが正常にマテリアライズされていることがわかりますね。
またdbtで定義したテストも Asset checks
という形で表示され、それらが通っていることも確認できます。
Snowflake側も見てみましょう。
指定したDBをみるとスキーマとその下にテーブルやビューが作成されていることがわかります。
またテーブルの更新履歴からも直前の実行によりテーブルにデータが書き込まれていることがわかります。
まとめ
今回はDagsterをECS on Fargateの構成で動かす方法を紹介しました。
dbtプロジェクトをDagsterのアセットとして管理し、ECSで実際に動かすことで、スケーラブルなデータパイプラインが構築できました。
前回のDocker構築記事と合わせて読んでもらえれば、AWSにデプロイするまでの一連の流れが掴めるはずです。
ぜひ試してみてください。
それではまた次の記事でお会いしましょう。