拡張ポイントを言語境界で開けるのは第三の選択肢である
「言語が決める」か「規約に委ねる」かという二択の外側に、拡張ポイントを言語境界で開けるという第三の選択肢がある。Crossplane Compositionsがその実例で、PulumiのMLC (multi-language components)も類似の発想にある。
CrossplaneはKubernetes API上に構築された二層IaCとして読める。
- YAML層は宣言的に閉じている — KubernetesリソースとしてCRUD可能、kubectlで操作でき、kustomizeやHelmと組み合わせられる
- function層に拡張性を全部押し付ける — パッチ変換・命名規則・複雑なロジックはfunction側で書く。functionはOCIイメージとして配布され、複数言語で書ける
- Composition Selector — XRのlabelに応じて適用Compositionを動的に選択でき、環境別(dev/staging/prod)に別Compositionを使い分けられる。これはTerraform / Bicep / Carinaにはない動的選択軸
この設計は「外部DSL × 言語が決める」象限と「汎用言語 × 規約に委ねる」象限の両方に同時に足を置く。BicepのfuncやCarinaのfnが言語内蔵の拡張機構であるのに対し、Crossplaneはツールチェーン全体で多言語を許容するという設計判断を取っている。「functionを組み込めば任意のDSL/汎用言語の特性を取り込める」という形で、拡張性の所在を言語の外に置く。
代償も明確である。得たのはKubernetes API上の宣言性、functionによる任意言語拡張、Composition Selectorによる環境切替。失ったのは全体像の見通し(YAML + functionコード + XRDの三者を読む必要がある)、デバッグの複雑化(function chainのどこで何が起きたか)、そしてtype safetyの弱さ(YAMLレイヤの型は動的)である。