Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a terraform file which fails when I run terraform plan and I get the error:

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

It makes sense since the bucket refers to the policy and vice versa:

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
}

How can I avoid this bidirectional reference?

like image 341
saronet Avatar asked May 18 '20 12:05

saronet


2 Answers

You can use the aws_s3_bucket_policy resource. This allows you to create the resources without a circular dependency.

This way, Terraform can:

  1. Create the bucket
  2. Create the template file, using the bucket ARN
  3. Create the policy, referring back to the template file and attaching it to the bucket.

The code would look something like this:

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
}
like image 119
Dennis Traub Avatar answered Oct 17 '22 10:10

Dennis Traub


You could build the ARN of the bucket yourself:

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
}
like image 3
ydaetskcoR Avatar answered Oct 17 '22 09:10

ydaetskcoR