Skip to main content

· 2 min read
Shunsuke Suzuki

mercari/tfnotify を Fork して 2 つほど OSS を作りました。

開発の経緯

これまで tfnotify を便利に使わせてもらってたのですが、幾つか改善したいと思うところがあり、本家に PR を投げました。 しかし残念ながらこれまでのところ反応がなく、そこまで本家が活発ではないこと、また他にも色々改修したいところがあったことから、自分でフォークしてメンテすることにしました。 最初は互換性を維持しながら suzuki-shunsuke/tfnotify を開発していました(今もしています)。 しかし、開発を進めるに連れ、自分にとって必要のないプラットフォームなどに関するコードが邪魔であると感じ、それらを消したバージョンを別に開発することにしました。 互換性がなくなることから、名前も変えて tfcmt としました。

https://github.com/suzuki-shunsuke/tfcmt

こういった経緯から、 tfcmt のほうを優先的に開発していますが、 tfcmt で実装した機能を後から suzuki-shunsuke/tfnotify にも実装してたりもします。

Fork 元のバージョン

suzuki-shunsuke/tfnotifymercari/tfnotify v0.7.0 fb178d8 をフォークしました。 一方 tfcmt は suzuki-shunsuke/tfnotify v1.3.3 をフォークしました。

mercari/tfnotify との違い

本家との違いは Release Note とドキュメントを参照してください。

· 9 min read
Shunsuke Suzuki

2019-10-01 から今の職場で SRE として働いています。 その中で自分がどういうことをやっているかという話をします。

2020-12-31 現在の内容です。

要約

  • プロダクト横断的な SRE チームで、プロダクトのプラットフォームを運用・開発している
  • 特に CI/CD の改善が得意
  • developer に CI/CD をいわばサービスとして提供しており、 DX の改善に取り組んでいる
  • Monorepo の負の側面(CIが遅い、関係ないTestがこけるetc)の解消にも取り組んでいる
  • 自分が直面している課題を解決する OSS を色々開発している

キーワード

  • SRE
  • Monorepo
  • CI/CD
  • Developer Experience
  • Terraform
  • Go / Shell script
  • k8s
  • CircleCI / CodeBuild
  • Conftest
  • Renovate

より具体的にやっていることを書いた記事

何をやっているか

プロダクト横断的な SRE チームで、プロダクトのプラットフォームを運用・開発しています。

SRE と一言で言っても、その領域は非常に多岐にわたります。 組織によって SRE の実態は異なるでしょう。 例えば SRE とは別にセキュリティの専門チームがあるような組織もあるとは思いますが、 現職ではそのようなものはないのでそこも SRE が見ています。 全ての領域に関して個人がスペシャリティを持つというのは非常に難しいので、 全体的にある程度カバーしつつも特定の領域に対しスペシャリティを持つというのが割と現実的な話だと思います。

自分の場合、 CI/CD の改善を強みとし、そこに主に取り組んでいます。 プラットフォームを運用・開発していると言いましたが、それには CI/CD も含まれます。 現職では Monorepo アーキテクチャが採用されています。 Monorepo にすることで複数のサービスにまたがる変更を 1 つの Pull Request (以下PR) でまとめて出来たり、 CI/CD などの仕組みを共通化することが出来ます。 現職では幾つかの Monorepo があります。

  • アプリケーションのコードと k8s manifest の Monorepo
  • Ansible の Monorepo
  • Terraform の Monorepo
  • などなど

Monorepo の中で CI/CD に関しては SRE が ownership を持ち、言わばサービスとして developer に提供しています。 といっても Jenkins や CircleCI のようなものを自作しているという意味ではありません。 CI/CD には主に CircleCI を使っていますが、CIの設定や CI/CD で使われるスクリプトなどをメンテしています。 全てを SRE が書くということではなく、むしろ developer が新しいサービスを追加する際に簡単に CI/CD をセットアップできるようにしています。

