我一直在尝试使用 Terraform 重新创建现有的基础设施,其中一项必需的服务是 S3 存储桶,它应该包含可公开访问的图像。
这是存储桶的 Terraform 代码:
resource "aws_s3_bucket" "foo_icons" {
bucket = join("-", [local.prefix, "foo", "icons"])
tags = {
Name = join("-", [local.prefix, "foo", "icons"])
Environment = var.environment
}
}
resource "aws_s3_bucket_acl" "icons_bucket_acl" {
bucket = aws_s3_bucket.foo_icons.id
acl = "public-read"
}
桶填充如下:
resource "aws_s3_object" "icon_repository_files" {
for_each = fileset("../files/icon-repository/", "**")
bucket = aws_s3_bucket.foo_icons.id
key = each.value
source = "../files/icon-repository/${each.value}"
etag = filemd5("../files/icon-repository/${each.value}")
}
我在控制台上看到的结果是,存储桶实际上是可公开访问的,但是根据显示的 ACL,存储桶中的每个对象都是不公开的。我也无法使用显示的 url 访问 S3 对象:这导致访问被拒绝。
在 Terraform 中创建包含可公开访问对象的存储桶的最佳方法是什么?我读到 ACL 不再是“现代的”,所以如果有更好的方法来实现这一点,我会很高兴听到它。
公共桶并不意味着其中的所有对象也是公共的。权限比这更细粒度。要允许任何人全面访问存储桶中的每个对象,您可以使用
aws_s3_bucket_policy
资源向所有人授予 s3:GetObject
权限。
这是一个公共存储桶的示例,使用更新的
aws_s3_bucket_public_access_block
资源,正如您提到的,它旨在取代 acl
论点。
resource "aws_s3_bucket" "foo_icons" {
bucket = join("-", [local.prefix, "foo", "icons"])
}
resource "aws_s3_bucket_ownership_controls" "foo_icons" {
bucket = aws_s3_bucket.foo_icons.id
rule {
object_ownership = "BucketOwnerPreferred"
}
}
resource "aws_s3_bucket_public_access_block" "foo_icons" {
bucket = aws_s3_bucket.foo_icons.id
block_public_acls = false
block_public_policy = false
ignore_public_acls = false
restrict_public_buckets = false
}
resource "aws_s3_bucket_acl" "foo_icons" {
bucket = aws_s3_bucket.foo_icons.id
acl = "public-read"
depends_on = [
aws_s3_bucket_ownership_controls.foo_icons,
aws_s3_bucket_public_access_block.foo_icons,
]
}
data "aws_iam_policy_document" "s3_bucket_foo_icons" {
policy_id = "s3_bucket_foo_icons"
statement {
actions = [
"s3:GetObject"
]
effect = "Allow"
resources = [
"${aws_s3_bucket.foo_icons.arn}/*"
]
principals {
type = "*"
identifiers = ["*"]
}
sid = "S3IconsBucketPublicAccess"
}
}
resource "aws_s3_bucket_policy" "foo_icons" {
bucket = aws_s3_bucket.foo_icons.id
policy = data.aws_iam_policy_document.s3_bucket.foo_icons.json
}
注意不要意外地将策略应用到其他存储桶,因为我们故意覆盖几乎所有的预防措施和 S3 存储桶在创建时默认获得的权限。