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
tfactionで作るTerraform CI統制 〜 apply実行基盤の構築に向けて 〜
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Sugita
September 17, 2026
250
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
tfactionで作るTerraform CI統制 〜 apply実行基盤の構築に向けて 〜
Sugita
September 17, 2026
More Decks by Sugita
See All by Sugita
SLAを満たすディザスタリカバリ(DR)構成 〜東京-大阪リージョン間の切り替え設計〜
sugitaseiya
0
600
SLAチェックしてみたら…マルチAZ未対応!? その改善プロセス
sugitaseiya
0
1.2k
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.4k
Fashionably flexible responsive web design (full day workshop)
malarkey
409
67k
Facilitating Awesome Meetings
lara
57
7.1k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
290
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
3.1k
Believing is Seeing
oripsolob
1
220
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.1k
How STYLIGHT went responsive
nonsquared
100
6.3k
GraphQLとの向き合い方2022年版
quramy
50
15k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
500
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
6.2k
Raft: Consensus for Rubyists
vanstee
142
7.7k
Transcript
tfactionで作るTerraform CI統制 〜 apply実行基盤の構築に向けて 〜 2026.09.17 SRE 杉田 青哉 Tamachi.sre
https://tamachi-sre.connpass.com/event/402227/
自己紹介 名前: 杉田 青哉 所属: ENECHANGE株式会社 SRE・infraチーム 技術スタック: AWS, Ruby
経歴 2023年1月 ENECHANGE入社 ウェブアプリケーション開発に従事 2025年4月 SREチーム発足 SREとしてオブザーバビリティや信頼性向上に注力 X: @Mnbvc124 Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 2
INDEX 目次 01 現状の課題と目指す理想像 02 Terraform CIの全体像 03 設計上の4つの判断 04
導入後の変化と今後 3 Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 3
現状の課題と目指す理想像 4 Copyright © ENECHANGE Ltd., All rights reserved. Confidential
/ not for distribution LON 4
前提: ENECHANGEのTerraform運用 複数プロダクトのインフラをTerraformで管理している 複数プロダクト 複数リポジトリ プロダクトごとにインフラをTerraformでコード管理 CIを入れる対象のTerraformリポジトリも複数ある この規模感が、後述するCI設計の判断に関わってくる Copyright ©
ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 5
課題 Terraform運用には大きく2つの課題があった 1 変数の値がローカル管理で、CIでplanを実行できない input variablesの値は各自のローカルにしかなく、CI上でplanが動か せない。plan結果がレビューに乗らず、レビュアーも変更の影響を 確認できなかった # 例)
xxxx.tf variable "instance_type" {} resource "aws_instance" "app" { instance_type = var.instance_type } ※ input variables = 外部から値を渡せるTerraformの変数 2 applyの実行経路が統制されていない 承認がなくてもterraform applyを実行できる状態で、 いつ・誰がapplyしたかを管理できていない Copyright © ENECHANGE Ltd., All rights reserved. local$ terraform apply # 承認なしでも実行できてしまう Confidential / not for distribution LON 6
目指す理想像 「開発者はPRを出すだけ、統制は仕組みが担保する」 変数の値を外から渡さない 値はAWS側(SSM Parameter Store等)の参照で解決し、ローカルに値を持たない。 CIだけでplanが完結する planはPRで自動実行 結果がPR上で確認でき、エラーならマージできない applyはCI経由のみ
ローカルからの実行経路を閉じる Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 7
理想に至る3ステップと現在地 目指す姿: 開発者はPRを出すだけ、統制は仕組みが担保する 今ここ(本発表) ステップ 1 ステップ 2 ステップ 3
input variablesの廃止 Terraform CIの強化 apply実行経路の標準化 秘匿情報はSSM Parameter Storeへ 固定値はlocalsに置き換え tfactionでplanを自動検証し エラーはマージブロック ローカルからのapplyを閉じ 統制された経路へ一本化 完了 対応中 今後 input variablesが残るとCIのplanが失敗するため 1 → 2 の順、 planの品質担保がapply統制の前提となるため 2 → 3 の順で進める Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 8
Terraform CIの全体像 9 Copyright © ENECHANGE Ltd., All rights reserved.
Confidential / not for distribution LON 9
CIに求めたことと、tfactionの採用 CIの強化にあたって、求めたことは次のとおり CIを強化して、最低限のガバナンス・統制を利かせる 変更したディレクトリだけplanが動き、結果がPRに表示され、失敗したらマージできない → tfactionを採用 変更検出・並列plan・PRコメント・マージブロックをすべて自作するのは実装・保守コストが見合わない。 tfactionはこれらが部品として揃っており、tflintやconftestなどのチェックを段階的に足せる ※ tfaction
= GitHub Actions で Terraform のワークフローを組むためのフレームワーク(OSS / suzuki-shunsuke 氏作) Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 10
CIの全体像 PRの作成・更新をトリガーに、4つのジョブが実行される PRを作成 / 更新 list 変更ファイルから plan 対象ディレクトリを検出 check-tfaction-yaml
tfaction.yaml の置き忘れを検知 check-and-plan GitHub Actionsのmatrixで、対象ディレクトリごとにジョブを生成して 並列実行 → init → fmt / validate → tflint → trivy → conftest → plan plan結果は tfcmt がPRコメントに投稿 ※ tfcmt = plan/apply結果を整形してPRコメントに投稿するツール ※ trivyのみ警告モード(詳細は後述) status-check Copyright © ENECHANGE Ltd., All rights reserved. 全ジョブの成否を集約 = required check Confidential / not for distribution LON 11
設計上の4つの判断 12 Copyright © ENECHANGE Ltd., All rights reserved. Confidential
/ not for distribution LON 12
設計上の4つの判断 この構成には、設計上の判断が4つある。順に説明する 1 plan対象はホワイトリスト方式で管理する 2 「置き忘れ」を構造的に防ぐ 3 マージブロックは集約ジョブで実現する 4 CI本体は専用リポジトリに集約する(Reusable
Workflow化) Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 13
判断①: plan対象はホワイトリスト方式で管理する tfactionは tfaction.yaml を置いたディレクトリだけをplan対象とみなす。除外設定は存在しない ディレクトリ構成のイメージ やったこと ・既存のroot module(backend定義を持つディレクトリ)すべ てに、中身
{} の tfaction.yaml を一括配置 product-a/ ・docsやmodules配下には置かない prod/ stg/ # backend定義を持つ terraform { required_providers { ... } backend "s3" { bucket = "xxxx" key = "xxxx" } } Copyright © ENECHANGE Ltd., All rights reserved. docs/ Confidential / not for distribution (backend 定義あり + tfaction.yaml) (backend 定義あり + tfaction.yaml) (置かない ) LON plan対象 plan対象 plan対象外 14
判断②: 「置き忘れ」を構造的に防ぐ ホワイトリスト方式には弱点がある 新しくroot moduleを作ったときに tfaction.yaml を置き忘れると、planが一度も実行されないまま静かにマージされてしまう → ガードジョブ check-tfaction-yaml
を追加 「backend定義があるのに tfaction.yaml がない」ディレクトリを検知して失敗させる。置き忘れはCIの失敗として顕在化し、チェッ ク漏れの経路が構造的に塞がる 新規作成時の対応は1行だけ $ echo '{}' > path/to/new-dir/tfaction.yaml Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 15
判断③: マージブロックは集約ジョブで実現する どれか1つでもplanが失敗したら、確実にマージを止めたい planが1つ失敗しても、マージできてしまう plan (dirA) ✓ plan (dirB) ✓
plan (dirC) ✗ → それでもマージ可 マージ条件は固定のチェック名単位でしか見られない planジョブはディレクトリごとに別名で生成されるため、すべてを登録して見張ることができない → 全ジョブの成否を status-check に集約し、これ1つをマージ条件に登録 どれか1つでも失敗すれば status-check が失敗し、確実にマージが止まる Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 16
判断④: CI本体は専用リポジトリに集約する(Reusable Workflow化) CIを入れる対象のTerraformリポジトリは複数ある 各リポジトリにワークフローやポリシーをコピーして回ると、修正のたびに全リポジトリへ反映する作業が発生し、バージョンもば らけていく → 専用リポジトリに集約し、各リポジトリはReusable Workflowとして呼び出すだけ ・集約したもの:
CIのロジック / 自社ポリシー(Regoとそのテスト)/ 各パッケージのバージョン管理(aqua)/ tfcmtのテンプレート ・CI本体を1つのリポジトリにまとめて、共通ワークフロー(Reusable Workflow)として全リポジトリに展開することで、 組織全体で統制 Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 17
Lintとポリシーチェックの組み込み 実行順: init → fmt -check / validate → tflint
→ trivy → conftest → plan チェック 扱い 内容 terraform fmt / validate マージブロック フォーマット崩れ、構文・参照エラー tflint マージブロック required_versionの欠如、未使用宣言などの品質ルール違反 conftest マージブロック 自社ポリシー違反(次ページ) terraform plan マージブロック plan自体の失敗 trivy 警告のみ セキュリティ設定ミス(公開S3、SG全開放など) trivyだけを警告モードにしている理由 既存コードへの指摘が一定数あり、導入と同時にブロックすると既存コードに触るすべてのPRが止まる。 まず指摘を可視化して棚卸しし、完了後にマージブロックへ昇格させる段階導入 Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 18
conftestによる自社ポリシー①: variable宣言の禁止 ステップ1で廃止したinput variablesが新しいコードで再び書かれることを、レビューではなく仕組みで防ぐ ✗ NG: variable宣言 → conftestがブロック variable
"instance_type" { type = string } ✓ OK: 置き換え先までエラーメッセージで案内 # 固定値は locals に locals { app_port = 3000 } # 既存リソースの参照は data に data "aws_ssm_parameter" ... ポリシー自体の品質もCIで担保 意図的に除外したい場合の設計 ・Regoは本体とテストをペアで専用リポジトリに配置 ・原則「できるだけ狭い範囲で、理由をコメントに書いて除外」 Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 19
conftestによる自社ポリシー②: コスト配分タグの強制 moduleのリリースタグの最新バージョンを使用していることもチェックする ✗ 違反時のエラーメッセージ(実際の出力) ✓ 求めるパターン(例) FAIL xxx/xxx.tf module
"tags" の ref が最新ではありません (現在: v0.2.1 )。source の ?ref= を 最新バージョン v0.3.0 に更新してください provider "aws" { default_tags { tags = module.tags.default_tags } 18 tests, 17 passed, 1 failure } module "tags" { source = "…/module?ref=v0.3.0" } → 有効化はリポジトリ側の1行だけ。オプトイン方式を採用 with: cost_tags_policy: true 管理したいタグがアカウントごとに異なるためオプトイン方式に。 ポリシー本体は専用リポジトリ(判断④)にあり、必要なリポジトリから1行で有効化できる Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 20
導入後の変化と今後 21 Copyright © ENECHANGE Ltd., All rights reserved. Confidential
/ not for distribution LON 21
導入後に変わったこと 個人の注意力に頼らない 品質チェック(lint指摘・モジュールのバージョン違反・plan失敗)をCIで統制し、失 敗したPRはマージできない 誰でも異常に気づける仕組み チェック結果はすべてPR上にCIの結果として表示され、開発者もレビュアーも同じ情 報を見られる 組織で全体で統制される CI本体を1つのリポジトリにまとめて、共通ワークフロー(Reusable Workflow)とし
て全リポジトリに展開 Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 22
今後: apply経路の標準化へ planの品質をマージ前に担保できるようになったため、次はステップ3に進む planでは防げない失敗がある planはstateと設定の差分を計算するもの。 サービスクォータやAPIレベルの制約など、applyして初めて分かる失敗までは防げない。 こうした失敗の検知・処理も含めて実行経路を設計していく 検討中の方針 applyの実行をローカルから切り離し、承認と実行をGitHubの外(AWS側)に置く 「開発者はPRを出すだけ、統制は仕組みが担保する」まで、あと一歩
Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 23
おまけ: tfactionの利用企業一覧に掲載されました 利用表明とフィードバックも、OSSへの貢献のひとつ "Thank you for using tfaction and sharing
a nice post!" — suzuki-shunsuke さん(tfaction作者)からの返信 本CIは tfaction / tfcmt / aqua など、suzuki-shunsukeさんのOSSに支えられています。感謝を込めて Copyright © ENECHANGE Ltd., All rights reserved. Confidential / not for distribution LON 24
Confidential © ENECHANGE Ltd. Copyright © ENECHANGE Ltd., All rights
reserved. Confidential / not for distribution LON 25