Terraformの特徴について整理してみた

# 背景・目的
Terraformについて、数年前にコードを読んだ程度だったので、
[詳解 Terraform 第3版](https://www.oreilly.co.jp/books/9784814400522/)を元に知識を整理します。

なお、本ページでは、第一章をもとに概要を整理しています。詳細が気になる方は、書籍を御覧いただければと思います。

# まとめ
下記に特徴をまとめます

|特徴|説明|
|:--|:--|
|DevOpsの起源|クラウドへの移行により、DevもOpsもSWに注力することになった|
|DevOpsのゴール|SWのデリバリを今までより遥かに効率化する|
|DevOpsの4つのコアバリュー|・文化（Culture）<BR>・自動化（Automation）<BR>・計測（measurement）<BR>・共有（Share）|
|IaCツールのカテゴリ|・アドホックなスクリプト<BR>・設定管理ツール<BR>・サーバテンプレーティングツール<BR>・オーケーストレーションツール<BR>・プロビジョニングツール|
|Terraformとは|Terraformは、Hashicorpにより作られ、Goで書かれたオープンソースツールである|
|Terraformの挙動|・Goのコードは、terraformという1つのバイナリファイルにコンパイルされる<BR>・このバイナリを使って、PCからインフラをデプロイしたり、サーバなどをデプロイしたりできる。<BR>・Terraformバイナリが裏側で、AWS等のプロバイダに対してAPIコールを行うことで、実現される|


# 概要
## なぜTerraformを使うのか
ソフトウェアデリバリの全体像のうち、Terrafromの使い所を説明している。

### DevOpsとは
以前（オンプレミス中心を指していると思われる。）は、DevとOpsの断絶していた。
Opsは、ミスを犯すこともあり、設定の違いにより設定ドリフトが起き、バグの数が増え、障害やダウンタイムが増える。
その結果、リリース間隔が延びることにつながった。

現在では、クラウドに移行し、HWへの投資からOpsチームは、下記のようなSWに時間を使っている
- Chef
- Puppet
- Terraform
- Docker
- k8s

この結果、DevとOpsの両者は、ほとんどの時間をSWに費やし、DevとOpsの垣根がなくなってくる。互いに協力し合うようになった。
これがDevOpsムーブメントの起源とのこと

### DevOpsのゴール
DevOpsのゴールは、「SWのデリバリを今までより遥かに効率化する」こと

### DevOpsの4つのコアバリュー
- 文化（Culture）
- 自動化（Automation）
- 計測（measurement）
- 共有（Share）

#### Infrastructure as Codeとはなにか
Iac(Infrasutructre as Code)の背景には、下記のためにコードを書いて実行する考えがある。
- インフラを定義
- デプロイ
- 更新
- 削除

対象がHWでも、あらゆる運用をSWとして考えるマインドである。

IaCツールには5つのカテゴリがある
- アドホックなスクリプト
- 設定管理ツール
- サーバテンプレーティングツール
- オーケーストレーションツール
- プロビジョニングツール


### アドホックなスクリプト
自動化で一番簡単で、手軽である。しかし多数管理スルのにアドホックなスクリプトは取り扱いが難しくなる。
1回限りのタスクには最適だが、すべてのインフラをコードで管理したいならIaCツールを使うべき。

### 設定管理ツール
下記は、既存のサーバ上にSWをインストールし、管理するための設定管理ツールである。
- Chef
- Puppet
- Ansible

アドホックなスクリプトとAnsibleは似ているが、下記の利点がある。
- コーディング規約
    - 書き方を強制する
    - 予測可能な構造を強制する
- 冪等性
    - スクリプトで何度も実行しても同じ結果を生むように書くのは難易度が高い。
- 配布
    - 多くのリモートサーバを管理するように特化している


### サーバテンプレーティングツール
設定管理ツールとは異なり、近年使用が増えているものに、下記のものがある。
- Docker
- Packer
- Vargrant

OS、SW、ファイル、その他すべてを含んだ完全な「スナップショット」を使ったイメージを作る。

Packerのようなサーバテンプレーティングツールにより、サーバのイメージを作成するのに使用し、このイメージを各サーバに適用するのにAnsibleのようなツールを使う。

### オーケーストレーションツール
サーバテンプレーティングツールは仮想マシン、コンテナを作るツールである。
その仮想マシンやコンテナの管理はどうするか？一般的には、下記が必要になる。

- HWを効率的に使うために、仮想マシンやコンテナをデプロイ
- ローリングデプロイ、　Blue/Greenデプロイ、カナリアデプロイ
- オートヒーリング：問題あるものを置き換え
- オートスケーリング：負荷に応じてスケーリング
- ロードバランシング：仮想マシンやトラフィックを分散
- サービスディスカバリ：仮想マシンやコンテナが互いにNW通信できるようにする

これらのタスクを行うのが、下記のようなオーケストレーションツール
- k8s
- Marathon/Mesos
- ECS
- Docker Swarm
- Nomad

例えば、k8sを使うとDockerコンテナをどのように管理するかをコードとして定義できる

### プロビジョニングツール
上記に上げた各種ツールは、各サーバで動くコードを定義するもの。
下記のプロビジョニングツールは、サーバ自身を作成する役割。
- Terraform
- Cfn
- OpenStack Heat

## IaCの利点とは
コードが強力である。手動の手順をコードに置き換えることでSWを世にだす能力は改善される
DevOpsを行う組織では、200倍程度頻繁にデプロイし、24倍高速に障害から復旧し、リードタイムが1/2555になっているそうだ。

下記のSWエンジニアリングを取り込める。
- セルフサービス
- スピードと安全性
- ドキュメント化
- バージョン管理
- バリデーション
- 再利用性
- 幸福？

## Terraformはどう動くのか
Terraformは、Hashicorpにより作られ、Goで書かれたオープンソースツールである。
Goのコードは、terraformという1つのバイナリファイルにコンパイルされる

このバイナリを使って、PCからインフラをデプロイしたり、サーバなどをデプロイしたりできる。
Terraformバイナリが裏側で、AWS等のプロバイダに対してAPIコールを行うことで、実現される

## Terraformと他のIaCの違い
IaCツールの選択は難しい。どれも実現できそうに見える。

これらを技術的に判断する際のトレードオフは下記のとおり。
- 設定管理ツール/プロビジョニングツール
- ミュータブル/イミュータブル
- 手続き型/宣言型
- 汎用言語/ドメイン言語
- マスタ/マスタレス
- エージェント/エージェントレス
- 有償/無償
- コミュニティの大小
- 成熟/最先端
- 複数ツールの組み合わせ

### 設定管理ツール/プロビジョニングツール
これらは、明確ではない。設定管理ツールはある程度プロビジョニングが可能。逆も然り。
ユースケースにあったツールを選ぶべき

### ミュータブル/イミュータブル
ミュータブルなものは、サーバごとに個別の変更履歴を持つようになり、各サーバは少しづつ他のサーバと異なった状態になる。
そして、診断が難しくなり、再現性がなくなる小さな設定バグを含むようになる。

Terraformのようなイミュータブルなプロビジョニングツールでは、全く新しいサーバをデプロイすることを意味する。

変更を加えた場合、前の状態を踏まえて把握する必要がある。
宣言型は最終的な状態を宣言するだけなので、どのようにその状態を維持するかTerraformが判断する
Terraformは、過去に作成した状態についても知っている

### 手続き型/宣言型
手続き型には、下記の問題点がある。

- 手続き型のコードではインフラの状態を完全に把握できない
    - 何がデプロイされたか完全にわからない
    - 順番も知る必要がある
- 再利用には制限がある
    - インフラの現在の状態を把握しなければならないので、再利用性は制限される

Terrformの宣言的なアプローチであれば、コードはインフラの最新の状態を常に表現できる。
過去の履歴やタイミングを気にしなくても、一見しただけで現在何がデプロイされていて、どんな設定がされているかわかる

### 汎用言語/ドメイン言語

ドメイン特化言語の優位性は下記の通り
- 学習が用意
- 明快で完結
- 同じ処理が同じ記述になりやすい
- 新しいことを学ぶ必要がない
- エコシステムが大きく、ツールが成熟されている
- 協力

### マスタ/マスタレス
マスターサーバによる問題点は下記の通り
- 余計なインフラ
- メンテナンス
- セキュリティ

Terraformは、マスタレス。しかしクラウドプロバイダのAPIを使用してやり取りするので、APIがマスタサーバとも言える。

### エージェント/エージェントレス
エージェント型の欠点
- ブートストラップ
- メンテナンス
- セキュリティ

Terraformは、エージェントをインストールすることは不要であり、クラウドプロバイダのエージェントが各サーバでそのコマンドを実行してくれる

### 有償/無償
Terraformは有償と無償バージョンがある。
- 無償＆オープンソースのバージョン
- 有償プロダクトのTerraform Cloudと組み合わせ


### コミュニティの大小
TerraformとAnsibleはコントリビューター数、スターの数、OSSライブラリ数、Stack　Overflowの記事数が増え続けている

### 成熟/最先端
Terraformは成熟してきている

### 複数ツールの組み合わせ
多くの会社でうまくいったツールの組み合わせを列挙する

#### プロビジョニングと設定管理の組み合わせ
TerraformにAnsibleを組み合わせる例。
NWトポロジ、データストアなどのインフラすべてをTerraformでデプロイし、Ansibleをつかってアプリケーションをデプロイする

追加のインフラが不要で、最初に取り組むには簡単な方法。
大きな欠点として、Ansibleがミュータブルなため、手続き的なコードを書く必要があり、メンテナンスが難しくなる

#### プロビジョニングとサーバテンプレーティングの組み合わせ
TerraformとPackerを組み合わせる例。
Packerでアプリケーションを仮想マシンとしてパッケージする。その仮想マシンイメージを使ったサーバとそれ以外のNW、データストアなどのインフラTerraformでデプロイする。

追加のインフラ不要。イミュータブルである。
欠点として、仮想マシンのビルドとデプロイは時間がかかり、イテレーションのスピードが下がる。
Terraformで、可能なデプロイ戦略には限りがある。（Terraformではネイティブなブルー・グリーンはできない）

#### プロビジョニング、サーバテンプレーティング、オーケストレーションの組み合わせ
Terraform、Packer、Docker、k8sを組み合わせる例。
Packerを使って、DockerとK8sがインストールされた仮想マシンイメージを作る。それからそのイメージを使ってサーバのクラスタを起動し、NWトポロジ、データストア等のインフラをTerraformでデプロイする。
最後にサーバが起動されたら、Docker化したアプリを動かして、K8sクラスタを構成する。

利点は下記の通り。
- Dockerイメージのビルドはかなり高速なので、ローカルPCでも起動してテストができる
- デプロイ戦略、オートヒーリング、オートスケーリングなどK８sのビルドイン機能を全て利用できる

欠点は、下記の通り。
- インフラが増えることで複雑性が高まってしまう

# 考察
今回、詳解 Terraform 第3版の第1章を元に、Terraformの特徴や、導入するメリット、他のIaCとの比較をまとめました。
引き続き、2章以降も確認し整理していきたいと思います。

# 参考
https://www.oreilly.co.jp/books/9784814400522/