Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
2026-09-18 gotanda.sre Terraformで複数環境作ったり、複数Sta...
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
SUZUKI Masashi
September 18, 2026
Technology
790
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
2026-09-18 gotanda.sre Terraformで複数環境作ったり、複数Stateに分割したりそれとTerragrunt / Terraform multi envs and multi states
https://gotanda-sre.connpass.com/event/402441/
で話す資料
SUZUKI Masashi
September 18, 2026
More Decks by SUZUKI Masashi
See All by SUZUKI Masashi
2026-09-26 Platform Engineering Kaigi 2026 インフラとアプリの境界線と委譲の設計 / Drawing the Infra and App Line
masasuzu
0
650
2026-09-04 SRE Tech Talk #15 怠惰なTerraform / Lazy Terraform
masasuzu
2
340
2026-08-15 JAWS-UG 茨城 #16 Secrets ManagerにおけるSecret値の管理(Terraformの場合) / Secrets Manager Secrets
masasuzu
2
890
2026-07-28 3-shakeテックランチ Cloud Run のデプロイパラメータを考える / Cloud Run Deploy Parameter
masasuzu
0
120
2026-07-24 tfpolicyを試してみたのですが、、、、
masasuzu
1
180
2026-06-18 ecspressoのtfstate参照が便利すぎた話
masasuzu
1
550
2026-04-14 Jagu'e'r Cloud Native分科会 Terraform Stateにおけるシークレットの平文保存という課題とその解決
masasuzu
1
100
2026-03-27 #terminalnight 変数展開とコマンド展開でターミナル作業をスマートにする方法
masasuzu
1
530
2026-03-23 Ops-JAWS Meetup39 Session Managerを使った セキュアなサーバーアクセス
masasuzu
3
210
Other Decks in Technology
See All in Technology
DAMOS - The Smart Cruise Control for RAM
ennael
PRO
1
130
freeeらしさをAIとともに作る / Creating the freee Experience with AI
ymrl
0
190
[2026 Oracle Technical Deep Dive] Apache Iceberg × Oracle AI Database -Oracle Autonomous AI Lakehouseが実現するAI時代のデータ基盤- (2026年9月17日開催)
oracle4engineer
PRO
0
100
Claude起点の仕様駆動開発
tanakaseiya
0
380
おそらく日本で唯一のDevRelインターン生として
husengs7
0
170
20260930_Gemma4_Hands-on
tsho
0
220
購入ドメインでの課題と取り組み
ykagano
0
130
More Freedom on the Same Shared GPU Cluster: A Small Team’s Experience with vCluster
nttcom
0
130
AI時代だからこそ推したい!Gitコマンド再入門
munakata
0
140
Deep Data Security 機能解説
oracle4engineer
PRO
2
690
調査タスクをAIと乗り切る 〜過去の調査をナレッジ化し 調査手順をスキルにする〜
mot_techtalk
1
110
インバスケット試験対策アプリを 作って見えたAIエージェント構築 ナレッジ2選
shichijoyuhi
1
130
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
Testing 201, or: Great Expectations
jmmastey
46
8.3k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.4k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
6.1k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Deep Space Network (abreviated)
tonyrice
0
350
How to Think Like a Performance Engineer
csswizardry
28
2.9k
Making Projects Easy
brettharned
120
6.8k
Writing Fast Ruby
sferik
630
63k
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.6k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
760
Transcript
Terraformで複数環境作ったり、 複数Stateに分割したり それとTerragrunt 2026-09-18 gotanda.sre#1 すずきまさし Copyright © 3-shake, Inc.
All Rights Reserved.
おまえだれよ • • • すずきまさし/masasuzu/@masasuz 株式会社スリーシェイクSreake事業部シニアアーキテクト クラウドインフラなんでも屋さんをしてます ◦ お客様の外部から ▪
設計、運用、構築等の技術支援を行います。 ◦ お客様の内部から ▪ インフラチームの一員として内製化支援も行います。 • 得意領域 ◦ AWS ▪ AWS Community Builder Cloud Operation Since 2024~2026 ▪ 2026 Japan All AWS Certifications Engineers ◦ Google Cloud ▪ Google Cloud Partner Top Engineer 2026 ◦ Terraform Copyright © 3-shake, Inc. All Rights Reserved. 2
怠惰にTerraformを使いたいでござる
怠惰 - Lazy • • • • プログラマの三大美徳の 1つ ◦
怠惰、短期、傲慢 Perl開発者ラリー・ウォールの言葉 全体として必要となる労力を減らすためには努力をおしまないこと あとからめんどくさくなるなるものは先回りして実装整備して、あとあとの面倒を減らす ◦ トイル減らしたいでござる Copyright © 3-shake, Inc. All Rights Reserved. 4
怠惰と横着 • • • • 人間楽をしたいんですよ。 ◦ 私は楽して暮らしたいです。 ◦ Terraformも楽して書きたいんですよ
気をつけたいのは怠惰のために減らすのは眼の前の労力でなく、全体の労力 ◦ 眼の前だけ減らすのは横着であとから利子付きで返済が求められます ◦ トイルが襲ってくるのです 怠惰は先払い、横着は後払い ◦ ただし、必ずしも先払いが正解とは限らないのは留意したい ◦ ある程度の規模でないなら横着したほうが正解かも 横着はその場で書けてしまうが、痛みが出るのは先の話なのが厄介なところ Copyright © 3-shake, Inc. All Rights Reserved. 5
怠惰にTerraform使いたいでござる https://speakerdeck.com/masasuzu/lazy-terraform Copyright © 3-shake, Inc. All Rights Reserved. 6
今日のテーマ • • • • Terraformのコードを書く際の面倒ごとを減らしたい 複数環境、複数 Stateを扱うときの面倒ごとを減らしたい 記述を減らすことで機能開発の際の編集する場所を減らしたい 最近Terragrunt便利!となってるので紹介したい
• つまり怠惰に Terraformを書きたい Copyright © 3-shake, Inc. All Rights Reserved. 7
目次 • • • • 複数環境を扱うときの課題 複数State扱うときの課題 それとTerragrunt まとめ Copyright
© 3-shake, Inc. All Rights Reserved. 8
01 複数環境扱うときの課題 Copyright © 3-shake, Inc. All Rights Reserved. 9
複数環境作りたいとき • 素直に実装するなら環境ごとにディレクトリを 切って、Stateを分けてそれぞれリソースを定義 する ◦ dev/ stg/ prd/ •
だいたい良さそう Copyright © 3-shake, Inc. All Rights Reserved. . ├── dev/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf ├── stg/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf └── prd/ ├── providers.tf ├── variables.tf └── main.tf 10
よくない(場合もある)よ?
環境増えるごとにコピペ • • • リソース定義が増えるごとにそれぞれのディレクトリファ イルごとにコピペしていかないとならない。 ◦ 変更のたびに各ファイルに同じ変更をコピペして いかないといけない コピペコピペコピペ
◦ 親指と人差し指が吊ります ▪ 超めっちゃトイル (ただ、本当に小規模であれば問題ない場合もある ) Copyright © 3-shake, Inc. All Rights Reserved. . ├── dev/ │ ├── providers.tf │ ├── variables.tf │ ├── db.tf │ ├── vpc.tf │ └── ec2.tf ├── stg/ │ ├── providers.tf │ ├── variables.tf │ ├── db.tf │ ├── vpc.tf │ └── ec2.tf └── prd/ ├── providers.tf ├── variables.tf ├── db.tf ├── vpc.tf └── ec2.tf 12
よしモジュールだ • • • • • TerraformにはModuleという処理を共通化する仕組みがあ る Moduleに共通リソースを切り出す。 各StateのRoot
ModuleからはModuleを呼び出す形にする Moduleに関してはいろいろ観点がありそれだけで 30分くら い語れるくらいなのでここでは語らないです。 よさそう、、、、 ? Copyright © 3-shake, Inc. All Rights Reserved. . ├── modules/ │ ├── vpc/ │ │ ├── providers.tf │ │ ├── variables.tf │ │ └── main.tf │ └── app/ └── envs/ ├── dev/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf ├── stg/ └── prod/ 13
モジュールに関しては同僚が語ってるのでこちらを https://speakerdeck.com/hayama17/terraformmoziyuruha-naze-mo-jing-hua-surunoka Copyright © 3-shake, Inc. All Rights Reserved. 14
まだめんどう • • 環境ごとにディレクトリが分かれているのはわかりやすい パラメータが違うだけでモジュールを呼び出す部分は同じものを使ってる ◦ 極端だとパラメータだけ異なっていて他はすべて同じはありうる ▪ terraform.tfvarsもしくはvariablesのデフォルト値、 local値
◦ symlinkでいいのでは ? ▪ windows問題 ▪ 微妙な環境差分が出てきたときにめんどう Copyright © 3-shake, Inc. All Rights Reserved. 15
そこでbackend切り替えパターン • • • • • 各環境で共通の Root Moduleを定義する backendとtfvarsのファイルを指定する
◦ 各環境ごとに差し替える Root Module分の重複が減ってよさそう ただ、環境切り替えるごとに init -reconfigureが必要 ◦ ミスりポイント miseなどのタスクランナー使っていればそのあたりは対処 できる . ├── main.tf ├── variables.tf ├── providers.tf ├── modules/ │ ├── vpc/ │ └── app/ └── envs/ ├── dev/ │ ├── backend.tfvars │ └── terraform.tfvars ├── stg/ └── prod/ ENV=dev # 環境変えるごとに init -reconfigureが必要 terraform init -backend-config=envs/${ENV}/backend.tfvars -reconfigure terraform plan -var-file=envs/${ENV}/terraform.tfvars Copyright © 3-shake, Inc. All Rights Reserved. 16
02 複数Stateの際の課題 Copyright © 3-shake, Inc. All Rights Reserved. 17
Stateを分けたいとき • • • ライフサイクルが違うものを分けたい ◦ VPCやDBは一回作るとほぼ変わらない ◦ EC2やECSはわりかし変更頻度が高い 頻度が高いものに引きづられて変わらないものを毎回
Planするのは無駄 同じStateにいると間違えて変更して事故になる可能性 がある Copyright © 3-shake, Inc. All Rights Reserved. . ├── vpc/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf ├── db/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf └── workload/ ├── providers.tf ├── variables.tf └── main.tf 18
分けると困りごとあります
依存関係、実行順序 • • • 分けることでState間の依存が生まれます 実行順がわからない ◦ 数字つけてもいいけど、、、 依存関係もわからない ◦
数字プリフィクスだけだとわからない db datastore vpc workload-a Copyright © 3-shake, Inc. All Rights Reserved. workload-b . ├── 01vpc/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf ├── 02db/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf ├── 03datastore/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf ├── 04workload-a/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf └── 05workload-b/ ├── providers.tf ├── variables.tf └── main.tf 20
前段のStateで作成済みが前提のリソース • • 開発環境は作成済みで、 STG環境を新しく作ろうとした ときにvpcが実行済みじゃないと、 dbのplanに失敗する ◦ vpc stateでdb_subnetが作られてる前提で
dataも しくはremote state参照されるので存在しないとこ ける 事前にplanしたいでござる vpc . ├── vpc/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf ├── db/ │ ├── providers.tf │ ├── variables.tf │ └── main.tf └── workload/ ├── providers.tf ├── variables.tf └── main.tf db db_subnet Copyright © 3-shake, Inc. All Rights Reserved. 21
規模拡大で顕在化する困りごとあります
provider、versionなど • • • providerやprovider version、backend、terraform versionは全部同じなのに毎 State書かないといけない 少ないうちはいいけど、複数環境、複数 State扱うと健
在化します コピペコピペコピペ ◦ 親指と人差し指が吊ります ▪ 超めっちゃトイル terraform { required_version = "~> 1.16.2" } required_providers { google = { source = "hashicorp/google" version = "~> 8.2.0" } } backend "gcs" { prefix = "terraform/state" } provider "google" { project = var.project_id region = var.region impersonate_service_account = local.impersonate_service_account default_labels = { project = var.project_name environment = var.env managed_by = "terraform" } } Copyright © 3-shake, Inc. All Rights Reserved. 23
複数Stateで共通の設定 • • • 全部のterraform.tfvarsに同じ値を書かないといけない 少ないうちはいいけど、複数環境、複数 State扱うと健在化 します コピペコピペコピペ ◦
親指と人差し指が吊ります ▪ 超めっちゃトイル Copyright © 3-shake, Inc. All Rights Reserved. # envs/dev/terraform.tfvars project_id = “xxxxxxx” env = “dev” project_prefix = “yyyy” 24
怠惰にTerraformを使いたいでござる
03 さっそうと登場するTerragrunt Copyright © 3-shake, Inc. All Rights Reserved. 26
Terragruntとは • • • Gruntworksが開発 OpenTofuとTerraformをオーケストレーター Terragrunt does not replace
OpenTofu/Terraform. It orchestrates them, and extends what they do. ◦ Why use Terragrunt instead of just OpenTofu/Terraform? • Terraformのコードを生成して、いい感じに使えるようにしてくれる便利ツール ◦ そのまま使うんじゃなくて Terraformのコードを生成する ◦ 抽象化、共通化されているのでコードが追いにくいデメリット Copyright © 3-shake, Inc. All Rights Reserved. 27
Terragrunt Stacks • • • • 2025年にリリースされた機能 いい感じに複数 Stateを実行できる機能 規模が大きいと便利
◦ 逆に小さいときは必要じゃない 逆にStacksじゃないTerragruntを使ってないので、素の Terragruntを説明できないです。 Copyright © 3-shake, Inc. All Rights Reserved. 28
stack実行 # terragrunt.stack.hcl を読んで.terragrunt-stack/ を生成 terragrunt stack generate # stack
に含まれる全unitに対し、DAG順で実行します terragrunt stack run plan terragrunt stack run apply terragrunt stack run destroy Copyright © 3-shake, Inc. All Rights Reserved. 29
どんな感じで生成されるか見ます
Terragrunt Stacks構成 . └── terraform/ ├── modules/ # module(root module含む)
│ ├── vpc/ │ └── workload/ ├── units/ # Terragrunt の unit テンプレート │ ├── vpc/ │ │ └── terragrunt.hcl # unitの設定(root module、依存関係) │ ├── db/ │ └── workload/ └── live/ # ── ここから下が環境別 ── ├── root.hcl # 共通設定 ├── dev/ │ ├── env.hcl # 環境ごとの設定 │ ├── terragrunt.stack.hcl # どのunitを使うか │ └── .terragrunt-stack/ # 生成物。gitignore 対象 ├── stg/ └── prd/ Copyright © 3-shake, Inc. All Rights Reserved. 31
Terragrunt Stacks構成 . └── terraform/ ├── modules/ # module(root module含む)
│ ├── vpc/ │ └── workload/ ├── units/ # Terragrunt の unit テンプレート │ ├── vpc/ │ │ └── terragrunt.hcl # unitの設定(root module、依存関係、 │ ├── db/ │ └── workload/ └── live/ # ── ここから下が環境別 ── ├── root.hcl # 共通設定 ├── dev/ │ ├── env.hcl # 環境ごとの設定 │ ├── terragrunt.stack.hcl # どのunitを使うか │ └── .terragrunt-stack/ # 生成物。gitignore 対象 ├── stg/ └── prd/ Copyright © 3-shake, Inc. All Rights Reserved. 32
設定ファイル # live/${env}/env.hcl 環境ごと locals { env = "dev" project_id
= "xxxxxx" } vpc = {# vpcの設定} workload = {# workloadの設定} # live/root.hcl 共通 locals { env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) env = local.env_vars.locals.env project_id = local.env_vars.locals.project_id region = "asia-northeast1" } Copyright © 3-shake, Inc. All Rights Reserved. 33
Terragrunt Stacks構成(再掲) . └── terraform/ ├── modules/ # module(root module含む)
│ ├── vpc/ │ │ └── main.tf │ ├── db/ │ └── workload/ ├── units/ # Terragrunt の unit テンプレート │ ├── vpc/ │ │ └── terragrunt.hcl # unitの設定(root module、依存関係、 │ ├── db/ │ └── workload/ └── live/ # ── ここから下が環境別 ── ├── root.hcl # 共通設定 ├── dev/ │ ├── env.hcl # 環境ごとの設定 │ ├── terragrunt.stack.hcl # どのunitを使うか │ └── .terragrunt-stack/ # 生成物。gitignore 対象 ├── stg/ └── prd/ Copyright © 3-shake, Inc. All Rights Reserved. 34
unit設定 # unit/workload/terragrunt.hcl include "root" { path = find_in_parent_folders("root.hcl") }
locals { env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) workload = local.env_vars.locals.workload } dependency "vpc" { config_path = "../vpc" } terraform { source = "${get_repo_root()}/terraform/modules/workload" } inputs = { env = local.env_vars.locals.env region = local.env_vars.locals.region instance_type = local.workload.instance_type } Copyright © 3-shake, Inc. All Rights Reserved. 35
Terragrunt Stacks構成(再掲) . └── terraform/ ├── modules/ # module(root module含む)
│ ├── vpc/ │ │ └── main.tf │ ├── db/ │ └── workload/ ├── units/ # Terragrunt の unit テンプレート │ ├── vpc/ │ │ └── terragrunt.hcl # unitの設定(root module、依存関係、 │ ├── db/ │ └── workload/ └── live/ # ── ここから下が環境別 ── ├── root.hcl # 共通設定 ├── dev/ │ ├── env.hcl # 環境ごとの設定 │ ├── terragrunt.stack.hcl # どのunitを使うか │ └── .terragrunt-stack/ # 生成物。gitignore 対象 ├── stg/ └── prd/ Copyright © 3-shake, Inc. All Rights Reserved. 36
.terragrunt-stack . └── terraform/ └── live/ ├── root.hcl └── dev/
├── env.hcl ├── terragrunt.stack.hcl └── .terragrunt-stack/ └── .terragrunt-cache-xxxxxx/ ├── vpc/backend.tf, provider.tf, main.tf ├── db/backend.tf, provider.tf, main.tf └── workload/backend.tf, provider.tf, main.tf Copyright © 3-shake, Inc. All Rights Reserved. 37
なるほど、わからない
わかりやすいメリットを紹介
provider生成 # root.hcl # provider.tf generate "provider" { path =
"provider.tf" if_exists = "overwrite_terragrunt" contents = <<EOF provider "google" { project = "${local.project}" region = "${local.region}" EOF } # Generated by Terragrunt. Sig: xxxxxx provider "google" { project = "xxxx" region = "asia-northeast1" } Copyright © 3-shake, Inc. All Rights Reserved. 40
backend生成 # root.hcl remote_state { backend = "gcs" config =
{ bucket = "${local.prefix}-tfstate" prefix = "${local.env}/${basename(get_terragrunt_dir())}" } generate = { path = "backend.tf" if_exists = "overwrite_terragrunt" } } # backend.tf # Generated by Terragrunt. Sig: xxxxxx terraform { backend "gcs" { bucket = "xxxx-tfstate" prefix = "dev/workload" } } Copyright © 3-shake, Inc. All Rights Reserved. 41
依存性解決 • • dependencyブロックで依存関係を明記できる 実行時はterragruntがDAG組んで順番通り実行してくれる # unit/workload-a/terragrunt.hcl dependency "vpc" {
config_path = "../vpc" } db datastore vpc workload-a Copyright © 3-shake, Inc. All Rights Reserved. workload-b 42
モック • • 依存元のアウトプットのモックが書ける 依存元のunitが作られていなくても planが実行できる # unit/workload/terragrunt.hcl dependency "vpc"
{ config_path = "../vpc" mock_outputs = { vpc_self_link = "https://www.googleapis.com/compute/v1/projects/${local.project_id}/global/networks/${local.prefix }-network" subnet_self_link = "https://www.googleapis.com/compute/v1/projects/${local.project_id}/regions/asia-northeast1/subnet works/${local.prefix}-network" } mock_outputs_allowed_terraform_commands = ["validate", "plan", "init", "providers"] } Copyright © 3-shake, Inc. All Rights Reserved. 43
メリットまとめ • • • • • • 全体で使う変数の共通化 環境ごとの変数の共通化 provider、backendの生成
State間の明示的な依存関係 モックアウトプットによる構築前の plan確認 規模が大きければ大きいほど記述量が減る ◦ 環境増やすときは live/${env} を増やすだけ ◦ State増やすときは unit/${state}と modules/${state} を増やす Copyright © 3-shake, Inc. All Rights Reserved. 44
デメリット • • • • 規模が小さいときはオーバースペック ◦ 学習コスト ◦ 複雑性
コードだけ見て全体が追いにくい 抽象化、共通化しているので追いにくい 実際のコードは生成しないとわからない Copyright © 3-shake, Inc. All Rights Reserved. 45
04 まとめ Copyright © 3-shake, Inc. All Rights Reserved. 46
まとめ • • • ある程度大きくなってきたら環境分割、 State分割が必要になります 環境分割、State分割するといろいろつらみがあります ある程度の規模になったときに怠惰になりたいなら Terragruntを使うといい感じにできます。 •
• 正直ちっちゃい規模で環境分割がないなら こぴぺ でもいいんです。 背伸びせずに規模にあったソリューションを選んでください。 Copyright © 3-shake, Inc. All Rights Reserved. 47
怠惰にTerraformを使いたいでござる