データベース技術調査ブログ

LinuxやPostgreSQL、Oracleデータベース、AWSの知識をアウトプットしていきます

【AWS/ECS/Fargate】Embulkのジョブをサーバレスに実行する基盤を作ってみるチュートリアル(パート3)

以下の記事のパート3です。


【パート1】開発環境の準備
【パート2】Embulkコンテナの作成・単体テスト
【パート3】ECSのタスク定義と動作確認(★本記事)
【パート4】Step Functionsで簡単に実行できるように設定する



前回までのパートで、ECSでEmbulkを実行するための準備が完了しました。満を持してECSの設定をしていきましょう。


本編に入る前にECSに関して前提の知識を振り返っておきます。詳しくは手を動かしながら確認していってみるのがおすすめです!
・ECSはAWSが提供するコンテナのワークロードを実行するための多種多様な機能を持つコンテナ管理のためのマネージドサービス
・ECSはあくまでコンテナを実行するためのコントロールに徹していて、実際にコンテナを起動する基盤(クラスタ)は「EC2」か「Fargate」を選べる(ほかにも外部のクラスターもあります)
・ECSで管理するワークロードの設定は「タスク定義」と呼ばれる
・Webサーバーのコンテナのようにデーモンプロセスが存在し、処理を待ち受けるようなタスクの集合を「サービス」と呼ぶ(※今回はバッチ処理なので単発のタスク)

f:id:jimatomo:20210920171426p:plain
ECSとFargateのイメージ(ざっくり)

目次

3-1) まず最初に追加のデータを投入

差分更新用のデータを投入しておきます。
ターゲットデータベースに接続して以下のSQLを実行します。

insert into test_tbl values (6,'increment_test', current_timestamp);

-- 確認
SELECT * FROM test_tbl;

3-2) ECSのクラスター(Fargate)を作成

まずはFargateのクラスターを作成します。FargateはAWSが基盤を管理してくれるので時間単価でいえばEC2を自分で管理するよりも高いですが、今回のユースケースのように特定のタイミングでのみ実行しているようなコンピュートリソースの場合は課金がされないのでコスト最適化ができます。その辺りに関して書いている以下のブログはいろいろ勉強になります。
aws.amazon.com


それではマネジメントコンソールを開き、ECSのページを開きましょう。(執筆時点で一部のページが新しいバージョンに対応し始めていました。)
クラスターのページを開き、「クラスターの作成」をクリックします。


1. 【クラスターテンプレートの選択】
ネットワーキングのみ」を選択して、次のステップへをクリックします。


2. 【クラスターの設定】
クラスター名:(好きな名前を入れてOK)
※それ以外はデフォルトで大丈夫です。

…これだけです!何とマネージドサービス過ぎてほぼ何も設定しなくて使えちゃうの素敵(*^▽^*)


3-3) ECSのタスクに割り当てるIAMロールを作成

先にタスクを実行するコンテナに割り当てるIAMロール(タスク用の IAM ロール)を作成します。
IAMのコンソールからロールを作成します。(手順はざっくり書きます)
(さっと探した限りユースケースの中にECSがいないので、一般的なユースケースのEC2をベースに作って、後で信頼関係を編集する方向で行きます)

(IAMロール作成時のユースケースの中にEKSがあってECSがないのはなんでなんだろう?)


ポリシーはパート2の単体テストを実施する際に作成しておいたポリシーを適用します。


任意の名前で作成します。


出来上がったらロールを選択して詳細画面を表示します。「信頼関係」のタブを開きます。「信頼関係の編集」をクリックします。
以下のポリシーに書き換えます。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "ecs-tasks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

ちなみに、ECSのタスク用のIAMロールはイメージ的に呼び出すサービスからコンテナにロールを割り当てるようなイメージの様です。そのため、タスクを呼び出すサービスのIAMポリシーにはiam:PassRoleの権限が必要になります(これを知らなくて後で実施するStep Functionsでジョブを実行させようとしたときにIAMロールの権限不足で詰まりました)。その辺りはドキュメントを読んでみてください。

注記
タスクおよびサービスを実行するために必要な標準の Amazon ECS アクセス権限を付与するだけでなく、IAM ユーザーにはタスクの IAM ロールを使用する iam:PassRole アクセス権限も必要です。

タスク用の IAM ロール - Amazon Elastic Container Service