例えば Terraform ではサービス・環境(staging, production, etc) ごとに State をディレクトリを分けていますが、新しいサービスを追加する際は、まずは generator を実行してコード生成し、そこに Terraform の configuration を書けば CI/CD で test や lint, apply が実行されるようになっています。 元々新しいサービスの追加時には .circleci/config.yml に設定を書き足す必要がありましたが、 最近 Terraform の CI/CD を CircleCI から CodeBuild に移行した ことでそれが一切不要になりました。日々進化しています。 単に PR で terraform plan して master で terraform apply するだけなら簡単ですが、 より DX の高いものにするのが自分の強み・専門性です。

Lint や Test を導入したりもします。勿論 Rails などで書かれたアプリケーションのテストを書くということではなく(それを書くのは基本 developer)、例えば k8s のマニフェストのテストや Terraform の lint などです。 Lint や Test は、導入して CI が失敗するようになったら終わり、ではありません。 現職では developer が k8s のマニフェストや Terraform の configuration も書きますが、必ずしも全員がそれらに習熟しているわけではありません。 失敗するようになっても、developer が失敗した原因を理解できなかったら、無駄に rerun してみて結局解決しなくて SRE に質問してくるだけです。 そうではなく、 なぜ CI がこけたのか、どうすればいいのか、その lint はどういう経緯で導入されたのかなどを developer が自分で理解し、自己解決できるようにすることが重要です(勿論必要に応じて問い合わせが発生するのは仕方ないですし、遠慮はしてほしくはありません)。 そこで PR にそれらの情報をコメントするようにしています。 シェルスクリプトから簡単にコメントできるように OSS としてツールも開発しています(gihtub-comment)。

Monorepo では単純に全てのサービスのテスト・ビルド・デプロイを実行すると時間がかかったり、 PR に関係ないテストが落ちたりします。 そのため、必要な job だけ実行するような仕組みが必要です。 そのへんをコードを書かずにいい感じに出来るのが理想ではありますが、 Monorepo のエコシステムはそこまで醸成していないと思っており、自分たちである程度コードを書く必要があります。 自分は Go や Shell Script でそういったコードを普段書きます。

現職の Monorepo のうち、アプリケーションのコードと k8s manifest の Monorepo は非常に大きく、 CI/CD をナイーブに実装すると非常に時間がかかったり効率が悪かったりします。 そういった問題点を見つけ出し、チューニングするといったこともやりました。

その中で生まれた OSS もあります。 自分が直面している課題を解決する OSS を開発するのが自分のライフワークです。

https://github.com/suzuki-shunsuke/profile#libraries

仕事でも使っているツールを幾つか紹介します。

  • gihtub-comment GitHub の PR, commit にコメントするツール
  • circleci-config-merge 分割された .circleci/config.yml をマージ
  • github-ci-monitor CI のステータスを DataDog でモニタリングする AWS SAM application
  • matchfile Monorepo の CI で、特定のサービスが依存するファイルに変更があったか判定するのに便利
  • ci-info GitHub API を使って CI の情報を取得
  • dd-time コマンドの実行時間を DataDog に送る
  • akoi バイナリのバージョン管理

· One min read
Shunsuke Suzuki

2020-11-01 から 2020-11-30 にかけて仕事でやったことを書ける範囲で書きます。

· 2 min read
Shunsuke Suzuki

Renovate による PR をレビューする際、差分がなんなのか分かりづらいときがあります。 例えば data source が github-release の場合、 PR の description に Release Note が含まれており、コードの差分も link があるので便利です。 一方 helm data source の場合、 そういったものがなく差分がなんなのか分からないことがあります。 そういう場合、 prBodyNotes を利用して link を追加すると便利です。

例えば、 datadog helm chart の場合

{
"datasources": ["helm"],
"packageNames": ["datadog"],
"prBodyNotes": [
"[compare](https://github.com/DataDog/helm-charts/compare/datadog-{{currentVersion}}...datadog-{{newVersion}})"
]
}

