Terraformを使ったAWS構築法

要約

[DevOps] Terraformで始めるAWSインフラ構築: 2026年版実践ガイドとベストプラクティス

Terraformを活用し、AWSインフラを効率的かつセキュアに自動構築するための2026年最新ガイド。

Keywords: Terraform, AWS, IaC

目次

1 はじめに:なぜ今、TerraformとIaCが不可欠なのか

2 Terraformの基本概念とAWSプロバイダの設定

3 Terraform State管理の深掘り:S3とDynamoDB

4 実践!AWS環境構築ステップバイステップ

5 Terraformベストプラクティス:モジュール化とセキュリティ

6 よくある課題と解決策

7 まとめ:Terraformで拓くDevOpsの未来

8 FAQ

INTRODUCTION

1. はじめに:なぜ今、TerraformとIaCが不可欠なのか

2026年現在、クラウドインフラの構築と運用は、ビジネスの成功に直結する重要な要素となっています。特に、変化の激しい現代において、手作業によるインフラ構築は、人的ミス、時間コスト、そしてセキュリティリスクの増大を招きかねません。そこで登場するのが、Infrastructure as Code(IaC)の概念であり、その代表的なツールがTerraformです。

Terraformは、HCL(HashiCorp Configuration Language)という宣言型の言語を用いて、インフラの状態をコードとして定義し、そのコードに基づいてクラウドプロバイダ(AWS, Azure, GCPなど)上のリソースを自動的にプロビジョニング、管理するツールです。これにより、インフラ構築のプロセスは劇的に効率化され、再現性、一貫性、そしてバージョン管理の恩恵を受けることができます。

“IaCは、単なる自動化ツールではありません。それは、インフラ管理をソフトウェア開発と同じ規律とベストプラクティスで扱うための文化的な変革であり、DevOpsの核となるアプローチです。”

— Kwontekiブログ編集部

本記事では、Terraformを使ってAWS上にインフラを自動構築するための実践的なガイドを提供します。初心者の方でも理解できるよう、Terraformの基本的な概念から丁寧に解説し、さらに中級者の方には、2026年現在のベストプラクティス、セキュリティ考慮事項、そしてチーム開発における課題解決策まで深く掘り下げていきます。具体的なコード例を交えながら、あなたのDevOps環境を強化し、運用を効率化するための一助となれば幸いです。

ポイント

IaCは、インフラのバージョン管理、コードレビュー、自動テストを可能にし、手動操作によるヒューマンエラーのリスクを大幅に削減します。

IaCがもたらす主要なメリット

メリット

再現性の向上: 常に同じ環境をデプロイできるため、開発・テスト・本番環境間の差異をなくせます。

デプロイの高速化: 数クリックで複雑なインフラを構築でき、市場投入までの時間を短縮します。

コスト削減: 不要なリソースの削除忘れを防ぎ、リソースの最適化を促進します。

セキュリティの強化: セキュリティポリシーをコードとして管理し、一貫した適用を保証します。

ガバナンスとコンプライアンス: 変更履歴がコードとして残り、監査が容易になります。

これらのメリットは、現代のDevOpsチームにとって不可欠なものであり、Terraformはその実現を強力にサポートします。特にAWSのような広範なサービスを提供するクラウドプロバイダでは、Terraformのようなツールがなければ、手動での管理はほぼ不可能です。

DevOps pipeline with Terraform and AWS


CORE CONCEPTS

2. Terraformの基本概念とAWSプロバイダの設定

Terraformを効果的に利用するためには、いくつかの基本的な概念を理解することが重要です。ここでは、主要な構成要素と、AWSプロバイダを設定する方法について詳しく見ていきましょう。

Terraformの主要な構成要素

Terraformの基本要素

Provider (プロバイダ) — AWS, Azure, GCPなど、Terraformが操作するクラウドプラットフォームやサービスを指します。各プロバイダは、そのサービス特有のリソースを管理するためのAPIとのインタフェースを提供します。

Resource (リソース) — プロバイダが提供する具体的なインフラ要素(EC2インスタンス、S3バケット、VPCなど)を定義します。コードで定義されたリソースが、実際のクラウド環境にプロビジョニングされます。

