S3 bucketname in policy, terraform

Viewed 802

I am creating a bucket to store lb logs. I don't want to hardcode the name as that would cause my code to break because of the unique name requirement by s3. I am using a bucket_prefix provided by terraform.

In bucket policy I require the name of the s3 bucket and my code is as follows:

resource "aws_s3_bucket" "aws-s3-lb-logs" {
  acl = "private"
  force_destroy = true
  bucket_prefix = "some-prefix"


  policy = <<POLICY
{
  "Id": "Policy",
  "Statement": [
    {
      "Action": [
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::${aws_s3_bucket.aws-s3-lb-logs.bucket}/AWSLogs/*",
      "Principal": {
        "AWS": [
          "${data.aws_elb_service_account.main.arn}"
        ]
      }
    }
  ]
}
POLICY
}

when I try to call ${aws_s3_bucket.aws-s3-lb-logs.bucket} inside policy, it gives and error:

Error: Self-referential block

  on main.tf line 350, in resource "aws_s3_bucket" "aws-s3-lb-logs":
 350:       "Resource": "arn:aws:s3:::${aws_s3_bucket.aws-s3-lb-logs.bucket}/AWSLogs/*",

Configuration for aws_s3_bucket.aws-s3-lb-logs may not refer to itself.

I know I cannot call the same resource block but in this case how do I get the name of the s3 bucket to put in the policy block?

1 Answers

The solution is to use a separate resource (aws_s3_bucket_policy) to set the bucket policy.

resource "aws_s3_bucket" "aws-s3-lb-logs" {
  acl = "private"
  force_destroy = true
  bucket_prefix = "some-prefix"
}

resource "aws_s3_bucket_policy" "aws-s3-lb-logs" {
  bucket = aws_s3_bucket.aws-s3-lb-logs.id

  policy = <<POLICY
{
  "Id": "Policy",
  "Statement": [
    {
      "Action": [
        "s3:PutObject"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:s3:::${aws_s3_bucket.aws-s3-lb-logs.bucket}/AWSLogs/*",
      "Principal": {
        "AWS": [
          "${data.aws_elb_service_account.main.arn}"
        ]
      }
    }
  ]
}
POLICY
}
Related