📘

歴史を知ることで変える勇気を持つADRのススメ

2022/01/18に公開

今回も技術的負債の話です。想定するシナリオは、次のものです。

「この設計イケてないと思うんだけれど、前の設計者の意図がわからないから多少おかしくなるけどとりあえず設計を崩さないように実装しよー。」

割とよくあるシチュエーションかと思います。根本的な原因は、次のものだと推測できます。

前の設計者が技術的に未熟だった
ドキュメントに実装意図が残ってないから前の実装者の意図がわからない

そのときにあるといいのがArchitecture Decision Recordsです。

Architecture Decision Recordsとはなにか?

ThoughtWorksのからの引用です。

ドキュメントの多くは、可読性の高いコードとテストで置き換えることができます。しかし、進化するアーキテクチャの世界では、将来のチームメンバーのためにも、また外部からの監視のためにも、特定の設計上の決定を記録することが重要です。Lightweight Architecture Decision Recordsは、重要なアーキテクチャ上の決定事項を、その背景や結果とともに記録するための手法である。これらの詳細をwikiやWebサイトではなく、ソースコントロールに保存することをお勧めします。ほとんどのプロジェクトでは、この手法を使わない理由はないでしょう。

https://www.thoughtworks.com/radar/techniques/lightweight-architecture-decision-records

引用した文脈からもわかるように、可読性の高いコードとテストでは担保できない文脈を補完するものがArchitecture Decision Recordsです。

なぜ設計の文脈を記録することが大切なのか?

冒頭でも説明したとおり現状の設計にある背景がわからないと、その設計がベストか判断できなかったり、その設計意図を勘違いして実装や修正が入ってしまうことがあります。

例えば、インフラ・ミドルウェアに関わる設計の場合は背景や影響範囲を完全に理解できてないとちょっとした設定のミスが大障害につながることがあります。

例えば、アプリケーションのアーキテクチャの場合は既存の設計にはないものをはじめて実装するときにその背景がわからないと変なところに実装してしまいそれが少しずつ積み重なって、技術的負債になることもあります。

上記の内容は時間をかけて調査して、なんとか過去の人の実装を読み取ったら解決する話でもあります。逆を言えば時間をかけないと解決できない問題でもあります。

新規で人が入ってくるたびに時間をかけてキャッチアップして、一年経ったら一人前になれるシステムであればヒトを入れれば入れるほど教育コストがかかってしまいます。そういった場合は、やめていく人も多かったりでいつまでも組織の開発力が上がらないものです。

またどんなつよつよエンジニアだったとしても、文脈がわかってない場合はその能力もうまく発揮できません。

そういったときに設計の決定のためのドキュメントがあることで調査コストや意思決定までの時間を短縮できます。

Architecture Decision Recordsの作成に時間がかかるのでは?

ADRを作るために必要な時間 > 他のヒトの作業効率の向上 になるようであれば本末転倒です。その他にも単純にちゃんとしたドキュメントを作れるほど時間が取れないというヒトもいるでしょう。

ただ、このADRはちょっとの時間さえ取れたらかけるくらいのシンプルなものです。なので、費用対効果も精神的な負担にもならないと考えています。

ADRとして書くべき項目数はおおくありません。

  • タイトル(Title)
  • コンテキスト(Context)
  • 決定(Decision)
  • ステータス(Status)
  • 結果(Consequences)

この5つのみです。

こちらにmarkdown式のテンプレートも記載しておきます。

https://github.com/peter-evans/lightweight-architecture-decision-records/blob/master/0001-ladr-template.md

実際にどんなことについて書くべきかについて実際の現実世界の例をもとに見ていきましょう。

イギリス政府関連(GOV.UK)のサイトのADR

こちらは、インフラのアーキテクチャや技術選定についてまとめられたADRです。

https://github.com/alphagov/govuk-aws

このなかからNo.10のterraform のディレクトリ構成について引っ張ってきてみましょう。

