「チームメンバーがAWSアカウントを持っていないため、ローカルで確認できない。」
Terraform開発では、コードを書く段階でも`terraform apply`を繰り返して結果を確認することが多くなります。本番のAWSに毎回アクセスすると、テストリソースの削除忘れが積み重なったり、ネットワークが使えない環境では作業が止まったりします。
この記事では、RHEL 9系(Rocky Linux 9 / AlmaLinux 9)を想定環境として、LocalStackを使ったTerraformのローカルテスト環境を構築する方法を解説します。S3バケット作成の確認から、本番AWSとの切り替え設計まで、実際のAWSアカウントなしでTerraformコードを開発・確認するパターンを紹介します。
この記事のポイント
・LocalStackはDockerで起動できるAWSモックサーバーで、S3・EC2・IAM・SQSなどに対応
・TerraformのproviderにLocalStack用のエンドポイントを設定することで接続できる
・ダミー認証情報(access_key / secret_key = "test")を使えば本物のAWSクレデンシャルは不要
・variable + tfvarsで本番AWSとLocalStackを環境ごとに切り替える設計が実用的
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
Terraform開発で「毎回本番AWSを使う」と起きやすい問題
Terraformのコードを書いている段階では、HCLの書き方を試したり、モジュール設計を検証したりするために`apply`を何度も繰り返すことがあります。本番のAWSに対して毎回`apply`すると、いくつかの問題が起きやすいです。
・テスト用リソースを作るたびに少額でも料金が発生する
・`terraform destroy`し忘れたリソースが積み重なる
・開発環境のAWSクレデンシャルをメンバー全員に払い出す必要が生じる
・ネットワーク接続のない環境や、オフサイトでの作業では手が止まる
特にTerraformを学び始めるフェーズや、HCL構文の確認・モジュール設計の試行を繰り返す場面では、LocalStackをモック環境として使うと開発が速くなります。
LocalStackとは何か
LocalStackは、Dockerコンテナとしてローカルで起動できるAWSモックサーバーです。S3・EC2・IAM・SQS・SNS・DynamoDB・Lambdaなど、主要なAWSサービスのAPIをエミュレートします。TerraformはAWSプロバイダー経由でAPIを呼び出しています。そのため、providerの向き先をLocalStackのURLに変えるだけで、コード自体を書き直さずにローカルで動かせます。
無償版(Community)でもS3・SQS・SNS・DynamoDB・IAM・Lambdaなどが使えます。有償版(Pro)になるとEKS・RDS・Cognitoなどカバー範囲が広がりますが、HCLの文法確認やモジュール設計の検証には無償版で十分な場面が多いです。
Terraformを使ったインフラ設計をより体系的に学びたい場合は、terraform.linuxmaster.jpもあわせて参照してください。
LocalStackのセットアップ
1. Dockerの確認
LocalStackはDockerコンテナで動くため、事前にDockerが起動している状態にしておきます。# Dockerの動作確認 docker --version docker info | head -5
2. docker-compose.ymlの作成とコンテナ起動
作業用ディレクトリを作り、`docker-compose.yml`を用意します。# 作業ディレクトリを作成 mkdir ~/localstack-tf && cd ~/localstack-tf # docker-compose.yml を作成 cat > docker-compose.yml << 'EOF' version: "3.8" services: localstack: container_name: localstack-main image: localstack/localstack:latest ports: - "127.0.0.1:4566:4566" environment: - SERVICES=s3,ec2,iam,sts - DEFAULT_REGION=ap-northeast-1 volumes: - "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack" - "/var/run/docker.sock:/var/run/docker.sock" EOF # コンテナを起動 docker compose up -d
3. 起動確認
起動後にヘルスチェックのエンドポイントを確認します。curl -s http://localhost:4566/_localstack/health | python3 -m json.tool
{ "services": { "ec2": "available", "iam": "available", "s3": "running", "sts": "available" }, "version": "3.8.0" }
TerraformからLocalStackに接続するprovider設定
1. provider設定とエンドポイントの向け先
通常のAWSプロバイダー設定に、LocalStackのエンドポイント(`http://localhost:4566`)を追加します。# provider.tf terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } provider "aws" { region = "ap-northeast-1" access_key = "test" secret_key = "test" skip_credentials_validation = true skip_requesting_account_id = true skip_metadata_api_check = true endpoints { s3 = "http://localhost:4566" ec2 = "http://localhost:4566" iam = "http://localhost:4566" sts = "http://localhost:4566" } }
2. ダミー認証情報とskipフラグの意味
LocalStackはAPIの認証チェックをしないため、`access_key`と`secret_key`は任意の文字列で構いません。`"test"`を使うのが慣例です。`skip_credentials_validation = true`と`skip_requesting_account_id = true`を設定しないと、プロバイダーが実際のAWS STSエンドポイントに接続を試みてエラーになります。LocalStack用のprovider設定では、この2つのフラグを忘れずに設定してください。
LocalStack上でS3バケットを作成して確認する
provider設定ができたら、S3バケットを作るシンプルなコードで動作確認をします。# main.tf resource "aws_s3_bucket" "example" { bucket = "my-test-bucket-localstack" }
terraform init terraform apply -auto-approve
aws_s3_bucket.example: Creating... aws_s3_bucket.example: Creation complete after 0s [id=my-test-bucket-localstack] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
aws --endpoint-url=http://localhost:4566 s3 ls
2026-01-01 00:00:00 my-test-bucket-localstack
本番AWSとLocalStackを切り替える設計
LocalStackで確認したコードを本番AWSで動かすには、切り替えの仕組みを最初から設計しておくと手間が省けます。1. variableでエンドポイントを受け取る
# variables.tf variable "localstack_endpoint" { description = "LocalStackのエンドポイント。空文字列にすると本番AWSを使用する" type = string default = "http://localhost:4566" }
# provider.tf(切り替え対応版) provider "aws" { region = "ap-northeast-1" # LocalStack用ダミー認証(本番ではIAMロールや環境変数を使用) access_key = var.localstack_endpoint != "" ? "test" : null secret_key = var.localstack_endpoint != "" ? "test" : null skip_credentials_validation = var.localstack_endpoint != "" ? true : false skip_requesting_account_id = var.localstack_endpoint != "" ? true : false skip_metadata_api_check = var.localstack_endpoint != "" ? true : false dynamic "endpoints" { for_each = var.localstack_endpoint != "" ? [1] : [] content { s3 = var.localstack_endpoint ec2 = var.localstack_endpoint iam = var.localstack_endpoint sts = var.localstack_endpoint } } }
2. tfvarsで環境を分離する
# local.tfvars(LocalStack用) localstack_endpoint = "http://localhost:4566" # production.tfvars(本番AWS用) localstack_endpoint = ""
# LocalStackで確認 terraform apply -var-file=local.tfvars # 本番AWSに適用 terraform apply -var-file=production.tfvars
よくあるエラーと対処法
LocalStack + Terraformを組み合わせる際に出やすいエラーを整理します。「dial tcp: connection refused」が出る
LocalStackコンテナが起動していないか、ポートが異なる場合に出ます。# コンテナの状態確認 docker compose ps docker compose logs localstack | tail -20 # ポートが使用中かを確認 ss -tlnp | grep 4566
「InvalidClientTokenId」や「AuthFailure」が出る
`skip_credentials_validation = true`と`skip_metadata_api_check = true`が設定されていないと発生します。provider設定を再確認してください。「NotImplemented: Operation not supported」が出る
LocalStack Community版では対応していないAPIが呼ばれた場合に出ます。リソースの種類がCommunity版でサポートされているかをLocalStackの公式ドキュメントで確認してください。Community版でサポートされていないリソース(EKS・RDSなど)を検証する場合はPro版が必要です。「Error: failed to refresh cached provider plugin」が出る
`.terraform`ディレクトリのキャッシュが古い場合に起きます。`terraform init -upgrade`を実行するか、`.terraform`ディレクトリを削除してから`terraform init`をやり直してください。本記事のまとめ
| やりたいこと | 対応方法 |
|---|---|
| LocalStackをDockerで起動する | docker compose up -d(docker-compose.ymlにSERVICESを列挙) |
| 起動確認をする | curl http://localhost:4566/_localstack/healthでrunning/availableを確認 |
| TerraformをLocalStackに向ける | providerのendpointsブロックにhttp://localhost:4566を設定 |
| ダミー認証情報を使う | access_key/secret_keyに"test"、skip系フラグをtrueに設定 |
| 本番AWSとLocalStackを切り替える | variableでエンドポイントを受け取り、-var-file=xxx.tfvarsで環境を分離 |
| 対応サービスを確認する | LocalStack公式ドキュメントのカバレッジページで確認(Community版は無償) |
TerraformなどのIaCツールを含む、サーバー自動化・セキュリティ設定・運用設計まで、実務で通用するスキルを少人数のハンズオンで体系的に学べるセミナーを開催しています。
>> 詳細・申込はこちら(terraform.linuxmaster.jp)
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:CDK for TerraformをCIに組み込む実践手順|TypeScriptでインフラ定義する流れ
- この記事の属するカテゴリ:Terraformへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます