1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Terraformのインストールから基本的な使い方まで徹底解説

1
Last updated at Posted at 2026-03-16

はじめに

Terraformは、HashiCorpが開発したInfrastructure as Code(IaC)ツールです

HCL(HashiCorp Configuration Language)でインフラ構成をコードとして定義し、コマンド一つでAWSリソースの作成・変更・削除ができます

AWSにはIaCツールとして純正のCloudFormationがありますが、Terraformにはマルチクラウド対応や、HCLによる簡潔な記述、豊富なコミュニティモジュールといった強みがあります
一方、CloudFormationはAWSネイティブのためAWSサポートを受けられる点や、スタックの自動ロールバック機能が魅力です
両者の詳しい比較は記事末尾の比較表にまとめています

この記事では、Terraformのインストールから認証設定、実践的な使い方まで、実際のコマンド例を交えて解説します

この記事でわかること

  • Terraformのインストール方法(Windows/Linux/Mac)
  • AWS認証の設定方法
  • Terraformの基本コマンド(init / plan / apply / destroy)
  • VPCの作成
  • セキュリティグループの作成
  • EC2インスタンスの作成とSSH接続
  • tfstateファイルの管理
  • 変数とoutputの活用

前提条件

  • AWSアカウントを持っている
  • AWS CLIがインストール・設定済み(aws configure 完了済み)
  • 基本的なコマンドライン操作ができる

AWS CLIの設定がまだの方は以下の記事を参考にしてください
AWS CLIのインストールから実践的な使い方まで徹底解説

手順1: Terraformのインストール

Windows

手動インストール

  1. Terraform公式ダウンロードページからWindows用ZIPをダウンロード
  2. ZIPを展開し、terraform.exe を任意のフォルダに配置(例: C:\terraform
  3. 環境変数のPathに配置先フォルダを追加

Chocolateyを使う場合

choco install terraform

Linux

sudo apt-get update && sudo apt-get install -y gnupg software-properties-common

HashiCorpのGPGキーを追加:

wget -O- https://apt.releases.hashicorp.com/gpg | \
  gpg --dearmor | \
  sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg > /dev/null

リポジトリを追加:

echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
  https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
  sudo tee /etc/apt/sources.list.d/hashicorp.list

インストール:

sudo apt-get update && sudo apt-get install terraform

Mac

Homebrewを使用:

brew tap hashicorp/tap
brew install hashicorp/tap/terraform

インストール確認(全OS共通)

terraform version

出力例(Windows):

image.png

ヘルプの表示:

terraform -help

手順2: AWS認証の設定

TerraformがAWSリソースを操作するには、AWS認証情報が必要です

方法1: AWS CLIの設定を利用(推奨)

AWS CLIで aws configure を実行済みであれば、Terraformは自動的に ~/.aws/credentials を参照します

aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: ap-northeast-1
Default output format [None]: json

方法2: 環境変数を使用

Windows(PowerShell):

$env:AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
$env:AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
$env:AWS_DEFAULT_REGION="ap-northeast-1"

Mac/Linux:

export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
export AWS_DEFAULT_REGION="ap-northeast-1"

方法3: AWS CLIのプロファイルを指定

provider "aws" {
  region  = "ap-northeast-1"
  profile = "Administrator"
}

複数のAWSアカウントを使い分ける場合に便利です

認証の確認

設定が正しいか確認するには、以下のコマンドを実行します

aws sts get-caller-identity

出力例:

{
    "UserId": "AIDAIOSFODNN7EXAMPLE",
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/terraform-user"
}

手順3: Terraformの基本構成

Terraformはディレクトリ単位でリソースを管理するため、専用のフォルダを作成し、役割ごとにファイルを分割します
main.tfにインフラの定義、variables.tfに設定値の変数、outputs.tfに作成後の出力情報を定義します

プロジェクトディレクトリの作成

mkdir terraform-ec2-demo

Windows(PowerShell):

New-Item -ItemType Directory -Path terraform-ec2-demo

ファイル構成

Terraformプロジェクトの基本的なファイル構成は以下の通りです

terraform-ec2-demo/
├── main.tf          # メインのリソース定義
├── variables.tf     # 変数定義
├── outputs.tf       # 出力定義
├── terraform.tfvars # 変数の値(Git管理外にすることも可能)
└── .gitignore       # Git管理外ファイルの指定

.gitignoreの作成

Terraformプロジェクトでは以下のファイルをGit管理外にします

# Terraform
.terraform/
*.tfstate
*.tfstate.backup
*.tfvars
.terraform.lock.hcl

手順4: VPCとサブネットの作成

AWS のネットワーク基盤(VPC 環境)を Terraform で作成します
VPC、パブリックサブネット、Internet Gateway、ルートテーブルを定義し、インターネットに接続可能なネットワークを構築します
これにより、後で作成する EC2 インスタンスがインターネット通信できる環境を準備しています

main.tfの作成

# プロバイダーの設定
terraform {
  required_version = ">= 1.0.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

# VPCの作成
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name = "${var.project_name}-vpc"
  }
}