https://github.com/alphagov/govuk-aws/blob/master/docs/architecture/decisions/0010-terraform-directory-structure.md

Title

  1. Terraform directory structure

Status

Accepted

Context

最初からTerraformのディレクトリ構造を統一しておく必要があります。

いくつかの初期要件があります。

  • コードとデータを分離し、将来的には実装の詳細を開示せずにコードをオープンソース化し、データはプライベートなGithubリポジトリに保管することができるようにしたい。
  • リポジトリ内のセンシティブなデータを暗号化できるようにしたい:センシティブなデータの暗号化を同じプロセスの一部としてサポートし、別のリポジトリや別のスクリプトなどで秘密を管理する必要がないようにしたい。
  • Terraformのモジュールを作成してコードを再利用したい
  • Terraformのコードを異なるプロジェクトに分け、それぞれがインフラ層やアプリケーションスタックを管理するようにしたい。これは、GOV.UKアプリケーション間でリソースを分けるために特に重要です。

Decision

初期のソリューションでは、data、modules、projectsの3つのディレクトリがあります。

  • dataディレクトリには、Terraformプロジェクトごとのサブディレクトリがあり、環境ごとにカスタマイズ可能な変数値を格納しています。
    データディレクトリには、機密データを「sops」で暗号化した_secretsファイルも含まれています。
  • modulesディレクトリには、Terraformのプロバイダごとのサブディレクトリがあります。
  • projectsディレクトリには、Terraformのスタック/ティアが格納されます。
  • プロジェクトは以下のような名前になります。
    共通のインフラを展開するプロジェクトには、govukというプレフィックスをつけます(例:ネットワーク、DNSゾーン)。
    アプリケーション(またはアプリケーション群)をデプロイするプロジェクトには、appというプレフィックスをつけます(例:frontend, puppetmaster)。
├── data
│   ├── base
│   │   ├── common.tfvars
│   │   └── integration.tfvars
│   └── my-application
│       ├── common.tfvars
│       ├── integration.tfvars
│       └── integration_secrets.json
├── modules
│   └── aws
│       ├── route53_zone
│       │   └──  ...
│       ├── mysql_database_instance
│       │   ├── ...
│       └── network
│           └── ...
└── projects
    ├── base
    │   ├── integration.backend
    │   ├── main.tf
    │   └── variables.tf
    └── my-application
        ├── integration.backend
        ├── main.tf
        └── variables.tf

Consequences

前述のようにシークレットを管理する場合、実行時にシークレットファイルを復号化し、Terraformコマンドの実行後に暗号化されていないファイルをクリーンアップする必要があります。

この設定では、プロジェクトを初期化するディレクトリに依存するTerraformスタックのモジュールをインポートするために相対パスが必要になります。モジュールを使いこなせるようになったら、Githubリポジトリに登録してTerraformスタックからURL経由でソースを取得できるようにすることを検討する必要があります。

書き方のまとめ

  • タイトルはシンプルで一つの物事に対してのみ決定であることがわかるように記載します。
  • ステータスはそれが採用されたのかどうかについて記載します。[Proposed, Accepted, Deprecated, Superseded]の中から状態を選びます。
  • コンテキストは、何をしたいのかや意思決定に影響を与えるものを書き出します。
  • 決定は、文脈に対してどのような設計をするのか具体的に記載します。
  • 結果は、採用した結果どのような事が起きたのかや懸念点などを記載します。

とはいえ、どこに何を書くのかについては、あくまでも設計の背景や文脈をつたえることができたらいいので細かくこだわることはないと思います。

まとめ

ADRを作成して設計の背景にある文脈を共有しましょう。それによって得られる時間的メリットは凄まじいものでしょう。またADR自体も簡単に作成できるものであるので、作成者の負担にはならないと思います。

ADRをのこしすことで、スケールする開発組織を作り上げることの手助けになるのではないでしょうか?

Discussion

ログインするとコメントできます