Infrastructure as Codeと組織文化


**まだ全然便所の落書き**

## Infrastructure as Codeとは何か？

- なんらかのアプリケーションを動かすためのインフラをコードで記述すること
- 領域はサーバの内部(いわゆるOSの設定やミドルウェアの設定)だけに限らない。サービスを動かすインフラ全体(ネットワークやそもそものサービススタック全体)が対象になり得る
	- これはクラウドがAPIを公開しているところによるものも大きい
		- インフラなのかサービスなのかの境界がなくなっていく
- コードで書くことによって、ソフトウェア開発のプラクティスがインフラにも適用可能になる
- コードで書くことで再現性を高められる

## アーキテクチャの複雑化

- 太古の3層アプリケーションのようなアーキテクチャ(Web + AP + RDBMSのようなもの)だけでは済まないケースが多数でてきた
- 例えばキャッシュ、キュー、NoSQL、オブジェクトストレージ、DWH、認証サービスなど
- このときは、単にサーバの中身を自動で設定するだけでは、サービスを再現できず、取り扱う範囲が膨大になる
	- Chefだけでどうにもならない領域が増えている
- すなわちアプリケーションと実行環境の密結合化が起こっているということでもある
	- 個人の開発環境を独立して持とうとした場合の登場要素が多い(単にVagrantfileが1つあれば済むという状態になりにくい、と言い換えてもOK)とも言える
	- CloudFormation、Azure Resource Managerテンプレート、Terraformなどとの組み合わせが必要に
- 密結合しているということは、変更時のテスト範囲が大きくなることにも繋がるし、何かの要素を変更するときに障害を起こさないように影響範囲の見極めや準備が必要にもなってくる
- その結果、変更の反映に時間がかかる

## アーキテクチャの単純化

- 一枚板の分割と疎結合化、いわゆるマイクロサービス化
- 何かを変更した場合の影響範囲を1つのサービスの中に隠蔽する
- 他から見たときの関心事は、そのサービスが利用可能かそうでないか、という点に収束する
	- 言い換えれば、サービスというオブジェクトのインスタンスを生成して使えるか
	- すなわちサービス単位で見るとサービスの中断がなく、インターフェイスの変更がなければ変更を容易にできる
- それぞれのサービスはそれぞれのサービスとして満たすべきSLAを達成できるようにする。あるサービスのSLAは低いかもしれないが、あるサービスは非常に高いかもしれない
- 個々のサービスではそれぞれ必要なインフラを利用すれば良い。ある箇所ではWeb + AP + RDBMSという構成かもしれないし、ある箇所はServerlessかもしれない。

## コード化によるアプリとインフラの境界線の不明瞭化

- コード化されているということは、どんなオブジェクトを作るか、という話になるので、実はアプリケーションロジックなのかインフラなのかという違いさえもなくなる可能性
- クラウド単体で見ても境界線はわかりにくくなりつつある。
	- 例えば、AWSでAuto Scalingを利用しているケースを考える。条件にマッチしたときにインスタンス数を増減するためには、あらかじめAMIを用意しておいたり、起動時に最新のアプリコードを取ってくるような起動処理を入れないといけない。これがインフラ構築の作業なのかアプリ側のデプロイ作業なのかどっちにも捉えられる


## 組織構造と組織の責任範囲

### インフラ担当部門とアプリ部門の分離の弊害

- インフラ担当部門と開発担当部門が分かれていて、インフラの構築がアプリケーション開発担当部門から外出しされ、依頼に基づく作業をするような形になっていると、予測と手続きによるインフラ調達をせざるをえなくなる。いわゆるBDUF。
- 折角クラウドを使っていて、リソースの作成を自動化できたとしても、調達から引き渡しまでのプロセスにおいて特に手続き論に時間がかかってしまう弊害
- OSやミドル部分はアプリ側で担当し、必要なリソースだけを提供するという形での分断も発生する
- このようなオーバーヘッドを理由として、アプリケーションの要件にあわせてインフラを変えることが難しくなる。従ってInfrastructure as Codeの文脈でいうと、サーバのConfigurationはアプリ側でできても、アプリ全体の再現性の担保はアプリ側ではできない
- アーキテクチャは組織構造に依存するというコンウェイの法則を地でいく形に
- 責任分担としては、あくまでインフラレベルでの問題(OS未満のレイヤー)のみインフラ部門が担保し、アプリケーションレベルのサービスレベルには関心がなくなる
- このような状況でマイクロサービス化を実現しようとするとオーバーヘッドの多さで破綻に向かう

### インフラ担当部門のアプリ部門への権限委譲

- 多くの場合インフラ担当部門が自分たちでインフラの調達と構築をおこなうのは、主に、費用効率、会計上の管理、そしてセキュリティの観点による
- 費用効率の観点でいえば、確かにオンプレミスでの構築の場合調達力やデータセンターの効率的な運営による効果もある。一方で手続きによる待ち時間やオーバーヘッドと比較して本当にそれが優位だったかは別の問題
- 一方でAzureやAWSであれば、誰がリソースを作ろうが費用効率は変わらない(大量利用による割引は請求を一本化したり、サブスクリプションを用意しておくことで対応可能)
- 会計の側面でいえば、クラウド化を前提にしてしまえばサービス利用料金の話に変わるのでハードウェア資産の会計上の管理からは解放される
- セキュリティの観点でいえば、一定のルールやガイドライン(設定・監査など)が必要であるが、だからといって全てをインフラ部門でやらないといけない理由とはならない
- これらを踏まえるとリソースの作成をアプリ側に委譲してもよい。もちろんネットワーク設定等全体に影響を及ぼす可能性のある部分はインフラ部門で維持するといった形で良い
	- AWSを例に考えれば、AWSアカウントの持ち主はインフラ部門で、IAMをアプリ側に払い出す。また既存のネットワークとの接続を考慮してVPCのCIDRのみインフラ側が指定するといった形
	- 従うべきOSの設定などがあるのであればインフラ部門側でベースとなるAMIを用意してもよい
	- 監査用のログ取得等が必要であれば、ログイン用に認証統合をおこなうといった仕掛は準備しておく
	- システム分離の基準やアクセスコントロールなどに一貫性を持つように設計しておく
		- クラウドでうれしいのはアカウント単位の独立性(分離)を維持しやすい点
- このような形にすることによってOS内部からさまざまなリソースの作成までをアプリ側に委譲できるため、オーバーヘッドは減る

### インフラ担当部門のアプリ開発プロジェクトへの継続的な参加

- もちろん権限委譲してもそもそもアプリ側では必要なスキルや経験を持っていないケースもある
	- それで良いのかはさておき。
- オーバーヘッドを避けて一貫性を保つことをゴールにするのであれば、インフラ担当部門のメンバーが定常的にアプリプロジェクトに参画する手もある
- これは品質保証部門をプロジェクトの最後に登場させるのではなく、初期の品質担保計画の策定の段階から巻き込むのと似ている。またアーキテクトチームをプロジェクトに継続的に参加させるのにも似ている