# パブリックサブネットの作成
resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "${var.aws_region}a"
  map_public_ip_on_launch = true

  tags = {
    Name = "${var.project_name}-public-subnet"
  }
}

# Internet Gatewayの作成
resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "${var.project_name}-igw"
  }
}

# ルートテーブルの作成
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}-public-rt"
  }
}

# ルートテーブルとサブネットの関連付け
resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

variables.tfの作成

variable "aws_region" {
  description = "AWSリージョン"
  type        = string
  default     = "ap-northeast-1"
}

variable "project_name" {
  description = "プロジェクト名(リソースのタグに使用)"
  type        = string
  default     = "terraform-demo"
}

variable "key_name" {
  description = "EC2キーペア名"
  type        = string
  default     = "test-ec2-key"
}

variable "my_ip" {
  description = "SSH接続を許可するIPアドレス(CIDR形式)"
  type        = string
  default     = "0.0.0.0/0"
}

outputs.tfの作成

output "vpc_id" {
  description = "作成したVPCのID"
  value       = aws_vpc.main.id
}

output "subnet_id" {
  description = "作成したサブネットのID"
  value       = aws_subnet.public.id
}

手順5: Terraformの基本コマンド

Terraform の基本コマンドを使い、インフラの作成と状態管理を行います

terraform init:Terraform プロジェクトを初期化し、プロバイダー(AWS)をダウンロード
terraform plan:どのリソースが作成・変更・削除されるかを事前確認
terraform apply:実際に AWS にリソースを作成
terraform show:現在 Terraform が管理しているリソースの状態を確認
terraform output:設定した出力値(VPC ID やサブネット ID など)を表示

この手順では Terraform の基本的な操作フロー(init → plan → apply) を学びます。

terraform init(初期化)

プロジェクトディレクトリで最初に実行するコマンドです

terraform init

出力例:

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.0"...
- Installing hashicorp/aws v5.80.0...
- Installed hashicorp/aws v5.80.0 (signed by HashiCorp)

Terraform has been successfully initialized!

このコマンドで以下が実行されます:

  • .terraform ディレクトリの作成
  • プロバイダープラグイン(AWS)のダウンロード
  • .terraform.lock.hcl(依存関係ロックファイル)の作成

terraform plan(実行計画の確認)

実際にリソースを作成する前に、何が作成されるか確認できます

terraform plan

出力例:

Terraform will perform the following actions:

  # aws_internet_gateway.main will be created
  + resource "aws_internet_gateway" "main" {
      + id       = (known after apply)
      + vpc_id   = (known after apply)
      + tags     = {
          + "Name" = "terraform-demo-igw"
        }
    }

  # aws_vpc.main will be created
  + resource "aws_vpc" "main" {
      + cidr_block           = "10.0.0.0/16"
      + enable_dns_hostnames = true
      + enable_dns_support   = true
      + id                   = (known after apply)
      + tags                 = {
          + "Name" = "terraform-demo-vpc"
        }
    }

Plan: 5 to add, 0 to change, 0 to destroy.

+ は新規作成、~ は変更、- は削除を意味します

terraform apply(リソースの作成)

terraform apply

確認プロンプトが表示されます:

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

yes を入力するとリソースが作成されます

確認をスキップする場合:

terraform apply -auto-approve

terraform show(現在の状態確認)

terraform show

作成済みリソースの詳細情報が表示されます

terraform output(出力値の確認)

terraform output

出力例:

vpc_id = "vpc-0a1b2c3d4e5f6g7h8"
subnet_id = "subnet-0a1b2c3d4e5f6g7h8"

特定の値のみ取得:

terraform output vpc_id

手順6: セキュリティグループとEC2インスタンスの追加

ネットワーク内にサーバーを配置し、必要な通信を許可するための設定を行います
ここでは、EC2インスタンスとセキュリティグループのリソースを Terraform に追加し、サーバーを起動できる環境を構築します

主な設定内容は以下の通りです

セキュリティグループを作成し、SSH(22)および HTTP(80)の通信を許可します
Amazon Linux 2023 の最新 AMI を取得します
EC2 インスタンスを作成します
さらに、outputs.tf に EC2 のパブリック IP や SSH 接続コマンドを出力する設定を追加します

これにより、Terraform 実行後に表示される情報を使って、すぐに EC2 インスタンスへ接続できるようになります

