『実践Terraform』を写経して完全に理解した時の学習メモ

## 「実践Terraform」で何を学んだか

本書ではAWS上にアプリケーションを構築するためにTerraformを使い、それを通してTerraformを学んでいくという構成になっている。

アーキテクチャの全体像をした上で、そのアーキテクチャの構築をTerraformを使って行なっていく。

> 本書は「入門編」「実践編」「運用・設計編」の3部で構成されています。第1章から第3章までが「入門編」です。第1章でAWSとTerraformのセットアップを行います。そして第2章と第3章で、Terraformの基礎知識を一気に学びます。第4章から第16章までが「実践編」です。第4章でシステムの全体設計を行います。

Terraformはインフラ構築をしていくために利用できるツールで、コードを記述することでAWSやGCPのようなクラウド上で構築するリソースを定義することができるため、Infrastructure as Codeを実現することができる。

> The key features of Terraform are:
> » Infrastructure as Code
> Infrastructure is described using a high-level configuration syntax. This allows a blueprint of your datacenter to be versioned and treated as you would any other code. Additionally, infrastructure can be shared and re-used.
> » Execution Plans
> Terraform has a "planning" step where it generates an execution plan. The execution plan shows what Terraform will do when you call apply. This lets you avoid any surprises when Terraform manipulates infrastructure.
> » Resource graph
> Terraform builds a graph of all your resources, and parallelizes the creation and modification of any non-dependent resources. Because of this, Terraform builds infrastructure as efficiently as possible, and operators get insight into dependencies in their infrastructure.
> » Change Automation
> Complex changesets can be applied to your infrastructure with minimal human interaction. With the previously mentioned execution plan and resource graph, you know exactly what Terraform will change and in what order, avoiding many possible human errors.
https://www.terraform.io/intro/index.html

本書を通じてTerraformの始め方、Terraformの基本的な操作や知識、そして実務における設計論や運用に関する知識を学ぶことができた。

本書では下記の技術スタックをTerraformで構築したため、コンテナを利用した一般的なアプリケーションにおけるアーキテクチャの構築ができたと考えて差し支えないだろう。

> 4.3テクノロジースタック
次のようなリソースを、各章で実装していきます（図4.1）。
・第5章「権限管理」：IAMポリシー、IAMロール
・第6章「ストレージ」：S3
・第7章「ネットワーク」：VPC、NATゲートウェイ、セキュリティグループ
・第8章「ロードバランサーとDNS」：ALB、Route53、ACM
・第9章「コンテナオーケストレーション」：ECSFargate
・第10章「バッチ」：ECSScheduledTasks
・第11章「鍵管理」：KMS
・第12章「設定管理」：SSMパラメータストア
・第13章「データストア」：RDS、ElastiCache
・第14章「デプロイメントパイプライン」：ECR、CodeBuild、CodePipeline
・第15章「SSHレスオペレーション」：EC2、SessionManager
・第16章「ロギング」：CloudWatchLogs、KinesisDataFirehose

そのためTerraformに限らず、AWSの全体的な技術スタックについても学ぶことができたと言える。

また本書ではAWSを使ったが、応用すればGCPやAzureについてもいろいろできると思われる。

## 通して写経した後での所感

### AWSを知っていないと事あるごとに詰まる可能性あり

基本的にAWSについての概念が理解できていれば、詰まるところはほとんどない。

が、AWS自体を理解できていない場合は概念の理解に苦しむことになると思う。

本書ではAWSの各サービスについての簡単な説明はしてくれるものの、AWS自体を教えることを目的としているわけではないので、AWS自体が全く分からない場合は自力でAWSについて調べながら進めるか、別の本を先に読んでおく必要がある。

### 逆引き辞典としても使えそう

また、実務で一つ一つのリソースを構築するときの逆引きとしても使えそうだなという印象を持った。

ベストプラクティスも有用だし、ハンドブック的な役割の参考書としても持ってて損はない、と感じた

### 全体をこなしてみるまで実感は湧きづらい

本書を写経するだけだと一つ一つのリソースを作っている間はCLIでやるのとあまり変わらないのかも？という印象を受けてしまう。

