LoginSignup
4
2

Terragrunt で躓いたところとその解決方法

Last updated at Posted at 2023-12-10

この記事は terraform Advent Calendar 2023の12日目です

Terragrunt を使って Terraform のリソースを管理

最近 O'Reilly Japan から 詳解 Terraform 第3版 が出ました。

その中で Terragrunt がおすすめされていたので、Terraform リソースの管理にはあまり困っていないものの個人的に導入してみることにしました。

いくつか躓いたポイントがあったため、他の方の参考になればと思い記事を書くことにしました。

なお導入にあたって次の記事を参考にさせていただきました。

執筆者の方に感謝するとともに、補足のような記事を書ければと思います。

Terragrunt がどのようなものかは上記の記事や公式ドキュメントを参考にしてください。

躓きポイント

環境ごとの remote state の設定

先ほど参照させていただいている記事だと全環境に対して同じ S3 バケットで .tfstate ファイルを管理する記述になっていましたが、 .tfstate ファイルを環境ごとに別バケットで管理したいため、その方法を調べました。

結論としては各環境ディレクトリに terragrunt.hcl を置けばよいです。

envs/staging/terragrunt.hcl
remote_state {
  backend = "gcs"
  config = {
    bucket  = "tfstate_bucket"
    prefix  = path_relative_to_include()
    project = "gcp-project-staging"
  }
  generate = {
    path      = "backend.tf"
    if_exists = "overwrite"
  }
}

モジュールの呼び出し側では次のように書くことで上記のファイルの設定を引き継ぐ事ができます。

envs/staging/modA/terragrunt.hcl
include {
  path = find_in_parent_folders()
}

map 型の変数の参照

staging/env.hcl にて map 型の変数を次のように定義したところエラーがでました。

locals {
  map_variable = {
    variable = 'value'
  }
}

エラーを見るとどうも

  {
    variable = 'value'
  }

を単なる文字列として読み込んでいたようです。
このエラーを解消するには module の variables.tf 内で型を定義する必要があります。

実行できる例

modules/modA/variables
variable "map_variable" {
  description = "map 型の変数"
  type        = map(any)
}

だめな例

modules/modA/variables
variable "map_variable" {
  description = "map 型の変数"
}

型の定義を怠けていたのがバレてしまいました。
ちゃんと型を定義しましょう。

provider の設定の EOF 中での var の使用

これは躓いたわけではないのですが、以下の定義中の var を使えるか疑心暗鬼になりつつ実行したら普通に使えました。

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.8.0"
    }
  }
}
provider "google" {
  project = var.project_id
  region  = var.region
}
EOF
}

EOF で囲んでいるため、 var で定義している project_id と region に値が入らないかと思いましたが、 .terragrunt-cache 内で生成されている provider.tf で普通に var.project_idvar.region が使えているわけですね。当たり前ですが実行するまでちょっと悩みました。

envs/staging/modA/.terragrunt-cache/hash/provider.tf
# Generated by Terragrunt. Sig: 
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.8.0"
    }
  }
}
provider "google" {
  project = var.project_id
  region  = var.region
}

terragrunt import の使い方

module に対して terraform import を実行するときは次のように書きます。
terraform import module.modA.service_name.resource_name resource_id
同じように terragrunt import を実行してもうまくいきませんでしたが、単に module.modA の部分を消して実行することでうまくいきました。

実行できる例

terragrunt import service_name.resource_name resource_id

だめな例

terragrunt import module.modA.service_name.resource_name resource_id

まとめ

Terragrunt は便利ですが、まだまだ日本語の技術記事が少ない印象です。この記事が Terragrunt を使い始めたばかりの方に役立つと幸いです。

また Terragrunt は2023年12月現在の最新 version が 0.54.0 と若いサービスです。
今後 Terragrunt そのものも、活用事例も発展していくことを楽しみにしています。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2