main.tfにリソースを追加

手順4で作成した main.tf に以下を追記します

# セキュリティグループの作成
resource "aws_security_group" "ec2_sg" {
  name        = "${var.project_name}-ec2-sg"
  description = "Security group for EC2 instance"
  vpc_id      = aws_vpc.main.id

  # SSH接続を許可
  ingress {
    description = "SSH"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.my_ip]
  }

  # HTTP接続を許可
  ingress {
    description = "HTTP"
    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"]
  }

  tags = {
    Name = "${var.project_name}-ec2-sg"
  }
}

# 最新のAmazon Linux 2023 AMIを取得
data "aws_ami" "amazon_linux_2023" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-2023*"]
  }

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

# EC2インスタンスの作成
resource "aws_instance" "ec2_server" {
  ami                    = data.aws_ami.amazon_linux_2023.id
  instance_type          = "t3.micro"
  key_name               = var.key_name
  subnet_id              = aws_subnet.public.id
  vpc_security_group_ids = [aws_security_group.ec2_sg.id]

  tags = {
    Name = "${var.project_name}-ec2"
  }
}

outputs.tfに追記

output "ec2_instance_id" {
  description = "EC2インスタンスID"
  value       = aws_instance.ec2_server.id
}

output "ec2_public_ip" {
  description = "EC2パブリックIPアドレス"
  value       = aws_instance.ec2_server.public_ip
}

output "ec2_ami_id" {
  description = "使用したAMI ID"
  value       = data.aws_ami.amazon_linux_2023.id
}

output "security_group_id" {
  description = "セキュリティグループID"
  value       = aws_security_group.ec2_sg.id
}

output "ssh_command" {
  description = "SSH接続コマンド"
  value       = "ssh -i ${var.key_name}.pem ec2-user@${aws_instance.ec2_server.public_ip}"
}

変更の適用

差分を確認:

terraform plan

出力例:

Plan: 3 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + ec2_ami_id        = (known after apply)
  + ec2_instance_id   = (known after apply)
  + ec2_public_ip     = (known after apply)
  + security_group_id = (known after apply)
  + ssh_command        = (known after apply)

適用:

terraform apply

yes を入力して実行します

SSH接続

outputで表示されたコマンドを使ってSSH接続します

terraform output ssh_command

出力例:

"ssh -i test-ec2-key.pem ec2-user@54.250.245.176"

キーペアの権限設定後、接続:

chmod 400 test-ec2-key.pem
ssh -i test-ec2-key.pem ec2-user@54.250.245.176

手順7: tfstateファイルの管理

Terraform がインフラの状態を管理する terraform.tfstate ファイルの仕組みと管理方法

このファイルには、作成したリソースの情報や属性値などが保存されます
チーム開発では S3 バケットに state ファイルを保存し、DynamoDB を利用してロック管理を行う「リモートバックエンド構成」を使用します
これにより、複数人で Terraform を実行する場合でも安全に状態管理を行うことができます

tfstateとは

Terraformは作成したリソースの状態を terraform.tfstate ファイルに記録します

terraform show

このファイルには以下の情報が含まれます:

  • 作成したリソースのID
  • リソースの属性値
  • リソース間の依存関係

tfstateの注意点

  • terraform.tfstate にはアクセスキーなどの機密情報が含まれる場合があります
  • Gitリポジトリにコミットしないでください
  • チーム開発ではS3バックエンドの利用を推奨します

S3バックエンドの設定(チーム開発向け)

S3バケットを事前に作成しておきます:

aws s3 mb s3://my-terraform-state-bucket --region ap-northeast-1

DynamoDBテーブルを作成(ロック機能用):

aws dynamodb create-table \
  --table-name terraform-lock \
  --attribute-definitions AttributeName=LockID,AttributeType=S \
  --key-schema AttributeName=LockID,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST \
  --region ap-northeast-1

main.tfterraform ブロックに追記:

