terragruntの使い方

##はじめに
この記事は、terragruntについて学習する機会があった投稿者の備忘録として記したものである。

###terragruntって何？
+ 複数のディレクトリで定義したterraformのコードを一括でデプロイ出来るようにする為のツール
+ ラップツールと呼ばれたりする



###どうやって使うの？
使い方は簡単。パッケージをインストールして、`terragrunt.hcl`で定義をつけるだけ。

####①インストールする。（投稿者はmac環境なので`brew`コマンドでインストールする）

```
# brew install terragrunt
```

####②全ディレクトリを一括で叩く為の場所をつくる
何を言っているのかわけがわからないと思うので、以下にディレクトリの構成図を例として記す
例として挙げているのはネットワークのデプロイ部分である。
従来の場合（terragruntを使用しない場合）、環境ごとのディレクトリを構成し、その配下にモジュールを配置し、そのディレクトリへ移動して_apply_を実行する形となっている。

_従来のterraform構成_

```
# tree
.
└── network
    ├── envs
    │   └── default
    │       ├── modules.tf
    │       ├── outputs.tf
    │       └── variables.tf
    └── modules
        ├── outputs.tf
        ├── security_group.tf
        └── variables.tf
```

一方、terragruntを使用すると環境ごとにモジュールを配置するにはするが、環境ごとに移動してアプライする必要なく、1つのまとまったディレクトリでアプライすれば、他環境分も_apply_できる。
_terragruntによる構成_

```
# tree
.
├── ec2
│   ├── modules.tf
│   ├── outputs.tf
│   └── variables.tf
├── network
│   ├── modules.tf
│   ├── outputs.tf
│   └── variables.tf
└── terragrunt.hcl
```

このように、従来は各ディレクトリで管理されていたものが、terragruntによって1つにまとめることが可能となる。
また、コマンドを叩く場所も1つで済むので作業の手間も無くなる。

####③planして作られるのか確認
planコマンドというものがあり、applyする前は必ず確認する為のもの。もし間違っていればここでエラーが判明する

```
# terragrunt run-all plan
```
####④実行コマンドを叩く
terragruntの実行コマンドは以下である。
terragruntはterraformのラッパーの為、基本的に`terragrunt apply`されれば、そこからファイルが読み込まれ`terraform apply`されるという認識。

```
# terragrunt run-all apply
```

ただし、オプションもいくつか用意されていて、確認したところ、以下のように表示された。(version 0.35.4の場合)

