Terraform初心者にもおすすめ！「詳解 Terraform 第3版」まとめ

## はじめに
今年(2023年)の11月に発売された「詳解 Terraform 第3版」を読んだので、書籍紹介&各章で理解に役立つ記事のリンクを紹介します。
タイトルにもある通り、Terraform歴2ヶ月の初心者の筆者でもスルスル読めたので、初心者の方にもおすすめです！！

https://www.oreilly.co.jp/books/9784814400522/

## サマリー

「詳解 Terraform 第3版」は、Terraformの基礎から応用まで幅広く解説した書籍で、DevOpsやIaCの概念、ステート管理、モジュール利用、シークレット管理、複数プロバイダ使用などが紹介されています。

1章や2章は初学者向けの内容であり、Terraformを初めて使う人にも親切です。
3章以降は実践的な内容が多く、辞書的に使うのも良いのかなと思います。（上級者にとっては少し物足りない可能性）


以下に各章でざっくりどんなことが書いてあったか&理解に役立つ記事や補足の記事のリンクを付記します。

## 1章:なぜTerraformを使うのか
:::note
対象:

Terraformの背景、必要性が知りたい方
:::

DevOps、Infrastructure as Code(IaC)、Terraformの仕組み(宣言型言語であること)について記載されています。

Terraformの仕組みについて、以下の記事などでわかりやすく解説されています。

https://blog.future.ad.jp/terraform-intro

https://gmor-sys.com/2021/04/28/terraform-japanese/



## 2章:Terraformをはじめよう
:::note
対象:

Terraformの基本的な使い方、AWSの基礎知識（EC2、VPC等)と基本的なterraformのプログラムの書き方が知りたい方。

:::

terraformの基礎(`plan`、`apply`や変数、データソース)について記述されています。また`terraform output`や`terraform graph`などの可視化のコマンドについても解説されています。

特に可視化については以下の記事がわかりやすいです。

https://gkzz.dev/posts/alternative-terraform-graph/

EC2やVPC、セキュリティグループ、ロードバランサーなどのAWSの基礎知識及び、それらをterraformプログラムを作成する方法が記載されています。



## 3章:Terraformステートを管理する

:::note
対象:

ステートの保存方法や異なる環境での分離方法が知りたい方。

:::
３章ではステートの管理方法が記載されています。

ステートの保存•共有方法としてS3＆DynamoDB(ロック)の方法が推奨されています。

具体的な方法は以下の記事で紹介されています。

https://blog-benri-life.com/terraform-state-aws-s3-dynamodb-backend/


また異なる環境（例:開発環境とテスト環境）のステート管理の方法として、(1)ワークスペースを用いた分離と(2)ファイルレイアウトを用いた分離が述べられています。

(2)ファイルレイアウトを用いた分離では、環境やモジュールの集合(vpc、dbなど)でフォルダ分けをする方法が記載されていました。フォルダ分けの方法については、所属チームで流派があると思いますが、参考になるかなと思います。

書籍では紹介されていませんが、Terraform Cloudを用いたステート管理もあるようです。

https://dev.classmethod.jp/articles/terraform_tfstate_management_tfc/

## 4章:モジュールで再利用可能なインフラを作る

:::note
対象:

モジュールの利点や使い方について知りたい方
:::

モジュールを使う上では欠かせない変数は、環境によって変わるものは`var`(例:dbのサイズ)、変わらないものは`locals`(例:ポート番号)を選択します。

モジュールのバージョン管理方法については、`live`(稼働中)と`modules`に分けて運用する方法が記載されています。
`modules`でコードを改修して`dev`や`stg`環境でテストを行い、テストが環境したら`live`にコードを移す運用ということです。（つまり`prd`のモジュールの`source`は`live`を参照している。）


## 5章:Terraformのテクニックやポイント
:::note
対象:

Terraformの文法やテクニックについて知りたい方
:::

紹介されているTerraformの文法は以下7つです。

| 関数•文法      | 説明                                                 |
|-------------|------------------------------------------------------|
| `count`     | countの個数だけリソースを作成 (0でリソースを作成しない) |
| `length`    | 配列の長さを返す                                      |
| `スプラット式` | 配列の全ての要素を指定                                |
| `for_each`  | リスト、集合、マップをループ                          |
| `for式`     | リスト内包表記                                        |
| `concat`    | 2つ以上のリストを1つにまとめる                         |
| `one`       | リストの要素数が0->null、1->要素、2以上:エラー         |




Terraform使用時のポイントとして、以下3つが紹介されています。

1. Terraformのみで環境を操作する
1. 既存インフラがある場合は`import`する
1. 実行前に`plan`で確認する(必要なリソースが削除されないかどうか)。ゼロダウンタイムデプロイするために、`lifecycle`の`create_before_destory=true`にすることで置き換え先のリソースを先に作成しておく。



`create_before_destory`のドキュメントは以下です。

https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle



## 6章:シークレットを管理する
:::note
対象:

シークレット情報(ex.パスワード)の管理方法を知りたい方
:::

