mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-20 11:48:24 -06:00
This commit adds a new "attachment" style resource for setting the policy of an AWS S3 bucket. This is desirable such that the ARN of the bucket can be referenced in an IAM Policy Document. In addition, we now suppress diffs on the (now-computed) policy in the S3 bucket for structurally equivalent policies, which prevents flapping because of whitespace and map ordering changes made by the S3 endpoint.
181 lines
4.6 KiB
Go
181 lines
4.6 KiB
Go
package aws
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/service/s3"
|
|
"github.com/hashicorp/terraform/helper/acctest"
|
|
"github.com/hashicorp/terraform/helper/resource"
|
|
"github.com/hashicorp/terraform/terraform"
|
|
"github.com/jen20/awspolicyequivalence"
|
|
)
|
|
|
|
func TestAccAWSS3BucketPolicy_basic(t *testing.T) {
|
|
name := fmt.Sprintf("tf-test-bucket-%d", acctest.RandInt())
|
|
|
|
expectedPolicyText := fmt.Sprintf(
|
|
`{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"s3:*","Resource":["arn:aws:s3:::%s","arn:aws:s3:::%s/*"]}]}`,
|
|
name, name)
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
Providers: testAccProviders,
|
|
CheckDestroy: testAccCheckAWSS3BucketDestroy,
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccAWSS3BucketPolicyConfig(name),
|
|
Check: resource.ComposeTestCheckFunc(
|
|
testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
|
|
testAccCheckAWSS3BucketHasPolicy("aws_s3_bucket.bucket", expectedPolicyText),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestAccAWSS3BucketPolicy_policyUpdate(t *testing.T) {
|
|
name := fmt.Sprintf("tf-test-bucket-%d", acctest.RandInt())
|
|
|
|
expectedPolicyText1 := fmt.Sprintf(
|
|
`{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"s3:*","Resource":["arn:aws:s3:::%s","arn:aws:s3:::%s/*"]}]}`,
|
|
name, name)
|
|
|
|
expectedPolicyText2 := fmt.Sprintf(
|
|
`{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":["s3:DeleteBucket", "s3:ListBucket", "s3:ListBucketVersions"], "Resource":["arn:aws:s3:::%s","arn:aws:s3:::%s/*"]}]}`,
|
|
name, name)
|
|
|
|
resource.Test(t, resource.TestCase{
|
|
PreCheck: func() { testAccPreCheck(t) },
|
|
Providers: testAccProviders,
|
|
CheckDestroy: testAccCheckAWSS3BucketDestroy,
|
|
Steps: []resource.TestStep{
|
|
{
|
|
Config: testAccAWSS3BucketPolicyConfig(name),
|
|
Check: resource.ComposeTestCheckFunc(
|
|
testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
|
|
testAccCheckAWSS3BucketHasPolicy("aws_s3_bucket.bucket", expectedPolicyText1),
|
|
),
|
|
},
|
|
|
|
{
|
|
Config: testAccAWSS3BucketPolicyConfig_updated(name),
|
|
Check: resource.ComposeTestCheckFunc(
|
|
testAccCheckAWSS3BucketExists("aws_s3_bucket.bucket"),
|
|
testAccCheckAWSS3BucketHasPolicy("aws_s3_bucket.bucket", expectedPolicyText2),
|
|
),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func testAccCheckAWSS3BucketHasPolicy(n string, expectedPolicyText string) resource.TestCheckFunc {
|
|
return func(s *terraform.State) error {
|
|
rs, ok := s.RootModule().Resources[n]
|
|
if !ok {
|
|
return fmt.Errorf("Not found: %s", n)
|
|
}
|
|
|
|
if rs.Primary.ID == "" {
|
|
return fmt.Errorf("No S3 Bucket ID is set")
|
|
}
|
|
|
|
conn := testAccProvider.Meta().(*AWSClient).s3conn
|
|
|
|
policy, err := conn.GetBucketPolicy(&s3.GetBucketPolicyInput{
|
|
Bucket: aws.String(rs.Primary.ID),
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("GetBucketPolicy error: %v", err)
|
|
}
|
|
|
|
actualPolicyText := *policy.Policy
|
|
|
|
equivalent, err := awspolicy.PoliciesAreEquivalent(actualPolicyText, expectedPolicyText)
|
|
if err != nil {
|
|
return fmt.Errorf("Error testing policy equivalence: %s", err)
|
|
}
|
|
if !equivalent {
|
|
return fmt.Errorf("Non-equivalent policy error:\n\nexpected: %s\n\n got: %s\n",
|
|
expectedPolicyText, actualPolicyText)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func testAccAWSS3BucketPolicyConfig(bucketName string) string {
|
|
return fmt.Sprintf(`
|
|
resource "aws_s3_bucket" "bucket" {
|
|
bucket = "%s"
|
|
tags {
|
|
TestName = "TestAccAWSS3BucketPolicy_basic"
|
|
}
|
|
}
|
|
|
|
resource "aws_s3_bucket_policy" "bucket" {
|
|
bucket = "${aws_s3_bucket.bucket.bucket}"
|
|
policy = "${data.aws_iam_policy_document.policy.json}"
|
|
}
|
|
|
|
data "aws_iam_policy_document" "policy" {
|
|
statement {
|
|
effect = "Allow"
|
|
|
|
actions = [
|
|
"s3:*",
|
|
]
|
|
|
|
resources = [
|
|
"${aws_s3_bucket.bucket.arn}",
|
|
"${aws_s3_bucket.bucket.arn}/*",
|
|
]
|
|
|
|
principals {
|
|
type = "AWS"
|
|
identifiers = ["*"]
|
|
}
|
|
}
|
|
}
|
|
`, bucketName)
|
|
}
|
|
|
|
func testAccAWSS3BucketPolicyConfig_updated(bucketName string) string {
|
|
return fmt.Sprintf(`
|
|
resource "aws_s3_bucket" "bucket" {
|
|
bucket = "%s"
|
|
tags {
|
|
TestName = "TestAccAWSS3BucketPolicy_basic"
|
|
}
|
|
}
|
|
|
|
resource "aws_s3_bucket_policy" "bucket" {
|
|
bucket = "${aws_s3_bucket.bucket.bucket}"
|
|
policy = "${data.aws_iam_policy_document.policy.json}"
|
|
}
|
|
|
|
data "aws_iam_policy_document" "policy" {
|
|
statement {
|
|
effect = "Allow"
|
|
|
|
actions = [
|
|
"s3:DeleteBucket",
|
|
"s3:ListBucket",
|
|
"s3:ListBucketVersions"
|
|
]
|
|
|
|
resources = [
|
|
"${aws_s3_bucket.bucket.arn}",
|
|
"${aws_s3_bucket.bucket.arn}/*",
|
|
]
|
|
|
|
principals {
|
|
type = "AWS"
|
|
identifiers = ["*"]
|
|
}
|
|
}
|
|
}
|
|
`, bucketName)
|
|
}
|