Skip to content

Commit

Permalink
hashicorp#2217: get default encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
trung committed Jan 17, 2018
1 parent 127a630 commit 778d440
Show file tree
Hide file tree
Showing 3 changed files with 211 additions and 0 deletions.
86 changes: 86 additions & 0 deletions aws/data_source_aws_s3_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,45 @@ func dataSourceAwsS3Bucket() *schema.Resource {
Type: schema.TypeString,
Required: true,
},
"server_side_encryption_configuration": {
Type: schema.TypeList,
MaxItems: 1,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"rule": {
Type: schema.TypeList,
MaxItems: 1,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"apply_server_side_encryption_by_default": {
Type: schema.TypeList,
MaxItems: 1,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"kms_master_key_id": {
Type: schema.TypeString,
Computed: true,
},
"sse_algorithm": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
},
},
},
},
},
"arn": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -70,6 +109,53 @@ func dataSourceAwsS3BucketRead(d *schema.ResourceData, meta interface{}) error {
return err
}

if err := bucketEncryption(d, bucket, conn); err != nil {
return err
}

return nil
}

func bucketEncryption(data *schema.ResourceData, bucket string, conn *s3.S3) error {
input := &s3.GetBucketEncryptionInput{
Bucket: aws.String(bucket),
}
output, err := conn.GetBucketEncryption(input)
if err != nil {
if isAWSErr(err, "ServerSideEncryptionConfigurationNotFoundError", "encryption configuration was not found") {
log.Printf("[DEBUG] Default encryption is not enabled for %s", bucket)
data.Set("server_side_encryption_configuration", []map[string]interface{}{
{
"enabled": false,
},
})
return nil
} else {
return err
}
}
if ruleCount := len(output.ServerSideEncryptionConfiguration.Rules); ruleCount != 1 {
return fmt.Errorf("expect one rule returned but there are %d rules. Changes required in the data source to support this", ruleCount)
}
defaultRuleConfiguration := output.ServerSideEncryptionConfiguration.Rules[0].ApplyServerSideEncryptionByDefault
defaultRule := make([]map[string]interface{}, 1)
defaultRule[0] = make(map[string]interface{})
masterKmsKeyId := ""
if defaultRuleConfiguration.KMSMasterKeyID != nil {
masterKmsKeyId = aws.StringValue(defaultRuleConfiguration.KMSMasterKeyID)
}
defaultRule[0]["kms_master_key_id"] = masterKmsKeyId
defaultRule[0]["sse_algorithm"] = aws.StringValue(defaultRuleConfiguration.SSEAlgorithm)

encryptionConfiguration := make([]map[string]interface{}, 1)
encryptionConfiguration[0] = make(map[string]interface{})
encryptionConfiguration[0]["enabled"] = true
rule := make([]map[string]interface{}, 1)
encryptionConfiguration[0]["rule"] = rule
rule[0] = make(map[string]interface{})
rule[0]["apply_server_side_encryption_by_default"] = defaultRule

data.Set("server_side_encryption_configuration", encryptionConfiguration)
return nil
}

Expand Down
119 changes: 119 additions & 0 deletions aws/data_source_aws_s3_bucket_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,125 @@ func TestAccDataSourceS3Bucket_website(t *testing.T) {
})
}

func TestAccDataSourceS3Bucket_whenDefaultEncryptionNotEnabled(t *testing.T) {
rInt := acctest.RandInt()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccAWSDataSourceS3BucketConfig_basic(rInt),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSS3BucketExists("data.aws_s3_bucket.bucket"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.enabled", "false"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.rule.#", "0"),
),
},
},
})
}

func TestAccDataSourceS3Bucket_whenDefaultEncryptionEnabledWithAES256(t *testing.T) {
rInt := acctest.RandInt()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccAWSDataSourceS3BucketConfigWithDefaultEncryptionAES256(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.#", "1"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.enabled", "true"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.rule.#", "1"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.rule.0.apply_server_side_encryption_by_default.#", "1"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.rule.0.apply_server_side_encryption_by_default.0.sse_algorithm", "AES256"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.rule.0.apply_server_side_encryption_by_default.0.kms_master_key_id", ""),
),
},
},
})
}

func TestAccDataSourceS3Bucket_whenDefaultEncryptionEnabledWithAWSKMS(t *testing.T) {
rInt := acctest.RandInt()

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccAWSDataSourceS3BucketConfigWithDefaultEncryptionAWSKMS(rInt),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.#", "1"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.enabled", "true"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.rule.#", "1"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.rule.0.apply_server_side_encryption_by_default.#", "1"),
resource.TestCheckResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.rule.0.apply_server_side_encryption_by_default.0.sse_algorithm", "aws:kms"),
resource.TestMatchResourceAttr(
"data.aws_s3_bucket.bucket", "server_side_encryption_configuration.0.rule.0.apply_server_side_encryption_by_default.0.kms_master_key_id", regexp.MustCompile("^arn")),
),
},
},
})
}

func testAccAWSDataSourceS3BucketConfigWithDefaultEncryptionAWSKMS(randInt int) string {
return fmt.Sprintf(`
resource "aws_kms_key" "arbitrary" {
description = "KMS Key for Bucket Testing %d"
deletion_window_in_days = 10
}
resource "aws_s3_bucket" "arbitrary" {
bucket = "tf-test-bucket-%d"
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = "${aws_kms_key.arbitrary.arn}"
sse_algorithm = "aws:kms"
}
}
}
}
data "aws_s3_bucket" "bucket" {
bucket = "${aws_s3_bucket.arbitrary.id}"
}`, randInt, randInt)
}

func testAccAWSDataSourceS3BucketConfigWithDefaultEncryptionAES256(randInt int) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "bucket" {
bucket = "tf-test-bucket-%d"
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
}
data "aws_s3_bucket" "bucket" {
bucket = "${aws_s3_bucket.bucket.id}"
}`, randInt)
}

func testAccAWSDataSourceS3BucketConfig_basic(randInt int) string {
return fmt.Sprintf(`
resource "aws_s3_bucket" "bucket" {
Expand Down
6 changes: 6 additions & 0 deletions website/docs/d/s3_bucket.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,9 @@ The following attributes are exported:
* `region` - The AWS region this bucket resides in.
* `website_endpoint` - The website endpoint, if the bucket is configured with a website. If not, this will be an empty string.
* `website_domain` - The domain of the website endpoint, if the bucket is configured with a website. If not, this will be an empty string. This is used to create Route 53 alias records.
* `server_side_encryption_configuration` - The encryption configuration for the bucket
* `enabled` - True if default encryption is enabled, false otherwise
* `rule` - Only available if `enabled` is true
* `apply_server_side_encryption_by_default` - Details about the default encryption
* `kms_master_key_id` - AWS KMS Key Id that is used to encrypt in server side
* `sse_algorithm` - Encryption algorithm used. Possible values are `AES256` and `aws:kms`

0 comments on commit 778d440

Please sign in to comment.