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

How to avoid cycle error when setting an S3 bucket policy with a template that depends on the bucket name?

我有一个 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
}

如何避免这种双向引用?

您可以自己构建存储桶的 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
}

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

这样,Terraform 可以:

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

代码看起来像这样:

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
}