ただそれら全てのリソースを一気に操作したいときにTerraformがかなり強力になってくるな、と感じた。

コスト削減のために作成したリソースを削除したいとなったときにGUIでポチポチしたり、CLIで一つ一つ削除するのは手間だし削除漏れが出る可能性もある。

Terraformであれば`terraform destroy`だけでもれなく全てのリソースを削除することができるので、ミスがないし圧倒的に早く作業が完了する。

リソースを削除するときだけでなく、一度作ったインフラと同じ環境を再構築する場合も同様のメリットが考えられる。

## 本書で利用した・紹介されたコマンド一覧

備忘録として本書で利用・紹介されたコマンドの一覧と概要をまとめておく。

### `terraform init`

作業ディレクトリをTerraformの実行のために初期化する。

設定を新規追加した場合やGitHubなどからクローンした場合に実行する。

> The terraform init command is used to initialize a working directory containing Terraform configuration files. This is the first command that should be run after writing a new Terraform configuration or cloning an existing one from version control. It is safe to run this command multiple times.
https://www.terraform.io/docs/commands/init.html

### `terraform plan`
「実行計画」が出力される、何が追加されたり削除されたりするのかが表示される。

これから実行される内容を把握するために用いる。

なお実際に実行が行われるわけではない。

> The terraform plan command is used to create an execution plan. Terraform performs a refresh, unless explicitly disabled, and then determines what actions are necessary to achieve the desired state specified in the configuration files.
https://www.terraform.io/docs/commands/plan.html

### `terraform apply`
planで出力される実行結果を実行する。
このコマンドで実際にリソースが追加・更新される。

> The terraform apply command is used to apply the changes required to reach the desired state of the configuration, or the pre-determined set of actions generated by a terraform plan execution plan.
https://www.terraform.io/docs/commands/apply.html

### `terraform destroy`
`terraform apply`で作成されたリソースを削除する。

ほとんどのリソースは問答無用に削除されるため、そうしたくない場合は適切な削除防止を行う必要がある。

> The terraform destroy command is used to destroy the Terraform-managed infrastructure.
https://www.terraform.io/docs/commands/destroy.html

### `terraform get`
.tfファイルの実行に必要なモジュールをダウンロードする。

> The terraform get command is used to download and update modules mentioned in the root module.
https://www.terraform.io/docs/commands/get.html

### `terraform fmt`
.tfファイルをフォーマットしてくれる。

`-recursive`で再起的にフォーマットしてくれる。

> The terraform fmt command is used to rewrite Terraform configuration files to a canonical format and style. This command applies a subset of the Terraform language style conventions, along with other minor adjustments for readability.
https://www.terraform.io/docs/commands/fmt.html

### `terraform validate`
`terraform fmt`はフォーマットに関するコマンドだったが、こちらはファイルの記述に間違いがないかをチェックしてくれる。

静的解析ツール。


### `terraform -install-autocomplete`
TerraformをCLIで操作するときのタブ保管機能をインストールしてくれる。

いらなくなったら`terraform -uninstall-autocomplete`で削除。

> If you use either bash or zsh as your command shell, Terraform can provide tab-completion support for all command names and (at this time) some command arguments.
https://www.terraform.io/docs/commands/index.html#shell-tab-completion

### `tflint`
`terraform validate`では発見できないプロバイダーに起因する不具合を見つけてくれる。

`tflint --deep --aws-region=ap-northeast-1 main.tf`の様な記述をすればregion specificに実行も可能。

> Since t1.2xlarge is a nonexistent instance type, an error will occur when you run terraform apply. But terraform plan and terraform validate cannot find this possible error beforehand. That's because it's an AWS provider-specific issue and it's valid as a Terraform configuration.
> https://github.com/terraform-linters/tflint#why-tflint-is-required

### `terraform console`
対話型のコンソールを開く。


### `terraform state`
作成されたリソースに関する種々の情報を保持しているStateに関するコマンド群。

> The terraform state command is used for advanced state management. As your Terraform usage becomes more advanced, there are some cases where you may need to modify the Terraform state. Rather than modify the state directly, the terraform state commands can be used in many cases instead.
https://www.terraform.io/docs/commands/state/index.html

