某社SREとしての1年間

これはSRE Advent Calendar 20195日目の記事です.

一昨日、6Vメタモンを入手することができてホクホク顔の@corrupt952です.

技術的なことは他の方が書いてくれると思うので、某社SREとして過ごしてきた約1年間の話を簡潔に書きます.
SREに興味ある人や某社SREに興味ある人の参考になれば幸いです.

某社SREになった経緯

前職はソフトウェアエンジニアとしてSIerで働いていました.
私がSREになった理由は、「転職しました」に書いてある

自分に足りない知識を身につけ、自分の知識を元に挑戦したいという思いがありました.

を実現するための手段としてSREにチャレンジしてみたかったからでした.

SREやインフラに興味を持ったきっかけは @f440@yoppiの3人でISUCON5に出たのがきっかけでした.
あの時は結果として予選落ちだったのですが、自分にとってはアプリケーションを動かすために速く動かすために、アプリケーションコードだけでなくサービスアーキテクチャやインフラ側により目を向けていたので良いきっかけになりました.

そういった経緯もあって声をかけてもらった某社にSREとして入社することを決めました.

そもそもSREって何?

これに関してはネットに情報が溢れているので割愛しますが、各社によって実際の役割や責務が異なります.

某社におけるSREは以下の役割を持っています.

  • サービスの環境構築・運用
  • サービスの可用性・パフォーマンスの維持・向上
  • 障害対応
  • CI/CD整備
  • 開発環境の整備
  • パフォーマンスに懸念があるロジックのレビューや改善
  • セキュリティの担保
  • ログ収集・分析基盤の構築・運用
  • 中長期を見据えたアーキテクチャや基盤を先回りして検討や設計 

などがあります. ※1
これだけ見ると、インフラエンジニアと言われる職種に他の役割を足したように見えますよね.

プライベートでやってきたこと

プライベートではこれといって活動をしてはいません.
強いてやっていることは、

  • 読書
  • 情報収集

の2つです.

技術書や技術書に限らず、気になる本やいずれ必要になりそうな本を空き時間に消化しています.
これは持論なんですが、「本に答えを求めておらず、読んだ内容を元に自分なりに咀嚼し解釈、背景の想像・理解、現実への適用方法、代替方法の模索・検討、他の技術・概念との関係性を考えるために読む」というのを意識して本を読んでいます.

業務としてやってきたこと

参考にはなるかは分かりませんが、当たり障りのない範囲で業務としてやってきたことを書きます.

  • 組織内の開発環境整備
  • 新サービスの設計、構築、CI/CD整備
  • バックアップ設計、開発、構築
  • 監視基盤設計・見直し・実装
  • 不要なリソースの洗い出しや削除
  • コンテナ推進
  • Infrastructure as a Code推進
  • SRE Office Hoursの開催
  • 社内勉強会でのLT
  • 技術書の輪読

それぞれの業務について概要を書きたいですが、長くなるのでいくつかピックアップします.

コンテナが最適解だとは思いませんが、コンテナ技術を導入することで効率が良くなったり、楽ができると判断したため開発環境の整備やコンテナ推進を進めています.
The Twelve-Factor Appをベースにしたチェックリストを作りましたも推進に向けて、プライベートの時間で自分なりに解釈した結果を書いていました.
実際の業務ではこれを組織に落とし込んで、各サービスレベルで落とし込んで作業をしています.

某社のSREは役割が多岐に渡るため、組織が急激に成長するといつか破綻してしまうというリスクがありました.
そういったリスクに対して事前に対策を打つための1手段として、SREが持っている知識や経験則を共有、SREと一緒に悩む場として「SRE Office Hours」という活動を毎週金曜日に枠を設けて実施しています.
この活動はマイクロサービスについて何でも聞けるOffice Hoursに参加したよ! #メルカリな日々に影響を受けて企画し、今も開催し続けています. ※2
技術書の輪読もそういった活動の一環で、「仕組みはどうなっているのか」「弊社ではどうなのか」「これを改善していけるのではないか」といった疑問を持つきっかけだったり、議論をする場として活動しています.
社内勉強会のLT枠でも、SREが持っている知識を共有する場の1つとして利用させてもらっています.

