この記事は terraform Advent Calendar 2023の12日目です
Terragrunt を使って Terraform のリソースを管理
最近 O'Reilly Japan から 詳解 Terraform 第3版 が出ました。
その中で Terragrunt がおすすめされていたので、Terraform リソースの管理にはあまり困っていないものの個人的に導入してみることにしました。
いくつか躓いたポイントがあったため、他の方の参考になればと思い記事を書くことにしました。
なお導入にあたって次の記事を参考にさせていただきました。
執筆者の方に感謝するとともに、補足のような記事を書ければと思います。
Terragrunt がどのようなものかは上記の記事や公式ドキュメントを参考にしてください。
躓きポイント
環境ごとの remote state の設定
先ほど参照させていただいている記事だと全環境に対して同じ S3 バケットで .tfstate ファイルを管理する記述になっていましたが、 .tfstate ファイルを環境ごとに別バケットで管理したいため、その方法を調べました。
結論としては各環境ディレクトリに 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"
}
}
モジュールの呼び出し側では次のように書くことで上記のファイルの設定を引き継ぐ事ができます。
include {
path = find_in_parent_folders()
}
map 型の変数の参照
staging/env.hcl
にて map 型の変数を次のように定義したところエラーがでました。
locals {
map_variable = {
variable = 'value'
}
}
エラーを見るとどうも
{
variable = 'value'
}
を単なる文字列として読み込んでいたようです。
このエラーを解消するには module の variables.tf 内で型を定義する必要があります。
実行できる例
variable "map_variable" {
description = "map 型の変数"
type = map(any)
}
だめな例
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_id
と var.region
が使えているわけですね。当たり前ですが実行するまでちょっと悩みました。
# 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 そのものも、活用事例も発展していくことを楽しみにしています。