ぼーっと CUE のドキュメントを読みながら
CUE という設定用の言語・・・と呼んで良いのかな?のドキュメントを読みながら
「これ、いろんな機能があるけど、それは置いといて、YAML の合成が簡単にできるのでは?・・・とすると、CircleCI の設定を簡単に分割できて面白いかもなぁ」
と思ったので試してみた。わりとアリかもしれない
今回のサンプルコードはここ:
どういう感じ?
こんな感じに適当に分割した設定を
❯ tree .circleci/configs .circleci/configs ├── header.yml ├── job1.yml ├── sample │ ├── job2.yml │ └── mixed\ sample.yml ├── workflow1.yml └── workflow2.yml 1 directory, 6 files
CircleCI の実行時に合成して、ワークフローを動かした。結果はこんな感じ:
ディレクトリ構造とかには特に制限はない
内容は適当にこんな感じで、バージョン部分だけ分けてみたり
header.yml
version: 2.1
ジョブを複数のファイルに分けて定義してみたり
job1.yml
jobs: say-hello: docker: - image: cimg/base:stable steps: - checkout - run: name: "Say hello" command: "echo Hello, World!"
job2.yml
jobs: say-hello2: docker: - image: cimg/base:stable steps: - checkout - run: name: "Say hello2" command: "echo Hello, World2!"
ワークフローを複数のファイルに分けてみたり
workflow1.yml
workflows: say-hello-workflow: jobs: - say-hello
workflow2.yml
workflows: say-hello-workflow2: jobs: - say-hello - say-hello2: requires: - say-hello
ジョブとワークフローを混ぜて定義したファイルを作ってみたりして
mixed sample.yml
jobs: say-hello3: docker: - image: cimg/base:stable steps: - checkout - run: name: "Say hello3" command: "echo Hello, World3!" workflows: say-hello-workflow3: jobs: - say-hello - say-hello2: requires: - say-hello - say-hello3: requires: - say-hello
ファイル名にスペース入れてみたり、サブフォルダの中に入れてみたりした
それを CUE で合成
この分割したファイルを CUE で合成するんだけど、なかなか強力。たとえば job1.yml
と job2.yml
を合成するとこんな感じになる
❯ cue export job1.yml sample/job2.yml --out yaml jobs: say-hello: docker: - image: cimg/base:stable steps: - checkout - run: name: Say hello command: echo Hello, World! say-hello2: docker: - image: cimg/base:stable steps: - checkout - run: name: Say hello2 command: echo Hello, World2!
内部的には、YAML から CUE に変換して、合成して、それを YAML で出力してるのかな。CUE の合成のルールが面白いからぜひドキュメント読んでみてー
CUE には型があって、一度決定した値は上書きできないので、同じ名前のジョブやワークフローを定義してたらエラーになるのも便利そう
実際の合成部分
config ディレクトリの中の YAML ファイルを cue export
に渡して生成
cd .circleci/configs find . -type f -name "*.yml" | awk '{printf "\"%s\" ", $0}' \ | xargs -0 -I {} sh -c 'cue export {} --out yaml' | tee ../generated_config.yml
こういうの得意じゃないから、ここにいちばん時間がかかった気がするw
もっといい書き方あったら教えて欲しいです
CircleCI のダイナミックコンフィグ
さて、その合成をするのに、CircleCI のダイナミックコンフィグ機能を使う
ダイナミックコンフィグは、設定ファイルを動的に生成する機能
config.yml
はこう
version: 2.1 # ダイナミックコンフィグのセットアップ用の設定だよーってしるし setup: true # 「生成した設定ファイルを使って起動してー!」てのに、この Orb を使う orbs: continuation: circleci/continuation@0.3.1 jobs: build: docker: # CUE を入れたイメージを作っといた - image: bufferings/cimg-cue steps: - checkout # さっき書いたやつ - run: name: Generate config command: | cd .circleci/configs find . -type f -name "*.yml" | awk '{printf "\"%s\" ", $0}' \ | xargs -0 -I {} sh -c 'cue export {} --out yaml' | tee ../generated_config.yml # 生成した設定ファイルを使ってパイプラインを実行 - continuation/continue: configuration_path: .circleci/generated_config.yml
これが実行されると、分割された YAML を CUE で合成して generated_config.yml
が生成されて、その生成された設定ファイルで CircleCI のパイプラインが実行される
ちなみに generated_config.yml
の内容はこう
version: 2.1 jobs: say-hello: docker: - image: cimg/base:stable steps: - checkout - run: name: Say hello command: echo Hello, World! say-hello2: docker: - image: cimg/base:stable steps: - checkout - run: name: Say hello2 command: echo Hello, World2! say-hello3: docker: - image: cimg/base:stable steps: - checkout - run: name: Say hello3 command: echo Hello, World3! workflows: say-hello-workflow: jobs: - say-hello say-hello-workflow2: jobs: - say-hello - say-hello2: requires: - say-hello say-hello-workflow3: jobs: - say-hello - say-hello2: requires: - say-hello - say-hello3: requires: - say-hello
CUE かしこいー
ということで
CircleCI の設定ファイルを分割して CUE で合成してみたら割と簡単で便利そうでしたー
設定ファイルが大きくなってメンテしづらいなぁってときに便利かもしれない!
試してみたい人は、config.yml
をそのままコピーして、configs
ディレクトリの中に、分割した設定ファイルを入れたら遊べると思うー!
参考にさせてもらいました!
なるほどー!と思いながら読ませてもらいました!ありがとうございましたー!
- 巨大な .circleci/config.yml を分割した話 - スタディサプリ Product Team Blog
- CircleCIのDynamic Configでconfig.ymlを分割管理する - Carpe Diem
bufferings/cimg-cue
cimg/go
に cue
を足しただけの Docker Image:
https://github.com/bufferings/cimg-cue/blob/main/Dockerfile
今日も宣伝
ぜひ遊びにきてくださいー!