最後に

技術的な話が皆無で申し訳ないですが、某社SREとして1年間やってきたことを書きました.
ぶっちゃけスキルの範囲が広いし、やることは尽きないし、障害対応もしなきゃないし大変な仕事ではあります.
裏を返せば「自分に足りない知識を身につけ、自分の知識を元に挑戦したい」を達成することができる仕事で面白いと個人的には思います.

興味があるかたは是非SREにチャレンジしてみてください.

次はfnaotoさんが6日目の記事を書くようですね. 楽しみです!

※1 全てをSREがやっているわけではなく他チームと協力してやっている業務もあります
※2 この活動の具体的な内容について気になる人は、12/11公開予定の某社アドベントカレンダーの記事を見てくれるとうれしいです

InkdropからBoostnoteに乗り換えた

1年半程度はInkdropでブログの下書き・メモ・議事録の下書きをしてきましたが、
Inkdropである必要がなくなってきたので一旦Inkdropを解約してBoostnoteに乗り換えました.

メモ書きツールに求めるモノ

khasegawa.hatenablog.com

以前書いた記事をベースにメモ書きツールに求めるモノがどう変化したのかをまとめてみます.

太字の項目が今回追加された求めるモノです.
欲張りですね.

複数のプラットフォーム間でデータを共有できること

マルチプラットフォームで動作することは大事ですが、データが共有されることも重要です.
同期速度が速いことが理想ですが、起動してネットワークに接続し、自動起動されるアプリケーションが起動し終わる頃に同期が終了していれば問題ありません.

キーバインドVimライクにできること

エンジニアとしてアルバイトをしている時から、開発するときにはVimもしくはNeovimを使っています.
そのため、メモツールでもできる限り同じ操作ができることが望ましいです.

何故、InkdropからBoostnoteへ変えたのか

まずは「何故、Inkdropをやめたのか」について書きます.
積極的な理由はなかったのですが、既に私が利用しているツールやサービスとOSSなツールで組み合わせて使える他の手段がないか?を模索していた結果、「一旦Inkdropを使うのをやめてみよう」と思うに至りました

次に「何故、Boostnoteを選んだのか」について書きます.
私のメモ書きツールに求めるモノを満たすのは、私が観測している範囲ではInkdropのみです.
では何故、Boostnoteにしたのか?という点が疑問になるはずですが、Boostnoteがどれだけ要求事項を満たしているかを書くにしてみましょう.

「複数のプラットフォーム間でデータを共有できること」以外は満たしていることになるため、何らかの形でデータを共有できれば全ての要求事項を満たすことができます.
Boostnoteでは、Cloud Syncing and Backupというページが公式から用意されており、DropboxGoogle Driveの共有フォルダを使うように書いてありました.
今回はそれに則ってGoogle Driveを利用して同期し、「複数のプラットフォーム間でデータを共有できること」を満たすようにしてみます.

Google Driveを使って同期する

Google Driveを手元のPCと同期させるには、バックアップと同期ドライブファイルストリームと2種類のやり方が存在します.
それぞれの違いについては、Googleドライブヘルプのバックアップと同期、ドライブ ファイル ストリームの違いを参照してください.

ここでは、今回の利用用途で関係ありそうな箇所を抜粋しました.

バックアップと同期 ドライブファイルストリーム
マイドライブ内のファイルを使用する
マイドライブ内の選択したフォルダのみを同期する
マイドライブの個別のファイルのみを同期する 不可
個人の Google アカウントで使用する 不可

これら2つの違いは、「個別ファイルの同期の可否」と「個人のGoogleアカウントでの利用可否」になりそうですね.
私の利用用途で考えると、Boostnote用のディレクトリのみを個別に同期したいですし、GSuiteを個人契約しているため、ドライブファイルストリームを使うのが良さそうです.

ドライブファイルストーリムを導入するを参考に導入し、Boostnote用のディレクトリ作成します.
後はそのディレクトリを同期すれば準備は完了です.

f:id:corrupt952:20210131110408j:plain