terraform {
  required_version = ">= 1.0.0"

  backend "s3" {
    bucket         = "my-terraform-state-bucket"
    key            = "terraform-ec2-demo/terraform.tfstate"
    region         = "ap-northeast-1"
    dynamodb_table = "terraform-lock"
    encrypt        = true
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

バックエンドの変更後は再初期化が必要です:

terraform init -migrate-state

手順8: リソースの変更と削除

Terraform を使用したインフラの変更や削除には、以下の操作があります

terraform plan で変更内容を確認
terraform apply で変更を適用
terraform destroy でリソースを削除
特定のリソースのみを対象に変更・削除することも可能

ここでは、Terraform を利用して インフラのライフサイクル管理(作成・変更・削除) を行います

リソースの変更

main.tf のインスタンスタイプを変更する例:

resource "aws_instance" "ec2_server" {
  ami           = data.aws_ami.amazon_linux_2023.id
  instance_type = "t3.small"  # t3.micro → t3.small に変更
  # ...
}

差分を確認:

terraform plan

出力例:

  # aws_instance.ec2_server must be replaced
-/+ resource "aws_instance" "ec2_server" {
      ~ instance_type = "t3.micro" -> "t3.small"
      # ...
    }

Plan: 0 to add, 1 to change, 0 to destroy.

適用:

terraform apply

特定リソースのみ操作

特定のリソースだけを対象にする場合:

terraform plan -target=aws_instance.ec2_server
terraform apply -target=aws_instance.ec2_server

リソースの削除

全リソースを削除:

terraform destroy

確認プロンプトが表示されます:

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

確認をスキップする場合:

terraform destroy -auto-approve

特定リソースのみ削除:

terraform destroy -target=aws_instance.ec2_server

よく使うTerraformコマンド集

基本操作

初期化:

terraform init

プロバイダーの再ダウンロード:

terraform init -upgrade

実行計画の確認:

terraform plan

リソースの作成・変更:

terraform apply

確認なしで適用:

terraform apply -auto-approve

リソースの削除:

terraform destroy

状態管理

現在の状態を表示:

terraform show

管理中のリソース一覧:

terraform state list

出力例:

aws_instance.ec2_server
aws_internet_gateway.main
aws_route_table.public
aws_route_table_association.public
aws_security_group.ec2_sg
aws_subnet.public
aws_vpc.main

特定リソースの詳細:

terraform state show aws_instance.ec2_server

リソースを管理対象から除外:

terraform state rm aws_instance.ec2_server

フォーマットとバリデーション

コードのフォーマット:

terraform fmt

再帰的にフォーマット:

terraform fmt -recursive

構文チェック:

terraform validate

出力例:

Success! The configuration is valid.

出力値

全出力値の表示:

terraform output

特定の出力値:

terraform output ec2_public_ip

JSON形式で出力:

terraform output -json

その他

依存関係のグラフ出力:

terraform graph

ワークスペース一覧:

terraform workspace list

ワークスペースの作成:

terraform workspace new dev

ワークスペースの切り替え:

terraform workspace select dev

トラブルシューティング

認証エラーが出る場合

Error: No valid credential sources found

対処法:

  1. aws configure が正しく設定されているか確認
  2. 環境変数 AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY が設定されているか確認
  3. ~/.aws/credentials ファイルが存在するか確認

terraform initが失敗する場合

Error: Failed to install provider

対処法:

  1. インターネット接続を確認
  2. プロキシ環境の場合は HTTPS_PROXY 環境変数を設定
  3. terraform init -upgrade で再試行

リソースの作成に失敗する場合

Error: creating EC2 Instance: UnauthorizedOperation

対処法:

  1. IAMユーザーに必要な権限があるか確認
  2. 必要なポリシー例: AmazonEC2FullAccess, AmazonVPCFullAccess
  3. aws sts get-caller-identity で正しいユーザーか確認

stateファイルのロックエラー

Error: Error acquiring the state lock

対処法:

  1. 他のユーザーが terraform apply を実行中でないか確認
  2. 強制的にロックを解除する場合:
terraform force-unlock <LOCK_ID>

terraform planとapplyの差分が出る場合

Note: Objects have changed outside of Terraform

対処法:

  1. AWSコンソールから手動で変更した場合に発生します
  2. terraform refresh で状態を同期:
terraform apply -refresh-only

AWS CLI・Terraform・CloudFormation の使い分け

AWS CLIは「今の状態を確認する」、Terraformは「あるべき状態を定義する」、CloudFormationは「AWSネイティブであるべき状態を定義する」という使い分けが効果的です

用途 AWS CLI Terraform CloudFormation
一時的な確認・調査 ×
リソースの一覧取得
インフラの構築・管理
環境の再現
チーム開発
変更履歴の管理 × ○(Git連携) ○(Git連携)
ドリフト検知 ×
マルチクラウド対応 × ×
AWS以外のツール不要 ×
スタックのロールバック × ○(自動)
AWSサポート対象 ×

まとめ

Terraformを使うことで、AWSインフラをコードとして管理できます

この記事で紹介した内容:

  • Terraformのインストール(Windows/Linux/Mac)
  • AWS認証の設定方法
  • VPC・サブネット・EC2の作成
  • 基本コマンド(init / plan / apply / destroy)
  • tfstateの管理とS3バックエンド
  • 変数とoutputの活用

Terraformに慣れると、インフラの構築・変更・削除がコマンド一つで完結し、環境の再現やチーム開発が格段に効率化されます

関連記事

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?