スキーマを通っても有効とは限らない
一言でいうと
カタログは、スキーマとポリシーの2つの層でふるい分けます。スキーマだけを通過したエンティティは、形が合っているだけなので、名前に空白があっても、specをタイプミスして書いても、入ってしまいます。
なぜ2つの層を両方見る必要があるのか
前のモジュールで、catalog-info.yamlをいくつも書きました。ところが、そのラボが動く場所には、Backstageバックエンドがなかったので、そのYAMLが実際に通過するかを確認する方法がありませんでした。
このラボは、Backstageを丸ごと起動しません。数百MBと、数分のビルドがかかるからです。代わりに、カタログに入れるときに使うまさにそのライブラリを、直接動かします。
スキーマとポリシーは、別のものを捕まえます
カタログは、2つの層でふるい分けます。
스키마 형태 — apiVersion·kind·필수 필드가 있는가
정책 규칙 — 이름 형식, 63자 제한, 모르는 루트 필드 거부
entitySchemaValidatorだけを使うと、スキーマだけを見ます。そのため、名前に空白があっても、specをspceと間違えて書いても、通過します。本物のカタログは、その上にポリシーを載せます。
知らないルートフィールドを止める理由が、特に価値があります。spceというタイプミスが通過すると、そのサービスはspecなしで、つまりownerもlifecycleもないまま、カタログに入ります。CNPAの構造的スキーマのプルーニングと、同じ精神です。
参照が関係を作ります
owner: team-aは、実はgroup:default/team-aを指す参照です。これらの参照が集まってグラフになり、Backstageの画面の「誰が所有し、何に依存しているか」は、すべて、このグラフをたどった結果です。参照が壊れると、関係が切れます。そのため、名前の形式が厳格です。
設定はキー単位で深くマージされます
最後のファイルがすべてを上書きするわけではありません。スカラーはあとが勝ち、片側にだけあるキーは残り、配列はまるごと置き換えられます。この配列のルールが落とし穴です。
検証をどこで行うのか
カタログが拒否するものを、いつ知るかが、開発者体験を分けます。同じエラーでも、気づく時点によって、コストがまったく違います。
- エディターで: スキーマをIDEに接続しておけば、フィールド名を間違えて書いた瞬間に、下線が引かれます。最も安上がりです。
- CIで: リポジトリの
catalog-info.yamlが変わったら、検証を動かします。マージの前に止まるので、間違ったものがそもそも入ってきません。 - カタログの収集のとき: すでにマージされたあとで失敗し、その事実は、ポータルのログにしか残りません。誰も見ません。
3つ目しか持っていない組織が大半で、それが、一覧が静かに古くなる理由です。検証をCIに移すのに必要なコストは、ほとんどありません。このラボで使うのと同じライブラリをスクリプトから呼び出し、失敗したら終了コードで知らせれば、終わりです。そして、そのスクリプトは、新しいリポジトリのテンプレートに一緒に入れておいてはじめて、あとで作られるリポジトリにも、自動でついていきます。
カタログが腐る仕組み
開発者ポータルが失敗する理由は、機能が足りないからではなく、一覧が現実とずれるからです。誰も信じない一覧は、誰も見なくなり、見ない一覧は、さらに速く古くなります。この悪循環が始まる場所は、いくつかに決まっています。
オーナーが空であるか、なくなったチームを指しています。組織再編があるとグループ名が変わるのに、エンティティはそのまま残ります。参照が壊れたエンティティは、画面で関係が切れたまま表示され、障害が起きたときに、誰に連絡すればよいかがわかりません。オーナーのないエンティティを定期的に数え、その数をメトリクスとして置くことが、最も安上がりな防御です。
サービスがなくなっても、項目は残ります。リポジトリを削除しても、カタログに最後に読み取った内容が残っていれば、存在しないサービスが、一覧に表示され続けます。元がなくなれば、項目もなくなるように、収集の方式を組む必要があり、手動で登録した項目は、特にこの問題から自由ではありません。
登録するだけで、誰も開きません。カタログが価値を持つには、その項目から、実際に必要なものへ行けなければなりません。ダッシュボード、オンコール担当、最近のデプロイ、ドキュメントです。このつながりがなければ、カタログは、名前とオーナーだけが書かれた表にとどまります。
そのため、成熟したチームは、カタログを検査の対象にします。必須フィールドが埋まっているか、オーナーが実在するグループか、ライフサイクルの値が決まったリストの中にあるかを、定期的に確認し、新しいリポジトリが作られるときに、テンプレートが正しいcatalog-info.yamlを一緒に入れるようにします。人が毎回手で書くようにしておくと、形式はそれぞれ違うものになり、その違いが積み重なると、一覧で何かを集計すること自体が、不可能になります。
実務で本当に大切なこと
知らないルートフィールドを拒否するポリシーを、必ず有効にします。specをspceと書いたタイプミスが通過すると、そのサービスは、ownerもlifecycleもないままカタログに入ります。登録は成功したのに、オーナーが空の項目が溜まることが、一覧が腐る最もよくある経路です。
参照の形式が厳格な理由は、それが関係のグラフだからです。owner: team-aはgroup:default/team-aを指す参照で、画面の「誰が所有し、何に依存しているか」は、すべてこのグラフをたどった結果です。参照が壊れると、関係がまるごと切れます。
設定のマージでは、配列はまるごと置き換えられます。スカラーはあとが勝ち、片側にだけあるキーは残りますが、配列だけルールが違います。環境ごとのファイルに配列を半分だけ書いておくと、前のファイルの項目がすべて消えます。
次のラボで、これらを本物のライブラリで、実際に拒否されながら確認します。