provider/aws: Add support for tags to aws_cloudfront_distribution

Fixes #8959

```
% make testacc TEST=./builtin/providers/aws TESTARGS='-run=TestAccAWSCloudFrontDistribution_S3OriginWithTags'
==> Checking that code complies with gofmt requirements...
go generate $(go list ./... | grep -v /terraform/vendor/)
2016/09/23 16:30:31 Generated command/internal_plugin_list.go
TF_ACC=1 go test ./builtin/providers/aws -v
-run=TestAccAWSCloudFrontDistribution_S3OriginWithTags -timeout 120m
=== RUN   TestAccAWSCloudFrontDistribution_S3OriginWithTags
--- PASS: TestAccAWSCloudFrontDistribution_S3OriginWithTags (1234.66s)
PASS
ok      github.com/hashicorp/terraform/builtin/providers/aws
1234.680s
```
This commit is contained in:
stack72 2016-09-23 12:46:27 +01:00
parent 582ba66e6c
commit 13cf370d07
No known key found for this signature in database
GPG Key ID: 8619A619B085CB16
4 changed files with 273 additions and 3 deletions

View File

@ -87,6 +87,7 @@ func expandDistributionConfig(d *schema.ResourceData) *cloudfront.DistributionCo
} else { } else {
distributionConfig.WebACLId = aws.String("") distributionConfig.WebACLId = aws.String("")
} }
return distributionConfig return distributionConfig
} }

View File

@ -22,6 +22,10 @@ func resourceAwsCloudFrontDistribution() *schema.Resource {
}, },
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"arn": {
Type: schema.TypeString,
Computed: true,
},
"aliases": &schema.Schema{ "aliases": &schema.Schema{
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
@ -485,17 +489,23 @@ func resourceAwsCloudFrontDistribution() *schema.Resource {
Optional: true, Optional: true,
Default: false, Default: false,
}, },
"tags": tagsSchema(),
}, },
} }
} }
func resourceAwsCloudFrontDistributionCreate(d *schema.ResourceData, meta interface{}) error { func resourceAwsCloudFrontDistributionCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).cloudfrontconn conn := meta.(*AWSClient).cloudfrontconn
params := &cloudfront.CreateDistributionInput{
DistributionConfig: expandDistributionConfig(d), params := &cloudfront.CreateDistributionWithTagsInput{
DistributionConfigWithTags: &cloudfront.DistributionConfigWithTags{
DistributionConfig: expandDistributionConfig(d),
Tags: tagsFromMapCloudFront(d.Get("tags").(map[string]interface{})),
},
} }
resp, err := conn.CreateDistribution(params) resp, err := conn.CreateDistributionWithTags(params)
if err != nil { if err != nil {
return err return err
} }
@ -530,6 +540,21 @@ func resourceAwsCloudFrontDistributionRead(d *schema.ResourceData, meta interfac
d.Set("last_modified_time", aws.String(resp.Distribution.LastModifiedTime.String())) d.Set("last_modified_time", aws.String(resp.Distribution.LastModifiedTime.String()))
d.Set("in_progress_validation_batches", resp.Distribution.InProgressInvalidationBatches) d.Set("in_progress_validation_batches", resp.Distribution.InProgressInvalidationBatches)
d.Set("etag", resp.ETag) d.Set("etag", resp.ETag)
d.Set("arn", resp.Distribution.ARN)
cloudFrontArn := resp.Distribution.ARN
tagResp, tagErr := conn.ListTagsForResource(&cloudfront.ListTagsForResourceInput{
Resource: cloudFrontArn,
})
if tagErr != nil {
log.Printf("[DEBUG] Error retrieving tags for ARN: %s", cloudFrontArn)
}
if tagResp != nil {
d.Set("tags", tagsToMapCloudFront(tagResp.Tags))
}
return nil return nil
} }
@ -545,6 +570,10 @@ func resourceAwsCloudFrontDistributionUpdate(d *schema.ResourceData, meta interf
return err return err
} }
if err := setTagsCloudFront(conn, d, d.Get("arn").(string)); err != nil {
return err
}
return resourceAwsCloudFrontDistributionRead(d, meta) return resourceAwsCloudFrontDistributionRead(d, meta)
} }

View File

