Open15
Terraform関連のコマンドを実行するのが面倒なのでラッパーコマンドが欲しい
Golang を使って terraform
や tfupdate
、 tfenv
などをラップするコマンドを作って、コマンド実行時にいちいちディレクトリ移動したり、セットで実行したいコマンドの実行の手間を減らすための試行錯誤。
Summary
tfhq
というコマンドを作る。
課題感
terraformコードをモノレポで管理しているとディレクトリ移動が面倒くさいので簡単に制御できるようにしたい。
なんなら、理想のディレクトリ構成をサクッと作成出来るようにして欲しい。
解決方法
- シェルスクリプト
- シェルスクリプトで書いたことがあって、それはいい感じに使えてたけど多機能なのでコードの見通しが悪かった。
- シェルスクリプトの場合はコードの中身を誰でもデバッグ・変更できるのでそれはそれで良い。
- 専用コマンド
- 作ってみたい。ついでに実装の見直ししたい。
Pros | Cons | |
---|---|---|
シェルスクリプト | - 中身を確認できる。 - カスタムしやすい。 - Unix/Linux/Windows(WSL)であれば実行可能 |
- デバッグの難易度が高い |
コマンド | - デバッグしやすい(テストコードが書ける) - 多機能に作り込みしやすい |
- インストールが必要 - GitHub Actions などでもインストールが必要 |
Specification
# 初期設定
my-cli init
# コンポーネントの追加
my-cli generate
my-cli generate system
my-cli generate env
my-cli generate component
# 対象システムで terraform plan の実行
# `.my-cli/` が存在するディレクトリ配下であれば実行可能
my-cli terraform plan --system system-A --env dev --component setup
my-cli terraform plan -s system-A -e dev -c setup
my-cli tfenv list -s system-A - dev -c setup
my-cli tflint -s system-A - dev -c setup
# 対象システムで terraform plan の実行(非推奨)
my-cli terraform plan --path custom/pash
Sub Commands
-
init
: 初期設定 -
generate
: system/env/componentを追加 -
terraform
: terraform コマンドを実行 -
tenv
: tfenv コマンドを実行 -
tflint
: tflint コマンドを実行 -
tfupdate
: tfupdate コマンドを実行 -
aqua
: aqua コマンドを実行 -
plan
- Commands:
terraform fmt/validate/plan
,tflint
,tfsec
- Option: all components, specific component
- Commands:
-
apply
- Commands:
terraform fmt/validate/apply
,tflint
,tfsec
- Option: all components, specific component
- Commands:
-
show
- Commands:
terraform fmt/validate/show
,tflint
,tfsec
- Option: specific component
- Commands:
-
import
- Commands:
terraform fmt/validate/import
,tflint
,tfsec
- Option: specific component
- Commands:
-
test
- Commands:
terraform fmt/validate/test
,tflint
,tfsec
- Option: all components, specific component
- Commands:
-
tfstate
- Commands:
aws s3 create-bucket
- Commands:
Directory
Basic Constructure
src/
└── terraform/
├── .my-cli/
├── system-A/ # カテゴライズも可能
│ ├── envs.yaml # システムAの環境メタ情報 (AWSアカウント名、バケット名など)
│ └── envs/
│ ├── prod/
│ │ ├── dependencies.yaml # コンポーネントの依存関係を定義
│ │ ├── setup/
│ │ │ ├── main.tf
│ │ │ ├── .terraform-version
│ │ │ ├── variables.tf
│ │ │ ├── outputs.tf
│ │ │ ├── README.md
│ │ │ ├── terraform.tfvars
│ │ │ ├── providers.tf
│ │ │ ├── versions.tf
│ │ │ └── backend.tf
│ │ ├── network/
│ │ ├── security/
│ │ ├── datastore/
│ │ └── app/
│ ├── stg/
│ └── dev/
├── system-B/
│ ├── ...
├── scripts/
│ ├── init.sh
│ ├── apply.sh
│ ├── destroy.sh
│ ├── tflint.sh
│ ├── tfupdate.sh
│ └── aqua.th
└── modules/ # 共通モジュール
# 例: system-A/envs.yaml
environments:
dev:
aws_account_name: "my-dev-account"
region: "us-east-1"
bucket_name: "my-dev-tfstate-bucket"
stg:
aws_account_name: "my-staging-account"
region: "us-east-1"
bucket_name: "my-stg-tfstate-bucket"
prod:
aws_account_name: "my-prod-account"
region: "us-east-1"
bucket_name: "my-prod-tfstate-bucket"
公開方法
- GitHub (Source, Binary)
- Homebrew
Support
- Unix
- Linux
- Windows
Inspired From
シェルスクリプトの方がシンプルだし、基本のディレクトリ構成が欲しいなら GitHub でそれぞれのパターンを用意しておいてコピる方が楽な気もする。
terraformコンポーネントのファイル構成
1. シンプルな構成(小規模プロジェクト)
- 目的: 小規模プロジェクトや単一コンポーネントに適した構成。
- 利点: シンプルで分かりやすい。
terraform/
├── main.tf # 主なリソース定義
├── variables.tf # 入力変数の定義
├── outputs.tf # 出力値の定義
├── terraform.tfvars# 変数の値(オプション、環境ごとに異なる値を設定可能)
├── providers.tf # プロバイダー設定(AWS, GCPなど)
└── versions.tf # Terraformのバージョンやプロバイダーのバージョンをロック
2. モジュールを使った構成(中~大規模プロジェクト)
- 目的: 再利用性の高いモジュール化を目指した構成。
- 利点:
- モジュールを使い回すことで効率的なリソース管理が可能。
- 環境ごとに設定を分離し、デプロイの衝突を防止。
terraform/
├── modules/ # モジュールを格納
│ ├── network/ # ネットワーク関連リソース
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ └── README.md
│ ├── compute/ # コンピュートリソース関連
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ └── README.md
├── environments/ # 環境ごとの設定
│ ├── dev/ # 開発環境
│ │ ├── main.tf
│ │ ├── terraform.tfvars # 環境固有の変数
│ │ └── backend.tf # S3やリモートバックエンド設定
│ ├── prod/ # 本番環境
│ │ ├── main.tf
│ │ ├── terraform.tfvars
│ │ └── backend.tf
├── main.tf # モジュール呼び出し
├── variables.tf # 共通変数
├── outputs.tf # 共通出力
├── providers.tf # プロバイダー設定
└── versions.tf # バージョン管理
3. 高度に組織化された構成(大規模プロジェクトや複雑なインフラ)
- 目的: 大規模チームやマルチクラウド環境での運用。
- 利点:
- 環境ごと、コンポーネントごとに厳密に分離。
- 複数チームが同時並行で作業しやすい。
terraform/
├── modules/ # モジュール
│ ├── network/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ └── README.md
│ ├── compute/
├── environments/ # 環境ごとの設定
│ ├── dev/
│ │ ├── network/
│ │ │ ├── main.tf # モジュール呼び出し
│ │ │ └── terraform.tfvars
│ │ ├── compute/
│ │ │ ├── main.tf
│ │ │ └── terraform.tfvars
│ ├── prod/
│ ├── network/
│ │ ├── main.tf
│ │ └── terraform.tfvars
├── shared/ # 共有設定やポリシー
│ ├── variables.tf
│ ├── outputs.tf
│ └── providers.tf
├── main.tf # 環境ごとのモジュール呼び出し
├── README.md # ドキュメント
└── scripts/ # 補助スクリプト
├── init.sh
├── apply.sh
└── destroy.sh
各ファイルの役割
- main.tf:
• リソースやモジュールの定義を記述。 - variables.tf:
• 入力変数の定義。 - outputs.tf:
• 外部に出力する値(例: VPC ID、EC2 IPなど)。 - terraform.tfvars:
• 環境固有の変数値を記述。 - providers.tf:
• 使用するクラウドプロバイダーの設定(例: AWS, GCP)。 - versions.tf:
• Terraformのバージョンやプロバイダーのバージョンをロック。 - backend.tf:
• Terraformのリモート状態(例: S3)を設定。 - README.md:
• 使用方法や注意事項を記載。
重要なポイント
- リモートバックエンドの利用:
• S3やGCSを使ってTerraformの状態ファイル(terraform.tfstate)をリモート管理するのが推奨されます。 - モジュールの再利用性:
• よく使うリソース(ネットワークやIAM)をモジュール化し、コードの重複を減らします。 - 環境ごとの分離:
• dev, staging, prod などの環境を明確に分離して管理。
Terraform Knowledges
Practice
- Learn Terraform recommended practices | Terraform | HashiCorp Developer
- Welcome | Terraform Best Practices
- 20 Terraform Best Practices to Improve your TF workflow
- 一般的なスタイルと構造に関するベスト プラクティス | Terraform | Google Cloud
Module の利用方法
HCP Terraform
HashiCorp Cloud Platform (HCP)
Open Policy Agent (OPA)
Slide
Books
- 実践Terraform AWSにおけるシステム設計とベストプラクティス | 野村 友規 |本 | 通販 | Amazon
- 詳解 Terraform 第3版 Infrastructure as Codeを実現する
-
Mastering Terraform By Mark Tinderholt , July 2024
- Part 1: Foundations of Terraform
- Chapter 1, Understanding Terraform Architecture
- Part 2: Concepts of Cloud Architecture and Automation
- Chapter 6, Connecting It All Together – GitFlow, GitOps, and CI/CD
- Part 6: Day 2 Operations and Beyond
- Chapter 17, Managing Production Environments with Terraform
- Chapter 18, Looking Ahead – Certification, Emerging Trends, and Next Steps
- Part 1: Foundations of Terraform
-
Terraform Cookbook By Kerim Satirli, Taylor Dolezal, October 2024
- Chapter 2. Terraform Basics
- 2.1 Formatting and Validating Terraform Code
- 2.2 Rapid Experimentation with terraform console
- 2.3 Improving Code Quality with TFLint
- 2.4 Improving Code Quality with TFSec
- 2.5 Validating Code with Preconditions and Postconditions
- 2.6 Validating Code with Open Policy Agent
- Chapter 3. Terraform Syntax Patterns
- Chapter 4. Terraform Modules and Providers
- Chapter 6. HCP Terraform and Terraform Enterprise
- Chapter 7. Consuming and Managing Secrets with Terraform
- Chapter 9. Advanced Terraform Techniques
- 9.3 Implementing Terraform Modules in CI/CD Pipelines
- 9.6 Terraform for Scalable Architectures
- 9.7 Terraform Custom Provider Development
- 9.9 Managing Security and Compliance with Terraform
- Chapter 10. Real-World Use Cases
- Chapter 2. Terraform Basics
-
Terraform in Action By Scott Winkler, July 2021
- 1 Getting started with Terraform
- 2 Life cycle of a Terraform resource
- 3 Functional programming
- 4 Deploying a multi-tiered web application in AWS ★
- 6 Terraform with friends
- 7 CI/CD pipelines as code
- 9 Zero-downtime deployments
- Customizing resource lifecycles with the create_before_destroy flag
- 10 Testing and refactoring
- 12 Automating Terraform
-
Practical GitOps: Infrastructure Management Using Terraform, AWS, and GitHub ActionsBy Rohit Salecha, December 2022
- 今回のメイントピックとは少し違う
- Terraform Cookbook - Second Edition
- Bootstrapping Microservices with Docker, Kubernetes, and Terraform
- System Design on AWS
-
Platform Engineering
- 今回の主題とは違うが良い本
-
Observability Engineering
Terraform と Open Policy Agent(OPA)
Links
Terraform による IaC の実現で実現すべき要素
Keywords
- GitOps
- Format
- Validation
- TFLint
- TFSec
- Precondition
- PostCondition
- Open Policy Agent
- Drift Detection
仕様
Terraform の Style, Module そして Test
-
Style Guide - Configuration Language | Terraform | HashiCorp Developer
- Code style
- Code formatting
- Code validation
- File names
-
backend.tf
: contains backend configuration main.tf
outputs.tf
-
providers.tf
: containsprovider
block -
terraform.tf
: contains a single terraform block which defines your required_version and required_providers. variables.tf
-
locals.tf
: contains local values -
override.tf
: contains override definitions
-
- Linting and static code analysis
- Resource naming
- Resource order
- you should define a data source before the resource that references it.
- Variables
- Outputs
- Local values
- Provider aliasing
- Dynamic resource count
- .gitignore
- Workflow style
- Version pinning
- Module repository names: The Terraform registry requires that repositories match a naming convention for all modules that you publish to the registry. Module repositories must use this three-part name terraform-<PROVIDER>-<NAME>, where <NAME> reflects the type of infrastructure the module manages and <PROVIDER> is the main provider the module uses. The <NAME> segment can contain additional hyphens, for example, terraform-google-vault or terraform-aws-ec2-instance.
- Module structure
- Local module
- Repository structure
- Branching strategy: we recommend using the GitHub flow.
- Multiple environments
- State sharing
- Secrets management
- Integration and unit testing:
- Terraform tests let you validate your modules and catch breaking changes. We recommend that you write tests for your Terraform modules and run them just as you run your tests for your application code, such as pre-merge check in your pull requests or as a prerequisite step in your automated CI/CD pipeline.
- Tests differ from validation methods such as variable validation, preconditions, postconditions, and check blocks. These features focus on verifying the infrastructure deployed by your code, while tests validate the behavior and logic of your code itself. For more information, refer to the Terraform test documentation and the Write Terraform tests tutorial.
- Policy
-
Modules Overview - Configuration Language | Terraform | HashiCorp Developer
- Creating Modules | Terraform | HashiCorp Developer
-
Module Composition | Terraform | HashiCorp Developer
- Dependency Inversion
- Assumptions and Guarantees
- Data-only Modules
-
Refactoring | Terraform | HashiCorp Developer
- Renaming a Resource
- Enabling count or for_each For a Resource
- Renaming a Module Call
- Splitting One Module into Multiple
- Removing moved Blocks
- Build and use a local module | Terraform | HashiCorp Developer
- Write Terraform Tests | Terraform | HashiCorp Developer
Architecting AWS with Terraform By Erol Kavas, December 2023
前半が良かった。
- Part 1:Introduction to IAC and Terraform in AWS
- Chapter 1, Understanding Patterns and Anti-Patterns of IaC and Terraform
- Chapter 2, How Not to Use IaC and Terraform
- Chapter 3, Building Your First Terraform Project
- Chapter 4, Discovering Best Practices for Terraform IaC Projects
- Part 2:Become an Expert in Terraform with AWS
- Chapter 5, Planning and Designing Infrastructure Projects in AWS
- Chapter 6, Making Decisions for Terraform Projects with AWS
- Chapter 7, Implementing Terraform in Projects
- Chapter 8, Deploying Serverless Projects with Terraform
- Chapter 9, Deploying Containers in AWS with Terraform
- Part 3:How to Structure and Advance Terraform in Enterprises
- Chapter 10, Leveraging Terraform for the Enterprise
- Chapter 11, Building Git Workflows for IaC and Terraform Projects
- Chapter 12, Automating the Deployment of Terraform Projects
- Chapter 13, Governing AWS with Terraform
- Chapter 14, Building a Secure Infrastructure with AWS Terraform
- Chapter 15, Perfecting AWS Infrastructure with Terraform
わかりやすい
Figure 1.1 – EKS deployment workflow
Figure 2.4 – Terraform’s workflow
Module creation - recommended pattern | Terraform | HashiCorp Developer ★
- Module creation workflow
- Scope the requirements into appropriate modules
- Create the module MVP
- Explore a scoping example
- Network module
- Application modules
- Database module
- Routing module
- Security module
- Module creation tips
- Nesting modules
- Label and document module elements
- Define and use a consistent module structure
- Collaborate on modules
- Use source control to track modules
- Develop a module consumption workflow
- Make modules easy to use
- Clarify how teams use modules
ログインするとコメントできます