記事の要約
インフラ構築を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 のセットアップ
docker compose upで起動しhttp://localhost:4566で待ち受け- AWSプロバイダの
endpointsブロックで各サービスのエンドポイントを向け、資格情報検証(credentials validation / metadata API check / account ID 取得)をスキップ - 環境変数
AWS_ENDPOINT_URL等で上書きすると環境差分をなくせる
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"
}
}
技術的な制約(押さえるべきポイント)
- APIカバレッジは不完全:Bedrock Runtimeはスタブ実装(ストリーミング501)など、必要な操作の対応要確認
- IAM認可は既定で評価されない:
test/testで何でも通る。FLOCI_SERVICES_IAM_ENFORCEMENT_ENABLEDで有効化するとポリシー評価される - ECSの
secretsは解決されない:valueFromの環境変数はコンテナに注入されない(通常のenvironmentはOK) - ネットワーク制御は再現されない:セキュリティグループは「ファイアウォールとして強制されない」、ルートテーブル・NACLもリソースとして保存されるだけ
- 料金・クォータ・レイテンシは対象外
- サービスを選んで起動できない:
SERVICES変数による絞り込みなし、全サービス起動
一方で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)が出る
- apply直後のplanで「1 to add, 6 to change, 1 to destroy」のような差分が出る
- ECSサービスの置き換え、tagsの再適用、SG ingressの再追加、RDS紐づSGのダミー値化(
sg-00000000)など - 「planがno-opであること」をCIの合格条件にすると記述が正しくても落ちる。冪等性の確認は実AWSサンドボックスに委ね、エミュレータではapplyの成否と動作確認までを見るのが良い
まとめ(著者所感)
- エミュレータが再現するのはコントロールプレーン(APIレスポンス)。ネットワーク制御・料金・クォータ等のデータプレーン・非機能面は再現されない
- 限定的なケースだが、構成レベルの誤りの早期検出には有効
- 静的解析(terraform validate、Trivy、Checkov、OPA等)の方がカバーできるケースは多い
- AWSセットアップ(アカウントやstate置き場)を気にせずコードを検証できる環境は普通に便利で、入れておいて損はない。ただし非対応サービスを使うケースは逆に手間が掛かる可能性も