Search code examples
amazon-s3terraformpolicy

Creating S3 policy with terraform


I am trying to create a S3 bucket and apply a policy to it. Bucket creation steps are fine and when I am trying to apply the below policy I am not able to find the bug in this tf file

The terraform version is - Terraform v0.12.23

{
        "Sid": "DenyUnEncryptedConnection",
        "Effect": "Deny",
        "Principal": "*",
        "Action": "*",
        "Resource": [
             "arn:aws:s3:::${var.s3_bucketName}",
             "arn:aws:s3:::${var.s3_bucketName}/*"
        ],
        "Condition": {
            "Bool": {
                "aws:SecureTransport": "false"
            }
        }
    }

In my main.tf file this is what I am passing to the variable

  module "s3-bucket-policy" {
  source                            = "../s3-policy/"
  s3_bucketName                     = "${aws_s3_bucket.s3_bucket.id}"
  bucket_arn                        = "${aws_s3_bucket.s3_bucket.arn}"
....

The terraform plan command is giving me the policy as below.(Running it through a Jenkins job Copied out of Jenkins log)

    module.s3_bucket.module.s3-bucket-policy.aws_s3_bucket_policy.communication_policy[0][0m will be created[0m[0m
00:00:07.805 [0m  [32m+[0m[0m resource "aws_s3_bucket_policy" "communication_policy" {
00:00:07.805       [32m+[0m [0m[1m[0mbucket[0m[0m = (known after apply)
00:00:07.805       [32m+[0m [0m[1m[0mid[0m[0m     = (known after apply)
00:00:07.805       [32m+[0m [0m[1m[0mpolicy[0m[0m = (known after apply)
00:00:07.805     }

But when I try to apply the same getting the below error and I am not sure how to proceed further.

 [31m
00:01:13.117 [1m[31mError: [0m[0m[1mError putting S3 policy: MalformedPolicy: Action does not apply to any resource(s) in statement
00:01:13.117    status code: 400, [0m
00:01:13.117 

Any pointers on this will be very much appreciated


Solution

  • You need to supply a proper Action compatible with your bucket, change your policy to the following and it should work:

    resource "aws_s3_bucket" "my_bucket" {
      bucket = "my-bucket"
    
      acl    = "public-read"
      policy = <<EOF
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "DenyUnEncryptedConnection",
                "Effect": "Deny",
                "Principal": "*",
                "Action": "s3:*",
                "Resource": [
                    "arn:aws:s3:::my-bucket",
                    "arn:aws:s3:::my-bucket/*"
                ],
                "Condition": {
                    "Bool": {
                        "aws:SecureTransport": "false"
                    }
                }
            }
        ]
    }
    EOF
    }
    

    (I changed the resource to use bucket_arn but it should work with s3_bucketName the way you did it too.)

    Note the "Action": "s3:*", this policy explicitly denies all actions on the bucket and objects when the request meets the condition "aws:SecureTransport": "false" (i.e. it's not an HTTPS connection).