TerragruntでTerraformを効率よく管理しよう
TerragruntでTerraformを効率よく管理しよう
クラウドワークスグループのソニックムーブでバックエンドエンジニアをしている岡村です。
Terraformでインフラ構成を管理しています。最近では、GithubActionでTerraformのPlan・Applyを行えるように色々と試行錯誤していました。その際に、出会ったTerragruntについて紹介したいと思います。
1. Terraformを使う上での課題
Terraformは強力なインフラ管理ツールですが、複数の環境やモジュールを運用していると以下の課題に直面します:
- 設定ファイルの重複
- ディレクトリ構成の煩雑化
- コードの再利用性が低い
以前は、自前スクリプトを用意して初期設定から、providerの定義等を自動生成する仕組みを用意していました。この方法だと再利用性や再現性に工夫が必要な状況でした。
これらの課題を解決するためのツールが Terragrunt です。
2. Terragruntとは?Terraformを強化するラッパーツール
Terragrunt はTerraformのコード管理を効率化するツールです。Terraformの機能を拡張し、コードの重複を減らして環境ごとの設定管理をシンプルにします。
Terragruntの特徴
- コードの共通化と再利用が可能。
- 開発環境や本番環境ごとの設定をシンプルに管理できる。
- DRY原則に沿った管理ができる(重複を避ける)。
3. Terragruntの導入手順
Step 1: aquaを使用してTerragruntをインストール
aquaはツールのバージョン管理を効率的に行うためのツールです。以下の手順でaqua経由でTerragruntをインストールします。
aquaのインストール(aquaが未導入の場合):
brew install aquaproj/aqua/aqua
aqua.yamlの作成
プロジェクトのルートディレクトリにaqua.yaml
ファイルを作成し、Terragruntを追加します。
packages:
- name: gruntwork-io/terragrunt@latest
インストール実行
aqua install
確認
terragrunt --version
これでTerragruntのインストールは完了です。
aquaを採用した理由はGithubActionで利用することを想定し、バージョンを簡易に指定できるツールを探していたのでこちらを採用しました。
aquaに関する情報は、こちらを参考にしてください。
Step 2: ファイル構成の準備
TerraformとTerragruntを組み合わせるためのファイル構成を作成します。
.
├── aqua.yaml # aquaの設定ファイル
├── _modules # Terraformモジュール
│ ├── vpc
│ │ ├── main.tf
│ │ └── variables.tf
│ └── ec2
│ ├── main.tf
│ └── variables.tf
├── _templates # テンプレート
│ ├── _providers.tf.tmpl
│ └── _versions.tf.tmpl
├── terragrunt.hcl # 共通設定ファイル
├── stage # ステージ環境
│ ├── terragrunt.hcl
│ └── main.tf # Terraformコード
└── prod # 本番環境
├── terragrunt.hcl
└── main.tf
4. ファイル構成の詳細解説
terragrunt.hcl
1. 共通設定ファイル:共通の設定を記述します。モジュールの参照先や変数の共通部分を定義します。
ここでproviderの定義の管理を行います。
locals {
common_vars = yamldecode(file("${get_parent_terragrunt_dir()}/common_vars.yaml"))
}
terraform {
source = "./_modules/vpc"
}
remote_state {
backend = "s3"
generate = {
path = "_backend.tf"
if_exists = "overwrite"
}
config = {
bucket = "${local.tfstate_bucket_prefix}-${local.aws_account_id}"
key = "${get_path_from_repo_root()}/terraform.tfstate"
region = "${local.aws_region}"
encrypt = true
dynamodb_table = "${local.tfstate_lock_table_prefix}-${local.aws_account_id}"
profile = "${local.aws_profile}"
}
}
generate "version" {
path = "_version.tf"
if_exists = "overwrite"
contents = templatefile("${get_parent_terragrunt_dir()}/../_templates/version.tf.tpl", {
terraform_version = "1.9.5"
aws_provider_version = "5.70.0"
})
}
inputs = {
}
stage/terragrunt.hcl
と prod/terragrunt.hcl
2. 環境ごとの設定ファイル:環境固有の変数を設定し、共通設定を継承します。
ここでは、親のterragrunt.hclで定義したproviderが参照されます。
ステージ環境
include {
path = find_in_parent_folders()
}
inputs = {
environment = "stage"
}
本番環境
include {
path = find_in_parent_folders()
}
inputs = {
environment = "prod"
}
modules/vpc
3. Terraformモジュール:VPCを作成するモジュールです。
modules/vpc/main.tf
resource "aws_vpc" "main" {
cidr_block = var.cidr_block
tags = {
Name = var.environment
}
}
variable "cidr_block" {}
variable "environment" {}
5. 実行時の挙動とファイル参照イメージ
実行コマンド
Terragruntを利用してステージ環境・本番環境の適用を行います。
ステージ環境
cd stage
terragrunt apply
本番環境
cd prod
terragrunt apply
.terragrunt-cache
の構成
Terragruntを実行すると、.terragrunt-cache
ディレクトリが生成されます。このディレクトリはTerraformのモジュールをローカルにキャッシュし、再利用するためのものです。以下が典型的な構成例です:
.terragrunt-cache/
└── <hash>/ # ハッシュ値に基づくディレクトリ
└── .terraform/ # Terraformのモジュールファイル
-
<hash>
:使用中のTerraformモジュールや設定に基づくユニークなハッシュ値。- この配下に自動生成されるファイル類、plan outのファイルが出力されます。
-
.terraform/
:Terraformのプラグインやモジュールが格納されるディレクトリ。
このキャッシュにより、同じコードを何度も実行する際のパフォーマンスが向上します。
実行時のファイル参照の流れ
Terragruntは環境ごとの設定ファイルを読み込み、共通設定を継承しつつTerraformを実行します。
-
環境固有の
terragrunt.hcl
(例:stage/terragrunt.hcl
) -
共通設定ファイル(
../terragrunt.hcl
) -
Terraformモジュール(
../modules/vpc
)
6. まとめ
TerragruntはTerraformを補完し、共通設定の管理や複数環境の運用をシンプルにします。簡単な使用例でしたのでまだまだ紹介しきれていない機能はありますが共通性の管理だけでも利用する価値はあったと感じています。また、aquaを使えばバージョン管理も容易です。
Discussion