• 457 Words

    terraformer で雑に生成した tf ファイル と state を分割したくてツールを書いた

    terraformer で雑に生成した Terraform の設定ファイル (以下 tf ファイル) と state を分割したくてツールを書きました。 tfmigrator 経緯 miam から Terraform へ移行したい miam というツールで管理されている大量のリソースを Terraform で管理したくなりました。 多くの AWS Resource は Terraform で管理されていますが、 IAM に関しては miam で管理されています。 なぜ Terraform ではなく miam で管理されているかというと、当時のことは自分には分かりませんが、歴史的な経緯もあると思います。 昔は今よりも Terraform の表現力が豊かではなく、 Ruby で自由にかける miam のほうが扱いやすかったとか、 miam だと miam でリソースを管理することを強制できるため、権限管理を厳格にやるという観点では都合が良いという点もあるかと思います。 ではなぜ Terraform で管理したくなったかというと、 一番大きな理由は miam で頻繁に rate limit に引っかかるようになったからです。 Terraform にしろ miam にしろ CI/CD で test, apply が実行されるようになっています。 miam では毎回全部のリソースを対象に処理が実行されるため、リソースの数が増えるにつれて rate limit に引っかかりやすくなります。 CI を rerun すれば成功するのですが、悪いときは 3 回連続で rate limit に引っかかり、 4 回目でようやく成功するということもありました。
    • 64 Words

    tfnotify を fork した

    mercari/tfnotify を Fork して 2 つほど OSS を作りました。 https://github.com/suzuki-shunsuke/tfnotify - tfnotify と互換性あり https://github.com/suzuki-shunsuke/tfcmt - tfnotify と互換性がない 開発の経緯 これまで tfnotify を便利に使わせてもらってたのですが、幾つか改善したいと思うところがあり、本家に PR を投げました。 しかし残念ながらこれまでのところ反応がなく、そこまで本家が活発ではないこと、また他にも色々改修したいところがあったことから、自分でフォークしてメンテすることにしました。 最初は互換性を維持しながら suzuki-shunsuke/tfnotify を開発していました(今もしています)。 しかし、開発を進めるに連れ、自分にとって必要のないプラットフォームなどに関するコードが邪魔であると感じ、それらを消したバージョンを別に開発することにしました。 互換性がなくなることから、名前も変えて tfcmt としました。 https://github.com/suzuki-shunsuke/tfcmt こういった経緯から、 tfcmt のほうを優先的に開発していますが、 tfcmt で実装した機能を後から suzuki-shunsuke/tfnotify にも実装してたりもします。 Fork 元のバージョン suzuki-shunsuke/tfnotify は mercari/tfnotify v0.7.0 fb178d8 をフォークしました。 一方 tfcmt は suzuki-shunsuke/tfnotify v1.3.3 をフォークしました。 mercari/tfnotify との違い 本家との違いは Release Note とドキュメントを参照してください。 suzuki-shunsuke/tfnotify https://github.com/suzuki-shunsuke/tfnotify/releases https://github.com/suzuki-shunsuke/tfnotify/blob/master/COMPARED_WITH_TFNOTIFY.md suzuki-shunsuke/tfcmt https://github.com/suzuki-shunsuke/tfcmt/releases https://github.
    • 92 Words

    Terraform の Docker Provider の Collaborator になりました

    先日 kreuzwerker/terraform-provider-docker の Collaborator になりました。 kreuzwerker/terraform-provider-docker は Terraform の Docker Provider であり、 Docker コンテナや image, network などを管理できます。 元々は Hashicorp の Official Provider であった terraform-providers/terraform-provider-docker が kreuzwerker/terraform-provider-docker に移管され、 Community Provider になりました。 元のリポジトリは hashicorp org に移され archive されています。 Collaborator になった経緯 リポジトリが移管される際に、メンテナを募集していて過去に contribution していた自分にも声をかけていただきました。 https://github.com/hashicorp/terraform-provider-docker/issues/306 Contributor になった経緯 自分がこの provider に contribution した経緯は、 Terraform の Hands on を書くのに丁度よい provider を探していたことでした。 Hands on の題材として Docker コンテナを作ったりできたらいいんじゃないかなと思って Docker provider を試してみました。 しかし当時の docker_container リソースは read をちゃんとサポートしていませんでした。 なので import や update がまともに動きませんでした。 それを見かねて修正して PR を投げたのが最初です。
    • 491 Words

    Splitting .circleci/config.yml

    In this post I introduce how to split a huge .circleci/config.yml. CircleCI doesn’t support to split .circleci/config.yml, so we manage all workflows and jobs configuration into one file .circleci/config.yml. If the repository is Monorepo, the more the number of services increases, the more the size of .circleci/config.yml becomes large and it’s hard to maintain .circleci/config.yml. By splitting .circleci/config.yml per service, it makes easy to maintain .circleci/config.yml and we can configure split file’s CODEOWNERS.
    • 229 Words

    github-ci-monitor: CI のステータスを DataDog で監視

    自作の OSS github-ci-monitor の紹介です。 GitHub リポジトリの CI のステータスを定期的に取得し、 DataDog に送ることで、 CI のステータスを監視するツールです。 現状は AWS Lambda で動かすことを想定していますが、他の方法でも動かせるようにするつもりです。 Motivation モチベーションは、 PR をマージしたあとに CI がこけた場合に通知が欲しいというものです。 マージしたあとに CI が一瞬で終わるなら無事終わるのを見届けてもいいんですが、 数分かかると待ってるのも時間がもったいないです。 しばらくしたあとに結果を確認すればいいんですが、それも面倒くさいですし、普通に忘れます。 そうするとデプロイしたつもりが実は CI がこけてたなんてことが普通にあります。 そういうことにすぐ気づけるよう、 Slack に通知がほしいと思っていました。 仕組み 仕組みは単純です。 GitHub API で各リポジトリのステータスを取得し、 DataDog API でステータスを送信しています。 DataDog API は Service Check API を使っています。 status は以下のようになります。 0: 正常 1: 異常 3: ステータスの取得に失敗 また以下の tag が付きます。 owner: リポジトリのオーナー repo: リポジトリ名 ref: ブランチ名 各リポジトリのステータスは現状 3 つをサポートしています。
    • 168 Words

    matchfile - 変更されたファイルの一覧から必要なタスクを導出するための CLI ツール

    自作の CLI ツール matchfile について紹介します。 https://github.com/suzuki-shunsuke/matchfile この記事の執筆時点で最新バージョンは v0.1.1 です。 変更されたファイルの一覧から実行する必要のあるタスクを導出するための CLI ツールです。 Go で書かれていて、バイナリをダウンロードしてくれば使えます。 Pull Request (以下 PR) の CI では PR で変更されたファイルに応じて 必要なタスク(build, test, lint, etc) だけを実行したかったりします。 そこで、 PR で変更されたファイルパスのリスト と タスクが依存するファイルパスの条件 を元に、そのタスクを実行する必要があるか判定するためのコマンドとして matchfile を開発しました。 ただし、 matchfile の機能としては PR や CI とは独立しているので、もっと別の目的でも使えるとは思います。 matchfile は PR で変更されたファイルパスのリスト や タスクが依存するファイルパスの条件 を取得したりする機能はありません。 PR で変更されたファイルパスのリスト は ci-info という自分が作った別のツールを使うと取得できます。 タスクが依存するファイルパスの条件 はタスクに大きく依存するので matchfile はカバーしていません。 matchfile の使い方としては $ matchfile run <PR で変更されたファイルパスのリストが書かれたファイルへのパス> <タスクが依存するファイルパスの条件が書かれたファイルへのパス> で、 PR で変更されたファイルパスのリスト のうち一つでも タスクが依存するファイルパスの条件 にマッチすれば true を、マッチしなければ false を標準出力します。 コマンドの exit code で結果を表現することも考えられましたが、そうすると set -e しているときに若干面倒くさいので、標準出力で表現しました。
    • 262 Words

    なぜ buildflow を作ったのか

    buildflow というツールを開発しているので buildflow というタグをつけて何回かに分けてブログを書きます。 この記事では なぜ buildflow を作ったのかについて説明します。 開発者である自分の好みや置かれた環境などが所々に反映された内容になっています。 解決したい課題 自分は CI/CD の DX の改善に業務として取り組んでいます。 リポジトリはたくさんあり、横断的にメンテナンスしています。 幾つかのリポジトリはモノレポになっており、 CI の複雑さが増していたり、 CI の実行時間が長かったりします。 現在の CI/CD には以下のような問題があると感じています(他にもあるんですが、 buildflow と関係ないので割愛)。 実行時間が長い PR とは関係ない処理(test, build, etc) が実行されている 金銭的に高い 実行時間が長いので無駄にお金がかかっている CI サービスによっては並列度を上げることで実行時間が縮む場合があるが、それでもその分お金がかかる PR とは直接関係ないところで失敗する PR とは関係ない処理(test, build, etc) が実行されていて、それらが flaky で失敗する メンテナンス性が悪い 属人化気味 何をやっているのか分かりにくい 同じような機能を複数のリポジトリで実装・メンテしたくない これらの問題を解決するために buildflow を開発しました。 buildflow で必要な処理だけを実行する buildflow では PR の情報を自動で取得し、それらに応じて実行する処理を変更できます。 変更されたファイルに応じてだけでなく、 label や PR の author などでも変更できます。 Tengo script を用いて柔軟なロジックを実装できます。 JSON や YAML の読み込みもサポートしているので、依存関係などの設定を別ファイルで管理することも出来ます。
    • 121 Words

    buildflow の実行結果の出力形式

    buildflow というツールを開発しているので buildflow というタグをつけて何回かに分けてブログを書きます。 この記事では buildflow の実行結果の出力フォーマットなどについて説明します。 ちょっと出力はわかりにくいかもしれません。 改善したいと思いつつ、どうあるべきなのかまだ見えてないのでこんな感じになっています。 task の標準出力、標準エラー出力はリアルタイムで出力されます。 また、複数のタスクを並列実行できます。 複数のタスクのログをリアルタイムで出力すると当然混じるので、区別がつくように各行の prefix に timestamp | task name | をつけて出力します。 それでも混じるとわかりにくいので、 phase が完了後に、 phase の全 task のログを混ざらないようにそれぞれ標準エラー出力します。 つまり同じログが 2 回出力されますが 2 回実行されているわけではないです。 ============== = Phase: phase 名 = ============== 10:47:54UTC | task A | + /bin/sh -c echo hello # 実行されるコマンド 10:47:54UTC | task B | + /bin/sh -c echo foo 10:47:54UTC | task A | hello # コマンドの標準(エラー)出力 10:47:54UTC | task A | .
    • 139 Words

    buildflow が自動で取得する Pull Request の情報

    buildflow というツールを開発しているので buildflow というタグをつけて何回かに分けてブログを書きます。 この記事では buildflow が自動で Pull Request (以下 PR) の情報を取得してくる機能について説明します。 この機能は GitHub のみサポートしています。 GitLab や BitBucket はサポートしていません。 これは単純に自分が GitHub しか使わないからです。 PR の CI では 変更されたものだけテストする 特定の PR ラベルがついていたら実行する 特定のユーザーの PR だけ処理を変える(bot とか) のように PR の情報に基づいて挙動を変えたくなったりします。 シェルスクリプトで GitHub API 叩いて情報とってきて jq でパースしてとか、頑張れば別にできるんですが、 毎回そういうコードを書きたくないなと感じていました。 なお、 PR の情報をとってくる機能はデフォルトで無効化されています(GitHub Access Token 必要ですしね)。 設定で pr: true を指定してください。 PR の情報をとってくるには、以下の情報が必要です。 repository owner: 設定ファイルで owner を設定するか、自動取得。 owner を設定してある場合はそちらが優先される repository name: 設定ファイルで repo を設定するか、自動取得。 repo を設定してある場合はそちらが優先される pull request number: 自動取得 GitHub Access Token: 環境変数 GITHUB_TOKEN または GITHUB_ACCESS_TOKEN を指定してください 取得される情報 以下のパラメータがテンプレートや Tengo script に渡されます。
    • 133 Words

    buildflow ではなぜ Tengo を採用しているのか

    buildflow というツールを開発しているので buildflow というタグをつけて何回かに分けてブログを書きます。 この記事では buildflow でなぜ Tengo を採用しているのかについて説明します。 https://github.com/d5/tengo Tengo に関しては https://techblog.szksh.cloud/buildflow-1/ でも多少触れています。 なぜ Tengo を採用しているのかに関しては なぜスクリプト言語を採用しているのか なぜ他の言語ではなく Tengo なのか の 2 つの観点で話します。 なぜスクリプト言語を採用しているのか 逆にスクリプト言語を採用しない方法としては、 YAML などで独自 DSL のようなものを定義する方法があります。 DSL と言うと大げさかもしれませんが、 AND, OR, NOT といった論理を YAML のようなデータ記述言語で表現しようと思うとそんな感じになると思います。 この方法は扱いたいロジックが単純なものに限られるのであれば問題ないですが、 より柔軟なロジックを表現したいとなった場合に、無理があります。 どうやって表現すればいいのか自分で考えないといけない どう頑張っても独自ルールになるため、ユーザーにとって直感的とは言えない 正しく実装しないといけない 仕様をドキュメント化しないといけない 一方、 Go では幾つかのスクリプト言語がサードパーティのライブラリとして実装されており、 buildflow のようなツールに組み込むことが出来ます。 https://github.com/avelino/awesome-go#embeddable-scripting-languages これらを活用すれば上記の問題は解決できるうえに、非常に柔軟にロジックを実装できます(勿論言語によりますが)。 なぜ他の言語ではなく Tengo なのか 単純に https://github.com/avelino/awesome-go#embeddable-scripting-languages で紹介されているライブラリの中で一番要件にマッチしてそうだったからです。 といっても全てをちゃんとチェックしたわけではありませんが。 Lua とかもあるのでそれでも良かったかもですが、自分は Lua を全然知りません。 あとちゃんとバージョンニングされていたのも理由の一つです。 Tengo より人気のある言語もありましたが、バージョニングされてないという理由で見送ったりしました。