diff --git a/aws/resource_aws_s3_bucket_object.go b/aws/resource_aws_s3_bucket_object.go index 124bcc1e050d..129afd45f64a 100644 --- a/aws/resource_aws_s3_bucket_object.go +++ b/aws/resource_aws_s3_bucket_object.go @@ -139,7 +139,15 @@ func resourceAwsS3BucketObject() *schema.Resource { "kms_key_id": { Type: schema.TypeString, Optional: true, + Computed: true, ValidateFunc: validateArn, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // ignore diffs where the user hasn't specified a kms_key_id but the bucket has a default KMS key configured + if new == "" && d.Get("server_side_encryption") == s3.ServerSideEncryptionAwsKms { + return true + } + return false + }, }, "etag": { diff --git a/aws/resource_aws_s3_bucket_object_test.go b/aws/resource_aws_s3_bucket_object_test.go index 05b82ce312b2..d11d6d8b33ca 100644 --- a/aws/resource_aws_s3_bucket_object_test.go +++ b/aws/resource_aws_s3_bucket_object_test.go @@ -955,6 +955,27 @@ func TestAccAWSS3BucketObject_ObjectLockRetentionStartWithSet(t *testing.T) { }) } +func TestAccAWSS3BucketObject_defaultBucketSSE(t *testing.T) { + var obj1 s3.GetObjectOutput + resourceName := "aws_s3_bucket_object.object" + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAWSS3BucketObjectDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSS3BucketObjectConfig_defaultBucketSSE(rInt, "stuff"), + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSS3BucketObjectExists(resourceName, &obj1), + testAccCheckAWSS3BucketObjectBody(&obj1, "stuff"), + ), + }, + }, + }) +} + func TestAccAWSS3BucketObject_ignoreTags(t *testing.T) { var obj s3.GetObjectOutput resourceName := "aws_s3_bucket_object.object" @@ -1656,3 +1677,30 @@ resource "aws_s3_bucket_object" "object" { } `, randInt, source) } + +func testAccAWSS3BucketObjectConfig_defaultBucketSSE(randInt int, content string) string { + return fmt.Sprintf(` +resource "aws_kms_key" "test" { + description = "Encrypts test bucket objects" + deletion_window_in_days = 7 +} + +resource "aws_s3_bucket" "object_bucket" { + bucket = "tf-object-test-bucket-%d" + server_side_encryption_configuration { + rule { + apply_server_side_encryption_by_default { + kms_master_key_id = aws_kms_key.test.arn + sse_algorithm = "aws:kms" + } + } + } +} + +resource "aws_s3_bucket_object" "object" { + bucket = aws_s3_bucket.object_bucket.bucket + key = "test-key" + content = %q +} +`, randInt, content) +} diff --git a/website/docs/r/s3_bucket_object.html.markdown b/website/docs/r/s3_bucket_object.html.markdown index a883e3102032..4641d300eaad 100644 --- a/website/docs/r/s3_bucket_object.html.markdown +++ b/website/docs/r/s3_bucket_object.html.markdown @@ -132,10 +132,9 @@ for the object. Can be either "`STANDARD`", "`REDUCED_REDUNDANCY`", "`ONEZONE_IA * `etag` - (Optional) Used to trigger updates. The only meaningful value is `${filemd5("path/to/file")}` (Terraform 0.11.12 or later) or `${md5(file("path/to/file"))}` (Terraform 0.11.11 or earlier). This attribute is not compatible with KMS encryption, `kms_key_id` or `server_side_encryption = "aws:kms"`. * `server_side_encryption` - (Optional) Specifies server-side encryption of the object in S3. Valid values are "`AES256`" and "`aws:kms`". -* `kms_key_id` - (Optional) Specifies the AWS KMS Key ARN to use for object encryption. -This value is a fully qualified **ARN** of the KMS Key. If using `aws_kms_key`, -use the exported `arn` attribute: - `kms_key_id = "${aws_kms_key.foo.arn}"` +* `kms_key_id` - (Optional) Amazon Resource Name (ARN) of the KMS Key to use for object encryption. If the S3 Bucket has server-side encryption enabled, that value will automatically be used. If referencing the +`aws_kms_key` resource, use the `arn` attribute. If referencing the `aws_kms_alias` data source or resource, use the `target_key_arn` attribute. Terraform will only perform drift detection if a configuration value +is provided. * `metadata` - (Optional) A map of keys/values to provision metadata (will be automatically prefixed by `x-amz-meta-`, note that only lowercase label are currently supported by the AWS Go API). * `tags` - (Optional) A map of tags to assign to the object. * `force_destroy` - (Optional) Allow the object to be deleted by removing any legal hold on any object version.