islamelkadi/terraform-aws-cloudfront

GitHub: islamelkadi/terraform-aws-cloudfront

生产级 Terraform CloudFront 模块,内置多框架合规支持和环境感知的安全控制,用于快速部署符合企业安全标准的静态网站 CDN。

Stars: 0 | Forks: 0

# Terraform AWS CloudFront 模块 [![Terraform Security](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/fd81fb2e05132548.svg)](https://github.com/islamelkadi/terraform-aws-cloudfront/actions/workflows/terraform-security.yaml) [![Terraform Lint & Validation](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/c216e6096e132549.svg)](https://github.com/islamelkadi/terraform-aws-cloudfront/actions/workflows/terraform-lint.yaml) [![Terraform Docs](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/5daf814ad6132550.svg)](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) | 自定义错误响应配置 |
list(object({
error_code = number
response_code = number
response_page_path = string
error_caching_min_ttl = number
}))
|
[
{
"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"
}
]
| no | | [default\_cache\_behavior](#input\_default\_cache\_behavior) | 默认缓存行为配置 |
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, 企业级, 内容分发网络, 加密传输, 安全合规, 无后门, 日志记录, 模块, 网络代理, 网络调试, 自动化, 访问控制, 静态网站托管