シークレット情報の認証を用いる状況として3つが説明されています。

1. プロバイダ
1. リソースとデータファイル
1. ステートファイルとプランファイル

### プロバイダ
個人ユーザーのシークレット情報を保存する方法は以下の2つです。

- 環境変数
- `aws-vault add`(AWSの認証)

`aws-vault`についての解説は以下です。

https://blog.microcms.io/aws-vault-introduction/

またマシンユーザであるCircleCIの場合はCircleCIコンテキストに保存します。

### リソースとデータファイル
リソースとデータファイルのシークレット情報は以下3つで管理します。

- 環境変数
- 暗号化されたファイル
    KMSを使う方法やPSGキーを使う方法があります。
- シークレットストア

KMSに関しては以下の記事でわかりやすく解説されています。

https://qiita.com/mksamba/items/a7e902c6d5a12f2a36dc



### ステートファイルとプランファイル
保存場所を暗号化がサポートされているバックエンドとし、ファイルを暗号化することが推奨されています。

## 7章:複数のプロバイダを使う
:::note
対象:

複数のプロバイダを扱う方法を理解したい方
:::

複数プロバイダを使う場面を以下3つに分類しています。


- 複数のAWSリージョンにデプロイ
- 複数のAWSアカウントにデプロイ
- 異なる複数のプロバイドにデプロイ

### 複数のAWSリージョン
複数リージョンにデプロイする際は、複数の`provider`ブロックを使い、それぞれ別々の`region`と`alias`で設定します。

### 複数のAWSアカウント
複数アカウントにデプロイする際は、別々の`assume_role`と`alias`と設定します。

### 異なる複数のプロバイダ
異なる複数のプロバイダを使う現実的に試しにくい例として、Docker化されたアプリケーションをAWSプロバイダとやKubernetesを組み合わせて使う方法が紹介されています。

またDockerの使い方、Kubernetesの使い方や特徴についても説明されています。

## 8章:本番レベルのTerraformコード
:::note
対象:

本番レベルのTerraformプロジェクトに必要な要素を知りたい方
:::

本番レベルのインフラで時間を要する理由として以下3つが挙げれています。

　-　ツールが急速に成長しており、発展途上であること
　-　偶有的複雑性:選択したツールによって発生する問題
　-　本質的複雑性:選択したツールに関わらず発生する問題

さらに本番レベルのインフラではチェック項目が以下のように多数あります。

- インストール
- 設定
- プロビジョニング
- デプロイ
- 高可用性
- スケーラビリティ
- パフォーマンス
- ネットワーク
- セキュリティ
- メトリクス
- ログ
- バックアップ
- コスト
- ドキュメント
- テスト

また本番レベルのインフラは、大規模であるためモジュールは**小さく、組み合わせ可能かつテスト可能でバージョン管理されている**必要があります。

## 9章:Terraformのコードをテストする
:::note
対象:

Teraformのテストについて知りたい方
:::

テスト手法は手動テストと自動テストの二つがあります。

### 手動テスト
手動テストでは、(1)リソースをAWS等に作成し、(2)curlやHTTPリクエストを送信して確認を行い、(3)リソースの削除を手動で行います。(つまり各工程でコマンドを手打ちします。)

手動テストでは開発者にサンドボックス環境を準備し、定期的に削除する手法が推奨されています。


### 自動テスト
自動テストでは、手動テストで行っていた各工程を一つにまとめて自動化します。

本書籍では自動テストツールとして、Goのライブラリである`Terratest`が紹介されており、ユニットテスト、統合テスト、E2Eテストの例について紹介されています。

https://pkg.go.dev/github.com/gruntwork-io/terratest

注意事項やテクニックについても記載されており、ユニットのテストの並列化の際はIDをrandomにすることで重複を防ぐこと、EC2の起動失敗等の失敗に対する回復力を持たせるために既知のエラーに対してリトライされるなどが紹介されています。

並列テストについては以下の記事でわかりやすく解説されています。

https://tech.unifa-e.com/entry/2021/11/02/100646

### その他
その他の解析として、静的解析(`terraform validate`、Policy of Code)やプランによる解析、サーバーテスト(InSpec、Serverspec、Goss)が紹介されています。


## 10章:チームでTerraformを使う
:::note 
対象:

チームにTerraformを導入したい方
:::

デプロイワークフローやデプロイ戦略など実際の運用方法について紹介されています。

デプロイ戦略については以下のサイト•記事で詳しく解説されています。

https://cloud.google.com/architecture/application-deployment-and-testing-strategies?hl=ja

https://www.softbank.jp/biz/blog/cloud-technology/articles/202303/deployment/


ファイルレイアウトやテスト方法など、各章で紹介されて事項が随所に出てきており、復習にも適しています。


## おわりに
「詳解 Terraform 第3版」の書籍紹介&参考リンクの紹介は以上となります。

terraform初心者の自分にとっては、知識の吸収と体系化に役に立つ良書でした。

少しでも参考になれば幸いです。

https://www.oreilly.co.jp/books/9784814400522/