Terragrunt事始め

業務でterragruntを使う事になったのでキャッチアップも兼ねて学習の経過を記事にしようと思います。

## Terragruntについて

Terragruntを導入するメリットは多々ありますが大きくは以下2つです。

- モジュール間の依存関係
- 複数環境での開発が楽になる


## 想定環境
- Docker上に構築したUbuntu 22.04.2 LTS
- Terraform 1.5.5
- Terragrunt 0.50.8

## 導入

下記リリースページを取得したいバージョンのバイナリーファイルを取得する。
※今回は最新版のv.50.8を取得します。
https://github.com/gruntwork-io/terragrunt/releases

```
$ sudo curl -Ls https://github.com/gruntwork-io/terragrunt/releases/download/v0.50.8/terragrunt_linux_amd64 -o /usr/local/bin/terragrunt
$ sudo chmod a+x /usr/local/bin/terragrunt
$ terragrunt -v
```

## ディレクトリ構成
今回以下のようなディレクトリ構成としました。

```
envs
  ┣dev
    ┣s3
      ┣terragrunt.hcl
    ┣vpc
      ┣terragrunt.hcl
    dev.hcl
  terragrunt.hcl
modules
  ┣s3
    ┣main.tf
    ┣variables.tf
  ┣vpc
    ┣main.tf
    ┣variables.tf
.gitignore

```


## ディレクトリ構成解説

```
envs/terragrunt.hcl

remote_state {
  backend = "s3"
  config = {
    region  = "ap-northeast-1"
    bucket  = "terragrunt-example-tfstate-445605964569"
    key     = "${path_relative_to_include()}/terraform.tfstate"
    encrypt = true
  }
  generate = {
    path      = "_backend.tf"
    if_exists = "overwrite_terragrunt"
  }
}

generate "provider" {
  path = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents = <<EOF
terraform {
  required_version = ">= 1.5.5"

  required_providers {
    aws = {
      # See https://github.com/terraform-providers/terraform-provider-aws
      version = "~> 5.1.0"
    }
  }
}
provider "aws" {
  region = "ap-northeast-1"
}
EOF
}


```
`terragrunt.hcl`には全体で共通の設定を記載しておきます。
- provider設定
- tf.stateファイルの設定
など


```
envs/dev.hcl

locals {
  env = "dev"
  vpc_name = "dev-vpc"
  cidr_block = "10.0.0.0/16"
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
}

```

`dev.hcl`では環境ごとに使用するリソースのパラメーターを定義しています。

例えば、本番環境などを作成したい場合は`prod.hcl`のように定義すればmodulesの使い回しが可能です。

```
envs/vpc/terragrunt.hcl

# 環境の定義 (`dev.hcl`) を local.env.locals として参照できるようにする
locals {
  env = read_terragrunt_config(find_in_parent_folders("dev.hcl"))
}

# 全環境の定義 (`envs/terragrunt.hcl`) をインクルードする
include "root" {
  path = find_in_parent_folders()
}
# モジュールを参照する
terraform {
  source = "../../../modules/vpc"
}

inputs = {
  vpc_name        = local.env.locals.vpc_name
  cidr_block      = local.env.locals.cidr_block
  private_subnets = local.env.locals.private_subnets
  public_subnets  = local.env.locals.public_subnets
}

```
`dev/vpc/terragrunt.hcl`で実際に作成するTerraformリソースの参照をしています。

リソースに渡す変数`input`で設定しています。


```
modules/vpc/main.tf

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = var.vpc_name
  cidr = var.cidr_block

  azs             = ["ap-northeast-1a", "ap-northeast-1c"]
  private_subnets = var.private_subnets
  public_subnets  = var.public_subnets

  enable_nat_gateway = true
  enable_vpn_gateway = false

  tags = {
    Terraform = "true"
    Environment = "dev"
  }
}
```

```
変数定義
modules/vpc/variables.tf

variable "vpc_name" { type = string }
variable "cidr_block" { type = string }
variable "private_subnets" { type = list(string) }
variable "public_subnets" { type = list(string) }
```


## 実行方法について

`envs/dev/vpc/` ディレクトリで

```
terragrunt plan

terragrunt apply
```
を実行します。

基本的に terraform が terragruntに変更されるだけですが、注意点としては

実行するディレクトリがhclファイルがある場所になります。

---

<br>
<br>




今回はここまで！

引き続きよろしくお願いします！！

---

最後に今回作成したコードを掲載しておきます。

https://github.com/jh6230/terragrunt-example