YAMLで書くC4モデル:archyl.yamlのフォーマットとGitワークフロー

アーキテクチャ図には賞味期限の問題があります。設計セッションの後に描き、1週間は見栄えが良いのですが、コードが進化するあいだに図は腐っていきます。半年後、新しく入ったメンバーが見つめるContainer図には、第2四半期に統合された3つのサービスが載っていて、第3四半期に作られた2つのサービスは載っていません。

Archylは創業当初からこの問題に取り組んできました。AI発見は情報を新鮮に保つのに役立ちます。ビジュアルエディタは更新を苦にならないものにします。けれども、インフラをコードとして、ポリシーをコードとして、あらゆるものをコードとして扱うチームは、もっと根本的なものを求めていました。

彼らは、アーキテクチャがそれを記述するコードの隣、つまりGitの中に置かれることを望んでいました。今日リリースするのは、まさにそれです。

この記事は、ファイルそのもののリファレンスです。何を書くのか、参照がどう解決されるのか、どう同期されるのか。Architecture as Code全般の意義や、Structurizr DSLのような他のフォーマットとの比較については、Architecture as Codeガイドをお読みください。

archyl.yaml とは?

アーキテクチャ全体を宣言的に記述する、単一のYAMLファイルです。リポジトリのルートに置けば、ArchylにおけるC4モデルの信頼できる唯一の情報源になります。

最小限のファイルは次のようになります。

version: "1.0"

project:
  name: "My Platform"
  description: "Microservices architecture"

systems:
  - name: Platform
    type: software_system
    containers:
      - name: API Gateway
        type: api
        technologies: [Go, gRPC]
      - name: User Database
        type: database
        technologies: [PostgreSQL]

relationships:
  - from: API Gateway
    to: User Database
    label: "Reads user data"
    type: reads_from

これだけです。Archylはこのファイルを読み込み、C4モデル全体を構築し、ダイアグラムをレンダリングし、すべてを同期し続けます。UIをクリックして回る必要も、手作業での同期も、「図の更新を忘れていた」もありません。

トップレベルキー

キー 内容
version フォーマットのバージョン。現在は "1.0"
project プロジェクト名と説明
technologies 要素が参照するテクノロジーカタログ
environments ステージングや本番などのデプロイ環境
systems システム。その中にコンテナ、コンポーネント、コード要素がネストされる
relationships 任意の2つの要素間の接続。名前またはドット記法のパスで指定
overlays ダイアグラム上の名前付きのビジュアルグループ
events Kafkaトピックなどのイベントチャネル。プロデューサーとコンシューマー付き
api_contracts OpenAPI、gRPCなどの仕様。それを公開する要素にリンクされる
releases リリースと、それがデプロイしたもの
adrs インラインのADR、またはリポジトリ内のADRフォルダ
docs プロジェクトのドキュメント。インラインまたはフォルダから
include マージする他の archyl.yaml ファイル。モノレポ向け

トップレベルで必須なのは version だけです。それ以外はすべて任意なので、ファイルは1つのシステムから始めて育てていけます。

すべてを1つのファイルに

このDSLは簡略化されたサブセットではありません。Archylでモデリングできるものの全範囲をカバーしています。

C4の4つのレベルすべて。 システムはコンテナを含み、コンテナはコンポーネントを含み、コンポーネントはコード要素を含みます。YAMLのネストがそのまま階層を表します。

ドット記法による関係。 Payment Service.API Gateway → Payment Service.Database のような読みやすい参照で、任意の2つの要素をつなげます。UUIDも暗号めいた識別子もありません。grepでき、差分に強く、人間が読めます。

テクノロジー、環境、リリース。 テクノロジーカタログを定義し、デプロイ環境(ステージング、本番)を宣言し、リリースを追跡します。すべて同じファイルからです。

ADRとドキュメント。 アーキテクチャ決定記録をインラインで書くことも、リポジトリ内のフォルダを指定することもできます。プロジェクトのドキュメントも同様です。

APIコントラクトとイベントチャネル。 OpenAPI仕様、gRPC定義、Kafkaトピックを宣言し、それを公開または消費するコンポーネントにリンクします。

ビジュアルオーバーレイ。 名前付きのオーバーレイでダイアグラム上の要素をグループ化し、色とレベルを制御します。

