使用依赖于存储桶名称的模板设置 S3 存储桶策略时如何避免循环错误?

Posted

技术标签:

【中文标题】使用依赖于存储桶名称的模板设置 S3 存储桶策略时如何避免循环错误?【英文标题】:How to avoid cycle error when setting an S3 bucket policy with a template that depends on the bucket name? 【发布时间】:2020-09-04 05:57:21 【问题描述】:

我有一个 terraform 文件,当我运行 terraform plan 时失败,我收到错误:

Error: Cycle: module.hosting.data.template_file.bucket_policy, module.hosting.aws_s3_bucket.website

这是有道理的,因为桶指的是策略,反之亦然:

data "template_file" "bucket_policy" 
  template = file("$path.module/policy.json")
  vars = 
    bucket = aws_s3_bucket.website.arn
  


resource "aws_s3_bucket" "website" 
  bucket = "xxx-website"

  website 
    index_document = "index.html"
  

  policy = data.template_file.bucket_policy.rendered

如何避免这种双向引用?

【问题讨论】:

【参考方案1】:

您可以使用aws_s3_bucket_policy 资源。这允许您在没有循环依赖的情况下创建资源。

这样,Terraform 可以:

    创建存储桶 使用存储桶 ARN 创建模板文件 创建策略,返回模板文件并将其附加到存储桶。

代码如下所示:

data "template_file" "bucket_policy" 
  template = file("$path.module/policy.json")
  vars = 
    bucket = aws_s3_bucket.website.arn
  


resource "aws_s3_bucket" "website" 
  bucket = "xxx-website"

  website 
    index_document = "index.html"
  


resource "aws_s3_bucket_policy" "b" 
  bucket = "$aws_s3_bucket.website.id"

  policy = data.template_file.bucket_policy.rendered

【讨论】:

【参考方案2】:

您可以自己构建存储桶的 ARN:

locals 
  bucket_name = "example"
  bucket_arn  = "arn:aws:s3:::$local.bucket_name"


data "template_file" "bucket_policy" 
  template = file("$path.module/policy.json")
  vars = 
    bucket = local.bucket_arn
  


resource "aws_s3_bucket" "website" 
  bucket = local.bucket_name

  website 
    index_document = "index.html"
  

  policy = data.template_file.bucket_policy.rendered

【讨论】:

不错的建议,但后来我得到另一个错误:Error putting S3 policy: MalformedPolicy: Policy has invalid resource 编辑我上面的评论: 完美。我还必须在 policy.json 文件中进行相应的更改 这行得通,但它比必要的复杂。此外,手动构建 Amazon S3 ARN 很简单,但还有其他资源类型可能与更复杂的 ARN 具有循环依赖关系。并且为所有这些手动构建 ARN 可能非常麻烦且容易出错。出于这个原因,有一些特定的可附加资源,例如在本例中的 aws_s3_bucket_policy,它们有助于解决循环依赖而不是 hacky。

以上是关于使用依赖于存储桶名称的模板设置 S3 存储桶策略时如何避免循环错误?的主要内容,如果未能解决你的问题,请参考以下文章

适用于 S3 事件的 Cloudformation SQS 策略

自动为整个 S3 存储桶设置缓存控制(使用存储桶策略?)

S3 存储桶策略 IAM 角色显示为 API 密钥

AWS S3 存储桶策略编辑器访问被拒绝

如何在存储桶名称中使用变量 AWS Cloudformation

如何在删除空S3 Elastic Beanstalk时修复“拒绝访问”?