Data Source (データソース) — 既存のインフラリソースの情報を取得するために使用します。例えば、既に存在するVPCのIDを取得して、新しいリソースをそのVPC内に作成するといった場合に利用します。

Variable (変数) — 設定ファイル内で再利用可能な値を定義します。環境固有の設定(リージョン、インスタンスタイプなど)を外部から渡す際に便利です。

Output (出力) — デプロイされたリソースの特定の属性(IPアドレス、エンドポイントURLなど)をTerraformの実行後に表示したり、他のTerraform設定で使用できるようにします。

Module (モジュール) — 関連するリソースの集合をカプセル化したものです。再利用可能なコンポーネントとして、複雑なインフラを整理し、保守性を高めます。

State (ステート) — Terraformが管理するインフラの現在の状態を記録するファイルです。どのTerraform設定がどのクラウド上のリソースに対応しているかを追跡するために不可欠です。

これらの要素を組み合わせることで、私たちは複雑なAWSインフラを宣言的に定義し、管理することができます。

ポイント

Terraformの宣言的アプローチは、インフラの「最終的な状態」を記述するものであり、その状態に到達するための手順はTerraform自身が判断します。

AWSプロバイダの設定と認証方法

TerraformがAWSリソースを操作するためには、AWSプロバイダを定義し、適切な認証情報を設定する必要があります。最も一般的な認証方法は以下の通りです。

AWS認証方法

1. 環境変数: AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY を設定する方法。開発環境での手軽な認証に適していますが、本番環境では非推奨です。

2. 共有認証情報ファイル (~/.aws/credentials): AWS CLIやSDKが使用する認証情報ファイルを利用します。複数のプロファイル管理が可能です。

3. IAMロール (EC2インスタンスやECSタスク、CodeBuildなど): AWSリソースにIAMロールを割り当てることで、一時的な認証情報が自動的に提供されます。最もセキュアで推奨される方法です。

4. AWS SSO/AssumeRole: AWS SSOを利用している場合や、クロスアカウントでAssumeRoleを使用する場合に、一時的な認証情報を取得して利用します。

コード解説

AWSプロバイダを定義し、デフォルトリージョンをap-northeast-1 (東京リージョン) に設定するTerraformコードです。認証情報は、環境変数やIAMロールなど、Terraformが自動的に検出するメカニズムに依存します。


# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0" # 2026年時点の推奨バージョン
    }
  }
}

provider "aws" {
  region = "ap-northeast-1" # 東京リージョン
  # profile = "my-aws-profile" # ~/.aws/credentials にプロファイルがある場合
  # access_key = "YOUR_ACCESS_KEY" # 環境変数またはIAMロールを推奨
  # secret_key = "YOUR_SECRET_KEY" # 環境変数またはIAMロールを推奨
}

上記のコードは、TerraformがAWSリソースを管理するために必要な最低限の設定です。特に本番環境では、セキュリティの観点からIAMロールを使用した認証を強く推奨します。これにより、認証情報をコードや環境変数に直接記述するリスクを排除し、一時的な認証情報によるアクセス制御が可能になります。

注意

アクセスキーとシークレットキーをTerraformファイルに直接記述することは、セキュリティ上の重大なリスクとなります。環境変数やIAMロール、AWS Secrets Managerなどの安全な方法で管理しましょう。


STATE MANAGEMENT

3. Terraform State管理の深掘り:S3とDynamoDB

Terraform State(状態ファイル)は、Terraformの最も重要な要素の一つです。Terraformは、このStateファイルを使って、実際にデプロイされているインフラリソースと、Terraformコードで定義されたインフラリソースとの対応関係を管理します。Stateファイルがなければ、Terraformはどのリソースを管理しているのか分からなくなり、インフラの変更や削除が適切に行えなくなります。

初期設定では、Stateファイルはローカルディレクトリに terraform.tfstate という名前で保存されます。しかし、このローカルStateは、チーム開発やCI/CDパイプラインでの利用には不向きです。複数の開発者が同時に作業する場合、Stateファイルの競合や上書きが発生するリスクがあるため、リモートState管理が必須となります。