同じ要領で、もう一つECSタスク実行IAMロールを作成しておきます。このロールは上で作ったロールと紛らわしいですが、FargateとかがコンテナイメージをプルしたりログをCloudWatch Logsへ連携したりするときに利用するIAMロールみたいです。(私の場合は以前に作っていたみたいなのでどうやって作ったかは忘れました。)
★紐づけるポリシーはAWSのマネージドポリシーである「AmazonECSTaskExecutionRolePolicy」です。詳しくはドキュメントを参照してください。
Amazon ECS タスク実行 IAM ロール - Amazon Elastic Container Service



3-4) ECSのタスク定義を作成

タスク定義のページを開きます。(執筆時点ではまだ古いページにリダイレクトされました。なれるまでちょっとわかりにくいので新しいコンソールの登場に期待したいところです)
新しいタスク定義の作成」をクリックします。


1. 【起動タイプの互換性の選択】
FARGATEを選択します。


2. 【タスクとコンテナの定義の設定】
タスク定義名:datafound-embulk-001-test_tbl(好きな名前でOK)
タスクロール:3-3で作成したコンテナに紐づける用のIAMロールを割り当てる
タスク実行ロール:マネージドポリシーである「AmazonECSTaskExecutionRolePolicy」をつけたロールを割り当てます。
タスクメモリ (GB):0.5(チュートリアルを実行する文には最小のサイズで事足ります。)
タスク CPU (vCPU):0.25(チュートリアルを実行する文には最小のサイズで事足ります。)

コンテナ定義は「コンテナ追加」ボタンをクリックして開いて以下の【コンテナ定義】を指定します。


【コンテナ定義】
コンテナ名:embulk-001-test_tbl(好きな名前でOK)
イメージ :<アカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/datafound-embulk:pg-pg(ECRのコンソールから「イメージのURI」をコピーしてくる)
・「詳細コンテナ設定」>「環境」>コマンド:(以下のコマンドを入力)

bash,-c,aws s3 cp s3://<バケット名>/job/001-test_tbl/ . --recursive && chmod +x -R . && ./run.sh

※コマンドはdockerのCMD的な感じで指定します。一つのコマンドしか実行できないので基本的にはスクリプトを用意して実行するのが定石ですが、今回はS3から再帰的にスクリプトファイル達をダウンロードしてきて実行権限をつけて、スクリプトを実行するというように、bashコマンドのオプションをさらに利用して実行するという方法を取っています。
Dockerfile リファレンス — Docker-docs-ja 20.10 ドキュメント


※その他の設定はデフォルトのままでOK


3-5) タスクの実行確認

それでは、タスクの実行をしていきましょう。

マネジメントコンソールで手動で実行する際には2つの方法があります。
クラスターのページを開き、タスクのタブを開き、「新しいタスクの実行」をクリック
②タスク定義のページを開き、実行したいタスクにチェックをして、アクションから「タスクの実行」をクリック


今回は①の方法で実行してみましょう。

①の手順を実行すると【デプロイ】の画面が表示されます。
【デプロイ設定】
アプリケーションタイプ:タスク(デフォルトでそうなっているはず)
タスク定義ファミリー:先ほど作成したタスク定義を指定(リビジョンは最新のものが設定されるのでそのままでOK)
必要なタスク:1(デフォルトでそうなっているはず)

【ネットワーキング】
VPC:(RDSを起動しているVPCを選択)
サブネット:(パブリックサブネットを選択)
セキュリティグループ:(パート1で作成したセキュリティグループを指定)
パブリックIP:有効(ECRとの接続などで必要です。)


※サブネットID、セキュリティグループIDは控えておくと後続のStep Functionsの設定の時に楽です。


設定ができたら、「デプロイ」をクリックします。(ジョブが動き出します!)


タスクが完了したら、ターゲットDBを確認してみましょう。

SELECT * FROM test_target_tbl;

これでECSでの実行確認もできたので、最後にStep Functionsでジョブフローを組んで実行できるようにしてみましょう。
※タスク実行時にいろいろネットワーキングの設定までしないといけないんだな~ということを覚えておいてください。Step Functionsではこれらの設定をjson形式で保持させます。

最後のパートへ進みましょう。あとちょっとです!(*^-^*)


【パート4】Step Functionsで簡単に実行できるように設定する