有没有办法将 CORS 规则添加到 Terraform aws_s3_bucket 数据源?

Is there a way to add CORS rule to Terraform aws_s3_bucket data source?

我有一个不是通过 Terraform 创建的现有存储桶。我目前正在为该存储桶设置额外访问权限的策略。我需要将 cors_rule 添加到存储桶中,但我发现的所有内容都表明您需要创建 resource 才能添加 cors 规则。有没有办法将 cors_rule 添加到现有存储桶数据源?

data "aws_s3_bucket" "my_bucket" {
  bucket = "my-bucket"

  # This produces a failure on plan
  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["GET", "HEAD"]
    allowed_origins = [
      "https://example.my-website.com"
    ]
    expose_headers  = [
      "Access-Control-Allow-Origin",
      "ETag"
    ]
    max_age_seconds = 3000
  }
}

resource "aws_s3_bucket_policy" "allow_access" {
  bucket = data.aws_s3_bucket.my_bucket.id
  policy = data.aws_iam_policy_document.allow_access.json
}

data "aws_iam_policy_document" "allow_access" {
  statement {
    sid = "Access"

    principals {
      type = "AWS"
      identifiers = ["arn:aws:iam::123456789012:user/test"]
    }

    actions = [
      "s3:GetObject",
      "s3:GetBucketLocation",
      "s3:ListBucket",
    ]

    resources = [
      data.aws_s3_bucket.my_bucket.arn,
      "${data.aws_s3_bucket.my_bucket.arn}/*"
    ]
  }
}

您只能修改由 terraform 管理的资源,不能修改作为数据源引入的资源。您可以做的是为您的存储桶创建资源,然后导入现有存储桶:

terraform import aws_s3_bucket.my_bucket my-bucket

导入命令将为您提供在存储桶上设置的所有属性的列表。对于您不想使用 terraform 管理的属性,请在生命周期块中使用 ignore 参数。

你真幸运。就在今天/昨天发布了 AWS 提供商的 4.0.0 版。
新的提供程序版本在 S3 存储桶处理方面进行了大量重构。您现在有一个独立的 s3_bucket_cors_configuration 资源,而不是直接在 aws_s3_bucket 资源上的 CORS 设置。这意味着您现在可以配置 CORS 设置(以及许多其他设置),而无需在您的状态下实际拥有存储桶本身。

resource "aws_s3_bucket_cors_configuration" "example" {
  bucket = aws_s3_bucket.example.bucket

  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["PUT", "POST"]
    allowed_origins = ["https://s3-website-test.hashicorp.com"]
    expose_headers  = ["ETag"]
    max_age_seconds = 3000
  }

  cors_rule {
    allowed_methods = ["GET"]
    allowed_origins = ["*"]
  }
}

唯一需要注意的是,您需要升级到 AWS 供应商的 4.0.0 以及随之而来的所有重大更改。

resource "aws_s3_bucket" "my_bucket" {
  bucket = "my-bucket"

  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["PUT", "POST", "DELETE", "GET"]
    allowed_origins = ["*"]
    expose_headers  = []
  }
}

这适用于我的 3.7 版