業界・業務から探す
導入目的・課題から探す
データ・AIについて学ぶ
News
Hakkyについて
ウェビナーコラム
◆トップ【データ基盤】
データハブとは
Ajust
データの保守運用
AI

執筆者:Handbook編集部

ECSでdbtを実行する方法【Terraformでの実装付】

この記事では、dbt(dbt-snowflake)を ECS で実行する方法について紹介します。環境構築は terraform で行います。

構成

この記事で作成する環境です。
ECR に docker イメージを配置し、それを使用して ECS タスクを実行することで、dbt-snowflake を処理します。

Terraform でのインフラ環境構築

まず、terraform を使用して、環境構築を行います。

ここで構築するリソースは下記の通りです。

  • ECR リポジトリ
  • ECS タスク定義
  • ECS クラスター
  • ECS 用 IAM ロール
resource "aws_ecr_repository" "dbt_on_ecs" {
  name                 = var.project
  image_tag_mutability = "MUTABLE"

  encryption_configuration {
    encryption_type = "AES256"
  }
  image_scanning_configuration {
    scan_on_push = false
  }
}

resource "aws_ecs_task_definition" "dbt_on_ecs" {
  family                   = var.project
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
  cpu                      = 1024
  memory                   = 2048
  execution_role_arn       = aws_iam_role.dbt_on_ecs.arn
  task_role_arn            = aws_iam_role.dbt_on_ecs.arn
  container_definitions = jsonencode(
    [
      {
        name      = var.project
        image     = "${aws_ecr_repository.dbt_on_ecs.repository_url}:latest"
        essential = true
        logConfiguration = {
          logDriver = "awslogs"
          options = {
            awslogs-create-group  = "true"
            awslogs-group         = "/ecs/${var.project}"
            awslogs-region        = "ap-northeast-1"
            awslogs-stream-prefix = "ecs"
          }
        }
      },
    ]
  )

  runtime_platform {
    cpu_architecture        = "X86_64"
    operating_system_family = "LINUX"
  }
}

resource "aws_ecs_cluster" "dbt_on_ecs" {
  name = var.project

  configuration {
    execute_command_configuration {
      logging = "DEFAULT"
    }
  }
  setting {
    name  = "containerInsights"
    value = "disabled"
  }
}

resource "aws_iam_role" "dbt_on_ecs" {
  name = "ecsTaskExecutionRole"
  assume_role_policy = jsonencode(
    {
      Version = "2008-10-17"
      Statement = [
        {
          Action = "sts:AssumeRole"
          Effect = "Allow"
          Principal = {
            Service = "ecs-tasks.amazonaws.com"
          }
          Sid = ""
        },
      ]
    }
  )
  managed_policy_arns = [
    "arn:aws:iam::aws:policy/AmazonS3FullAccess",
    "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy",
  ]
}

terraform apply して環境構築します。

Docker

次に、ECS タスクで実行する Docker イメージを作成します。 dbt の処理内容はSnowflake と dbtと同様のものを使用しています。

.dbt/profiles.yml

リポジトリ内に.dbt/ディレクトリを作成して、snowflake 接続用の profile を記述しておきます。

jaffle_shop:
  outputs:
    snowflake:
      account: ******
      database: ******
      password:
      role: ******
      schema: jaffle_shop
      threads: 1
      type: snowflake
      user: ******
      warehouse: ******
  target: snowflake

Dockerfile

FROM python:3.9

# Update and install system packages
RUN apt-get update -y && \
    apt-get install --no-install-recommends -y -q \
    git libpq-dev python3-dev unzip && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Install DBT
RUN pip install --upgrade pip && \
    pip install dbt-snowflake

# Install AWS CLI v2
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
    unzip awscliv2.zip && \
    ./aws/install

# Set environment variables
ENV PYTHONIOENCODING=utf-8
ENV LANG C.UTF-8

# Copy .dbt directory
COPY ./.dbt/ /usr/app/.dbt/
COPY ./snowflake/jaffle_shop/ /usr/app/jaffle_shop/

# Copy docker-entrypoint.sh
WORKDIR /usr/app/jaffle_shop/
COPY ./docker-entrypoint.sh ./
RUN chmod +x ./docker-entrypoint.sh

# Set entrypoint
ENTRYPOINT ["./docker-entrypoint.sh"]

docker-entrypoint.sh

#!/bin/bash
dbt run --profiles-dir /usr/app/.dbt

最後に、上記の Docker イメージを ECR へ push するため下記コマンドを実行します。リージョンは適宜変更してください。

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin *******.dkr.ecr.ap-northeast-1.amazonaws.com
docker build -t dbt-on-ecs .
docker tag dbt-on-ecs:latest *******.dkr.ecr.ap-northeast-1.amazonaws.com/dbt-on-ecs:latest
docker push *******.dkr.ecr.ap-northeast-1.amazonaws.com/dbt-on-ecs:latest

ECS タスク実行

ECS タスク定義を更新し、ECS タスクを実行してみると dbt を実行できていることが確認できます。

CICD

GitHub Actions を使用してイメージのビルドや、ECR への push、タスク定義の更新を行う場合は下記の Workflow で実現できます。詳細はHakky | GitHub Actions 経由で AWS の ECR/ECS を更新を参照してください。

.github/workflows/deploy-docker-image-to-ecr.yml

name: deploy-docker-image-to-ecr

on:
  push:
    branches:
      - <適宜>

permissions:
  id-token: write
  contents: read

jobs:
  build-and-push:
    runs-on: ubuntu-18.04
    strategy:
      matrix:
        service: ["./dbt-on-ecs"]
    steps:
      - name: Checkout
        uses: actions/checkout@v1

      - name: chage dbt profiles
        uses: mikefarah/yq@master
        with:
          cmd: |
            cd ${{ matrix.service }}
            # dbtのprofileにpasswordを直書きするのを防ぐ
            DBT_PASSWORD=${{ secrets.DBT_PASSWORD }} yq eval '.jaffle_shop.outputs.snowflake.password = env(DBT_PASSWORD)' .dbt/profiles_template.yml > .dbt/profiles.yml

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ap-northeast-1

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Build and push api image to Amazon ECR
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }}
        run: |
          cd ${{ matrix.service }}
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY . --no-cache
          docker push $ECR_REGISTRY/$ECR_REPOSITORY

      - name: Download task definition
        env:
          TASK_DEFINITION_FAMILY_NAME: ${{ secrets.TASK_DEFINITION_FAMILY_NAME }}
        run: |
          aws ecs describe-task-definition --task-definition $TASK_DEFINITION_FAMILY_NAME --query taskDefinition > task-definition.json

      - name: Deploy Amazon ECS task definition
        uses: aws-actions/amazon-ecs-deploy-task-definition@v1
        with:
          task-definition: task-definition.json
          cluster: ${{ secrets.ECS_CLUSTER_NAME }}
          wait-for-service-stability: true

まとめ

この記事では、dbt-snowflake を ECS で実行する方法について紹介しました。ECS スケジュールタスク等で dbt を定期実行することで、dbt を用いたデータ加工を自動化することができます。

参考

info
備考

Hakky ではエンジニアを募集中です!まずは話してみたいなどでも構いませんので、ぜひお気軽に採用ページからお問い合わせくださいませ。

2025年07月06日に最終更新
読み込み中...