Boostnote with DFSの導入自体は非常に簡単でした.

Boostnoteに乗り換えて良かったこと・不満に感じていること

導入し実際に使ってみて以下の項目は良かったと感じました.

  • 1つのスニペットで複数のファイルを定義できる
  • Inkdropよりも軽快に感じる
  • GSuiteを契約していれば別途利用料金は発生しない

しかし、Boostnoteに乗り換えてみて良かったことばかりではありません.
以下の項目は導入してみて多少なりとも不満に感じている項目です.

最後に

久しぶりに自分のメモツールについて見直しました.
改めて振り返ると自分の求めているモノを言語化する必要性を感じます.

Boostnoteに乗り換えて良かったことが私が想定していたよりも少なかったですが、Inkdropの時と比べて不便というのは感じていません.
そのため、正直InkdropかBoostnoteかはたまた別のエディタなのかは、個人の求めるモノによって大きく変わりそうです.

また近いうちに変更しそうですが、今年度はBoostnoteでメモを書いてみようと思います.

The Twelve-Factor Appをベースにしたチェックリストを作りました

最近の仕事では、コンテナ化を推進しています.
あるサービスをコンテナ化するにあたって、参考にされるのはThe Twelve-Factor Appですが、原文でも邦訳でも各項目の解釈しづらいです.
そこでもう少し抽象度を下げたチェックリストを書きました.

Containerization checklist

作成したチェックリストは以下になりますが、Gistでも公開しているのでそちらを参照するのが良いと思います.

Codebase

  • [ ] Codebaseとアプリケーションは1対1であること
    • アプリケーション≠サービス
    • 複数のCodebaseから1つのアプリケーションが作られる場合はパイプラインが複雑になってしまうため
    • Configが異なる環境が複数あるのはアプリケーションが複数あるのではなく、デプロイが複数あると解釈する
  • [ ] 1つのCodebaseから複数の環境で実行可能な状態であること
    • ただし環境ごとに異なる設定についてはここでは触れない

Dependencies

システム側にインストールされるパッケージのことを、便宜上Site packagesと呼ぶ.
また、システム側にインストールされないGemなどのパッケージのことを、便宜上Vendoringと呼ぶ.

  • [ ] アプリケーションの実行に必要なSite packagesは、開発・テスト・ステージング・本番で利用される共通コンテナイメージでインストールしていること
    • libmysql-clientやimagemagickなどのパッケージのこと
  • [ ] アプリケーションから外部コマンドを実行しないこと
    • Rubyの場合、systemメソッドなどで外部コマンドを実行するのが該当する
  • [ ] アプリケーションの実行に必要なVendoringは、Gemfileなどのファイルに定義していること
  • [ ] アプリケーションの実行に必要なVendoringは、ステージング・本番向けのコンテナイメージにはインストールしていること

Config

Config

  • データベースなどのバックエンドサービスへの接続情報
  • AWSTwitterなどの外部サービスの認証情報
  • ホスト名や環境ごとに異なる値

のようなものを指す.

  • [ ] 環境によって異なる設定ファイルを定義しないこと
    • Frameworkなどが提供する設定ファイル(config/environments/test.rbなど)は対象外とする
  • [ ] 環境によって異なる設定値は環境変数で上書き可能な状態であること
  • [ ] 認証情報などのセンシティブな設定値はCodebaseに含めないこと
    • 「開発・テストでしか使わない情報」かつ「ステージング・本番で使う情報と異なる」場合はCodebaseに含めても良い

Backing services

Backing servicesは、アプリケーションがネットワーク越しに利用する全てのサービスやアプリケーションを指す.

  • [ ] 環境によって異なる接続先であっても、Codebaseを変更せず環境変数の変更のみで切替えられること

Build, Release, Run

  • [ ] デプロイメントパイプラインは、Build, Relase, Runの3つのステージに分離していること
    • [ ] Build ... アプリケーションが実行可能なコンテナイメージにビルドされること
    • [ ] Release ... コンテナイメージをRegistryにアップロードし、k8sのManifestやECSのTask Definitionが生成していること
    • [ ] Run ... Releaseで生成されたManifestなどを元にアプリケーションが実行されること
  • [ ] 全てのReleaseは一意のIDから特定できること
    • 連番やタイムスタンプなど一意に特定できれば良い