とすると、 PR の description にリンクが追加されます。地味ですが便利です。 Release page へのリンクを追加しても便利かもしれませんね。

ex. https://github.com/suzuki-shunsuke/test-renovate-2/pull/28

template で使える変数は https://docs.renovatebot.com/templates/ を参照してください。 helm chart ごとに設定を書かないといけないのが面倒ですが、仕方ないですね。

· 5 min read
Shunsuke Suzuki

普段 Renovate を主に使っている自分が、 Dependabot と Renovate の違いについて調べてみました。 普段 Renovate を主に使っているので、 Renovate 寄りの内容になっています。 気分を害する人がいましたら申し訳ありません。 Dependabot の理解が浅いので間違ってたら指摘してもらえると助かります。 2020-12-01 時点の情報です。

設定項目の数

まずは設定のドキュメントを見比べると、 Renovate のほうが設定項目が多いです。 Renovate はよく言うと設定項目が多く、柔軟な設定ができるといえる一方、すべての設定を理解し使いこなすのは難しいです。 決して日本語の情報も多くないので、色々試行錯誤したりすることもあります。 Dependabot の場合、設定がそんなに多くなく割と分かりやすい印象があります。

scheduling

Dependabot は schedule の設定が必須です。 Renovate でも schedule の設定は出来ます。

Dependabot は 1 個 1 個設定しないといけない?

Renovate は renovate.json さえ作れば中身がほぼ空でも勝手に update されます。 逆に対象を絞りたかったら明示的に指定する必要があります。

一方で Dependabot は対象を 1 つ 1 つ指定しないといけないようですね。

もちろん、これは必ずしも悪いことではないですし、良い面もあります。 設定が明示的に書かれていたほうが挙動を理解しやすいですしね。

ただし、数が多いと大変ですし、サービスを追加するたびに設定を追加しないといけなさそうです。

Renovate は .circleci/config.yml などの update もサポート

Renovate は .circleci/config.yml や .drone.yml の Docker image のバージョンの update もサポートしています。 Dependabot はサポートしていないようですね。

Renovate は正規表現による update をサポート

https://docs.renovatebot.com/modules/manager/regex/

GitHub Releases からバイナリをダウンロードしてきているような場合でも、 Renovate では Regex Manager を使えば update 出来ます。 CI で使っているツールを GitHub Releases からダウンロードしてきているケースが多いので重宝しています。

Renovate は Grouping をサポート

Renovate は複数のソフトウェアのアップデートを同じ PR でまとめて update できます。

https://docs.renovatebot.com/configuration-options/#group

Renovate で PR をまとめられたくない場合は additionalBranchPrefix などの設定が必要

https://docs.renovatebot.com/configuration-options/#additionalbranchprefix

Renovate だと同じパッケージを複数のサービスで使っている場合、何も設定しないと 1 つの PR に更新がまとめられてしまいます。 additionalBranchPrefix を設定することで回避ができますが、この解決策を見つけるまでに少々苦労しました。 Renovate の難しいところですね。

Renovate は設定をライブラリのように共有できる

https://docs.renovatebot.com/config-presets/

Renovate は汎用的な設定を OSS のように公開し再利用することが出来ます。 仕事だと特に使ってないですが、 個人の Go の Project なんかは同じものを使っていて、便利です。

· 2 min read
Shunsuke Suzuki

先日 kreuzwerker/terraform-provider-docker の Collaborator になりました。 kreuzwerker/terraform-provider-docker は Terraform の Docker Provider であり、 Docker コンテナや image, network などを管理できます。 元々は Hashicorp の Official Provider であった terraform-providers/terraform-provider-dockerkreuzwerker/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 を投げたのが最初です。

その後も幾つか contribution をしました。

なお、 PR を投げたものの、 Hands on は MySQL Provider を使って書きました。

https://techblog.szksh.cloud/terraform-hands-on-with-mysql-provider/