```
# terragrunt -help
DESCRIPTION:
   terragrunt - Terragrunt is a thin wrapper for Terraform that provides extra tools for working with multiple
   Terraform modules, remote state, and locking. For documentation, see https://github.com/gruntwork-io/terragrunt/.

USAGE:
   terragrunt <COMMAND> [GLOBAL OPTIONS]

COMMANDS:
   run-all               Run a terraform command against a 'stack' by running the specified command in each subfolder. E.g., to run 'terragrunt apply' in each subfolder, use 'terragrunt run-all apply'.
   terragrunt-info       Emits limited terragrunt state on stdout and exits
   validate-inputs       Checks if the terragrunt configured inputs align with the terraform defined variables.
   graph-dependencies    Prints the terragrunt dependency graph to stdout
   hclfmt                Recursively find hcl files and rewrite them into a canonical format.
   aws-provider-patch    Overwrite settings on nested AWS providers to work around a Terraform bug (issue #13018)
   render-json           Render the final terragrunt config, with all variables, includes, and functions resolved, as json. This is useful for enforcing policies using static analysis tools like Open Policy Agent, or for debugging your terragrunt config.
   *                     Terragrunt forwards all other commands directly to Terraform

GLOBAL OPTIONS:
   terragrunt-config                            Path to the Terragrunt config file. Default is terragrunt.hcl.
   terragrunt-tfpath                            Path to the Terraform binary. Default is terraform (on PATH).
   terragrunt-no-auto-init                      Don't automatically run 'terraform init' during other terragrunt commands. You must run 'terragrunt init' manually.
   terragrunt-no-auto-retry                     Don't automatically re-run command in case of transient errors.
   terragrunt-non-interactive                   Assume "yes" for all prompts.
   terragrunt-working-dir                       The path to the Terraform templates. Default is current directory.
   terragrunt-download-dir                      The path where to download Terraform code. Default is .terragrunt-cache in the working directory.
   terragrunt-source                            Download Terraform configurations from the specified source into a temporary folder, and run Terraform in that temporary folder.
   terragrunt-source-update                     Delete the contents of the temporary folder to clear out any old, cached source code before downloading new source code into it.
   terragrunt-iam-role                          Assume the specified IAM role before executing Terraform. Can also be set via the TERRAGRUNT_IAM_ROLE environment variable.
   terragrunt-iam-assume-role-duration          Session duration for IAM Assume Role session. Can also be set via the TERRAGRUNT_IAM_ASSUME_ROLE_DURATION environment variable.
   terragrunt-iam-assume-role-session-name      Name for the IAM Assummed Role session. Can also be set via TERRAGRUNT_IAM_ASSUME_ROLE_SESSION_NAME environment variable.
   terragrunt-ignore-dependency-errors          *-all commands continue processing components even if a dependency fails.
   terragrunt-ignore-dependency-order           *-all commands will be run disregarding the dependencies
   terragrunt-ignore-external-dependencies      *-all commands will not attempt to include external dependencies
   terragrunt-include-external-dependencies     *-all commands will include external dependencies
   terragrunt-parallelism <N>                   *-all commands parallelism set to at most N modules
   terragrunt-exclude-dir                       Unix-style glob of directories to exclude when running *-all commands
   terragrunt-include-dir                       Unix-style glob of directories to include when running *-all commands
   terragrunt-check                             Enable check mode in the hclfmt command.
   terragrunt-hclfmt-file                       The path to a single hcl file that the hclfmt command should run on.
   terragrunt-override-attr                     A key=value attribute to override in a provider block as part of the aws-provider-patch command. May be specified multiple times.
   terragrunt-debug                             Write terragrunt-debug.tfvars to working folder to help root-cause issues.
   terragrunt-log-level                         Sets the logging level for Terragrunt. Supported levels: panic, fatal, error, warn (default), info, debug, trace.
   terragrunt-strict-validate                   Sets strict mode for the validate-inputs command. By default, strict mode is off. When this flag is passed, strict mode is turned on. When strict mode is turned off, the validate-inputs command will only return an error if required inputs are missing from all input sources (env vars, var files, etc). When strict mode is turned on, an error will be returned if required inputs are missing OR if unused variables are passed to Terragrunt.
   terragrunt-json-out                          The file path that terragrunt should use when rendering the terragrunt.hcl config as json. Only used in the render-json command. Defaults to terragrunt_rendered.json.

VERSION:
   v0.35.4

AUTHOR(S):
   Gruntwork <www.gruntwork.io>
```

ヘルプコマンドだけ貼られても感があるので、個人的にゆるくまとめたのがこちら

|command|説明|使用例|
|---|---|---|
|run-all|今いるディレクトリから再帰的にモジュールを検索し、依存関係の順番でterraformコマンドを実行する|# terragrunt run-all apply|
|plan-all|公式には非推奨とあるので、あまり使わない方がよさそう|# terragrunt plan-all|
|apply-all|非推奨。使う場合は`run-all apply`の代わりになる|# terragrunt apply-all|
|output-all|非推奨。使う場合は`run-all output`の代わりになる|# terragrunt output-all|
|destroy-all|非推奨。使う場合は`run-all destroy`の代わりになる|# terragrunt destroy-all|
|validate-all|非推奨。使う場合は`run-all validate`の代わりになる|# terragrunt validate-all|
|terragrunt-info|terragruntの状態をJSON形式で終了させる|# terragrunt terragrunt-info|
|validate-inputs|terragrunt構成で構成されている入力変数の情報を出す|# terragrunt validate-inputs|
|graph-dependencies|依存関係のグラフをDOT形式で出す|# terragrunt graph-dependencies|
|hclfmt|hclファイルを再帰的に探して正規形式に書き換えるコマンド|# terragrunt hclfmt|


##apply結果
上手くいくと、以下のようにコンプリートされる

```
# terragrunt run-all apply
Apply complete! Resources: 21 added, 0 changed, 0 destroyed.
```

##感想

* 一括にまとめることによって管理しやすくなるので良い。
* 一方で、terraformからterragruntにする際の指定方法が若干修正必要になるので、脳内での整理が大事になってくる


##参考資料
[Terragrunt Install](https://terragrunt.gruntwork.io/docs/getting-started/install/)
[Terragruntによるシステム管理](https://zenn.dev/aquamarinearia/articles/56202d4ae825dd)
[CLI options](https://terragrunt.gruntwork.io/docs/reference/cli-options/#run-all)