islamelkadi/terraform-aws-s3
GitHub: islamelkadi/terraform-aws-s3
面向企业合规场景的 AWS S3 Terraform 模块,内置多框架安全控制与环境感知策略。
Stars: 0 | Forks: 0
# Terraform AWS S3 模块
[](https://github.com/islamelkadi/terraform-aws-s3/actions/workflows/terraform-security.yaml)
[](https://github.com/islamelkadi/terraform-aws-s3/actions/workflows/terraform-lint.yaml)
[](https://github.com/islamelkadi/terraform-aws-s3/actions/workflows/terraform-docs.yaml)
一个可复用的 Terraform 模块,用于创建符合 AWS Security Hub 合规性(FSBP、CIS、NIST 800-53、NIST 800-171、PCI DSS)的 AWS S3 存储桶,支持 KMS 加密、版本控制、生命周期策略以及灵活的安全控制覆盖。
## 目录
- [前置条件](#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 Security Hub 合规性,并配备了一个可扩展的覆盖系统。
### 可用的安全控制覆盖
| 覆盖标志 | 描述 | 常见理由 |
|--------------|-------------|---------------------|
| `disable_kms_requirement` | 允许 AWS 管理的加密 | "公共网站资产,无敏感数据" |
| `disable_versioning_requirement` | 禁用版本控制 | "静态网站,内容在 Git 中进行版本控制" |
| `disable_logging_requirement` | 禁用访问日志 | "低价值存储桶,成本优化" |
| `disable_lifecycle_requirement` | 禁用生命周期策略 | "短期数据,手动清理" |
| `disable_public_access_block` | 允许公共访问 | "公共网站托管,已通过安全团队审查" |
### 安全最佳实践
**生产环境存储桶:**
- 使用 KMS 客户托管密钥
- 启用版本控制以保护数据
- 启用访问日志
- 配置生命周期策略
- 阻止所有公共访问(除非明确需要)
**开发环境存储桶:**
- 仍然建议使用 KMS 加密
- 版本控制可选,以节省成本
- 访问日志可选
### 基于环境的安全控制
安全控制通过 [terraform-aws-metadata](https://github.com/islamelkadi/terraform-aws-metadata?tab=readme-ov-file#security-profiles) 模块的安全配置文件根据环境自动应用:
| 控制 | 开发环境 | 预发布环境 | 生产环境 |
|---------|-----|---------|------|
| KMS 客户托管密钥 | 可选 | 必需 | 必需 |
| 版本控制 | 可选 | 必需 | 必需 |
| 访问日志 | 可选 | 必需 | 必需 |
| 公共访问阻止 | 推荐 | 必需 | 必需 |
| 生命周期策略 | 可选 | 推荐 | 必需 |
有关安全配置文件以及控制如何随环境变化的完整详细信息,请参阅 [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 可选功能**
- **生命周期规则 (CKV_AWS_300)**:中止不完整分片上传的规则是可选的,并视用例而定
- **事件通知 (CKV2_AWS_62)**:S3 事件通知视用例而定;根据事件处理要求启用
- **跨区域复制 (CKV_AWS_144)**:可选的灾难恢复功能,会增加成本和复杂性
- **MFA 删除 (CKV_AWS_21)**:可选的安全功能,会增加操作复杂性;根据安全要求启用
## 功能
- 支持 KMS 加密的 S3 存储桶
- 用于数据保护的版本控制
- 访问日志支持
- 用于成本优化的生命周期策略
- 默认阻止公共访问
- 存储桶策略管理
- 安全控制集成
## 用法示例
### 基本示例
```
module "s3_bucket" {
source = "github.com/islamelkadi/terraform-aws-s3"
namespace = "example"
environment = "prod"
name = "data"
region = "us-east-1"
kms_key_arn = module.kms.key_arn
tags = {
Project = "CorporateActions"
}
}
```
### 带安全控制的生产环境存储桶
```
module "s3_bucket" {
source = "github.com/islamelkadi/terraform-aws-s3"
security_controls = module.metadata.security_controls
namespace = "example"
environment = "prod"
name = "corporate-actions-data"
region = "us-east-1"
kms_key_arn = module.kms.key_arn
# Versioning enabled
enable_versioning = true
# Access logging
enable_logging = true
logging_target_bucket = module.logs_bucket.bucket_name
logging_target_prefix = "corporate-actions-data/"
# Lifecycle policy
enable_lifecycle_policy = true
glacier_transition_days = 90
noncurrent_version_expiration_days = 30
# Bucket policy
allowed_principals = [
module.lambda.role_arn,
module.step_function.role_arn
]
tags = {
Project = "CorporateActions"
DataClass = "Confidential"
Compliance = "PCI-DSS"
}
}
```
### 带覆盖的静态网站存储桶
```
module "website_bucket" {
source = "github.com/islamelkadi/terraform-aws-s3"
security_controls = module.metadata.security_controls
security_control_overrides = {
disable_versioning_requirement = true
disable_kms_requirement = true
disable_public_access_block = true
justification = "Public static website hosting. Content is version-controlled in Git. No sensitive data. Public access required for CloudFront distribution. Reviewed and approved by security team."
}
namespace = "example"
environment = "prod"
name = "public-website"
region = "us-east-1"
# Use AWS-managed encryption for public content
kms_key_arn = null
# Versioning not needed (Git is source of truth)
enable_versioning = false
# No lifecycle policy needed
enable_lifecycle_policy = false
tags = {
Project = "PublicWebsite"
Purpose = "StaticContent"
}
}
```
### 带 OAC 的 CloudFront 静态网站
```
# 集成 CloudFront OAC 的 S3 bucket
module "website_bucket" {
depends_on = [module.cdn]
source = "github.com/islamelkadi/terraform-aws-s3"
namespace = "example"
environment = "prod"
name = "website"
region = "us-east-1"
kms_key_arn = module.kms.key_arn
# CloudFront OAC integration - automatically creates bucket policy
cloudfront_distribution_arn = module.cdn.distribution_arn
tags = {
Project = "Website"
Purpose = "StaticContent"
}
}
# 带有 OAC 的 CloudFront distribution(推荐以此取代旧版 OAI)
module "cdn" {
source = "github.com/islamelkadi/terraform-aws-s3"
origin_domain_name = module.website_bucket.bucket_regional_domain_name
use_origin_access_control = true # Use OAC (recommended)
# ... other CloudFront configuration
}
```
## MCP 服务器
此模块包含两个在 `.kiro/settings/mcp.json` 中配置的 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 服务器,供 Kiro 使用:
| 服务器 | 包 | 描述 |
|--------|---------|-------------|
| `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) 步骤外,无需额外安装。
## 用法
```
# S3 Bucket 示例
# 演示带有安全控制覆盖的各种 S3 bucket 配置
# ============================================================================
# 示例 1:基础 S3 Bucket(最小配置)
# 使用虚构的 KMS key ARN - 请替换为您实际的 KMS key
# 覆盖:禁用日志记录以优化 dev 环境成本
# ============================================================================
module "basic_bucket" {
source = "github.com/islamelkadi/terraform-aws-s3"
namespace = var.namespace
environment = var.environment
name = var.bucket_name
region = var.region
# KMS encryption - replace with your actual KMS key ARN
kms_key_arn = var.kms_key_arn
# Versioning enabled for data protection
enable_versioning = var.enable_versioning
# Lifecycle policy - transition to Glacier after 90 days
enable_lifecycle_policy = var.enable_lifecycle_policy
glacier_transition_days = var.glacier_transition_days
# 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 = var.project_name
Example = "basic"
}
}
# ============================================================================
# 示例 2:具有完全合规性的生产环境 S3 Bucket
# 强制执行所有安全控制(Versioning、Logging、Lifecycle)
# ============================================================================
module "production_bucket" {
source = "github.com/islamelkadi/terraform-aws-s3"
namespace = var.namespace
environment = "prod"
name = "${var.bucket_name}-prod"
region = var.region
# KMS encryption - replace with your actual KMS key ARN
kms_key_arn = var.kms_key_arn
# Versioning enabled for compliance
enable_versioning = true
# Lifecycle policy - transition to Glacier after 90 days
enable_lifecycle_policy = true
glacier_transition_days = 90
# Noncurrent version expiration after 1 year
noncurrent_version_expiration_days = 365
# Access logging enabled - replace with your actual logging bucket
enable_logging = true
logging_target_bucket = var.logging_bucket_name
logging_target_prefix = "production-bucket/"
# Bucket policy - allow specific IAM roles
# Replace with your actual IAM role ARNs
allowed_principals = var.allowed_principals
allowed_actions = [
"s3:GetObject",
"s3:PutObject"
]
tags = {
Environment = "Production"
Compliance = "FullyCompliant"
Project = var.project_name
Example = "production"
}
}
# ============================================================================
# 示例 3:归档 Bucket(长期存储)
# 针对不频繁访问进行优化,采用激进的 lifecycle 策略
# ============================================================================
module "archive_bucket" {
source = "github.com/islamelkadi/terraform-aws-s3"
namespace = var.namespace
environment = var.environment
name = "${var.bucket_name}-archive"
region = var.region
# KMS encryption - replace with your actual KMS key ARN
kms_key_arn = var.kms_key_arn
# Versioning enabled for audit trail
enable_versioning = true
# Aggressive lifecycle policy - transition to Glacier after 30 days
enable_lifecycle_policy = true
glacier_transition_days = 30
# Noncurrent versions expire after 90 days
noncurrent_version_expiration_days = 90
# Security Control Override: Logging disabled for dev
security_control_overrides = {
disable_logging_requirement = true
justification = "Development environment - archive bucket for testing. Production will enable logging."
}
tags = {
Project = var.project_name
Purpose = "archive"
Example = "archive"
}
}
```
## 要求
| 名称 | 版本 |
|------|---------|
| [terraform](#requirement\_terraform) | >= 1.14.3 |
| [aws](#requirement\_aws) | >= 6.34 |
## Providers
| 名称 | 版本 |
|------|---------|
| [aws](#provider\_aws) | >= 6.34 |
## 模块
| 名称 | 来源 | 版本 |
|------|--------|---------|
| [metadata](#module\_metadata) | github.com/islamelkadi/terraform-aws-metadata | v1.1.0 |
## 资源
| 名称 | 类型 |
|------|------|
| [aws_s3_bucket.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
| [aws_s3_bucket_lifecycle_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_lifecycle_configuration) | resource |
| [aws_s3_bucket_logging.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_logging) | resource |
| [aws_s3_bucket_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
| [aws_s3_bucket_public_access_block.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
| [aws_s3_bucket_server_side_encryption_configuration.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
| [aws_s3_bucket_versioning.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
| [aws_iam_policy_document.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
## 输入
| 名称 | 描述 | 类型 | 默认值 | 必需 |
|------|-------------|------|---------|:--------:|
| [allowed\_actions](#input\_allowed\_actions) | 允许主体执行的 S3 操作列表 | `list(string)` |
仅在存在书面业务理由时使用。
示例用例:
- disable\_versioning\_requirement:静态网站托管(内容在 Git 中进行版本控制)
- disable\_kms\_requirement:公共网站资产(无敏感数据)
- disable\_logging\_requirement:低价值存储桶(成本优化)
重要提示:出于审计目的,请在 'justification' 字段中记录原因。 |
[| no | | [allowed\_principals](#input\_allowed\_principals) | 允许访问存储桶的 IAM 角色/用户 ARN 列表 | `list(string)` | `[]` | no | | [attributes](#input\_attributes) | 用于命名的附加属性 | `list(string)` | `[]` | no | | [bucket\_policy](#input\_bucket\_policy) | 自定义存储桶策略 JSON。如果未提供,将创建默认策略 | `string` | `null` | no | | [cloudfront\_distribution\_arn](#input\_cloudfront\_distribution\_arn) | 用于带 OAC 的存储桶策略的 CloudFront 分配 ARN。提供时,使用 Origin Access Control 授予 CloudFront 读取权限(推荐优先于 OAI) | `string` | `null` | no | | [delimiter](#input\_delimiter) | 名称组件之间使用的分隔符 | `string` | `"-"` | no | | [enable\_lifecycle\_policy](#input\_enable\_lifecycle\_policy) | 为存储桶启用生命周期策略 | `bool` | `true` | no | | [enable\_logging](#input\_enable\_logging) | 为存储桶启用访问日志 | `bool` | `false` | no | | [enable\_versioning](#input\_enable\_versioning) | 为存储桶启用版本控制 | `bool` | `true` | no | | [environment](#input\_environment) | 环境名称(dev、staging、prod) | `string` | n/a | yes | | [glacier\_transition\_days](#input\_glacier\_transition\_days) | 对象转换为 Glacier 存储类之前的天数 | `number` | `90` | no | | [kms\_key\_arn](#input\_kms\_key\_arn) | 用于存储桶加密的 KMS 密钥 ARN | `string` | n/a | yes | | [logging\_target\_bucket](#input\_logging\_target\_bucket) | 访问日志的目标存储桶。如果 enable\_logging 为 true 则必需 | `string` | `null` | no | | [logging\_target\_prefix](#input\_logging\_target\_prefix) | 访问日志对象的前缀。默认为存储桶名称 | `string` | `null` | no | | [name](#input\_name) | S3 存储桶的名称 | `string` | n/a | yes | | [namespace](#input\_namespace) | 命名空间(组织/团队名称) | `string` | n/a | yes | | [noncurrent\_version\_expiration\_days](#input\_noncurrent\_version\_expiration\_days) | 非当前版本过期前的天数。设置为 0 以禁用 | `number` | `0` | no | | [region](#input\_region) | 将创建资源的 AWS 区域 | `string` | n/a | yes | | [security\_control\_overrides](#input\_security\_control\_overrides) | 覆盖此 S3 存储桶的特定安全控制。
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
]
仅在存在书面业务理由时使用。
示例用例:
- disable\_versioning\_requirement:静态网站托管(内容在 Git 中进行版本控制)
- disable\_kms\_requirement:公共网站资产(无敏感数据)
- disable\_logging\_requirement:低价值存储桶(成本优化)
重要提示:出于审计目的,请在 'justification' 字段中记录原因。 |
object({
disable_kms_requirement = optional(bool, false)
disable_versioning_requirement = optional(bool, false)
disable_logging_requirement = optional(bool, false)
disable_lifecycle_requirement = optional(bool, false)
disable_public_block = optional(bool, false)
# Audit trail - document why controls are disabled
justification = optional(string, "")
}) | {
"disable_kms_requirement": false,
"disable_lifecycle_requirement": false,
"disable_logging_requirement": false,
"disable_public_access_block": false,
"disable_versioning_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
})
data_protection = object({
require_versioning = bool
require_mfa_delete = bool
require_automated_backups = bool
block_public_access = bool
require_lifecycle_policies = bool
})
}) | `null` | no |
| [tags](#input\_tags) | 应用于资源的附加标签 | `map(string)` | `{}` | no |
## 输出
| 名称 | 描述 |
|------|-------------|
| [bucket\_arn](#output\_bucket\_arn) | S3 存储桶 ARN |
| [bucket\_domain\_name](#output\_bucket\_domain\_name) | S3 存储桶域名 |
| [bucket\_id](#output\_bucket\_id) | S3 存储桶 ID(与存储桶名称相同) |
| [bucket\_name](#output\_bucket\_name) | S3 存储桶名称 |
| [bucket\_region](#output\_bucket\_region) | S3 存储桶区域 |
| [bucket\_regional\_domain\_name](#output\_bucket\_regional\_domain\_name) | S3 存储桶区域域名 |
| [tags](#output\_tags) | 应用于 S3 存储桶的标签 |
## 示例
有关包含所有功能的完整工作示例,请参阅 [example/](example/)。
标签:AWS, CIS, DPI, EC2, ECS, IaC, KMS加密, NIST, PCI DSS, S3, Security Hub, Terraform, 云存储, 人工智能安全, 企业级, 合规性, 安全可观测性, 安全基线, 教学环境, 模块, 版本控制, 特权提升, 生命周期管理, 自动化部署, 逆向工具