287日目　Terraformに慣れてきたので改めてまとめてみる by社畜S

## :robot:はじめに
こんにちは、社畜Sです。　
社畜Sは今月でTerraformを触り始めてちょうど半年くらいになります。
半年間TerraformとAWSに触れる中で、仙人とまではいきませんがだいぶ知識も深まってきたので、今回は自身の知識の整理も兼ねて、改めてTerraformについてまとめていこうと思います。
初心者なりに、わかりやすくまとめていこうと思うので、同じTerraform初心者の助けになれれば幸いです。

## :robot:Terraformの概要
TerraformはHashiCorpによって開発されたIaC（Infrastructure as Code）ツールです。
他のIaCツールだと「AWS Cloud Formation」、「Pulumi」などがあります。

Terraformの大きな特徴は
・さまざまなプラットフォームに対応している
・「HCL」という独自の言語を使用している
この二つだと思います。

まず１つ目の「さまざまなプラットフォームに対応している」という点ですが、軽くあげるだけでも
・AWS
・Azure
・Google Cloud Platform
のようなクラウドサービス各種に対応。また、
・Docker
・Kubernetes
のようなコンテナサービスにも対応しています。
他にも対応サービスは多くあり、Terraformの汎用性の高さがわかります。
これらの対応サービスをまたがった構築をすることも可能なようです。

２つ目の特徴の「HCL」という独自言語ですが、これはとにかく読みやすいです
設計段階から人間が読みやすく、書きやすいように設計されているようで、JSON形式に比べて視覚的に理解しやすいです。
もちろん、初めのうちは理解しにくいかと思いますが、自分もTerraformを書いている内に慣れてきてある程度は理解できるようになってきました。

また、深いところまでいくと、変数を利用してコードを動的に変化させることも、モジュールを使用してのコードの再利用などもできるようになり、簡単でありながらも、色々なことができる奥の深い言語だと思います。

## :robot:AWS CloudFormationとの違い
細かい点を挙げだすときりがないので、大まかに分けて3つ紹介します:bow:
|  | Terraform | Cloudformation |
|:-:|:-:|:-:|
| ①対応プラットフォーム  | 複数のサービスに対応  | AWSのみ  |
| ②状態管理の仕方  | 状態ファイルをS3などで管理  | AWS内で管理  |
| ③スタックの自動ロールバック  | エラーが出ても自動ロールバックされない（デプロイ成功した分のリソースはそのまま） | エラーが発生したらスタック作成前の状態まで自動ロールバックされる。  |
### ①対応プラットフォーム
ぱっとわかりやすいのはこれだと思います。
CloudformationはAWS専用のツールなのに対して、Terraformは先ほど概要でも挙げたように複数のサービスに対応しています。
こう書くと複数対応しているTerraformのほうが…となるかもしれませんが、CloudFormationはAWSが公式に提供しているツールなので、新しいAWSサービスへの対応が非常に速いというメリットがあります。
AWSの新しいサービスを交えたシステムを構築したい際はCloudformationを使用するのが良いのかもしれません。
### ②状態管理の仕方
TerraformとCloudformationでインフラ状態の管理が違います

Terraform：状態ファイル（stateファイル）を使用。状態ファイルはリモート（S3など）に保存してチームで共有することができる。
状態ファイルを基にインフラの変更計画を作成するから、現在の構成と差分を正確に把握できる。

Cloudformation：AWS内で管理するから追加の設定などが必要ない。
ただし、現在の状態を追跡する機能はTerraformほど強力ではないので柔軟性に欠ける。

という風に分かれています。
ざっくりとまとめると
Terraformは管理が大変な代わりに柔軟な対応ができ、構成や差分を把握しやすい。
Cloudformationは管理が簡単な代わりに構成や差分を把握するのが難しく、柔軟性に欠ける
という特徴があります。

### ③スタックの自動ロールバック
地味ですがこれも結構重要な違いだと思います。
IaC実行中にエラーが起きた場合
CloudformationはIaC実行前の状態まで戻る（全か無か（all-or-nothing））のですが、
Terraformの場合はエラーが起きるまでの変更は適応されたままIaCが途中終了するようになっています（エラーが起きるまでのリソースは作成されるが、エラー移行のリソースは作成されない）。
そのためTerraformの場合、半端な状態が残ることで、環境の整合性を保つのが複雑になる場合があります。

こうして並べてみると、CloudformationもTerraformもAWSで使用する場合はお互い一長一短で状況や熟練度に応じて選択する形が良さそうです。

## :robot:よく使用するコマンド
Terraformを使用するうえで必須級の4つのコマンドを簡単に紹介しようと思います。すべてターミナル上から使用します。
### ①terraform init
```terraform:
terraform init
```
簡単にいうと”プロジェクトの準備をするためのコマンド”です

必要なプラグイン（Terraformプロバイダーなど）をダウンロードし、プロジェクトのディレクトリをTerraformが使えるように準備します。
initはプロジェクトで最初に必ず行うコマンドなので、しっかり覚えておきましょう。
プロバイダーやTerraformモジュールが更新された場合にも再実行する必要があります

### ②terraform plan
```terraform:
terraform plan
```
簡単にいうと”Terraformが「どのリソースを作成・更新・削除するか」を確認するコマンド”です
これをapply前に実行することで実際に変更が適用される内容を事前に確認できるので、チームで作業する場合も、この結果を確認することで安心して進めることができます。

applyでもどのリソースが作成されるかは出てきますが、applyと違い環境を変更することがないので、まずはこのコマンドで試してみるのが良いと思われます。
### ③terraform apply
```terraform:
terraform apply
```
簡単にいうと”terraform planで確認した内容を実際に適用して、リソースを作成・更新・削除するコマンド”です

Terraformコード（*.tfファイル）の内容に基づいてリソースを作成または変更します。
成功するとTerraformの状態ファイルが更新され、現在のインフラの状態が記録されます。

planによる事前確認はありますが、先ほど上であげたように途中でエラーを出してしまうと半端な状態が残ってしまい、環境の整合性を保つのが難しくなるときがあるので、本番環境で実行する際はしっかり開発環境などで下調べをすることをおすすめします。

### ④terraform fmt
```terraform:
terraform fmt
```
簡単にいうと”Terraformのコードを自動的に整形して、見やすくするコマンド”です
例として
```terraform:
resource "aws_s3_bucket" "test" {
   bucket =       "test-bucket-sample"

  tags={
      Name = "test-bucket"
   Environment  =     "test"
}
     }
```
こんな感じのインデントめちゃくちゃの汚いコードにterraform fmtを実行すると
```terraform:
resource "aws_s3_bucket" "test" {
  bucket = "test-bucket-sample"

  tags = {
    Name        = "test-bucket"
    Environment = "test"
  }
}
```
こんな風に綺麗なコードに整形してくれます。
また、複数のtfファイルをまとめて整形することもできるので、プロジェクト全体でフォーマットをそろえることもできます。

自分は使用していませんが、VSCodeの拡張機能で、保存した際にtfファイルに自動でterraform fmtを実行してくれる拡張機能もあるようです。
## :robot:まとめ
今回はTerraformの概要について本当に触りだけですがまとめてみました。
最初のうちはわからないことも多いと思いますが、わかりやすいツールなので触っている内にどんどん身についていくと思います。

私もまだまだ初心者ですので、これからもTerraform仙人を目指して頑張っていこうと思います。