Processes

  • [ ] アプリケーションはステートレスであること
    • 例)セッション情報をオンメモリに保存しない
  • [ ] アプリケーションが何らかのステートを持つ場合は、ステートフルなBacking servicesに保存していること

Port binding

  • [ ] アプリケーションは単体でポートを公開し、サービスとして動作すること

Concurrency

  • [ ] 水平スケール可能なアプリケーションになっていること
    • Processesが守られていればこちらも守られているといえる

Disposability

  • [ ] SIGTERMシグナルが送られたプロセスはグレースフルに終了すること
    • [ ] Webプロセスの場合は、新規にリクエストを受け付けず、決められた時間内にレスポンスを返すこと
    • [ ] Workerプロセスの場合は、決められた時間内にジョブを完了させるか、ジョブのロックを解除し終了すること

Dev/prod parity

  • [ ] 開発・ステージング・本番で動作する環境はできる限り同一であること
    • できる限りはチーム内で合意を取り進める
  • [ ] アプリケーション開発者がステージング・本番環境へデプロイ可能であること

Logs

  • [ ] ログ収集の仕組みに乗せないログは、stdout,stderrに出力していること
  • [ ] ログ収集の仕組みに乗せるログは、チームで合意をとった方法で出力していること

Admin processes

Ruby on Railsならrails db:migrateAdmin processesに該当する.

  • [ ] 一度のみ実行されるようなAdmin processesはデプロイパイプラインに組み込まれていること
  • [ ] Admin processesで実行されるスクリプトやコードは、アプリケーションと同じコードベースで管理していること

さいごに

The Twelve-Factor Appをベースにチェックリストを作りましたが、本番環境で動作させるためにはまだまだ足りないです.
また今回は抽象度を少し下げましたが、各サービス固有のドメインについてのチェックリストまでには触れていません.
仕事で必要になる度にアウトプットをある程度まとめていくために

aws ssm start-sessionのラッパースクリプトを書きました

最近はsshではなくsession-manager-plguinを使い、Session Manager経由でインスタンス上で操作を行っています. ただsession-manager-pluginを使って接続する時はインスタンスIDを毎回指定するのが面倒だったので、
インスタンスIDの代わりにインスタンス名を選択すれば良くなるラッパースクリプトを作りました.

何故、Session Managerを使うの?

そもそも何故、Session Managerを使うの?と疑問に思う方もいるので
Session Managerとsshを比べた時のPros/Consを書いておきます.

Pros

  • (AWS上に)証跡を残すことができる
  • インスタンスへ接続するための鍵管理をしなくてよい
  • インスタンスへの接続制限をIAMポリシーで定義できる
  • ssh用のインバウンド通信を許可しなくてよい
  • どうしてもssh使いたい場合はSession Manager経由でsshも可能

