islamelkadi/terraform-aws-cloudfront
GitHub: islamelkadi/terraform-aws-cloudfront
生产级 Terraform CloudFront 模块,内置多框架合规支持和环境感知的安全控制,用于快速部署符合企业安全标准的静态网站 CDN。
Stars: 0 | Forks: 0
# Terraform AWS CloudFront 模块
[](https://github.com/islamelkadi/terraform-aws-cloudfront/actions/workflows/terraform-security.yaml)
[](https://github.com/islamelkadi/terraform-aws-cloudfront/actions/workflows/terraform-lint.yaml)
[](https://github.com/islamelkadi/terraform-aws-cloudfront/actions/workflows/terraform-docs.yaml)
创建一个 AWS CloudFront distribution,用于使用 S3 origin 进行静态网站托管,支持 SSL/TLS 以及全面的安全控制。
## 目录
- [前置条件](#prerequisites)
- [安全性](#security)
- [功能](#features)
- [用法](#usage)
- [要求](#requirements)
- [MCP Servers](#mcp-servers)
## 前置条件
本模块专为 macOS 设计。您的计算机上必须已安装以下软件:
- Python 3 和 pip
- [Kiro](https://kiro.dev) 和 Kiro CLI
- [Homebrew](https://brew.sh)
要安装其余开发工具,请运行:
```
make bootstrap
```
这将安装/升级:tfenv、Terraform (通过 tfenv)、tflint、terraform-docs、checkov 和 pre-commit。
## 安全性
### 安全控制
本模块实施安全控制以符合以下标准:
- AWS Foundational Security Best Practices (FSBP)
- CIS AWS Foundations Benchmark
- NIST 800-53 Rev 5
- NIST 800-171 Rev 2
- PCI DSS v4.0
### 已实施的控制
- [x] **传输中加密**:TLS 1.2+ 最低协议版本
- [x] **HTTPS 强制执行**:将 HTTP 重定向到 HTTPS 或仅限 HTTPS
- [x] **访问日志**:用于 distribution 访问的 S3 bucket 日志记录
- [x] **Origin Access Control**:用于 S3 bucket 访问的现代 OAC
- [x] **ACM 证书**:用于自定义域名的 SSL/TLS 证书
- [x] **地理限制**:可选的地理访问控制
- [x] **WAF 集成**:Web Application Firewall 支持
- [x] **安全控制覆盖**:具有审计理由的可扩展覆盖系统
### 安全最佳实践
**生产环境 Distributions:**
- 使用 TLS 1.2+ 最低协议版本
- 启用仅限 HTTPS 或重定向到 HTTPS
- 启用到 S3 的访问日志记录
- 对 S3 origins 使用 Origin Access Control (OAC)
- 对自定义域名使用 ACM 证书
- 配置 WAF 以获得额外保护
- 监控 CloudWatch 指标
**开发环境 Distributions:**
- 仍需要 TLS 1.2+
- 访问日志可选,以节省成本
- 仍建议使用 OAC
有关完整的安全标准和实施细节,请参阅 [AWS Security Standards](../../../.kiro/steering/aws/aws-security-standards.md)。
### 基于环境的安全控制
安全控制通过 [terraform-aws-metadata](https://github.com/islamelkadi/terraform-aws-metadata?tab=readme-ov-file#security-profiles) 模块的安全配置文件,根据环境自动应用:
| 控制项 | Dev | Staging | Prod |
|---------|-----|---------|------|
| TLS 1.2+ 最低版本 | 必需 | 必需 | 必需 |
| HTTPS 强制执行 | 必需 | 必需 | 必需 |
| 访问日志 | 可选 | 必需 | 必需 |
| WAF 集成 | 可选 | 推荐 | 必需 |
| Origin Access Control | 推荐 | 必需 | 必需 |
有关安全配置文件以及控制如何随环境变化的完整详细信息,请参阅 [Security Profiles](https://github.com/islamelkadi/terraform-aws-metadata?tab=readme-ov-file#security-profiles) 文档。
### 安全扫描抑制
本模块抑制了某些 Checkov 安全检查,这些检查要么不适用于示例/演示代码,要么代表可选功能。以下检查在 `.checkov.yaml` 中被抑制:
**模块源版本控制 (CKV_TF_1, CKV_TF_2)**
- 被抑制是因为我们使用语义版本标签 (`?ref=v1.0.0`) 而非提交哈希,以获得更好的可维护性和可读性
- 语义版本控制是稳定版本有效且广泛接受的版本控制策略
**KMS IAM 策略 (CKV_AWS_111, CKV_AWS_356, CKV_AWS_109)**
- 在示例代码中被抑制,其中 KMS 模块使用灵活的 IAM 策略用于演示目的
- 生产部署应根据特定安全要求自定义 KMS 策略并应用最小权限原则
**S3 和 CloudFront 可选功能**
- **S3 生命周期规则 (CKV_AWS_300)**:中止不完整分片上传的规则是可选的,且取决于具体用例
- **CloudFront Origin Failover (CKV_AWS_310)**:需要多个 origins 并增加复杂性;根据可用性要求启用
- **CloudFront 地理限制 (CKV_AWS_374)**:取决于具体用例;根据内容分发要求进行配置
- **CloudFront TLS 版本 (CKV_AWS_174)**:自定义 TLS 配置需要自定义 SSL 证书;在使用自定义域名时配置
- **CloudFront 响应头策略 (CKV2_AWS_32)**:可选的安全功能;根据安全要求配置
- **S3 事件通知 (CKV2_AWS_62)**:取决于具体用例;根据事件处理要求启用
- **带有 Log4j 防护的 CloudFront WAF (CKV2_AWS_47)**:可选的安全功能,会增加成本和复杂性
- **S3 跨区域复制 (CKV_AWS_144)**:可选的灾难恢复功能,会增加成本和复杂性
## 功能
- **S3 Origin 支持**:配置 S3 bucket 作为 origin,支持 Origin Access Control (OAC) 或旧版 OAI
- **SSL/TLS**:HTTPS 强制执行,支持 ACM 证书,TLS 1.2+ 最低版本
- **缓存**:可配置的缓存行为,包含 TTL 设置和压缩
- **安全性**:内置针对 HTTPS、日志记录和 WAF 集成的安全控制
- **自定义错误**:SPA 友好的错误响应 (404/403 → index.html)
- **日志**:可选的到 S3 的访问日志记录
- **地理限制**:可选的地理限制
- **Metadata 集成**:通过 metadata 模块实现一致的命名和标记
## MCP Servers
本模块包含两个在 `.kiro/settings/mcp.json` 中配置的 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 服务器,用于 Kiro:
| Server | Package | Description |
|--------|---------|-------------|
| `aws-docs` | `awslabs.aws-documentation-mcp-server@latest` | 提供 AWS 文档访问,用于服务功能、API 参考和最佳实践的上下文查找。 |
| `terraform` | `awslabs.terraform-mcp-server@latest` | 支持直接从 IDE 执行 Terraform 操作(init、validate、plan、fmt、tflint),并为常见工作流提供自动批准的命令。 |
两个服务器都通过 `uvx` 运行,除了 [bootstrap](#prerequisites) 步骤外,无需额外安装。
## 用法
```
# CloudFront Distribution 示例
# 演示各种带有安全控制覆盖的 CloudFront 配置
# ============================================================================
# 示例 1:基础静态网站(最小配置)
# 使用虚拟 S3 bucket 源 - 请替换为您的实际 bucket
# 覆盖:在开发环境中禁用日志记录以优化成本
# ============================================================================
module "basic_cloudfront" {
source = "github.com/islamelkadi/terraform-aws-cloudfront"
namespace = var.namespace
environment = var.environment
name = "static-website"
region = var.region
# S3 origin configuration - replace with your actual bucket
origin_domain_name = "my-static-website-bucket.s3.us-east-1.amazonaws.com"
use_origin_access_control = true
# Use CloudFront default certificate (no custom domain)
acm_certificate_arn = null
# Default cache behavior (optimized for static content)
default_cache_behavior = {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
viewer_protocol_policy = "redirect-to-https"
forward_query_string = false
forward_headers = []
forward_cookies = "none"
min_ttl = 0
default_ttl = 3600 # 1 hour
max_ttl = 86400 # 24 hours
compress = true
function_associations = []
}
# SPA-friendly error responses
custom_error_responses = [
{
error_code = 404
response_code = 200
response_page_path = "/index.html"
error_caching_min_ttl = 300
},
{
error_code = 403
response_code = 200
response_page_path = "/index.html"
error_caching_min_ttl = 300
}
]
# Security Control Override: Logging disabled for dev
security_control_overrides = {
disable_logging_requirement = true
justification = "Development environment - access logging disabled for cost optimization. Production will enable logging to separate audit bucket."
}
tags = {
Project = "static-website"
Example = "basic"
}
}
# ============================================================================
# 示例 2:具有完全合规性的生产环境 CloudFront
# 强制执行所有安全控制(HTTPS, Logging, WAF)
# ============================================================================
module "production_cloudfront" {
source = "github.com/islamelkadi/terraform-aws-cloudfront"
namespace = var.namespace
environment = "prod"
name = "production-website"
region = var.region
# S3 origin configuration - replace with your actual bucket
origin_domain_name = "my-production-bucket.s3.us-east-1.amazonaws.com"
use_origin_access_control = true
# Custom domain with ACM certificate (must be in us-east-1)
# acm_certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/abc123"
# aliases = ["www.example.com", "example.com"]
# HTTPS enforcement
minimum_protocol_version = "TLSv1.2_2021"
# Access logging enabled - replace with your actual logging bucket
enable_logging = true
logging_bucket = "my-cloudfront-logs-bucket.s3.amazonaws.com"
logging_prefix = "cloudfront/"
logging_include_cookies = false
# WAF integration (optional)
# web_acl_id = "arn:aws:wafv2:us-east-1:123456789012:global/webacl/example/abc123"
# Cache behavior optimized for production
default_cache_behavior = {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
viewer_protocol_policy = "redirect-to-https"
forward_query_string = false
forward_headers = []
forward_cookies = "none"
min_ttl = 0
default_ttl = 86400 # 24 hours
max_ttl = 31536000 # 1 year
compress = true
function_associations = []
}
# Geo restrictions (optional)
geo_restriction_type = "none"
geo_restriction_locations = []
# Custom error responses
custom_error_responses = [
{
error_code = 404
response_code = 200
response_page_path = "/index.html"
error_caching_min_ttl = 300
}
]
tags = {
Environment = "Production"
Compliance = "FullyCompliant"
Example = "production"
}
}
# ============================================================================
# 示例 3:具有自定义缓存行为的 CloudFront
# 针对不同内容类型的多种缓存行为
# ============================================================================
module "multi_behavior_cloudfront" {
source = "github.com/islamelkadi/terraform-aws-cloudfront"
namespace = var.namespace
environment = var.environment
name = "multi-behavior"
region = var.region
# S3 origin configuration - replace with your actual bucket
origin_domain_name = "my-app-bucket.s3.us-east-1.amazonaws.com"
use_origin_access_control = true
# Default cache behavior for HTML
default_cache_behavior = {
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
viewer_protocol_policy = "redirect-to-https"
forward_query_string = false
forward_headers = []
forward_cookies = "none"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
compress = true
function_associations = []
}
# Ordered cache behaviors for specific paths
ordered_cache_behaviors = [
# Static assets (CSS, JS, images) - long cache
{
path_pattern = "/static/*"
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
viewer_protocol_policy = "redirect-to-https"
forward_query_string = false
forward_headers = []
forward_cookies = "none"
min_ttl = 0
default_ttl = 86400 # 24 hours
max_ttl = 31536000 # 1 year
compress = true
},
# API endpoints - no cache
{
path_pattern = "/api/*"
allowed_methods = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
cached_methods = ["GET", "HEAD"]
viewer_protocol_policy = "https-only"
forward_query_string = true
forward_headers = ["Authorization", "CloudFront-Forwarded-Proto"]
forward_cookies = "all"
min_ttl = 0
default_ttl = 0
max_ttl = 0
compress = false
}
]
# Security Control Override: Logging disabled for dev
security_control_overrides = {
disable_logging_requirement = true
justification = "Development environment - demonstrating cache behaviors. Production will enable logging."
}
tags = {
Example = "multi-behavior"
}
}
```
## 要求
| Name | Version |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.14.3 |
| [aws](#requirement\_aws) | >= 6.34 |
## Providers
| Name | Version |
|------|---------|
| [aws](#provider\_aws) | >= 6.34 |
## Modules
| Name | Source | Version |
|------|--------|---------|
| [metadata](#module\_metadata) | github.com/islamelkadi/terraform-aws-metadata | v1.1.0 |
## Resources
| Name | Type |
|------|------|
| [aws_cloudfront_distribution.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_distribution) | resource |
| [aws_cloudfront_origin_access_control.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudfront_origin_access_control) | resource |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| [acm\_certificate\_arn](#input\_acm\_certificate\_arn) | 自定义域名的 ACM 证书 ARN。必须位于 us-east-1 区域 | `string` | `null` | no |
| [aliases](#input\_aliases) | distribution 的备用域名 (CNAMEs) | `list(string)` | `[]` | no |
| [comment](#input\_comment) | distribution 的注释 | `string` | `""` | no |
| [custom\_error\_responses](#input\_custom\_error\_responses) | 自定义错误响应配置 |
仅在存在书面业务理由时使用。
示例用例:
- disable\_https\_requirement:内部测试(仅限非生产环境)
- disable\_logging\_requirement:低流量站点(成本优化)
- disable\_waf\_requirement:非敏感内容(公开文档)
重要提示:出于审计目的,请在 'justification' 字段中记录原因。 |
list(object({
error_code = number
response_code = number
response_page_path = string
error_caching_min_ttl = number
})) | [| no | | [default\_cache\_behavior](#input\_default\_cache\_behavior) | 默认缓存行为配置 |
{
"error_caching_min_ttl": 300,
"error_code": 404,
"response_code": 200,
"response_page_path": "/index.html"
},
{
"error_caching_min_ttl": 300,
"error_code": 403,
"response_code": 200,
"response_page_path": "/index.html"
}
]
object({
allowed_methods = list(string)
cached_methods = list(string)
viewer_protocol_policy = string
forward_query_string = bool
forward_headers = list(string)
forward_cookies = string
min_ttl = number
default_ttl = number
max_ttl = number
compress = bool
function_associations = list(object({
event_type = string
function_arn = string
}))
}) | {
"allowed_methods": [
"GET",
"HEAD",
"OPTIONS"
],
"cached_methods": [
"GET",
"HEAD"
],
"compress": true,
"default_ttl": 3600,
"forward_cookies": "none",
"forward_headers": [],
"forward_query_string": false,
"function_associations": [],
"max_ttl": 86400,
"min_ttl": 0,
"viewer_protocol_policy": "redirect-to-https"
} | no |
| [default\_root\_object](#input\_default\_root\_object) | 当查看器请求根 URL 时 CloudFront 返回的对象 | `string` | `"index.html"` | no |
| [enable\_ipv6](#input\_enable\_ipv6) | 为 distribution 启用 IPv6 | `bool` | `true` | no |
| [enable\_logging](#input\_enable\_logging) | 为 distribution 启用访问日志记录 | `bool` | `false` | no |
| [enabled](#input\_enabled) | distribution 是否已启用 | `bool` | `true` | no |
| [environment](#input\_environment) | 环境名称 (dev, staging, prod) | `string` | n/a | yes |
| [geo\_restriction\_locations](#input\_geo\_restriction\_locations) | 用于地理限制的 ISO 3166-1-alpha-2 国家代码 | `list(string)` | `[]` | no |
| [geo\_restriction\_type](#input\_geo\_restriction\_type) | 按地理位置限制 distribution 的方法 (none, whitelist, blacklist) | `string` | `"none"` | no |
| [logging\_bucket](#input\_logging\_bucket) | 用于 CloudFront 访问日志的 S3 bucket(必须以 .s3.com 结尾)。如果 enable\_logging 为 true 则为必需 | `string` | `null` | no |
| [logging\_include\_cookies](#input\_logging\_include\_cookies) | 在访问日志中包含 cookie | `bool` | `false` | no |
| [logging\_prefix](#input\_logging\_prefix) | CloudFront 访问日志对象的前缀 | `string` | `"cloudfront/"` | no |
| [minimum\_protocol\_version](#input\_minimum\_protocol\_version) | 最低 TLS 协议版本 | `string` | `"TLSv1.2_2021"` | no |
| [name](#input\_name) | CloudFront distribution 的名称 | `string` | n/a | yes |
| [namespace](#input\_namespace) | Namespace(组织/团队名称) | `string` | n/a | yes |
| [ordered\_cache\_behaviors](#input\_ordered\_cache\_behaviors) | 有序缓存行为列表 | list(object({
path_pattern = string
allowed_methods = list(string)
cached_methods = list(string)
viewer_protocol_policy = string
forward_query_string = bool
forward_headers = list(string)
forward_cookies = string
min_ttl = number
default_ttl = number
max_ttl = number
compress = bool
})) | `[]` | no |
| [origin\_access\_identity\_path](#input\_origin\_access\_identity\_path) | CloudFront origin access identity 路径(旧版,请改用 OAC)。如果 use\_origin\_access\_control 为 false 则为必需 | `string` | `null` | no |
| [origin\_domain\_name](#input\_origin\_domain\_name) | S3 bucket origin 的域名(例如 bucket-name.s3.amazonaws.com 或 bucket-name.s3-website-region.amazonaws.com) | `string` | n/a | yes |
| [price\_class](#input\_price\_class) | distribution 的价格等级 (PriceClass\_All, PriceClass\_200, PriceClass\_100) | `string` | `"PriceClass_100"` | no |
| [region](#input\_region) | 将创建资源的 AWS 区域 | `string` | n/a | yes |
| [security\_control\_overrides](#input\_security\_control\_overrides) | 覆盖此 CloudFront distribution 的特定安全控制。仅在存在书面业务理由时使用。
示例用例:
- disable\_https\_requirement:内部测试(仅限非生产环境)
- disable\_logging\_requirement:低流量站点(成本优化)
- disable\_waf\_requirement:非敏感内容(公开文档)
重要提示:出于审计目的,请在 'justification' 字段中记录原因。 |
object({
disable_https_requirement = optional(bool, false)
disable_logging_requirement = optional(bool, false)
disable_waf_requirement = optional(bool, false)
# Audit trail - document why controls are disabled
justification = optional(string, "")
}) | {
"disable_https_requirement": false,
"disable_logging_requirement": false,
"disable_waf_requirement": false,
"justification": ""
} | no |
| [security\_controls](#input\_security\_controls) | 来自 metadata 模块的安全控制配置。用于强制执行安全标准 | object({
encryption = object({
require_kms_customer_managed = bool
require_encryption_at_rest = bool
require_encryption_in_transit = bool
enable_kms_key_rotation = bool
})
logging = object({
require_cloudwatch_logs = bool
min_log_retention_days = number
require_access_logging = bool
require_flow_logs = bool
})
}) | `null` | no |
| [tags](#input\_tags) | 应用于资源的额外标签 | `map(string)` | `{}` | no |
| [use\_origin\_access\_control](#input\_use\_origin\_access\_control) | 使用 Origin Access Control (OAC) 进行 S3 origin 访问。推荐使用,优于 OAI | `bool` | `true` | no |
| [use\_s3\_website\_endpoint](#input\_use\_s3\_website\_endpoint) | 使用 S3 网站端点作为 origin(用于支持 index.html 的静态网站托管) | `bool` | `false` | no |
| [web\_acl\_id](#input\_web\_acl\_id) | 要与 distribution 关联的 AWS WAF web ACL ID | `string` | `null` | no |
## Outputs
| Name | Description |
|------|-------------|
| [distribution\_arn](#output\_distribution\_arn) | CloudFront distribution ARN |
| [distribution\_domain\_name](#output\_distribution\_domain\_name) | CloudFront distribution 域名 |
| [distribution\_hosted\_zone\_id](#output\_distribution\_hosted\_zone\_id) | CloudFront distribution Route 53 托管区域 ID |
| [distribution\_id](#output\_distribution\_id) | CloudFront distribution ID |
| [distribution\_status](#output\_distribution\_status) | CloudFront distribution 状态 |
| [origin\_access\_control\_id](#output\_origin\_access\_control\_id) | Origin Access Control ID(如果已创建) |
| [tags](#output\_tags) | 应用于 CloudFront distribution 的标签 |
## 示例
有关包含所有功能的完整工作示例,请参阅 [example/](example/)。
标签:AWS, CDN, CIS, CISA项目, CloudFront, DPI, EC2, ECS, ETW劫持, HTTPS, IaC, MacOS, NIST, OAC, PCI DSS, Python, S3, SSL/TLS, Streamlit, Terraform, 企业级, 内容分发网络, 加密传输, 安全合规, 无后门, 日志记录, 模块, 网络代理, 网络调试, 自动化, 访问控制, 静态网站托管