“リモートState管理は、Terraformを実運用で活用するための基盤です。特にS3とDynamoDBの組み合わせは、高い可用性と整合性を提供し、チーム開発における不可欠な要素となります。”

— HashiCorp公式ドキュメントより

AWS S3とDynamoDBによるリモートState管理

AWS環境でTerraformを利用する際、リモートStateの保存先として最も一般的で推奨されるのが、S3バケットとDynamoDBテーブルの組み合わせです。

S3とDynamoDBの役割

S3バケット: Stateファイルの永続的な保存場所として機能します。S3は高い耐久性と可用性を持ち、バージョン管理機能を有効にすることで、Stateファイルの変更履歴を追跡し、誤って上書きされた場合でも復元できるため非常に安全です。

DynamoDBテーブル: Stateファイルのロック機能を提供します。複数の開発者やCI/CDパイプラインが同時に terraform apply を実行しようとした際に、Stateファイルへの同時書き込みを防ぎ、データの破損を防ぎます。これは、競合状態を避けるために不可欠です。

コード解説

S3バケットとDynamoDBテーブルをバックエンドとして設定するTerraformコードです。この設定は、Terraformを実行するすべてのディレクトリのmain.tfまたは別のbackend.tfファイルに記述します。


# backend.tf (または main.tf)
terraform {
  backend "s3" {
    bucket         = "my-kwonteki-terraform-state-2026" # ユニークなS3バケット名
    key            = "dev/network/terraform.tfstate"     # Stateファイルのパス
    region         = "ap-northeast-1"                   # S3バケットのリージョン
    encrypt        = true                               # Stateファイルを暗号化
    dynamodb_table = "my-kwonteki-terraform-lock-2026"  # DynamoDBテーブル名
  }
}

上記のバックエンド設定を適用する前に、まずはS3バケットとDynamoDBテーブルを手動で(または別のTerraform設定で)作成しておく必要があります。

コード解説

S3バケットとDynamoDBテーブルを作成するためのTerraformコードです。これは通常、Stateファイルを保存するルートのTerraformプロジェクトとは別の、より上位の「インフラ基盤」プロジェクトで管理されることが多いです。


# infrastructure-foundation/main.tf (例)
resource "aws_s3_bucket" "terraform_state" {
  bucket = "my-kwonteki-terraform-state-2026"
  tags = {
    Name        = "Terraform State Bucket"
    Environment = "Shared"
  }
}

resource "aws_s3_bucket_versioning" "terraform_state_versioning" {
  bucket = aws_s3_bucket.terraform_state.id
  versioning_configuration {
    status = "Enabled" # バージョニングを有効にする
  }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "terraform_state_encryption" {
  bucket = aws_s3_bucket.terraform_state.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "AES256" # 暗号化を有効にする
    }
  }
}

resource "aws_dynamodb_table" "terraform_lock" {
  name           = "my-kwonteki-terraform-lock-2026"
  hash_key       = "LockID"
  read_capacity  = 5
  write_capacity = 5

  attribute {
    name = "LockID"
    type = "S"
  }

  tags = {
    Name        = "Terraform State Lock Table"
    Environment = "Shared"
  }
}

ポイント

S3バケットのバージョン管理と暗号化は、Stateファイルの安全性と復元性を高めるために必ず有効にすべきです。DynamoDBのロック機能は、並行実行によるState破損を防ぐための生命線です。


PRACTICAL APPLICATION

4. 実践!AWS環境構築ステップバイステップ

それでは、具体的なTerraformコードを使って、AWS上にシンプルなWebサーバー環境を構築する手順を見ていきましょう。ここでは、VPC、サブネット、インターネットゲートウェイ、ルートテーブル、セキュリティグループ、そしてEC2インスタンスを作成します。

プロジェクト構造

まず、プロジェクトのディレクトリ構造を以下のように設定します。

ディレクトリ構造の例

.
├── main.tf
├── variables.tf
├── outputs.tf
└── backend.tf

この構造は、小規模なプロジェクトに適しています。大規模なプロジェクトでは、モジュールや環境ごとのディレクトリ分けを検討します。

ステップ1: backend.tf の設定

前述の通り、リモートState管理は必須です。まずはS3とDynamoDBを利用する設定を記述します。