Cons

  • sshを利用するコマンドが愚直には使えない(scp)
  • ブラウザ版を使っているとレスポンスが悪いときがある
  • 接続後にログインシェルを起動しないとコマンド履歴が残らない
  • インスタンス自身が外部と通信できるようにしなければならない(Public IPの割当やNat Gateway

と個人的には感じています.
そのため、「開発をする想定でなければ事足りる」という判断で、Session Managerを使っています.
IAMとは別に接続用の鍵を管理するのはできればやりたくないです. ※1

ssm-session

このように事前にインスタンスIDを控えておく必要があるため、接続することになった時にリズムが崩れてしまいます.
私は開発でもオペレーションでもリズムを重視しているので、これは看過できません.
というわけでこれのラッパースクリプトを書きました.

github.com

シンプルなラッパースクリプトなので難しいことはしていません.

  1. インスタンス一覧を取得
  2. 取得した情報からインスタンス名とインスタンスIDのみを切り出す
  3. 2で切り出した情報をfzfで1つ選択する
  4. 選択したインスタンスaws ssm start-sessionを行う

といった一連の操作をパイプで繋げるだけの簡単なスクリプトになっています.
使い方としては

ssm-session start

を実行すれば起動しているインスタンス一覧が出てくるのは、接続したいインスタンスを選択すれば後は接続してくれます.
大分お手軽になりました.

さいごに

今の所SSMの中でもSession Managerしか使っていないため、Documentを実行する時がきたら、名前やコマンドを見直すかもしれません.
また引数でインスタンスIDを受け取ったり、インスタンス名とインスタンスID以外の情報を出せるようにするかもしれません.

※1 EC2 Instance Connectでも十分ですが、ユースケースに応じて選択すればよいと思います.

ゼロトラスト超入門

同僚でもあるおかしんさんが技術書典で出していたゼロトラスト超入門を読んだ.

第1章 ゼロトラストとは

過去と比べてシステムの多様化が進んでおり、従来の境界モデルでの防御方法では現代におけるシステム利用やリスクへの対処として適切ではなくなってきた.
境界モデルの場合、ゾーン外からのトラフィックへの防御は優れているが、ゾーン内からのトラフィックはおざなりになりやすい.
ゼロトラストという考え方は、この課題に対してどう取り組むのかといったセキュリティ戦略である.
ゼロトラストでは以下の5つの考え方から構成されている.

ネットワークは常に敵意にさらされているとみなす 常に外部と内部の驚異が存在する ローカネットワークであることは、ネットワークを信頼するための条件として十分でない 全てのデバイス、ユーザー、およびネットワークフローが認証および承認されていること ポリシはー動的で、できるだけ多くのデータソースから決定されていること

※ ゼロトラスト入門から引用

所感

これはプライベートでも仕事でも普段から抱えていた問題をうまく言語してくれた内容だと思った.
故意・過失に関わらず、どうしてもインシデントというものは大なり小なり発生してしまう.
であれば、どうやってそれを最小に防ぐのか?ということを考える必要があって、このゼロトラストという考え方は非常にしっくりときた.

第2章 境界モデルの歴史

ネットワークの進化に伴って、境界モデルは生まれ進化してきた.
そして攻撃手法もより進化しており、境界モデルではそれに耐えられなくなったきた.

所感

改めて歴史を振り返れたのは面白かった.
脅威の進化の下りで書かれているのは攻撃手法の歴史でもあり、共感しながら読み進めた.
ここは知ってる人は飛ばしても良い内容かもしれない.

第3章 境界モデルの脆弱性

境界モデルは外部から内部への直接的な攻撃を防ぐことはできるが、内部へ何らかの方法でマルウェアなどが侵入できた場合は、非常に脆い.(メールの添付ファイルなど)

所感

攻撃手法にイメージがつかない人でも理解しやすいのではないのかな、と思いながら読み進めた.
実際流れも良く、事例も載っていてよかった.

第4章 境界モデルからゼロトラストへ

ゼロトラストモデルは境界モデルとは異なるアーキテクチャで構成される.
コントロールプレーンによってクライアントが認証・承認が行われ、それに基づきデータプレーンに対してクライアントからのアクセスを動的に設定する.
ユーザー認証、デバイス認証、信頼度に基づいて動的にポリシーが設定される.

所感

ゼロトラストモデルのアーキテクチャが載っており理解しやすかったように思う.
俺がゼロトラストを適用したいのは、それこそ自宅のネットワークだったり、サービス開発・運用をするネットワークに対してだ.
正直これを実現するのは今だと少し難しいという印象.
とはいえ方向性が見えた.

第5章 Googleのゼロトラスト(BeyondCorp)

Googleではゼロトラストの考え方を取り入れたBeyondCorpというセキュリティモデルがある.
バイスやユーザーのセキュアな識別が可能な仕組みを用意し、ネットワークにおける信頼を排除を行う.
アクセスレベルは時間とともに変化する可能性があり、アクセスコントロールはこれを複数のデータソースから動的に推測することが求めらる.
またBeyondCoprへ移行するための戦略を考え、段階的に実行している.

所感

ゼロトラストモデルを取り入れたセキュリティモデルの具体的な話は良かった.
またドキュメントが公開されているというのも良い.
この章を読むことで実装するために必要なことをイメージがついたのではないかな、と思う.

まとめ

境界モデルに問題意識がある人は一度読んでみると、ゼロトラストという考え方が以下に良いかが分かる本だと思う.
またゼロトラスト単体に着眼するわけではなくなりたちまで述べているので、ゼロトラストっていう言葉が気になった人は一読してみると面白いかもしれない.
これからゼロトラストを実践していかなけれれば.

進化的アーキテクチャ 後半

khasegawa.hatenablog.com

の続き

5章 進化的データ

データベースのスキーマは、アプリケーションのクラスやクラス階層と同じで、具体的な物事を抽象化したものである.
この物事に変化があったならば、スキーマも変更すべきである.
そうでなければ、物事と抽象化したスキーマとの間の関係性には乖離が生じる.
スキーマの進化を容易にするためには、「テスト」「バージョン管理」「漸進的に進む」といった仕組みが必要である.
共有データベースという複数のアプリケーションが1つのデータベースを参照する場合、あるアプリケーションがスキーマ変更をした場合に、他のアプリケーションが動作しなくなるといったことが起こりうる.
ならば、スキーマの状態に古い状態と新しい状態を残し、古いスキーマを参照するアプリケーションがなくなったら、削除すれば良くなる.

所感

乖離が生じると、実装に対してのコストがかかるだけでなく、暗黙的なコンテキストが多く増えると思われる.
最初のうちはいいかもしれないが、これが数年続いた時のリスクやコストは馬鹿にできないもになっていても不思議ではない.
これは何もアプリケーションだけでなく、ビジネス・ドメイン要件側でもそういった考えをしておく必要はありそうな気がしている.

6章 進化可能なアーキテクチャの構築

進化可能なアーキテクチャを構築するためには、以下3つの手順を行う.

  1. 進化の影響を受ける次元を特定する
  2. 各次元に対して適応度関数を定義する
  3. デプロイメントパイプラインを使って適応度関数を自動化する

新規プロジェクトを進化可能なアーキテクチャに構築していくのは、既存プロジェクトを改良するよりかは遥かに容易である.
既存のアーキテクチャを改良するには、適切な結合適応度関数を考えておく必要がある.
この適切な結合を推進するためには、モノリスから大きなサービスが協調して動作するアーキテクチャに変えていく必要がある.
うまく分割できないときもあるが、それはライブラリといった形式でそれぞれのサービスに提供するのが良い.
可逆性のある仕組みを構築することも重要.
可逆性のある仕組みとは、Blue/Greenデプロイのようなデプロイメントパイプラインを構築することにある.
DDDでの腐敗防止層を、ライブラリやフレームワークといった外的要因に対して用意しておくことで、アップデート時の影響を最小限にしておくことができる.
ライブラリなどといった依存は、メリットをもらたす反面、制約を課すということを忘れてはならない.
この利益と代償を考えながらアーキテクチャを構築していく必要がある.
また現時点で最善を考えつつも、数年後にはアーキテクチャの再構築などがしやすいようにアーキテクチャを構築する犠牲的アーキテクチャというアプローチも重要である.

所感

アーキテクチャやアプリケーション開発に具体的な手法について述べられているが、インフラ的な観点は少ないように見受けられる.
DDDの思想がベースになっているため、DDDの勉強をしておく必要がありそう.
アーキテクチャを設計するうえで必要になる観点を改めて考えることができる章でもあったように感じる.

7章 進化的アーキテクチャの落とし穴とアンチパターン

ベンダーキングアンチパターン
ベンダー依存になり、ベンダーがいないとダメな構造になることは非常に良くない.
腐敗防止層を用意しておけば防げる.

抽象化の欠如
抽象化には漏れがあるということを前提としておいた方がよい.
作業する抽象化レイヤよりも下にあるレイヤの少なくとも1つを理解することで多少は防げるが、複雑なアーキテクチャになるにつれてそれは難しいこととなる.
こういった点をうまく適応度関数で守れる仕組みを用意した方が良いだろう.

ラスト10%の罠
顧客が望む残り10%は実現可能だが、かなり難しい.

コード再利用の乱用
コードの再利用は、レゴブロックを組み立てるというよりは、臓器移植に似ている.
無理に再利用できるようなコードを書くと、使いやすさが損なわれる.
マイクロサービスでは、ドメイン間のエンティティを分離することにあるため、ある程度の重複は許容する.
重複を促しているわけではないことに注意.

不適切なガバナンス
ガバナンスモデルは、単一の関心事に対して解決策を求める.
これでは今の世の中では不十分で、ゴルディロックスガバナンスモデルを利用した、単純・中間・複雑といった3つの技術スタックを選定しておき、各サービス要件によって技術スタック要件がを導けるようにしておくことができる.

リリース速度の欠如
生物の進化にはライフサイクルの短さは重要である.
それと同じでソフトウェアのライフサイクルも短い方が進化可能性を高めるうえで必要になる.

製品のカスタマイズ
顧客ごとにカスタマイズを請け負うと、それだけコストがかかるということを認識しておく.

レポート機能
アプリケーションとレポート機能はデータを共有する必要はないのに不必要に共有してしまう.
共有しないようにレポートではレポート用のデータを書き出すようなアーキテクチャにすべきである.

計画範囲
大幅な先行投資が必要とする技術には従ってはいけない.

所感

最近、自分が考えていることと同じような結論になっている箇所があって納得感があった.
ベンダーキングアンチパターンは腐敗防止層を入れる典型的な例で良さそう.
DDDをほぼ知らない状態なので、DDDを知るべきだという強い意識を持てる.
また現職では自社サービスを提供しているところであるため、より納得できる例が載っているのが面白い.

8章 進化的アーキテクチャの実践

進化的アーキテクチャを実践していくには、多くの関心事がある.
それは技術的なものだけでなく、ビジネス上の問題や組織・チームといった問題である.
組織・チームでいえばコミュニケーションコストがある.
機能横断型の方が調整の手間が少なくなりやすい.
ただ闇雲にすればいいというものではなく、Jeff Bezos氏が提唱した2枚のピザという概念がある.
大きな2枚のピザで賄える人数が1チームに最適だという話です.
チームの人が増えるとそれだけ各メンバー間のリンクが増えて管理するのが難しくなる.
実験するための基盤を組織に築くことも重要である.
外部からアイデアを取り入れる経路を作ったり、改善のサイクルを作ったり、イノベーションの時間を用意する必要がある.
全て進化的アーキテクチャにすればよいというものでもないことに注意.

所感

見出し通りの内容だったかと思う.
進化的なアーキテクチャであるかどうかは別として、それ以外でも有用そうな話はあった.
2枚のピザは割と有名な話だが、もう少し学術的な面で気になるところではある.
組織構造的な話には首を突っ込みたくないけど、そうは言ってられないしな.

まとめ

トータルとしては、1~5章までは軽く読む程度でいよい内容であったと思います.
細かい例が載っていたりしたが、要点さえ抑えておけば良さそうです.
7,8章をしっかり読めばこの本が言いたいことが載っているところなのかもしれない.
現職ではチャレンジが必要なフェーズであるので、そこで自分が議論するために必要な情報の1つを知れたという意味では良い本だったと思えます.
組織的な話は面倒そうなので必要な限り首突っ込みたくない.
とは言いつつ、何故か首を突ちっ込みがち...

進化的アーキテクチャ 前半

会社の福利厚生を利用して購入した進化的アーキテクチャを読んでいる.

TL;DR

  • 進化的アーキテクチャは、具体的なアーキテクチャを決める手法ではなく、継続的に変更可能なアーキテクチャを支援するための手法
  • 漸進的な変更適応度関数適切な結合から構成される
  • 適応度関数は、要件が担保できているかを確認する仕組みのことで、自動テストや手動テスト・監査・セキュリティレビューがある
  • 漸進的な変更は、開発とデプロイメントの2つの側面からなり、「テストがしやすいアーキテクチャにすること」「継続的デリバリーができるデプロイメントパイプラインを定義すること」が大事
  • オーバーヘッドが少なく最大の利益をもらたす適切な結合があるアーキテクチャを選択しましょう

1章 ソフトウェアアーキテクチャ

1章では、進化的アーキテクチャとは何かを定義している.

将来を見据えたアーキテクチャを設計するのは非常に難しい.
アーキテクチャを設計するには、ビジネス・ドメイン要件から、セキュリティ・パフォーマンス・スケーラビリティなどといったアーキテクチャ特性を踏まえて、それぞれの釣り合いをとりながら最適解を見つけることである.
しかし、ある時点で決定した段階では最適解だったアーキテクチャでも、時間が経つにつれ最適解ではなくなる場合がある.
何故最適解でなくなるかといえば、ビジネス・ドメイン要件の変更といった要因や、言語やプラットフォームのアップデートなど多岐に渡る.
これらはいつ起こるのは予測しづらいが、いつか起きること自体は分かっている.
ならば、それらに対応し変化し続け、最適解であり続けるためのアーキテクチャ特性進化可能性を設計する際の関心事に入れる.
これらを踏まえ、進化的アーキテクチャとは

複数の次元にわたる漸進的で誘導的な変更を支援するものである。

と定義される.
また進化的アーキテクチャは、漸進的な変更適応度関数適切な結合という側面から構成される. これらの具体的な話は後の章で述べられる.

2章 適応度関数

2章では、適応度関数の定義と、種類が記載されている.

アーキテクチャは、様々な要因やアーキテクチャ特性から構成されている.
これらの各要件を担保するために適応度関数という仕組みを用意する.
適応度関数は、それぞれの粒度やトリガー、自動か手動かなどといった分類があり、それぞれ得意不得意がある.
そのため、それらを適切に組み合わせていく必要がある.
早い段階で適応度関数を定義しておくことで、不必要な時間やお金を減らすことができる.
また、適応度関数も定期的に見直す必要がある.
適応度関数自体も様々な要因から影響を受けるからだ.

3章 漸進的な変更を支える技術

3章では、漸進的な変更の定義と、手法や具体例が記載されている.

漸進的な変更が支援するのは、開発とデプロイメントの2つである.
アーキテクチャを設計していく上で無視されがちなのはテスト可能性である.
テスト可能性は、アーキテクチャ特性を自動テストによって検証可能かどうかを示す特性である.
全てのアーキテクチャ特性をテストする必要はなく、容易にテスト可能な特性には、ガイドラインを作り、テストの自動化することが可能である.
デプロイメントは、適応度関数を検証するステージを組み込んだデプロイメントパイプラインを使って継続的なデリバリーを実践することである.
2つのケーススタディがあり、そこでどういったパイプラインが構成されているのかがよく分かる.
このパイプラインの中には自動化されたものだけではなく、手動で実施されるものが含まれるのが何とも面白い.

できる限り自動化できるに越したことはないのだが、2章適応度関数の話にあったメリデメに依存するのだろう.

4章 アーキテクチャ上の結合

4章では、アーキテクチャを組む上で必要となる、適切な結合についての具体的なアーキテクチャが記載されている.

アーキテクチャを設計するうえで、結合は必要悪だと避難されがちだが、結合なしに複雑なソフトウェアを構築するのは困難である.
進化的アーキテクチャでは、最小のオーバーヘッドで最大の利益をもたらす結合すべきアーキテクチャを特定する方法に注目している.
モノリスアーキテクチャから、レイヤード、そしてマイクロサービスなアーキテクチャを含めたいくつかのアーキテクチャが記載されている.
それぞれは、漸進的な変更適応度関数による誘導的な変更適切な結合の3つの観点から述べられている.

疎結合されたアーキテクチャであれば、進化を容易にするための多くの手段を提供することとなる.

感想

読む前は、具体的なアーキテクチャの手法の1つかな?と思って読みすすめていたが、そうではなかったことに少し驚いきました]. だが読み進めていくうえで確かに考慮が漏れやすいポイントであるなということが納得できるような内容でした.
まだ後半を読んでいないので楽しみです.