Open6

Earthly で Terraform の CI/CD workflow を実装する

Shunsuke SuzukiShunsuke Suzuki
  • 数秒で終わるようなコマンドを earthly でローカルで実行するのはオーバーヘッドが大きくて体験があまり良くない
  • コマンドを直列で実行するだけのような短時間で終わるシンプルな CI でも earthly のオーバーヘッドは気になる
  • 1 分以上時間がかかるような job であれば earthly によるオーバーヘッドはあまり問題にならない気もする
  • デバッグをどうすればいいのか https://docs.earthly.dev/docs/guides/debugging
  • SAVE ARTIFACTCOPY でディレクトリを扱う場合がちょっとややこしい
  • arg の validaiton が宣言的に出来ると便利
  • log がわかりにくい
  • target の help を出力したい
  • CI に関する情報(環境変数, GitHub_EVENT_PATH, etc) をどうやって earthly に渡すか
  • CI で cache を活用するために、 Docker Layer Cache を Registry に store/restore する必要がある
Shunsuke SuzukiShunsuke Suzuki

log が分かりづらい

例えば arg が空だったら validation error にするとする。

validate-arg-dir:
    ARG dir
    RUN echo "arg dir is required" >&2
    RUN exit 1
   +validate-arg-dir | dir=.
   +validate-arg-dir | --> RUN echo "arg dir is required" >&2
   +validate-arg-dir | arg dir is required
   +validate-arg-dir | dir=.
   +validate-arg-dir | --> RUN exit 1
             context | transferred 39 file(s) for context . (13 MB, 176 file/dir stats)
             context | [██████████] 100% transferring .:
   +validate-arg-dir | ERROR Earthfile line 13:4
   +validate-arg-dir |       The command
   +validate-arg-dir |           RUN exit 1
   +validate-arg-dir |       did not complete successfully. Exit code 1

============================ ❌ FAILURE [2. Build 🔧] ============================

Repeating the output of the command that caused the failure
   +validate-arg-dir *failed* | dir=.
   +validate-arg-dir *failed* | --> RUN exit 1
   +validate-arg-dir *failed* | [no output]
   +validate-arg-dir *failed* | ERROR Earthfile line 13:4
   +validate-arg-dir *failed* |       The command
   +validate-arg-dir *failed* |           RUN exit 1
   +validate-arg-dir *failed* |       did not complete successfully. Exit code 1
Share your logs with an Earthly account (experimental)! Register for one at https://ci.earthly.dev.
Error: build target: build main: failed to solve: process "/bin/sh -c EARTHLY_LOCALLY=false PATH=/root/.local/share/aquaproj-aqua/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin dir=. /usr/bin/earth_debugger /bin/sh -c 'exit 1'" did not complete successfully: exit code: 1
Shunsuke SuzukiShunsuke Suzuki

Import

Earthly の target を Module として再利用するための機能として Import が使えそうなので検証する

https://docs.earthly.dev/basics/part-5-importing

https://docs.earthly.dev/docs/earthfile#import

VERSION 0.6
FROM alpine:3.16.2
WORKDIR /workspace
IMPORT github.com/suzuki-shunsuke/example-earthly-terraform:44c6e254e0f4450357eeca60760dfbbd1acb045a AS upstream

tf-init:
    ARG dir=.
    FROM upstream+tf-init -dir $dir

https://github.com/suzuki-shunsuke/example-earthly-terraform/blob/44c6e254e0f4450357eeca60760dfbbd1acb045a/Earthfile#L18-L25

実行できた。

と思ったが、残念ながら import 元の file (foo や aqua.yaml) が参照されてしまっており、参照元のコードのテストが出来ていない。。

これは import 元のコードから COPY を消して、参照先で COPY を実行すれば良い気がする

Shunsuke SuzukiShunsuke Suzuki

Import は新しい環境を構築するので、自分がやりたこととしては COMMAND, DO で実現できる気がしてきた。
https://docs.earthly.dev/docs/guides/udc

出来た。現状記述が冗長でありがたみが薄いが、改善していく。

VERSION 0.6
IMPORT github.com/suzuki-shunsuke/example-earthly-terraform/lib:7ba2ec37773824645e6e75c333b50b844f280610 AS lib
FROM DOCKERFILE .
WORKDIR /workspace
COPY aqua.yaml .
RUN aqua i -l
ARG ci

tf-init:
    ARG dir=.
    DO lib+VALIDATE_ARG_DIR -dir $dir
    COPY $dir $dir
    DO lib+TF_INIT -dir=$dir

COPY の source で他の target の output を参照している場合、 COMMAND で COPY を実行できない(COMMAND 内でその target を参照できないので)