Terraform Workspaceで実現する環境分離とリモートステート連携
Terraform Workspaceを使った複数環境の分離方法とリモートステート連携の実践ガイド。同一コードベースでprod/stg環境を管理し、ワークスペース間でステートをS3バックエンド参照する具体的な手順を用いて解説します。

目次
はじめに
こんにちは、今回は、より実践的な内容として、Terraformでの環境分離についてお話ししたいと思います。
Terraformを利用して、複数環境の構築をする際、環境間の設定差異などを考慮する必要があり、単一環境と比べて管理方法などが複雑になってくることがあります。
今回、紹介するTerraform Workspaceを利用する事でどの様にして環境間の分離を実現し、リモートステートを連携させるかについて紹介します。
なお、Terraformで環境分離する手法として、今回紹介する、ワークスペースによる分離とファイルレイアウトによる分離 など複数存在しますが、今回はワークスペースを利用した方法にフォーカスして紹介します。
Terraform Workspaceとは
Terraform Workspaceを使うと、Terraformの状態を管理するステートファイルを複数作成でき、ワークスペースごとに名前を付けて同じコードベースで複数の環境を管理できます。
動作確認内容
Terraform Workspaceは、同一フォルダ内で複数のワークスペースを作成し管理する機能になります。
環境間のリソース参照を実現するため、最初に参照元となるprodワークスペースを作成します。
次に参照先のstgワークスペースを作成し、stgワークスペースからprodワークスペースのリモートステートを参照する動作確認を行います。
流れ
環境準備
事前作業として、AWS CLIコマンドを使用し、Terraformのステートファイルを管理するS3バケットを作成します。
S3バケットの作成
export BUCKET=terraform-workspace-demo01
export REGION=ap-northeast-1
- バケット作成
aws s3api create-bucket \
--bucket "$BUCKET" \
--region "$REGION" \
--create-bucket-configuration LocationConstraint="$REGION"
- バージョニング有効化
aws s3api put-bucket-versioning \
--bucket "$BUCKET" \
--versioning-configuration Status=Enabled
検証用Terraformファイルの作成
以下の内容でmain.tfファイルを作成します。
terraform {
required_version = "1.11.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.89.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
locals {
env = terraform.workspace
}
# ここがVPC作成定義(各workspaceで独立したVPCが作成されます)
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${local.env}-vpc"
Environment = local.env
ManagedBy = "Terraform"
}
}
# このworkspaceで作成したVPCのID
output "vpc_id" {
description = "各workspaceで作成したVPCのID"
value = aws_vpc.main.id
}
# 環境間参照デモ: prodのstateを、prod以外のworkspaceから参照
data "terraform_remote_state" "prod" {
count = terraform.workspace == "prod" ? 0 : 1
backend = "s3"
workspace = "prod"
config = {
bucket = "terraform-workspace-demo01" # backend.tfと同じ
region = "ap-northeast-1"
encrypt = true
workspace_key_prefix = "env"
key = "stack/terraform.tfstate"
}
}
# prodのVPC IDを表示(prod自身ではnull)
output "prod_vpc_id" {
description = "prod workspace の VPC ID(prod以外で表示)"
value = try(data.terraform_remote_state.prod[0].outputs.vpc_id, null)
}
次に、以下の内容でbackend.tfファイルを作成します。
terraform {
backend "s3" {
bucket = "terraform-workspace-demo01" # 一意のS3バケット名に置換
region = "ap-northeast-1"
encrypt = true
use_lockfile = true # DynamoDB不要のS3ネイティブロック
workspace_key_prefix = "env" # S3上: env/<workspace>/stack/terraform.tfstate
key = "stack/terraform.tfstate"
}
}
プロジェクト初期化
Terraformのプロジェクトを初期化します。
正常に成功すると、S3バックエンドが設定され、Terraformの初期化が完了します。
terraform init
Initializing the backend...
Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
...{中略}
Terraform has been successfully initialized!
...{中略}
prodワークスペースの作成と適用
terraform workspace new {環境名}コマンドを使用して、任意のワークスペース名を作成できます。
terraform workspace new prod
Created and switched to workspace "prod"!
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
terraform workspace listコマンドで、現在のワークスペースを確認します。
今回の場合、defaultワークスペースとprodワークスペースが存在することが確認できます。
defaultワークスペースはTerraform初期化時に自動的に作成されるワークスペースかつ削除できないため、こちらのワークスペースは利用せずにprodワークスペースを利用します。
terraform workspace list
default
* prod
terraform plan 実行後、terraform apply を実行し、prodワークスペースのVPCを作成します。
...{中略}
aws_vpc.main: Creating...
aws_vpc.main: Still creating... [10s elapsed]
aws_vpc.main: Creation complete after 12s [id=vpc-01f858cac1ff4826c]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
vpc_id = "vpc-01f858cac1ff4826c"
適用後、以下AWS CLIコマンドでterraform applyで作成されたVPCを確認します。
Nameタグがprod-vpcであることが確認できます。
aws ec2 describe-vpcs --vpc-ids vpc-01f858cac1ff4826c --query 'Vpcs[].{VpcId:VpcId, State:State, CidrBlock:CidrBlock, IsDefault:IsDefault, Name: Tags[?Key==`Name`].Value | [0]}' --output table
| CidrBlock | IsDefault | Name | State | VpcId |
|---|---|---|---|---|
| 10.0.0.0/16 | False | prod-vpc | available | vpc-01f858cac1ff4826c |
stgワークスペースの作成と適用
同様に、terraform workspace new {環境名}コマンドを使用して、stgワークスペースを作成します。
terraform workspace new stg
Created and switched to workspace "stg"!
You're now on a new, empty workspace. Workspaces isolate their state,
so if you run "terraform plan" Terraform will not see any existing state
for this configuration.
terraform workspace listコマンドで、現在のワークスペースを確認します。
stgワークスペースが作成されていることが確認でき、stgワークスペースに切り替わっていることが確認できます。
terraform workspace list
default
prod
* stg
terraform plan 実行後、terraform apply を実行し、stgワークスペースのVPCを作成します。
...{中略}
aws_vpc.main: Creating...
aws_vpc.main: Still creating... [10s elapsed]
aws_vpc.main: Creation complete after 11s [id=vpc-04184270516210ce1]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Outputs:
prod_vpc_id = "vpc-01f858cac1ff4826c"
vpc_id = "vpc-04184270516210ce1"
情報
- stgワークスペースではterraform_remote_stateデータソースを利用して、prodワークスペースのVPC IDを参照しています。
- prod_vpc_id出力値にprodワークスペースで作成されたVPC IDが表示されていることが確認できます。
適用後、以下AWS CLIコマンドでterraform applyで作成されたVPCを確認します。
Nameタグがstg-vpcであることが確認できます。
aws ec2 describe-vpcs --vpc-ids vpc-04184270516210ce1 --query 'Vpcs[].{VpcId:VpcId, State:State, CidrBlock:CidrBlock, IsDefault:IsDefault, Name: Tags[?Key==`Name`].Value | [0]}' --output table
| CidrBlock | IsDefault | Name | State | VpcId |
|---|---|---|---|---|
| 10.0.0.0/16 | False | stg-vpc | available | vpc-04184270516210ce1 |
S3バケット内の状態確認
S3バケット内に、ワークスペースごとにステートファイルが保存されていることが確認できます。
aws s3api list-objects --bucket terraform-workspace-demo01 --query 'Contents[].{Key: Key, Size: Size, LastModified: LastModified}' --output table
| Key | LastModified | Size |
|---|---|---|
| env/prod/stack/terraform.tfstate | 2025-11-09T08:34:05+00:00 | 1981 |
| env/stg/stack/terraform.tfstate | 2025-11-09T08:58:20+00:00 | 3386 |
まとめ
Terraform Workspaceを利用する事で、同一コードベースで複数環境の分離を実現できることが確認できました。
ディレクトリを分けることなく、環境ごとにワークスペースを切り替えるだけで、環境分離が可能になるため、管理が容易になる点がメリットです。
反面、同一リソースを作成しない場合は、ワークスペースごとに条件分岐をコードに追加する必要があるため、コードが複雑になる点がデメリットとなります。