ゼロからの Terraform: HCL、プロバイダー、および計画、適用、破棄のサイクル
2026 年、Infrastructure as Code 市場は、Terraform を無視することと同等の成熟度に達しています。 トランザクションを知らずに SQL を記述することは、技術的には可能ですが、専門的には危険です。 HashiCorp の Terraform は本日、 32.8%の市場シェア IaC ツールの中でも、 registry.terraform.io には毎月 400 万件のプロバイダーがインストールされています。このガイドはあなたをゼロから導きます 計画、適用、破棄のサイクルをしっかりと理解した上で、AWS および Azure 上で作業環境を構築する これにより、本番環境でのコストのかかるエラーが回避されます。
IaC に取り組む開発者から最もよく聞かれる質問は次のとおりです。 「ただ使うだけじゃないから bash スクリプトですか、それとも AWS コンソールですか?」。答えは、という概念の中にあります。 宣言型インフラストラクチャ: Terraform には伝えません として リソースを作成します、とあなたは言います どの州 達成したいと思っています。テラフォーム 操作のシーケンスを理解し、リソース間の依存関係を管理し、冪等性を確保することに関係しています。
何を学ぶか
- Terraform をインストールし、複数のバージョンを処理できるように tfenv を構成する
- HCL 構文: ブロック、属性、式、組み込み関数
- 安全な認証を使用して AWS プロバイダーと Azure プロバイダーを構成する
- 完全なライフサイクル:
terraform init,plan,apply,destroy - 状態ファイルの理解: 状態ファイルとは何か、どこに存在するのか、手動で変更してはいけない理由
- スケーラブルな方法で Terraform プロジェクトを最初から構築する
- 変数、ローカル、出力: 専門的な方法で構成を整理します
前提条件とインストール
HCL の最初の行を記述する前に、専門的に環境をセットアップしましょう。 最も一般的な初心者の間違いは、パッケージ マネージャーを使用して Terraform をグローバルにインストールすることです。 そして、特定のバージョンで行き詰まっていることに気づきます。正しい解決策は tfenv、 Terraform のバージョン マネージャー (Node.js の nvm に相当)。
# Installa tfenv (macOS/Linux)
git clone https://github.com/tfutils/tfenv.git ~/.tfenv
echo 'export PATH="$HOME/.tfenv/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
# Installa l'ultima versione stabile di Terraform
tfenv install latest
tfenv use latest
# Verifica installazione
terraform version
# Output: Terraform v1.9.x on linux_amd64
# Installa una versione specifica se il progetto la richiede
tfenv install 1.8.5
tfenv use 1.8.5
# Lista versioni installate
tfenv list
Windows の場合、2026 年および Ubuntu または Chocolatey を使用した WSL2 で推奨されるアプローチ:
# Windows con Chocolatey
choco install terraform
# Oppure scarica il binario da releases.hashicorp.com
# e aggiungilo al PATH manualmente
VS Code プラグインもインストールします HashiCorp Terraform (id: hachicorp.terraform):
構文の強調表示、オートコンプリート、プロバイダーの定義への移動、および統合を提供します。
と terraform fmt。これは、HCL で利用できる最も堅牢な IDE エクスペリエンスです。
HCL: HashiCorp 構成言語
HCL (HashiCorp Configuration Language) は、特別に設計された宣言型言語です。
インフラストラクチャの構成用。これは汎用プログラミング言語ではありません。
命令型ループがありません (使用 for_each e count)、例外はありません。
非同期 I/O はありません。これは 特徴、制限ではありません: シンプルであることで、
構成が偶然複雑になってしまう。
すべての Terraform プロジェクトの基本ファイル main.tf。共通の慣例
そして、構成を次のファイルに分割します。
progetto-terraform/
├── main.tf # Risorse principali
├── variables.tf # Dichiarazione variabili
├── outputs.tf # Output values
├── versions.tf # Required providers e terraform block
├── locals.tf # Valori locali computati
└── terraform.tfvars # Valori delle variabili (non committare se contiene segreti)
基本的なブロック タイプを含む HCL の基本構造は次のとおりです。
# versions.tf — blocco terraform: configura il comportamento del core
terraform {
required_version = ">= 1.8.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.100"
}
}
}
# variables.tf — dichiarazione variabili di input
variable "environment" {
description = "Nome dell'ambiente (dev, staging, prod)"
type = string
default = "dev"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "L'ambiente deve essere dev, staging o prod."
}
}
variable "aws_region" {
description = "AWS Region dove deployare le risorse"
type = string
default = "eu-west-1"
}
variable "instance_count" {
description = "Numero di istanze EC2 da creare"
type = number
default = 2
}
variable "tags" {
description = "Tag comuni da applicare a tutte le risorse"
type = map(string)
default = {
ManagedBy = "Terraform"
Project = "demo"
}
}
# locals.tf — valori computati a partire da variabili
locals {
# Naming convention uniforme
name_prefix = "${var.environment}-${var.tags["Project"]}"
# Merge tag comuni con tag specifici per risorsa
common_tags = merge(var.tags, {
Environment = var.environment
CreatedAt = timestamp()
})
}
AWS プロバイダーを構成する
I プロバイダー Terraform が外部 API と対話できるようにするプラグインです。 AWS、Azure、GCP、Kubernetes、GitHub、Datadog — 事実上すべてのサービスに Terraform プロバイダーがあります。 AWS プロバイダーは最も成熟しており、1,200 を超えるリソース タイプがサポートされています。
AWS認証の場合は、 HCL コードではハードコードされたアクセス キーを決して使用しないでください。 AWS プロバイダーは、優先順位に従って次のモードをサポートします。
# main.tf — configurazione provider AWS
provider "aws" {
region = var.aws_region
# NON fare questo in produzione:
# access_key = "AKIA..." # MAI
# secret_key = "..." # MAI
# Metodo consigliato 1: assume role (best practice per CI/CD)
# assume_role {
# role_arn = "arn:aws:iam::123456789:role/TerraformRole"
# }
# I tag di default vengono applicati a tutte le risorse
default_tags {
tags = local.common_tags
}
}
# Configurazione autenticazione (fuori da main.tf)
# La best practice e usare il file ~/.aws/credentials oppure
# variabili di ambiente:
# export AWS_ACCESS_KEY_ID="..."
# export AWS_SECRET_ACCESS_KEY="..."
# export AWS_DEFAULT_REGION="eu-west-1"
#
# In produzione: IAM Instance Profile o OIDC con GitHub Actions
次に、最初の AWS リソース、つまりパブリック サブネットとプライベート サブネットを持つ VPC を作成しましょう。
# main.tf — prime risorse AWS
# Data source: recupera gli AZ disponibili nella region
data "aws_availability_zones" "available" {
state = "available"
}
# VPC principale
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${local.name_prefix}-vpc"
}
}
# Subnet pubblica (una per AZ)
resource "aws_subnet" "public" {
count = min(length(data.aws_availability_zones.available.names), 2)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index)
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "${local.name_prefix}-public-${count.index + 1}"
Tier = "Public"
}
}
# Subnet privata
resource "aws_subnet" "private" {
count = min(length(data.aws_availability_zones.available.names), 2)
vpc_id = aws_vpc.main.id
cidr_block = cidrsubnet(aws_vpc.main.cidr_block, 8, count.index + 10)
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "${local.name_prefix}-private-${count.index + 1}"
Tier = "Private"
}
}
# Internet Gateway per le subnet pubbliche
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = {
Name = "${local.name_prefix}-igw"
}
}
# Route table pubblica
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = {
Name = "${local.name_prefix}-rt-public"
}
}
# Associazione route table - subnet pubblica
resource "aws_route_table_association" "public" {
count = length(aws_subnet.public)
subnet_id = aws_subnet.public[count.index].id
route_table_id = aws_route_table.public.id
}
# outputs.tf — valori di output
output "vpc_id" {
description = "ID della VPC creata"
value = aws_vpc.main.id
}
output "public_subnet_ids" {
description = "IDs delle subnet pubbliche"
value = aws_subnet.public[*].id
}
output "private_subnet_ids" {
description = "IDs delle subnet private"
value = aws_subnet.private[*].id
}
計画、適用、破棄のサイクル
Terraform ライフサイクルは 4 つの基本的なコマンドで構成されます。それらを徹底的に理解する 生産において最も一般的な事故を回避することが不可欠です。
テラフォームの初期化
# Inizializza il working directory:
# - Scarica i provider (plugin binaries)
# - Configura il backend per lo state
# - Installa i moduli referenziati
terraform init
# Output atteso:
# Initializing the backend...
# Initializing provider plugins...
# - Finding hashicorp/aws versions matching "~> 5.0"...
# - Installing hashicorp/aws v5.54.1...
# Terraform has been successfully initialized!
# Upgrade dei provider all'ultima versione compatibile
terraform init -upgrade
# Ricrea il .terraform.lock.hcl (file di lock dei provider)
terraform providers lock -platform=linux_amd64 -platform=darwin_amd64
.terraform.lock.hcl ファイル
ファイル .terraform.lock.hcl リポジトリにコミットする必要があります。
すべてのチームメンバーと CI パイプラインがまったく同じものを使用することが保証されます。
プロバイダーのバージョンを使用して、インフラストラクチャの「自分のマシンで動作する」を回避します。
ディレクトリ .terraform/ 代わりに、それは .gitignore.
テラフォーム計画
# Genera il piano di esecuzione (DRY RUN)
terraform plan
# Salva il piano in un file binario (consigliato per CI/CD)
terraform plan -out=tfplan
# Specifica le variabili inline
terraform plan -var="environment=staging" -var="instance_count=3"
# Usa un file di variabili
terraform plan -var-file="staging.tfvars"
# Output tipico di plan:
# Terraform will perform the following actions:
#
# # aws_vpc.main will be created
# + resource "aws_vpc" "main" {
# + arn = (known after apply)
# + cidr_block = "10.0.0.0/16"
# + enable_dns_hostnames = true
# ...
# }
#
# Plan: 8 to add, 0 to change, 0 to destroy.
シンボル + 創造を示し、 ~ インプレイス編集、
-/+ 破壊して再作成 (強制ダウンタイム)、 - 破壊。
マークされたブロックを常に注意深く読んでください -/+:
これはリソースを再作成する必要があることを意味し、多くの場合、ダウンタイムやデータ損失が発生します。
テラフォーム適用
# Applica le modifiche (chiede conferma interattiva)
terraform apply
# Applica il piano salvato (NON chiede conferma - usare in CI/CD)
terraform apply tfplan
# Auto-approve per ambienti non critici (attento in prod!)
terraform apply -auto-approve
# Apply con variabili
terraform apply -var="environment=prod" -var-file="prod.tfvars"
# Output dopo apply:
# Apply complete! Resources: 8 added, 0 changed, 0 destroyed.
#
# Outputs:
# vpc_id = "vpc-0123456789abcdef0"
# public_subnet_ids = [
# "subnet-0abc123def456gh78",
# "subnet-0def456abc789ij01",
# ]
テラフォームの破壊
# Distrugge TUTTE le risorse gestite dallo state corrente
terraform destroy
# Destroy con auto-approve (ATTENZIONE: irreversibile)
terraform destroy -auto-approve
# Distrugge solo una risorsa specifica (con grande cautela)
terraform destroy -target=aws_subnet.public[0]
# In produzione, preferisci eliminare le risorse dal codice
# e fare terraform apply: Terraform le distruggerà correttamente
アンチパターン: 本番環境での terraform の破壊
決して走らないでください terraform destroy 回復計画なしで。
ベスト プラクティスは、HCL コードからリソースを削除して実行することです。 terraform apply:
同じ結果が得られますが、最初に確認できる明示的な計画が必要です。
一部の組織は、IAM ポリシー レベルで破棄を実行する機能をブロックしています。
本番環境で。
Azureプロバイダーを構成する
プロバイダー アズレルム Azure リソースを管理します。 AWSと違って、 Azure では、認証にサービス プリンシパルまたはマネージド ID を使用します。
# versions.tf aggiornato con provider Azure
terraform {
required_version = ">= 1.8.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.100"
}
}
}
# Configurazione provider Azure
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = true
}
key_vault {
purge_soft_delete_on_destroy = false
recover_soft_deleted_key_vaults = true
}
}
# Autenticazione via variabili d'ambiente (consigliato)
# ARM_CLIENT_ID, ARM_CLIENT_SECRET, ARM_TENANT_ID, ARM_SUBSCRIPTION_ID
# oppure Azure CLI: az login
}
# Risorse Azure di base
resource "azurerm_resource_group" "main" {
name = "${local.name_prefix}-rg"
location = "West Europe"
tags = local.common_tags
}
resource "azurerm_virtual_network" "main" {
name = "${local.name_prefix}-vnet"
address_space = ["10.1.0.0/16"]
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
tags = local.common_tags
}
resource "azurerm_subnet" "public" {
name = "public-subnet"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.1.1.0/24"]
}
resource "azurerm_subnet" "private" {
name = "private-subnet"
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.1.2.0/24"]
}
変数、ローカル、データ ソース
変数、ローカル、データ ソースを上手に使用すると、Terraform 構成が区別されます アドホックスクリプトのプロフェッショナル。基本的なパターンは次のとおりです。
# Tipi di variabili in HCL
# Stringa semplice
variable "app_name" {
type = string
default = "myapp"
}
# Numero con validazione
variable "min_instances" {
type = number
default = 1
validation {
condition = var.min_instances >= 1 && var.min_instances <= 10
error_message = "Il numero di istanze deve essere tra 1 e 10."
}
}
# Lista di stringhe
variable "allowed_cidr_blocks" {
type = list(string)
default = ["10.0.0.0/8"]
}
# Map di stringhe
variable "database_config" {
type = map(string)
default = {
engine = "postgres"
version = "15.4"
size = "db.t3.medium"
}
}
# Oggetto con schema tipizzato
variable "network_config" {
type = object({
vpc_cidr = string
subnet_count = number
enable_nat = bool
})
default = {
vpc_cidr = "10.0.0.0/16"
subnet_count = 2
enable_nat = false
}
}
# Locals: valori computati (non input dall'utente)
locals {
# Concatenazioni
full_name = "${var.environment}-${var.app_name}"
# Condizionale ternario
instance_type = var.environment == "prod" ? "t3.medium" : "t3.micro"
# Ciclo su lista (for expression)
subnet_cidrs = [
for i in range(var.network_config.subnet_count) :
cidrsubnet(var.network_config.vpc_cidr, 8, i)
]
# Map transformation
tag_map = {
for k, v in var.database_config :
"db_${k}" => v
}
}
# Data sources: recuperano informazioni da risorse esistenti
# non gestite da questo state
# AMI Amazon Linux 2023 piu recente
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}
# Account ID corrente (utile per ARN)
data "aws_caller_identity" "current" {}
# Uso nei resource:
# ami = data.aws_ami.amazon_linux.id
# account_id = data.aws_caller_identity.current.account_id
状態ファイル: Terraform の核心
ファイル terraform.tfstate Terraform の「真実の情報源」です。すべてのアセットをマップします。
HCL で定義されたものを、クラウド上の現実世界の対応物に合わせて定義します。どのように機能するかを理解することが不可欠です
最も深刻な問題を回避します。
// Struttura semplificata di terraform.tfstate
{
"version": 4,
"terraform_version": "1.9.0",
"serial": 42,
"lineage": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"outputs": {
"vpc_id": {
"value": "vpc-0123456789abcdef0",
"type": "string"
}
},
"resources": [
{
"mode": "managed",
"type": "aws_vpc",
"name": "main",
"provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
"instances": [
{
"schema_version": 1,
"attributes": {
"id": "vpc-0123456789abcdef0",
"cidr_block": "10.0.0.0/16",
"enable_dns_hostnames": true,
...
}
}
]
}
]
}
状態ファイルの黄金律
- 決して編集しないでください
terraform.tfstate手動で - 決してコミットしないでください Git リポジトリにそれを記述します (
.gitignore) - チームで使用する 常にリモート バックエンド ロック付き (シリーズの記事 03 を参照)
- 国家はそれを封じ込めることができる 公になった秘密 (RDS パスワード、認証情報): これを機密データとして扱います
- 危険な作業の前に、 手動バックアップを実行する:
terraform state pull > backup.tfstate
状態検査コマンド
# Lista tutte le risorse gestite dallo state
terraform state list
# Mostra i dettagli di una risorsa specifica
terraform state show aws_vpc.main
# Rinomina una risorsa nello state (senza toccare l'infrastruttura)
terraform state mv aws_subnet.public aws_subnet.public_new
# Rimuove una risorsa dallo state (Terraform non la gestirà piu)
# La risorsa rimane nel cloud ma non è piu "owned" da Terraform
terraform state rm aws_subnet.private[0]
# Importa una risorsa esistente nello state
# (vedi articolo 03 per dettagli)
terraform import aws_vpc.main vpc-0123456789abcdef0
# Mostra l'output senza fare apply
terraform output vpc_id
terraform output -json # tutti gli output in formato JSON
推奨されるプロジェクト構造
実際のプロジェクトでは、単一のディレクトリ構造はすぐに管理できなくなります。 本番環境で Terraform インフラストラクチャを編成するための 2 つの一般的なパターンを次に示します。
# Pattern 1: Organizzazione per ambiente
infra/
├── modules/ # Moduli riusabili
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── compute/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
├── environments/
│ ├── dev/
│ │ ├── main.tf # Usa i moduli
│ │ ├── variables.tf
│ │ ├── terraform.tfvars # Valori specifici per dev
│ │ └── versions.tf
│ ├── staging/
│ │ └── ...
│ └── prod/
│ └── ...
└── .gitignore # Esclude .terraform/, *.tfstate
# Pattern 2: Terragrunt (wrapper per DRY)
infra/
├── terragrunt.hcl # Config globale
├── modules/
│ └── networking/
├── live/
│ ├── dev/
│ │ └── networking/
│ │ └── terragrunt.hcl
│ └── prod/
│ └── networking/
│ └── terragrunt.hcl
始めるためのベストプラクティス
理論を見た後、Terraform を使用する人を区別する経験則を次に示します。 初日から技術的負債を生み出す人々によって正しく行われます。
# 1. Formatta sempre prima di committare
terraform fmt -recursive
# 2. Valida la sintassi
terraform validate
# 3. Usa tflint per linting avanzato (trova deprecazioni, pattern errati)
tflint --init
tflint
# 4. Esegui checkov per security scanning
pip install checkov
checkov -d .
# 5. Pre-commit hooks per automatizzare tutto
# .pre-commit-config.yaml
# repos:
# - repo: https://github.com/antonbabenko/pre-commit-terraform
# hooks:
# - id: terraform_fmt
# - id: terraform_validate
# - id: terraform_tflint
# - id: terraform_checkov
Terraform の .gitignore
# .gitignore per progetti Terraform
.terraform/
*.tfstate
*.tfstate.backup
*.tfstate.*.backup
.terraform.tfstate.lock.info
*.tfvars # Se contengono segreti (crea terraform.tfvars.example)
override.tf
override.tf.json
*_override.tf
*_override.tf.json
crash.log
.terraformrc
terraform.rc
完全な例: AWS 上の Web アプリ
実際の例ですべてをまとめてみましょう: セキュリティ グループを持つ EC2 インスタンス、 ロード バランサーと RDS データベースが正しく構造化されていること。
# main.tf — infrastruttura web app completa
# Security Group per le istanze web
resource "aws_security_group" "web" {
name = "${local.name_prefix}-sg-web"
description = "Security group per istanze web"
vpc_id = aws_vpc.main.id
ingress {
description = "HTTP dal load balancer"
from_port = 80
to_port = 80
protocol = "tcp"
security_groups = [aws_security_group.alb.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = { Name = "${local.name_prefix}-sg-web" }
}
# Security Group per ALB
resource "aws_security_group" "alb" {
name = "${local.name_prefix}-sg-alb"
description = "Security group per Application Load Balancer"
vpc_id = aws_vpc.main.id
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# Launch Template per le istanze EC2
resource "aws_launch_template" "web" {
name_prefix = "${local.name_prefix}-lt-"
image_id = data.aws_ami.amazon_linux.id
instance_type = local.instance_type
network_interfaces {
associate_public_ip_address = false
security_groups = [aws_security_group.web.id]
}
user_data = base64encode(<<-EOF
#!/bin/bash
dnf update -y
dnf install -y nginx
systemctl enable nginx
systemctl start nginx
echo "Deploy Terraform - ${var.environment}
" > /usr/share/nginx/html/index.html
EOF
)
tag_specifications {
resource_type = "instance"
tags = merge(local.common_tags, {
Name = "${local.name_prefix}-web"
})
}
}
# Auto Scaling Group
resource "aws_autoscaling_group" "web" {
name = "${local.name_prefix}-asg"
vpc_zone_identifier = aws_subnet.private[*].id
target_group_arns = [aws_lb_target_group.web.arn]
health_check_type = "ELB"
min_size = var.environment == "prod" ? 2 : 1
max_size = var.environment == "prod" ? 6 : 2
desired_capacity = var.environment == "prod" ? 2 : 1
launch_template {
id = aws_launch_template.web.id
version = "$Latest"
}
tag {
key = "Name"
value = "${local.name_prefix}-web"
propagate_at_launch = true
}
}
# Application Load Balancer
resource "aws_lb" "main" {
name = "${local.name_prefix}-alb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.alb.id]
subnets = aws_subnet.public[*].id
enable_deletion_protection = var.environment == "prod"
tags = local.common_tags
}
resource "aws_lb_target_group" "web" {
name = "${local.name_prefix}-tg-web"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.main.id
health_check {
enabled = true
healthy_threshold = 2
unhealthy_threshold = 3
timeout = 5
interval = 30
path = "/health"
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.main.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.web.arn
}
}
結論と次のステップ
これで、Terraform を専門的に操作するための強固な基盤ができました。構文を理解しました。 HCL さん、AWS および Azure プロバイダーの構成方法を理解しており、計画、適用、破棄のサイクルとルールを理解しています。 状態ファイルを安全に管理するために不可欠です。
Terraform を使用した成長における次の自然なステップは、コードを整理することを学ぶことです で 再利用可能なモジュール: インフラストラクチャが 200 ~ 300 行を超えると HCL では、保守性を確保するためにモジュール化が不可欠になります。
完全なシリーズ: Terraform と IaC
- 第01条(本) — ゼロからの Terraform: HCL、プロバイダー、およびプラン、適用、破棄
- 第02条 — 再利用可能な Terraform モジュールの設計: 構造、I/O、およびレジストリ
- 第03条 — Terraform 状態: S3/GCS を使用したリモート バックエンド、ロックおよびインポート
- 記事 04 — CI/CD の Terraform: GitHub アクション、Atlantis、およびプル リクエストのワークフロー
- 第 05 条 — IaC テスト: Terratest、Terraform ネイティブ テスト、および契約テスト
- 第 06 条 — IaC セキュリティ: Checkov、Trivy、OPA のポリシー・アズ・コード
- 記事 07 — Terraform マルチクラウド: 共有モジュールを使用した AWS + Azure + GCP
- 記事 08 — Terraform 用 GitOps: Flux TF コントローラー、スペースリフトおよびドリフト検出
- 記事 09 — Terraform vs Pulumi vs OpenTofu: 最終比較 2026
- 第 10 条 — Terraform エンタープライズ パターン: ワークスペース、センチネル、チーム スケーリング
公式リソース
- Terraform 公式ドキュメント
- Terraform レジストリ — プロバイダー、モジュール、ポリシー
- HashiCorp Learn — インタラクティブなチュートリアル







