我一直在尝试使用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}")
}
我在控制台上看到的结果是,bucket实际上是可公开访问的,但是根据所显示的ACL, bucket中的每个对象都不是公共的。我也无法使用显示的url访问S3对象:这会导致访问被拒绝。
在Terraform中创建具有可公开访问对象的桶的最佳方法是什么?我读到ACL不再是"现代的"。因此,如果有更好的方法来实现这一点,我很乐意听到。
公共桶并不意味着其中的所有对象都是公共的。权限比这更细粒度。为了允许任何人对bucket中的每个对象进行全面访问,您可以使用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桶在创建时默认获得的几乎所有预防措施和权限。