CodeBuildを使って依存関係のあるコマンドの順序制御と並列化をやってみた

2022.03.08

CX事業本部、MAD事業部の小倉@大阪オフィスです。

CodeBuildを使って複数のコマンドを直列実行させていたのですが、
依存関係の無いコマンドはできるだけ並列に実行させたくなったので、方法を調べてみました。

モチベーション

以下の様なコマンド(taskX)をできるだけ並列に実行し、実行時間を短くしたいと思います。

前提条件

  • 図のtask1〜task9は全て異なるコマンド
  • 矢印でつながっている各taskは、先行するtaskが全て完了した場合のみ実行可能
  • (テスト実行の為sleepコマンドで代用)

戦略

CodeBuildのBatchビルド機能のうち、build-graphを使用します。

このBatchビルド、基本はCodeBuildプロジェクトで指定したbuildspecのビルドコマンドを、各ビルドタスクで実行するのですが、
実は各ビルドタスクにbuildspecを指定して、それぞれ異なる処理を指示することが出来るのです!!(見落としていました)
(以下はCodeBuildのドキュメントより引用)

buildspec
    Optional. The path and file name of the buildspec file to use for this task. If this parameter is not specified, the current buildspec file is used.

やってみる

上記の仕様をふまえて、以下の様な方法を考えてみました。

task_group_X の単位にbuildspecファイルを作成してまとめ、
メインとなるbuildspecbuild-graphを使用して実行順序を制御します。

メインとなるbuildspec (CodeBuildプロジェクトにて指定)

version: 0.2
batch:
  build-graph:
    - identifier: task_group_a
      buildspec: task_group_a.yml
    - identifier: task_group_b
      buildspec: task_group_b.yml
    - identifier: task_group_c
      buildspec: task_group_c.yml
      depend-on:
        - task_group_a
        - task_group_b
    - identifier: task_group_d
      buildspec: task_group_d.yml
      depend-on:
        - task_group_c
    - identifier: task_group_e
      buildspec: task_group_e.yml
      depend-on:
        - task_group_c
phases:
  build:
    commands:
      # ここは今回よびだされない想定
      - echo Default Start on `$(date)`
      - sleep 60
      - echo Default Start on `$(date)`

グループ化されたコマンドを定義するbuildspec

task_group_a.yml

version: 0.2
phases:
  build:
    commands:
      # Task 1
      - echo Task 1 Build started on `date`
      - sleep 100
      - echo Task 1 Build stopped on `date`
      # Task 2
      - echo Task 2 Build started on `date`
      - sleep 200
      - echo Task 2 Build stopped on `date`

他グループも同様のイメージでymlファイルを作成しておきます。

準備が出来たら、マネジメントコンソールからバッチビルドを実行してみます。

実行開始後、画面上にも依存関係が表示されています。

CloudWatchLogsに出力された各コマンドのログを確認してみます。

# TaskGroupA
2022-03-08T10:24:21.661+09:00	Task 1 Build started on Tue Mar 8 01:24:17 UTC 2022
2022-03-08T10:25:59.759+09:00	Task 1 Build stopped on Tue Mar 8 01:25:57 UTC 2022
2022-03-08T10:25:59.759+09:00	Task 2 Build started on Tue Mar 8 01:25:57 UTC 2022
2022-03-08T10:29:17.903+09:00	Task 2 Build stopped on Tue Mar 8 01:29:17 UTC 2022

# TaskGroupB
2022-03-08T10:24:50.557+09:00	Task 3 Build started on Tue Mar 8 01:24:46 UTC 2022
2022-03-08T10:26:28.671+09:00	Task 3 Build stopped on Tue Mar 8 01:26:26 UTC 2022
2022-03-08T10:26:28.671+09:00	Task 4 Build started on Tue Mar 8 01:26:26 UTC 2022
2022-03-08T10:29:48.789+09:00	Task 4 Build stopped on Tue Mar 8 01:29:46 UTC 2022
2022-03-08T10:29:48.789+09:00	Task 5 Build started on Tue Mar 8 01:29:46 UTC 2022
2022-03-08T10:34:46.951+09:00	Task 5 Build stopped on Tue Mar 8 01:34:46 UTC 2022

# TaskGroupC
2022-03-08T10:35:12.487+09:00	Task 6 Build started on Tue Mar 8 01:35:08 UTC 2022
2022-03-08T10:36:50.887+09:00	Task 6 Build stopped on Tue Mar 8 01:36:48 UTC 2022

# TaskGroupD
2022-03-08T10:37:52.467+09:00	Task 7 Build started on Tue Mar 8 01:37:48 UTC 2022
2022-03-08T10:39:30.549+09:00	Task 7 Build stopped on Tue Mar 8 01:39:28 UTC 2022
2022-03-08T10:39:30.549+09:00	Task 8 Build started on Tue Mar 8 01:39:28 UTC 2022
2022-03-08T10:44:30.911+09:00	Task 8 Build stopped on Tue Mar 8 01:44:28 UTC 2022

# TaskGroupE
2022-03-08T10:37:52.216+09:00	Task 9 Build started on Tue Mar 8 01:37:48 UTC 2022
2022-03-08T10:41:10.635+09:00	Task 9 Build stopped on Tue Mar 8 01:41:08 UTC 2022

実行時間をガントチャートにしてみました。

想定通りに並列化出来ている様子が確認できました。

まとめ

build-graphを使うことで、依存関係があるコマンドを順序制御しながら実行することが出来ました。
実行に時間のかかるコマンド(ビルド等)であればある程、並列化の恩恵を大きく受けられそうですね。

尚、build-listbuild-matrixでも各ビルドタスクにbuildspecを個別指定することは可能ですので、 興味のある方は試して頂ければと思います。

参考資料