モノレポ対応。 include を使えば、アーキテクチャを複数のファイル(サービス、チーム、境界づけられたコンテキストごとに1つ)に分割でき、Archylがそれらを自動的にマージします。

なぜYAMLなのか?

独自のDSL構文(StructurizrのDSLやTerraformのHCLのようなもの)を作ることも検討しました。YAMLを選んだのは実用的な理由からです。

  1. 学習コストがゼロ。 開発者なら誰でもYAMLを知っています。新しい構文を学ぶ必要も、パーサーをインストールする必要も、エディタのプラグインも要りません。

  2. IDEサポートが無料で手に入る。 /api/v1/dsl/schema でJSON Schemaを公開しています。IDEにそれを指定すれば、Archyl専用のツールなしで、補完、バリデーション、インラインドキュメントが得られます。

  3. 差分に強い。 YAMLの差分はプルリクエストの中でもきれいで読みやすいです。レビュアーは「ああ、Payment Serviceに新しいコンテナを追加してRedisにつないだんだな」とすぐにわかります。

  4. ツールのエコシステム。 リンター、フォーマッター、テンプレートエンジン(Helm、Kustomize)が、YAMLならそのまま使えます。

Gitネイティブなワークフロー

本当の威力はここにあります。archyl.yaml はリポジトリにあるので、アーキテクチャの変更はコードの変更と同じワークフローに従います。

  1. ブランチ。 フィーチャーブランチを作り、YAMLを編集します。
  2. レビュー。 プルリクエストを開きます。チームはコードの変更と一緒にアーキテクチャの変更もレビューします。
  3. マージ。 承認されたら、mainにマージします。
  4. 同期。 Archylが変更を取り込み、ダイアグラムを自動的に更新します。

「図ではXなのにコードはYをしている」はもうありません。レビューを経ないアーキテクチャの変更も、更新されたことを誰も知らないドキュメントもなくなります。

CI/CD統合

CI/CDパイプラインとのファーストクラスの統合を作りました。GitHub向けには、ファイルの読み込み、APIの呼び出し、変更内容のレポートまで、すべてを処理する公式のGitHub Actionを提供しています。

GitHub Actions(公式アクション):

name: Sync Architecture
on:
  push:
    branches: [main]
    paths: ['archyl.yaml']
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: archyl-com/actions/sync@v1
        with:
          api-key: ${{ secrets.ARCHYL_API_KEY }}
          project-id: 'your-project-uuid'

これだけです。3行の設定で、プッシュのたびにアーキテクチャが同期されます。このアクションは、カスタムのファイルパス(モノレポ向け)やセルフホストのArchylインスタンスに対応し、後続のステップ向けに summary、systems-created、relationships-created などの出力を公開しています。

GitLab CI:

sync-architecture:
  stage: deploy
  script:
    - |
      curl -X POST \
        https://api.archyl.com/api/v1/projects/$ARCHYL_PROJECT_ID/dsl/ingest \
        -H "X-API-Key: $ARCHYL_API_KEY" \
        -H "Content-Type: application/json" \
        -d "{\"content\": \"$(cat archyl.yaml | jq -Rs .)\"}"
  only:
    changes:
      - archyl.yaml

/ingest エンドポイントはAPIキー認証を受け付けるので、CIでOAuthフローは不要です。モデル全体をインポートし、すべての要素を作成または更新し、何が変わったかの詳細なサマリーを返します。

ArchylのUIから直接同期することもできます。プロジェクトにGitリポジトリが接続されていれば、Architecture as Codeの設定で「Sync Now」を押すだけで、Archylがリポジトリから直接ファイルを取得します。

双方向:エクスポートとインポート

ワークフローは一方通行ではありません。すでにArchylのビジュアルエディタでモデリングしたプロジェクトがありますか? エクスポートしましょう。

  • Export は、現在のモデルから完全な archyl.yaml を生成します。すべてのシステム、コンテナ、コンポーネント、関係、オーバーレイ、ADR、APIコントラクト、イベントチャネル、リリースが、きれいなYAMLにシリアライズされます。
  • Import は archyl.yaml を解析し、プロジェクト内のすべての要素を作成または更新します。冪等なので、同じファイルを2回インポートしても重複は生まれません。要素は名前で照合され、アップサートされます。
  • Import as Project は、YAMLファイルからまったく新しいプロジェクトを作成します。archyl.yaml を置けば、ワンクリックで内容が揃ったプロジェクトが手に入ります。