· 2 min read

2020-10-01 から 2020-10-31 にかけて仕事でやったことを書きます。 勿論全部は書けないのでいくつかピックアップして書きます。

  • Terraform
  • Docker Hub 認証するようにした
  • kustomize build のテスト(失敗したら PR にコメントをして、なぜ失敗したか分かるようにした)
    • 元々 kustomize build に失敗して CI がこけても、なぜこけたのか分かりにくく、 SRE に問い合わせが来て調べるみたいなことがあった
    • どの k8s manifest の kustomize build に失敗したのか、 PR に分かりやすくコメントするようにした
  • CI で kubectl apply --server-dry-run によるテストを導入
  • Monorepo
    • 差分検知・デプロイパイプラインの改善
  • Renovate

· One min read
Shunsuke Suzuki

2020-07-01 から 2020-09-30 にかけて仕事でやったことを書きます。 勿論全部は書けないのでいくつかピックアップして書きます。

  • Terraform
    • CircleCI から CodeBuild への移行
      • Security + DX
      • 10月以降も継続
    • tfnotify の導入
      • Monorepo で導入するには一工夫が必要
      • コメントが消える挙動がドキュメント化されてなくて軽くハマった
  • Renovate の導入
    • Regex Manager 便利
  • Monorepo
    • 差分検知・デプロイパイプラインの改善
  • DataDog からのアラートのハンドリング業務の改善
    • どんなアラートがあって、どう対応したかなどのナレッジの共有の改善
    • 割とアナログな手法だが、ちゃんと work している

· One min read
Shunsuke Suzuki

2020-04-01 から 2020-06-30 にかけて仕事でやったことを書きます。 勿論全部は書けないのでいくつかピックアップして書きます。

  • Monorepo
    • CI で kustomize build の diff を PR にコメント
    • Conftest で k8s manifest の validation の導入
    • Go で書かれた差分検知のコードのリファクタリング
    • CI の高速化・コスト削減
  • GitOps
    • GitOps を導入するためのツールの開発のサポート
  • Terraform
    • input variables を local value に置き換え
  • GuardDuty の導入
    • Terraform で IaC
    • False Positive なアラートが多くてハンドリングできてない
  • ブログの執筆
  • Argo Workflows の検証
  • MongoDB Atlas への移行サポート
    • Go で Restore Job の開発
    • オペレーション

· 3 min read
Shunsuke Suzuki

2020-01-01 から 2020-03-31 にかけて仕事でやったことを書きます。 勿論全部は書けないのでいくつかピックアップして書きます。

  • Monorepo
  • サーバの OS upgrade
  • Ansible
    • CI の更新検知で、 PR の label で対象を指定できるようにした(コードに変更がなくてもテストが実行できるようにした)
      • たまにテストしたいときはある
      • それまではてきとうにコードを修正しないとテストが実行されなかったが、 PR の label で対象の playbook を指定できるようにした
    • key=value 形式を YAML に変換
  • .circleci/config.yml のリファクタリング
    • job を parameterize して共通化したり
    • parameterize された command を使って共通化したり
    • コード量の大幅な削減
  • Terraform
    • CircleCI の環境変数を設定することで、 master での CI を一時的に禁止できるようにした
      • State を弄ってたりするときに予期せぬ apply が実行されないようにするため
    • master branch の CI が終わるまで wait
      • master の CI が走っている間に PR の CI でまだ apply されていないリソースが差分として出るのを防ぐ
    • shfmt, shellcheck の導入
      • CI/CD でシェルスクリプトを書いているので、それらを lint
    • State Locking の導入
    • Terraform Cloud の検証
      • 結果、見送り
      • すでに CI/CD pipeline を構築している自分たちにとっては、わざわざ移行するメリットが薄いと判断
  • MongoDB upgrade
  • Jenkins Alternative の検証
    • RunDeck
    • Argo Workflows
    • 結局、ローカルで検証した程度