🛠️ ローカル AWS エミュレータで Terraform を検証する

記事の要約

インフラ構築をAIに任せるようになり「ローカルで素早くフィードバックループを回せる環境」が欲しくなったe-dashが、Terraformから使えるローカルAWSエミュレータ「Floci」を実際にECS + RDS構成で検証した記事。エミュレータが再現するのはAPIレスポンス(コントロールプレーン)のみで、ネットワーク制御などのデータプレーンは再現されない——何が検証できて何ができないかを7つのケースで体系的に整理している。

主要なローカル AWS エミュレータ3選

ツール特徴注意点
LocalStack 最普及。110以上のサービス対応 無償Community版はコアサービス(Lambda/S3/DynamoDB/SQS/SNS/IAM)のみ。RDS等は有償。2026年3月以降、無償でも認証トークン登録が必須
Floci(本記事の主役) 2026年登場の新興。68サービス対応、MITライセンスOSS、登録・トークン不要。Quarkus Native製で起動約24ms・アイドルメモリ約13MiB。ポート4566でLocalStack互換 APIカバレッジは完全ではない
moto Pythonテスト用モックライブラリ。moto_serverでTerraformからも利用可 Pythonのテストコードとの組み合わせに向く

Floci のセットアップ

provider "aws" {
  access_key                  = "test"
  secret_key                  = "test"
  region                      = "us-east-1"
  skip_credentials_validation = true
  skip_metadata_api_check     = true
  skip_requesting_account_id  = true
  s3_use_path_style           = true

  endpoints {
    s3       = "http://localhost:4566"
    dynamodb = "http://localhost:4566"
    rds      = "http://localhost:4566"
    ec2      = "http://localhost:4566"
  }
}

技術的な制約(押さえるべきポイント)

一方でRDS・ElastiCacheなどはモックではなく実Dockerコンテナ(実PostgreSQL/MySQL/Redis)で動くため、DBについては本物のエンジンにSQLを流して挙動を確認できる。

実機検証:7つの設定ミスケース(ECS + RDS構成)

ECS(Fargate)をpublicサブネット、RDS(MySQL)をprivateサブネットに置く一般的な2層構成を題材に検証。検証コードは GitHub: a2-ito/tf-samples で公開。

ケース検証可否理由・詳細
1. DBのホスト名orポート番号の誤り検証できるRDSが実MySQLコンテナのため、接続先ミスは実際に接続拒否されて検出可能
2. RDSのSGでECSからのアクセス未許可検証できないSGは通信制御に使われない。RDSに紐づくSGはsg-00000000というダミー値。疎通はDockerネットワーク次第
3. Parameter GroupでSSL必須なのにクライアント未指定検証できないパラメータグループはメタデータとして保存されるだけで、実MySQLコンテナの設定には反映されない(再起動後もOFFのまま)
4. Route Tableの設定ミス検証できないルートテーブルは保存されるだけで経路制御に使われない。route欠落でもapplyが通り通信も通ってしまう
5. Secret ManagerのIAM Role不足部分的に検証可APIレベルの認可はIAM enforcement有効化で評価できるが、実AWSでECSエージェントが行うシークレット解決(とResourceInitializationError)はECS経由では再現しない
6. SGの循環参照(デッドロック)静的解析で補完Trivy/Checkovは直接は検出しないが、引き金となる「inlineとstandaloneの混在」等をCheckovのポリシーで捕まえられる。踏み込むならterraform plan -jsonをConftest/OPAへ
7. 循環参照terraform validateで弾ける依存グラフ構築はTerraform自身の仕事。validateがCycleとして即検出。検証の初手に置くべき

実機評価でわかった実用ノウハウ

ECS→RDS接続にはFloci側のプロキシ設定が必要

FlociのRDSは実MySQLコンテナを 7001-7099 のプロキシポートで中継。既定ではエンドポイントにlocalhostを埋め込むため、別コンテナのECSタスクからは自分自身を指してしまい繋がらない。FlociとRDS・ECSコンテナを同一Dockerネットワークに載せ、FLOCI_HOSTNAME=floci を設定すると aws_db_instance.address がDNS解決可能な floci:7001 を返し接続できる。

ホストからアプリへのアクセスにはsocatプロキシ

ECSタスクはホストにポートを公開しないため、floci-net上でsocatコンテナを起動してホストの3000番をアプリコンテナへ転送する。

毎回差分(drift)が出る

まとめ(著者所感)