コード解説

S3バケットとDynamoDBテーブルをバックエンドとして設定します。バケット名とキーパスは、ご自身の環境に合わせて変更してください。


# backend.tf
terraform {
  backend "s3" {
    bucket         = "my-kwonteki-terraform-state-2026"
    key            = "webserver-env/terraform.tfstate"
    region         = "ap-northeast-1"
    encrypt        = true
    dynamodb_table = "my-kwonteki-terraform-lock-2026"
  }
}

ステップ2: variables.tf の定義

環境によって異なる値や、頻繁に変更される可能性のある値を変数として定義します。これにより、コードの再利用性が高まり、管理が容易になります。

コード解説

AWSリージョン、VPCのCIDRブロック、EC2インスタンスタイプ、AMI IDなどを変数として定義します。デフォルト値を設定することで、変数を指定しなかった場合の挙動を明確にできます。


# variables.tf
variable "aws_region" {
  description = "AWS Region"
  type        = string
  default     = "ap-northeast-1"
}

variable "project_name" {
  description = "Project name for tagging resources"
  type        = string
  default     = "KwontekiWebserver"
}

variable "vpc_cidr_block" {
  description = "CIDR block for the VPC"
  type        = string
  default     = "10.0.0.0/16"
}

variable "public_subnet_cidr_block" {
  description = "CIDR block for the public subnet"
  type        = string
  default     = "10.0.1.0/24"
}

variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t3.micro"
}

variable "ami_id" {
  description = "AMI ID for the EC2 instance (Amazon Linux 2023)"
  type        = string
  default     = "ami-0b3273397d3967817" # ap-northeast-1 の Amazon Linux 2023 AMI ID (2026年3月時点の一例)
}

variable "key_pair_name" {
  description = "Name of the EC2 Key Pair to use"
  type        = string
  default     = "kwonteki-keypair" # 既存のキーペア名を指定
}

ステップ3: main.tf の作成

いよいよメインのTerraformコードです。AWSプロバイダの定義から、VPC、サブネット、インターネットゲートウェイ、ルートテーブル、セキュリティグループ、EC2インスタンスまでを順に作成します。

コード解説

AWSプロバイダを設定し、VPCと関連ネットワークリソース、および基本的なセキュリティグループとEC2インスタンスを定義します。EC2インスタンスには、Webサーバー(Apache)をインストールするシェルスクリプトをuser_dataとして渡しています。


# main.tf
provider "aws" {
  region = var.aws_region
}

# ----------------------------------------------------
# VPC
# ----------------------------------------------------
resource "aws_vpc" "main" {
  cidr_block = var.vpc_cidr_block
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name        = "${var.project_name}-VPC"
    Environment = "Development"
  }
}

# ----------------------------------------------------
# Subnet
# ----------------------------------------------------
resource "aws_subnet" "public" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = var.public_subnet_cidr_block
  availability_zone = "${var.aws_region}a" # 例えば ap-northeast-1a
  map_public_ip_on_launch = true # パブリックIPを自動割り当て

  tags = {
    Name        = "${var.project_name}-PublicSubnet"
    Environment = "Development"
  }
}

# ----------------------------------------------------
# Internet Gateway
# ----------------------------------------------------
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name        = "${var.project_name}-IGW"
    Environment = "Development"
  }
}

# ----------------------------------------------------
# Route Table
# ----------------------------------------------------
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        = "${var.project_name}-PublicRouteTable"
    Environment = "Development"
  }
}

resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

# ----------------------------------------------------
# Security Group (for Web Server)
# ----------------------------------------------------
resource "aws_security_group" "web_sg" {
  vpc_id      = aws_vpc.main.id
  name        = "${var.project_name}-WebSecurityGroup"
  description = "Allow HTTP/HTTPS and SSH access"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # HTTP (Webアクセス)
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # HTTPS (Webアクセス)
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] # SSH (管理アクセス)
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"] # 全ての outbound を許可
  }

  tags = {
    Name        = "${var.project_name}-WebSecurityGroup"
    Environment = "Development"
  }
}

# ----------------------------------------------------
# EC2 Instance (Web Server)
# ----------------------------------------------------
resource "aws_instance" "web_server" {
  ami           = var.ami_id
  instance_type = var.instance_type
  subnet_id     = aws_subnet.public.id
  vpc_security_group_ids = [aws_security_group.web_sg.id]
  key_name      = var.key_pair_name
  associate_public_ip_address = true # パブリックIPを割り当て

  user_data = <<-EOF
              #!/bin/bash
              sudo yum update -y
              sudo yum install -y httpd
              sudo systemctl start httpd
              sudo systemctl enable httpd
              echo "<h1>Hello from Kwonteki Terraform!</h1>" | sudo tee /var/www/html/index.html
              EOF

  tags = {
    Name        = "${var.project_name}-WebServer"
    Environment = "Development"
  }
}

ステップ4: outputs.tf の定義

デプロイ後に必要な情報(例: EC2のパブリックIPアドレス)をTerraformの出力として定義します。

コード解説

EC2インスタンスのパブリックIPアドレスを出力として定義します。これにより、terraform apply の実行後に、デプロイされたWebサーバーにアクセスするためのIPアドレスを簡単に確認できます。


# outputs.tf
output "web_server_public_ip" {
  description = "The public IP address of the web server"
  value       = aws_instance.web_server.public_ip
}

output "web_server_public_dns" {
  description = "The public DNS name of the web server"
  value       = aws_instance.web_server.public_dns
}

ステップ5: Terraformコマンドの実行

全てのファイルが準備できたら、以下のコマンドを順に実行してインフラをデプロイします。

1

Terraform初期化

Terraformプロジェクトを初期化し、プロバイダプラグインをダウンロードします。リモートバックエンドを使用する場合、このステップでバックエンド設定が適用されます。


terraform init

2

実行計画の確認

Terraformがどのような変更を行うかを事前に確認します。これにより、意図しないリソースの作成や変更を防ぐことができます。


terraform plan

3

インフラのデプロイ

Terraformが実行計画に基づいてAWSリソースを作成します。確認プロンプトが表示されるので、yes と入力して実行を続行します。


terraform apply

ポイント

デプロイ完了後、terraform output コマンドでWebサーバーのパブリックIPアドレスを確認し、ブラウザでアクセスして「Hello from Kwonteki Terraform!」が表示されるか確認しましょう。

環境を削除したい場合は、以下のコマンドを実行します。

4

インフラの削除

作成したすべてのリソースを削除します。このコマンドも実行計画を確認し、yes と入力することで削除が実行されます。


terraform destroy

BEST PRACTICES

5. Terraformベストプラクティス:モジュール化とセキュリティ

Terraformを本番環境で運用するには、単にコードを記述するだけでなく、保守性、再利用性、そしてセキュリティを考慮したベストプラクティスに従うことが重要です。ここでは、特にモジュール化とセキュリティに焦点を当てて解説します。

“大規模なクラウドインフラを管理する上で、Terraformのモジュールは複雑性を抽象化し、チーム間の連携をスムーズにするための鍵となります。”

— HashiCorp Terraformホワイトペーパー

モジュール化によるコードの再利用と整理

モジュールは、関連するリソースをまとめたTerraformの設定のコンテナです。これにより、コードの再利用、整理、抽象化が可能になります。

モジュール化のメリット

再利用性: 共通のインフラパターン(例: VPC、Webサーバーセットアップ)をモジュールとして定義し、異なるプロジェクトや環境で再利用できます。

保守性: 複雑なインフラを小さな管理しやすい単位に分割することで、コードの可読性とメンテナンス性が向上します。

一貫性: 標準化されたモジュールを使用することで、デプロイされるインフラの一貫性を保ち、設定のばらつきを防ぎます。

抽象化: ユーザーはモジュールの内部実装を知る必要がなく、入力変数と出力値を通じてモジュールを利用できます。

例えば、前述のWebサーバー環境をモジュール化する場合、以下のような構造になります。

コード解説

Webサーバーモジュールを呼び出す親モジュールの例です。これにより、複数のWebサーバー環境を異なる設定で簡単にデプロイできるようになります。