@ -9,6 +9,7 @@ import (
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudfront" "github.com/aws/aws-sdk-go/service/cloudfront"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
) )
@ -41,6 +42,46 @@ func TestAccAWSCloudFrontDistribution_S3Origin(t *testing.T) {
}) })
} }
func TestAccAWSCloudFrontDistribution_S3OriginWithTags(t *testing.T) {
ri := acctest.RandInt()
preConfig := fmt.Sprintf(testAccAWSCloudFrontDistributionS3ConfigWithTags, ri, testAccAWSCloudFrontDistributionRetainConfig())
postConfig := fmt.Sprintf(testAccAWSCloudFrontDistributionS3ConfigWithTagsUpdated, ri, testAccAWSCloudFrontDistributionRetainConfig())
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFrontDistributionDestroy,
Steps: []resource.TestStep{
{
Config: preConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.s3_distribution",
),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.%", "2"),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.environment", "production"),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.account", "main"),
),
},
{
Config: postConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExistence(
"aws_cloudfront_distribution.s3_distribution",
),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.%", "1"),
resource.TestCheckResourceAttr(
"aws_cloudfront_distribution.s3_distribution", "tags.environment", "dev"),
),
},
},
})
}
// TestAccAWSCloudFrontDistribution_customOriginruns an // TestAccAWSCloudFrontDistribution_customOriginruns an
// aws_cloudfront_distribution acceptance test with a single custom origin. // aws_cloudfront_distribution acceptance test with a single custom origin.
// //
@ -262,6 +303,107 @@ resource "aws_cloudfront_distribution" "s3_distribution" {
} }
`, rand.New(rand.NewSource(time.Now().UnixNano())).Int(), testAccAWSCloudFrontDistributionRetainConfig()) `, rand.New(rand.NewSource(time.Now().UnixNano())).Int(), testAccAWSCloudFrontDistributionRetainConfig())
var testAccAWSCloudFrontDistributionS3ConfigWithTags = `
variable rand_id {
default = %d
}
resource "aws_s3_bucket" "s3_bucket" {
bucket = "mybucket.${var.rand_id}.s3.amazonaws.com"
acl = "public-read"
}
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = "${aws_s3_bucket.s3_bucket.id}"
origin_id = "myS3Origin"
}
enabled = true
default_root_object = "index.html"
aliases = [ "mysite.${var.rand_id}.example.com", "yoursite.${var.rand_id}.example.com" ]
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myS3Origin"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
price_class = "PriceClass_200"
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = [ "US", "CA", "GB", "DE" ]
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
tags {
environment = "production"
account = "main"
}
%s
}
`
var testAccAWSCloudFrontDistributionS3ConfigWithTagsUpdated = `
variable rand_id {
default = %d
}
resource "aws_s3_bucket" "s3_bucket" {
bucket = "mybucket.${var.rand_id}.s3.amazonaws.com"
acl = "public-read"
}
resource "aws_cloudfront_distribution" "s3_distribution" {
origin {
domain_name = "${aws_s3_bucket.s3_bucket.id}"
origin_id = "myS3Origin"
}
enabled = true
default_root_object = "index.html"
aliases = [ "mysite.${var.rand_id}.example.com", "yoursite.${var.rand_id}.example.com" ]
default_cache_behavior {
allowed_methods = [ "DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT" ]
cached_methods = [ "GET", "HEAD" ]
target_origin_id = "myS3Origin"
forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
viewer_protocol_policy = "allow-all"
min_ttl = 0
default_ttl = 3600
max_ttl = 86400
}
price_class = "PriceClass_200"
restrictions {
geo_restriction {
restriction_type = "whitelist"
locations = [ "US", "CA", "GB", "DE" ]
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
tags {
environment = "dev"
}
%s
}
`
var testAccAWSCloudFrontDistributionCustomConfig = fmt.Sprintf(` var testAccAWSCloudFrontDistributionCustomConfig = fmt.Sprintf(`
variable rand_id { variable rand_id {
default = %d default = %d

View File

@ -0,0 +1,98 @@
package aws
import (
"log"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudfront"
"github.com/hashicorp/terraform/helper/schema"
)
func setTagsCloudFront(conn *cloudfront.CloudFront, d *schema.ResourceData, arn string) error {
if d.HasChange("tags") {
oraw, nraw := d.GetChange("tags")
o := oraw.(map[string]interface{})
n := nraw.(map[string]interface{})
create, remove := diffTagsCloudFront(tagsFromMapCloudFront(o), tagsFromMapCloudFront(n))
if len(remove) > 0 {
log.Printf("[DEBUG] Removing tags: %s", remove)
k := make([]*string, 0, len(remove))
for _, t := range remove {
k = append(k, t.Key)
}
_, err := conn.UntagResource(&cloudfront.UntagResourceInput{
Resource: aws.String(arn),
TagKeys: &cloudfront.TagKeys{
Items: k,
},
})
if err != nil {
return err
}
}
if len(create) > 0 {
log.Printf("[DEBUG] Creating tags: %s", create)
_, err := conn.TagResource(&cloudfront.TagResourceInput{
Resource: aws.String(arn),
Tags: &cloudfront.Tags{
Items: create,
},
})
if err != nil {
return err
}
}
}
return nil
}
func diffTagsCloudFront(oldTags, newTags *cloudfront.Tags) ([]*cloudfront.Tag, []*cloudfront.Tag) {
// First, we're creating everything we have
create := make(map[string]interface{})
for _, t := range newTags.Items {
create[*t.Key] = *t.Value
}
// Build the list of what to remove
var remove []*cloudfront.Tag
for _, t := range oldTags.Items {
old, ok := create[*t.Key]
if !ok || old != *t.Value {
// Delete it!
remove = append(remove, t)
}
}
createTags := tagsFromMapCloudFront(create)
return createTags.Items, remove
}
func tagsFromMapCloudFront(m map[string]interface{}) *cloudfront.Tags {
result := make([]*cloudfront.Tag, 0, len(m))
for k, v := range m {
result = append(result, &cloudfront.Tag{
Key: aws.String(k),
Value: aws.String(v.(string)),
})
}
tags := &cloudfront.Tags{
Items: result,
}
return tags
}
func tagsToMapCloudFront(ts *cloudfront.Tags) map[string]string {
result := make(map[string]string)
for _, t := range ts.Items {
result[*t.Key] = *t.Value
}
return result
}