Skip to content

Commit

Permalink
Merge pull request #5453 from bigkraig/aws-s3-kms-key
Browse files Browse the repository at this point in the history
provider/aws: Support KMS encryption of S3 objects
  • Loading branch information
phinze committed Mar 10, 2016
2 parents 5ce68fd + 76b3c74 commit 82765ea
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
17 changes: 17 additions & 0 deletions builtin/providers/aws/resource_aws_s3_bucket_object.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ func resourceAwsS3BucketObject() *schema.Resource {
ConflictsWith: []string{"source"},
},

"kms_key_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},

"etag": &schema.Schema{
Type: schema.TypeString,
// This will conflict with SSE-C and SSE-KMS encryption and multi-part upload
Expand Down Expand Up @@ -117,6 +122,12 @@ func resourceAwsS3BucketObjectPut(d *schema.ResourceData, meta interface{}) erro
return fmt.Errorf("Must specify \"source\" or \"content\" field")
}

if _, ok := d.GetOk("kms_key_id"); ok {
if _, ok := d.GetOk("etag"); ok {
return fmt.Errorf("Unable to specify 'kms_key_id' and 'etag' together because 'etag' wouldn't equal the MD5 digest of the raw object data")
}
}

putInput := &s3.PutObjectInput{
Bucket: aws.String(bucket),
Key: aws.String(key),
Expand All @@ -143,6 +154,11 @@ func resourceAwsS3BucketObjectPut(d *schema.ResourceData, meta interface{}) erro
putInput.ContentDisposition = aws.String(v.(string))
}

if v, ok := d.GetOk("kms_key_id"); ok {
putInput.SSEKMSKeyId = aws.String(v.(string))
putInput.ServerSideEncryption = aws.String("aws:kms")
}

resp, err := s3conn.PutObject(putInput)
if err != nil {
return fmt.Errorf("Error putting object in S3 bucket (%s): %s", bucket, err)
Expand Down Expand Up @@ -186,6 +202,7 @@ func resourceAwsS3BucketObjectRead(d *schema.ResourceData, meta interface{}) err
d.Set("content_language", resp.ContentLanguage)
d.Set("content_type", resp.ContentType)
d.Set("version_id", resp.VersionId)
d.Set("kms_key_id", resp.SSEKMSKeyId)

log.Printf("[DEBUG] Reading S3 Bucket Object meta: %s", resp)
return nil
Expand Down
36 changes: 36 additions & 0 deletions builtin/providers/aws/resource_aws_s3_bucket_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,24 @@ func testAccCheckAWSS3BucketObjectExists(n string, obj *s3.GetObjectOutput) reso
}
}

func TestAccAWSS3BucketObject_kms(t *testing.T) {
rInt := acctest.RandInt()
var obj s3.GetObjectOutput

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSS3BucketObjectDestroy,
Steps: []resource.TestStep{
resource.TestStep{
PreConfig: func() {},
Config: testAccAWSS3BucketObjectConfig_withKMSId(rInt),
Check: testAccCheckAWSS3BucketObjectExists("aws_s3_bucket_object.object", &obj),
},
},
})
}

func testAccAWSS3BucketObjectConfigSource(randInt int, source string) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "object_bucket" {
Expand Down Expand Up @@ -322,3 +340,21 @@ resource "aws_s3_bucket_object" "object" {
}
`, randInt, source, source)
}

func testAccAWSS3BucketObjectConfig_withKMSId(randInt int) string {
return fmt.Sprintf(`
resource "aws_kms_key" "kms_key_1" {
}
resource "aws_s3_bucket" "object_bucket_2" {
bucket = "tf-object-test-bucket-%d"
}
resource "aws_s3_bucket_object" "object" {
bucket = "${aws_s3_bucket.object_bucket_2.bucket}"
key = "test-key"
content = "stuff"
kms_key_id = "${aws_kms_key.kms_key_1.key_id}"
}
`, randInt)
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ The following arguments are supported:
* `content_language` - (Optional) The language the content is in e.g. en-US or en-GB.
* `content_type` - (Optional) A standard MIME type describing the format of the object data, e.g. application/octet-stream. All Valid MIME Types are valid for this input.
* `etag` - (Optional) Used to trigger updates. The only meaningful value is `${md5(file("path/to/file"))}`
* `kms_key_id` - (Optional) Specifies the AWS KMS key ID to use for object encryption.

Either `source` or `content` must be provided to specify the bucket content.
These two arguments are mutually-exclusive.
Expand Down

0 comments on commit 82765ea

Please sign in to comment.