つまり、UIから始めてYAMLにエクスポートし、Gitにコミットしてコードファーストのワークフローに切り替えることも、その逆も可能です。どちらのアプローチにもロックインされません。

スマートな参照解決

DSLで最も厄介な部分の1つが、関係、オーバーレイ、イベント、APIコントラクトにおける要素参照の解決です。私たちはこれを自然に扱えるリゾルバーを作りました。

  • 短い名前は、曖昧でなければそのまま使えます。その名前を持つ要素が1つしかなければ、API Gateway は直接解決されます。
  • ドット記法で曖昧さを解消します。Payment Service.API Gateway と Analytics.API Gateway のように。
  • 任意の深さに対応します。深くネストされた参照には System.Container.Component.CodeElement のように書けます。

リゾルバーはすべての要素をあらゆる深さのパスでインデックス化するので、常に曖昧さのない最短の参照を使えます。エクスポートも同じロジックを逆方向に使い、できるだけ読みやすい参照を生成します。

副作用のないバリデーション

YAMLが正しいか自信がない? /validate エンドポイント(とインポートモーダルの「Validate」ボタン)は、データベースに触れずにファイルを解析・チェックします。

  • スキーマバージョンのチェック
  • 必須フィールドのバリデーション
  • 重複した名前の検出
  • 型の列挙値のバリデーション(コンテナタイプ、関係タイプなど)
  • 相互参照の解決

エラーは正確なパス(systems[2].containers[1].name)と明確なメッセージとともに返されます。pre-commitフックやCIのチェックに組み込めば、mainに届く前に問題を捕まえられます。

実践的なパターン

モノレポ

# Root archyl.yaml
version: "1.0"
project:
  name: "Our Platform"
include:
  - services/payments/archyl.yaml
  - services/users/archyl.yaml
  - services/notifications/archyl.yaml

各サービスは、自分のコンテナとコンポーネントを定義する独自の archyl.yaml を保守します。ルートのファイルがそれらをマージし、サービスをまたぐ関係はルートレベルで定義します。テクノロジーと環境は自動的に重複排除されます。

ブートストラップ

新しいプロジェクトを始めるなら、コードを書く前に archyl.yaml を作りましょう。作る予定のシステムとコンテナを定義し、Archylの「Import as Project」でアーキテクチャを即座に生成します。開発が進むにつれ、YAMLもコードとともに進化します。

監査証跡

YAMLはGitにあるので、完全な履歴が無料で手に入ります。git log archyl.yaml を実行すれば、すべてのアーキテクチャ変更、それを行った人、日時、そして議論が行われたPRがわかります。作図ツールで同じことをやろうとしてみてください。

ドキュメントジェネレーター

アーキテクチャをYAMLにエクスポートし、任意のテンプレートエンジンに通せば、Markdownのドキュメント、Confluenceのページ、社内Wikiを生成できます。構造化されたフォーマットなので、自動化はごく簡単です。

今後の予定

これはDSLフォーマットのバージョン1.0です。次に取り組んでいるのは以下です。

ドリフト検出。 リポジトリ内のYAMLとライブのモデルを比較し、差分をハイライトします。UIで追加されたがファイルにはない要素、あるいはその逆です。

PRプレビューコメント。 PRが archyl.yaml を変更すると、ボットがアーキテクチャで何が変わったかをビジュアルな差分でコメントします。

スキーマの進化。 Archylに新機能が加わるにつれ、DSLも成長します。後方互換性を保ち、移行ツールを提供します。

今すぐ試す

Architecture as Codeは、今日からArchylのすべてのプランで利用できます。すでにプロジェクトがあるなら:

  1. プロジェクトのArchitecture as Codeページに移動します
  2. Exportをクリックして archyl.yaml を生成します
  3. リポジトリにコミットします
  4. 公式のGitHub Actionをワークフローに追加すれば完了です

ゼロから始めるなら、archyl.yaml を作ってImport as Projectを使えば、数秒で完全にレンダリングされたC4アーキテクチャが手に入ります。

アーキテクチャにも、コードと同じ厳密さがふさわしい。バージョン管理し、レビューし、自動化しましょう。


C4が初めてですか? C4モデルガイドから始めましょう。最初のアーキテクチャをAIに生成させたいなら、AI駆動のアーキテクチャ発見をご覧ください。すでにAIアシスタントを使っているなら、MCPサーバーで接続しましょう。