# root/main.tf (親モジュール)
module "web_app_environment" {
  source = "./modules/webserver-stack" # ローカルモジュールへのパス

  project_name          = "ProductionWebApp"
  aws_region            = "ap-northeast-1"
  vpc_cidr_block        = "10.10.0.0/16"
  public_subnet_cidr_block = "10.10.1.0/24"
  instance_type         = "t3.medium"
  ami_id                = "ami-0b3273397d3967817" # Amazon Linux 2023
  key_pair_name         = "prod-keypair"
}

output "prod_web_server_ip" {
  value = module.web_app_environment.web_server_public_ip
}

そして、modules/webserver-stack ディレクトリ内には、先ほどの main.tf と同じ内容のファイルが配置され、変数や出力が適切に定義されます。

Terraform module abstraction flowchart

Terraformにおけるセキュリティベストプラクティス

IaCはインフラのセキュリティをコードとして管理できるため、非常に強力なツールとなりますが、同時に誤った設定が大規模なセキュリティリスクを招く可能性も秘めています。

注意

Terraformコードは機密情報を含む可能性があるため、Gitリポジトリでの管理には特に注意が必要です。公開リポジトリへのプッシュは絶対に避けましょう。

以下の点は、Terraformコードを記述・運用する上で常に意識すべきセキュリティプラクティスです。

セキュリティ対策の要点

1. 最小権限の原則 (Least Privilege): Terraformを実行するIAMユーザー/ロールには、必要最小限の権限のみを付与します。例えば、EC2インスタンスしか作成しないのであれば、S3バケットの作成権限は不要です。

2. 機密情報の管理: データベースのパスワードやAPIキーなどの機密情報は、Terraformコードに直接記述せず、AWS Secrets ManagerやAWS Systems Manager Parameter Storeなどのサービスを利用して安全に管理します。

3. Stateファイルの保護: S3バケットでのバージョン管理、暗号化、アクセス制限(バケットポリシー、IAMポリシー)を徹底し、Stateファイルが外部に漏洩したり、不正に改ざんされたりしないようにします。

4. セキュリティグループの厳格な設定: 必要なポートとIPアドレス範囲のみを許可し、0.0.0.0/0 (全世界からのアクセス) の利用は最小限に留めます。

5. コードレビューと静的解析: Terraformコードも通常のアプリケーションコードと同様に、定期的なコードレビューを実施し、CheckovSentinel のようなツールでセキュリティ脆弱性やベストプラクティス違反を自動的にチェックします。

6. 定期的な監査と監視: AWS ConfigやCloudTrailを利用して、Terraformによる変更が適切に行われているか、セキュリティポリシーに違反していないかを監視します。

これらのプラクティスを実践することで、Terraformを使ったインフラ管理のセキュリティレベルを大幅に向上させることができます。セキュリティは一度設定すれば終わりではなく、継続的な見直しと改善が必要です。

Secure Terraform credential management diagram


TROUBLESHOOTING

6. よくある課題と解決策

Terraformは非常に強力なツールですが、実際の運用ではいくつかの課題に直面することがあります。ここでは、特によく遭遇する問題とその解決策について解説します。

問題 01

State Drift (状態のズレ)

State Driftとは、TerraformのStateファイルに記録されているインフラの状態と、実際のクラウドプロバイダ上のインフラの状態が一致しなくなる現象です。これは、Terraform以外の方法(AWSコンソールでの手動変更など)でリソースが変更された場合に発生します。

解決策 — 定期的な terraform refresh と計画的な変更

terraform refresh コマンドは、Stateファイルを実際のインフラの状態に合わせて更新します。しかし、これはStateファイルを更新するだけで、実際のインフラを変更するわけではありません。State Driftが検出された場合は、手動変更をTerraformコードに反映させるか、terraform plan を実行して変更内容を確認し、terraform apply で修正を適用します。原則として、インフラへの変更はすべてTerraform経由で行うべきです。


# Stateファイルを現在のインフラ状態に合わせて更新
terraform refresh

# 変更計画を確認 (refresh後、driftが検出されると差分が表示される)
terraform plan

# 計画に基づいて修正を適用 (手動変更をコードの状態に戻すか、コードをインフラの状態に合わせる)
terraform apply