### `terraform state list`
作成されたリソースを列挙する。
追加の引数を与えればリソースの絞り込みが可能。

> The terraform state list command is used to list resources within a Terraform state.
https://www.terraform.io/docs/commands/state/list.html

### `terraform state show`
リソースの細かな情報を表示してくれる。

> The terraform state show command is used to show the attributes of a single resource in the Terraform state.
https://www.terraform.io/docs/commands/state/show.html

### `terraform state pull`
前提としてStateは基本的にはローカルで保持されるが、チーム開発の際には全体で同一のStateを持っておく必要があるためTerraform CloudやS3といったクラウドストレージなどで管理される。

このコマンドはそのステートをローカルに持ってくるためのコマンド。

> The terraform state pull command is used to manually download and output the state from remote state. This command also works with local state.
https://www.terraform.io/docs/commands/state/pull.html

### `terraform state push`
ローカルにあるStateでリモートのステートを書き換える。
基本的には使うべきではない。

> The terraform state push command is used to manually upload a local state file to remote state. This command also works with local state.
https://www.terraform.io/docs/commands/state/push.html

### `terraform state rm aws_instance.remove`
Terraformで管理しているリソースをStateから削除する。
あまり想像はつかないが、Terraformの管理から外したい場合に使う。

> The terraform state rm command is used to remove items from the Terraform state. This command can remove single resources, single instances of a resource, entire modules, and more.
https://www.terraform.io/docs/commands/state/rm.html

### `terraform state mv`
複数のステートがある場合に、あるステートから別のステートへリソースを移動させたいという場合に用いる。

> The terraform state mv command is used to move items in a Terraform state. This command can move single resources, single instances of a resource, entire modules, and more. This command can also move items to a completely different state file, enabling efficient refactoring.
https://www.terraform.io/docs/commands/state/mv.html

### `terraform import`
存在はしているがTerraformで管理されていないリソースをTerraformの管理下に持ってくるためのコマンド。

今まではGUIとCLIだけでAWSをやってたけど、これからTerraformを導入しよう！というときに使ったりしそう。

> The terraform import command is used to import existing resources into Terraform.
https://www.terraform.io/docs/commands/import.html

### `terraform workspace`
単一のコードで複数の環境を構築するWorkspaceについてのコマンド群。

> The terraform workspace command is used to manage workspaces.
https://www.terraform.io/docs/commands/workspace/index.html

### `terraform workspace new`
新規ワークスペースを追加する。

なおワークスペースについて操作を行なっていない場合、暗黙的に`default`というワークスペースで作業をしていることになっている。

> The terraform workspace new command is used to create a new workspace.
https://www.terraform.io/docs/commands/workspace/new.html

### `terraform workspace show`
現在のワークスペースを表示する。

> The terraform workspace show command is used to output the current workspace.
https://www.terraform.io/docs/commands/workspace/show.html

### `terraform workspace list`
ワークスペースの一覧を表示する
> The terraform workspace list command is used to list all existing workspaces.
https://www.terraform.io/docs/commands/workspace/list.html

### `terraform workspace select`
作業を行うワークスペースを設定する。

> The terraform workspace select command is used to choose a different workspace to use for further operations.
https://www.terraform.io/docs/commands/workspace/select.html

### `TF_LOG=debug`
環境変数。

デバッグレベルのログを標準出力に出力することができる。
文字通りデバッグに使える。

> Terraform has detailed logs which can be enabled by setting the TF_LOG environment variable to any value. This will cause detailed logs to appear on stderr.
https://www.terraform.io/docs/internals/debugging.html

### `terraform 0.12upgrade`
0.12へのアップグレードのためのコマンド。
0.11以前のバージョンを使っている場合に、手作業ではなく公式のコマンドでアップグレードを行うことができる。

> The terraform 0.12upgrade command applies several automatic upgrade rules to help prepare a module that was written for Terraform v0.11 to be used with Terraform v0.12.
https://www.terraform.io/docs/commands/0.12upgrade.html