SnaetWarre/aws-fargate-vault-terraform
GitHub: SnaetWarre/aws-fargate-vault-terraform
使用 Terraform 构建的 AWS ECS Fargate 生产级基础设施,通过 IAM 身份验证与 Vault Agent sidecar 实现无静态密钥的运行时密钥分发。
Stars: 0 | Forks: 0
# 基于 Vault Workload Identity 的 AWS Fargate 基础设施
[](https://github.com/SnaetWarre/aws-fargate-vault-terraform/actions/workflows/terraform.yml)
一个使用 Terraform 构建的、面向生产环境的 AWS 基础设施设计。它在私有子网中的 ECS Fargate 上运行一个小型 Web 工作负载,通过 Application Load Balancer 对外提供服务,并使用 AWS IAM workload identity 对 Vault Agent sidecar 进行身份验证,而无需分发静态的 Vault token。
该应用程序特意保持简单。工程重心在于其周边平台:网络、身份验证、运行时 secret 分发、健康检查、可观测性、自动扩缩容、安全部署、成本意识以及无凭证的基础设施测试。
## 架构
```
flowchart TB
User((Internet client))
Vault[(HCP or self-managed Vault)]
subgraph AWS[AWS account]
CW[CloudWatch Logs
and Container Insights] IAM[IAM task role
workload identity] subgraph VPC[VPC 10.42.0.0/16 across two availability zones] IGW[Internet Gateway] subgraph Public[Public subnets] ALB[Application Load Balancer
HTTP or ACM TLS] NAT[NAT Gateway] end subgraph Private[Private Fargate subnets] subgraph ECS[ECS service] App[Application container
read-only root filesystem] Agent[Vault Agent sidecar] Volume[(Ephemeral shared volume)] Agent -->|renders index.html| Volume App -->|reads rendered file| Volume end end end end User -->|80 or 443| IGW --> ALB ALB -->|security-group scoped 8080| App Agent --> NAT -->|HTTPS| Vault IAM -. ECS task credentials .-> Agent App --> CW Agent --> CW ``` ALB 是唯一的公网入口。Fargate 任务没有公网 IP 地址,仅接受来自 ALB 安全组的应用流量。单一的 NAT gateway 保持了示例的易懂性和相对经济性;生产环境会根据可用性和流量成本评估是否使用多 AZ NAT gateway 或 VPC endpoints。 ## 运行时 secret 流程 ``` sequenceDiagram participant ECS as ECS task participant Agent as Vault Agent sidecar participant IAM as AWS IAM participant Vault as Vault AWS auth and KV v2 participant Volume as Shared ephemeral volume participant App as Application container participant ALB as Application Load Balancer ECS->>Agent: Supply rotating task-role credentials Agent->>IAM: Create signed AWS identity request Agent->>Vault: Authenticate with signed IAM request Vault-->>Agent: Return short-lived token with narrow policy Agent->>Vault: Read midnight-postcard/data/config Vault-->>Agent: Return permitted runtime content Agent->>Volume: Render /vault/secrets/index.html Agent-->>ECS: Health check becomes ready ECS->>App: Start application container App->>Volume: Read rendered page App-->>ALB: Application health check passes ALB-->>App: Begin routing requests ``` 应用程序永远不会收到硬编码的 AWS access key 或 Vault token。Vault 将一个角色绑定到精确的 ECS task-role ARN,并且其策略仅允许从所需的 KV v2 路径进行读取。 ## 部署与质量流程 ``` flowchart LR PR[Pull request or push] --> Fmt[terraform fmt -check] Fmt --> Init[terraform init
backend disabled] Init --> Validate[terraform validate] Validate --> Tests[terraform test
mocked AWS and Vault] Tests --> Review{Human review} Review -->|No credentials in CI| Stop[Quality gate complete] Review -->|Sandbox credentials| Plan[make plan] Plan --> Inspect[terraform show
review plan and cost] Inspect --> Gate{ALLOW_APPLY=yes?} Gate -->|No| Refuse[Refuse deployment] Gate -->|Yes| Apply[Apply reviewed plan] Apply --> Health[ALB and container
health verification] ``` 签入的 GitHub Actions workflow 故意在格式化、验证和模拟的 plan 之后停止。真正的部署需要临时的 AWS 凭证、经过明确审查的 plan,以及单独选择执行 apply。 ## 项目展示的内容 | 关注点 | 实现方式 | | --- | --- | | 基础设施即代码 | 用于网络、IAM、Vault 配置和 ECS 服务的可重用 Terraform modules | | 网络隔离 | 公有 ALB 子网、私有 Fargate 子网、严格限制的安全组,以及无公网任务 IP | | Workload identity | 通过 Vault 的 AWS auth method 进行身份验证的 ECS task role | | Secret 分发 | Vault Agent sidecar 将批准的 KV v2 数据渲染到任务范围的临时卷中 | | 可靠性 | ALB 和容器健康检查、部署断路器、自动回滚和自动扩缩容 | | 可观测性 | CloudWatch 日志组、30 天保留期、awslogs 和 ECS Container Insights | | 成本意识 | Fargate Spot 加权容量、受限的自动扩缩容、单一 NAT gateway 和明确的清理指南 | | 传输安全 | 可选的 ACM certificate,支持 HTTP 到 HTTPS 的重定向以及现代化的 TLS 策略 | | 可测试性 | 使用模拟的 providers 对纯 AWS、启用 Vault 和 HTTPS 变体进行离线 Terraform 测试 | | 交付安全性 | 非部署型 CI,以及一个需要经过审查的 plan 加上明确确认的 apply 目标 | ## 仓库结构 ``` . ├── .github/workflows/ │ └── terraform.yml # Non-deploying Terraform quality gate ├── docs/ │ └── architecture.md # Runtime sequence and design tradeoffs ├── modules/ │ ├── identity/ # ECS execution role and workload task role │ ├── network/ # Two-AZ VPC, subnets, routes, IGW, and NAT │ ├── service/ # ALB, ECS, sidecar, logs, health, and scaling │ └── vault-config/ # AWS auth, KV v2, role, and read-only policy ├── preview/ # Credential-free local application preview ├── tests/ │ └── architecture.tftest.hcl # Mocked Terraform plan tests ├── main.tf # Module composition and dependency order ├── variables.tf # Validated configuration interface ├── outputs.tf # Service URL, cluster, role, and Vault command └── terraform.tfvars.example # Safe example configuration ``` ## 无需云凭证进行验证 要求:Terraform 1.15.x。不需要 AWS 和 Vault 凭证。 ``` git clone https://github.com/SnaetWarre/aws-fargate-vault-terraform.git cd aws-fargate-vault-terraform cp terraform.tfvars.example terraform.tfvars terraform init -backend=false terraform fmt -check -recursive terraform validate terraform test ``` 当前测试套件验证: 1. 安全的纯 AWS 默认配置; 2. Vault sidecar 和轮换输出; 3. 由 ACM 支持的 HTTPS 变体。 可以使用 `make check` 运行相同的检查。要在没有 AWS 或 Vault 的情况下查看微型应用程序: ``` make preview # 打开 http://127.0.0.1:8765 ``` ## 创建经过审查的 AWS plan 复制示例变量,通过具有临时凭证的 AWS 沙盒进行身份验证,并创建一个 plan: ``` cp terraform.tfvars.example terraform.tfvars AWS_PROFILE=your-sandbox-profile make plan terraform show midnight-postcard.tfplan ``` `make plan` 绝不会应用基础设施。即使存在 plan 之后,除非提供了明确的安全闸门,否则 Makefile 也会拒绝部署: ``` ALLOW_APPLY=yes make apply ``` 这会产生付费资源。在应用之前,请审查 NAT Gateway、ALB、Fargate、CloudWatch 和外部 Vault 的成本,并在实验完成后销毁沙盒资源。 ## 启用 Vault 模式 Vault 是按需启用的,并期望有一个可从私有子网访问的现有 HCP Vault 或自建集群。 1. 设置 `enable_vault = true`。 2. 配置真实的 HTTPS `vault_address`。 3. 仅在用于配置 Vault 的本地 shell 中导出管理员权限的 `VAULT_TOKEN`。 4. 创建并检查新的 Terraform plan。 Terraform 配置了 AWS auth mount、绑定到 ECS task role 的 Vault 角色、狭窄的策略,以及故意的公开演示 KV 内容。真正的 secret 值必须在 Terraform 之外写入,因为 Terraform 的资源参数会存储在 state 中。 ## 远程 state 对于不应自动部署的仓库,本地 state 是安全的默认设置。真实环境应使用: - 专用的 S3 state bucket; - 加密和版本控制; - 受限的 IAM 访问权限; - S3 原生 state locking; - 每个环境独立的 state 和凭证。 [backend.tf.example](backend.tf.example) 中提供了一个示例后端。 ## 安全边界 - 没有提交任何 AWS 凭证、Vault token、state 文件、变量文件或 plan。 - 应用程序任务拥有与 ECS execution role 分离的独立 workload role。 - Fargate 任务以私有方式运行,并具有只读根文件系统。 - Vault token 是短期的,并且排除了默认策略。 - Vault 策略只能读取唯一所需的 KV 路径。 - ALB 会丢弃无效的标头,并可以通过 ACM 强制执行 TLS。 - 容器镜像和 Terraform providers 都固定了版本。 有关限制和生产环境强化说明,请参阅 [SECURITY.md](SECURITY.md)。 ## 延伸阅读 - [详细的架构决策](docs/architecture.md) - [作品集案例研究](https://snaetwarre.github.io/My-Portofolio/work/aws-fargate-vault.html)
and Container Insights] IAM[IAM task role
workload identity] subgraph VPC[VPC 10.42.0.0/16 across two availability zones] IGW[Internet Gateway] subgraph Public[Public subnets] ALB[Application Load Balancer
HTTP or ACM TLS] NAT[NAT Gateway] end subgraph Private[Private Fargate subnets] subgraph ECS[ECS service] App[Application container
read-only root filesystem] Agent[Vault Agent sidecar] Volume[(Ephemeral shared volume)] Agent -->|renders index.html| Volume App -->|reads rendered file| Volume end end end end User -->|80 or 443| IGW --> ALB ALB -->|security-group scoped 8080| App Agent --> NAT -->|HTTPS| Vault IAM -. ECS task credentials .-> Agent App --> CW Agent --> CW ``` ALB 是唯一的公网入口。Fargate 任务没有公网 IP 地址,仅接受来自 ALB 安全组的应用流量。单一的 NAT gateway 保持了示例的易懂性和相对经济性;生产环境会根据可用性和流量成本评估是否使用多 AZ NAT gateway 或 VPC endpoints。 ## 运行时 secret 流程 ``` sequenceDiagram participant ECS as ECS task participant Agent as Vault Agent sidecar participant IAM as AWS IAM participant Vault as Vault AWS auth and KV v2 participant Volume as Shared ephemeral volume participant App as Application container participant ALB as Application Load Balancer ECS->>Agent: Supply rotating task-role credentials Agent->>IAM: Create signed AWS identity request Agent->>Vault: Authenticate with signed IAM request Vault-->>Agent: Return short-lived token with narrow policy Agent->>Vault: Read midnight-postcard/data/config Vault-->>Agent: Return permitted runtime content Agent->>Volume: Render /vault/secrets/index.html Agent-->>ECS: Health check becomes ready ECS->>App: Start application container App->>Volume: Read rendered page App-->>ALB: Application health check passes ALB-->>App: Begin routing requests ``` 应用程序永远不会收到硬编码的 AWS access key 或 Vault token。Vault 将一个角色绑定到精确的 ECS task-role ARN,并且其策略仅允许从所需的 KV v2 路径进行读取。 ## 部署与质量流程 ``` flowchart LR PR[Pull request or push] --> Fmt[terraform fmt -check] Fmt --> Init[terraform init
backend disabled] Init --> Validate[terraform validate] Validate --> Tests[terraform test
mocked AWS and Vault] Tests --> Review{Human review} Review -->|No credentials in CI| Stop[Quality gate complete] Review -->|Sandbox credentials| Plan[make plan] Plan --> Inspect[terraform show
review plan and cost] Inspect --> Gate{ALLOW_APPLY=yes?} Gate -->|No| Refuse[Refuse deployment] Gate -->|Yes| Apply[Apply reviewed plan] Apply --> Health[ALB and container
health verification] ``` 签入的 GitHub Actions workflow 故意在格式化、验证和模拟的 plan 之后停止。真正的部署需要临时的 AWS 凭证、经过明确审查的 plan,以及单独选择执行 apply。 ## 项目展示的内容 | 关注点 | 实现方式 | | --- | --- | | 基础设施即代码 | 用于网络、IAM、Vault 配置和 ECS 服务的可重用 Terraform modules | | 网络隔离 | 公有 ALB 子网、私有 Fargate 子网、严格限制的安全组,以及无公网任务 IP | | Workload identity | 通过 Vault 的 AWS auth method 进行身份验证的 ECS task role | | Secret 分发 | Vault Agent sidecar 将批准的 KV v2 数据渲染到任务范围的临时卷中 | | 可靠性 | ALB 和容器健康检查、部署断路器、自动回滚和自动扩缩容 | | 可观测性 | CloudWatch 日志组、30 天保留期、awslogs 和 ECS Container Insights | | 成本意识 | Fargate Spot 加权容量、受限的自动扩缩容、单一 NAT gateway 和明确的清理指南 | | 传输安全 | 可选的 ACM certificate,支持 HTTP 到 HTTPS 的重定向以及现代化的 TLS 策略 | | 可测试性 | 使用模拟的 providers 对纯 AWS、启用 Vault 和 HTTPS 变体进行离线 Terraform 测试 | | 交付安全性 | 非部署型 CI,以及一个需要经过审查的 plan 加上明确确认的 apply 目标 | ## 仓库结构 ``` . ├── .github/workflows/ │ └── terraform.yml # Non-deploying Terraform quality gate ├── docs/ │ └── architecture.md # Runtime sequence and design tradeoffs ├── modules/ │ ├── identity/ # ECS execution role and workload task role │ ├── network/ # Two-AZ VPC, subnets, routes, IGW, and NAT │ ├── service/ # ALB, ECS, sidecar, logs, health, and scaling │ └── vault-config/ # AWS auth, KV v2, role, and read-only policy ├── preview/ # Credential-free local application preview ├── tests/ │ └── architecture.tftest.hcl # Mocked Terraform plan tests ├── main.tf # Module composition and dependency order ├── variables.tf # Validated configuration interface ├── outputs.tf # Service URL, cluster, role, and Vault command └── terraform.tfvars.example # Safe example configuration ``` ## 无需云凭证进行验证 要求:Terraform 1.15.x。不需要 AWS 和 Vault 凭证。 ``` git clone https://github.com/SnaetWarre/aws-fargate-vault-terraform.git cd aws-fargate-vault-terraform cp terraform.tfvars.example terraform.tfvars terraform init -backend=false terraform fmt -check -recursive terraform validate terraform test ``` 当前测试套件验证: 1. 安全的纯 AWS 默认配置; 2. Vault sidecar 和轮换输出; 3. 由 ACM 支持的 HTTPS 变体。 可以使用 `make check` 运行相同的检查。要在没有 AWS 或 Vault 的情况下查看微型应用程序: ``` make preview # 打开 http://127.0.0.1:8765 ``` ## 创建经过审查的 AWS plan 复制示例变量,通过具有临时凭证的 AWS 沙盒进行身份验证,并创建一个 plan: ``` cp terraform.tfvars.example terraform.tfvars AWS_PROFILE=your-sandbox-profile make plan terraform show midnight-postcard.tfplan ``` `make plan` 绝不会应用基础设施。即使存在 plan 之后,除非提供了明确的安全闸门,否则 Makefile 也会拒绝部署: ``` ALLOW_APPLY=yes make apply ``` 这会产生付费资源。在应用之前,请审查 NAT Gateway、ALB、Fargate、CloudWatch 和外部 Vault 的成本,并在实验完成后销毁沙盒资源。 ## 启用 Vault 模式 Vault 是按需启用的,并期望有一个可从私有子网访问的现有 HCP Vault 或自建集群。 1. 设置 `enable_vault = true`。 2. 配置真实的 HTTPS `vault_address`。 3. 仅在用于配置 Vault 的本地 shell 中导出管理员权限的 `VAULT_TOKEN`。 4. 创建并检查新的 Terraform plan。 Terraform 配置了 AWS auth mount、绑定到 ECS task role 的 Vault 角色、狭窄的策略,以及故意的公开演示 KV 内容。真正的 secret 值必须在 Terraform 之外写入,因为 Terraform 的资源参数会存储在 state 中。 ## 远程 state 对于不应自动部署的仓库,本地 state 是安全的默认设置。真实环境应使用: - 专用的 S3 state bucket; - 加密和版本控制; - 受限的 IAM 访问权限; - S3 原生 state locking; - 每个环境独立的 state 和凭证。 [backend.tf.example](backend.tf.example) 中提供了一个示例后端。 ## 安全边界 - 没有提交任何 AWS 凭证、Vault token、state 文件、变量文件或 plan。 - 应用程序任务拥有与 ECS execution role 分离的独立 workload role。 - Fargate 任务以私有方式运行,并具有只读根文件系统。 - Vault token 是短期的,并且排除了默认策略。 - Vault 策略只能读取唯一所需的 KV 路径。 - ALB 会丢弃无效的标头,并可以通过 ACM 强制执行 TLS。 - 容器镜像和 Terraform providers 都固定了版本。 有关限制和生产环境强化说明,请参阅 [SECURITY.md](SECURITY.md)。 ## 延伸阅读 - [详细的架构决策](docs/architecture.md) - [作品集案例研究](https://snaetwarre.github.io/My-Portofolio/work/aws-fargate-vault.html)
标签:AWS Fargate, ECS, HashiCorp Vault, Terraform, 自动化运维