Skip to content

Commit

Permalink
resource/aws_cloudfront_distribution: Fix active_trusted_signers at…
Browse files Browse the repository at this point in the history
…tribute for Terraform 0.12

Reference: #8902

This attribute implemented a legacy Terraform library (`flatmap`), which does not work with Terraform 0.12's data types and whose only usage was on this single attribute. This was missed during the Terraform 0.12 upgrade since there were no covering acceptance tests and the CloudFront setup itself is fairly esoteric (requires root AWS account login to manage CloudFront Keys).

The attribute now correctly implements (in the closest approximation) the standard Terraform Provider SDK types and methodology for saved nested object data to the Terraform state. The `items` subattribute list is now accessible again in Terraform 0.12. It does, however, unavoidably switch the root `active_trusted_signers` attribute to `TypeList` instead of `TypeMap` (which does not support map elements of different types in the current Terraform Provider SDK), so any potential references to nested attributes will need to be changed in user configurations, e.g.

Previously:

```
aws_cloudfront_distribution.example.active_trusted_signers.enabled
```

Now:

```
aws_cloudfront_distribution.example.active_trusted_signers.0.enabled
```

Output from acceptance testing:

```
--- PASS: TestAccAWSCloudFrontDistribution_DefaultCacheBehavior_TrustedSigners (611.33s)
```
  • Loading branch information
bflad committed Sep 5, 2019
1 parent 3ec4261 commit ebdc976
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 26 deletions.
39 changes: 24 additions & 15 deletions aws/cloudfront_distribution_configuration_structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudfront"
"github.com/hashicorp/terraform/flatmap"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
Expand Down Expand Up @@ -1097,20 +1096,30 @@ func flattenViewerCertificate(vc *cloudfront.ViewerCertificate) []interface{} {
return []interface{}{m}
}

// Convert *cloudfront.ActiveTrustedSigners to a flatmap.Map type, which ensures
// it can probably be inserted into the schema.TypeMap type used by the
// active_trusted_signers attribute.
func flattenActiveTrustedSigners(ats *cloudfront.ActiveTrustedSigners) flatmap.Map {
m := make(map[string]interface{})
s := []interface{}{}
m["enabled"] = *ats.Enabled
func flattenCloudfrontActiveTrustedSigners(ats *cloudfront.ActiveTrustedSigners) []interface{} {
if ats == nil {
return []interface{}{}
}

m := map[string]interface{}{
"enabled": aws.BoolValue(ats.Enabled),
"items": flattenCloudfrontSigners(ats.Items),
}

return []interface{}{m}
}

for _, v := range ats.Items {
signer := make(map[string]interface{})
signer["aws_account_number"] = *v.AwsAccountNumber
signer["key_pair_ids"] = aws.StringValueSlice(v.KeyPairIds.Items)
s = append(s, signer)
func flattenCloudfrontSigners(signers []*cloudfront.Signer) []interface{} {
result := make([]interface{}, 0, len(signers))

for _, signer := range signers {
m := map[string]interface{}{
"aws_account_number": aws.StringValue(signer.AwsAccountNumber),
"key_pair_ids": aws.StringValueSlice(signer.KeyPairIds.Items),
}

result = append(result, m)
}
m["items"] = s
return flatmap.Flatten(m)

return result
}
34 changes: 30 additions & 4 deletions aws/resource_aws_cloudfront_distribution.go
Original file line number Diff line number Diff line change
Expand Up @@ -695,8 +695,33 @@ func resourceAwsCloudFrontDistribution() *schema.Resource {
Computed: true,
},
"active_trusted_signers": {
Type: schema.TypeMap,
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"items": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"aws_account_number": {
Type: schema.TypeString,
Computed: true,
},
"key_pair_ids": {
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
},
},
},
},
},
"domain_name": {
Type: schema.TypeString,
Expand Down Expand Up @@ -815,10 +840,11 @@ func resourceAwsCloudFrontDistributionRead(d *schema.ResourceData, meta interfac
return err
}
// Update other attributes outside of DistributionConfig
err = d.Set("active_trusted_signers", flattenActiveTrustedSigners(resp.Distribution.ActiveTrustedSigners))
if err != nil {
return err

if d.Set("active_trusted_signers", flattenCloudfrontActiveTrustedSigners(resp.Distribution.ActiveTrustedSigners)); err != nil {
return fmt.Errorf("error setting active_trusted_signers: %s", err)
}

d.Set("status", resp.Distribution.Status)
d.Set("domain_name", resp.Distribution.DomainName)
d.Set("last_modified_time", aws.String(resp.Distribution.LastModifiedTime.String()))
Expand Down
82 changes: 82 additions & 0 deletions aws/resource_aws_cloudfront_distribution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,39 @@ func TestAccAWSCloudFrontDistribution_DefaultCacheBehavior_ForwardedValues_Heade
})
}

func TestAccAWSCloudFrontDistribution_DefaultCacheBehavior_TrustedSigners(t *testing.T) {
var distribution cloudfront.Distribution
resourceName := "aws_cloudfront_distribution.test"
retainOnDelete := testAccAWSCloudFrontDistributionRetainOnDeleteFromEnv()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckAWSCloudFront(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckCloudFrontDistributionDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSCloudFrontDistributionConfigDefaultCacheBehaviorTrustedSignersSelf(retainOnDelete),
Check: resource.ComposeTestCheckFunc(
testAccCheckCloudFrontDistributionExists(resourceName, &distribution),
resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.#", "1"),
resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.0.items.#", "1"),
resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.#", "1"),
resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.trusted_signers.#", "1"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{
"retain_on_delete",
"wait_for_deployment",
},
},
},
})
}

func TestAccAWSCloudFrontDistribution_Enabled(t *testing.T) {
var distribution cloudfront.Distribution
resourceName := "aws_cloudfront_distribution.test"
Expand Down Expand Up @@ -2312,6 +2345,55 @@ resource "aws_cloudfront_distribution" "test" {
`, retainOnDelete)
}

func testAccAWSCloudFrontDistributionConfigDefaultCacheBehaviorTrustedSignersSelf(retainOnDelete bool) string {
return fmt.Sprintf(`
resource "aws_cloudfront_distribution" "test" {
# Faster acceptance testing
enabled = false
retain_on_delete = %[1]t
wait_for_deployment = false
default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "test"
trusted_signers = ["self"]
viewer_protocol_policy = "allow-all"
forwarded_values {
query_string = false
cookies {
forward = "all"
}
}
}
origin {
domain_name = "www.example.com"
origin_id = "test"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "https-only"
origin_ssl_protocols = ["TLSv1.2"]
}
}
restrictions {
geo_restriction {
restriction_type = "none"
}
}
viewer_certificate {
cloudfront_default_certificate = true
}
}
`, retainOnDelete)
}

// CloudFront Distribution ACM Certificates must be created in us-east-1
func testAccAWSCloudFrontDistributionConfigViewerCertificateAcmCertificateArnBase(commonName string) string {
return testAccUsEast1RegionProviderConfig() + fmt.Sprintf(`
Expand Down
4 changes: 2 additions & 2 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,6 @@ github.com/hashicorp/hil/scanner
github.com/hashicorp/logutils
# github.com/hashicorp/terraform v0.12.7
github.com/hashicorp/terraform/plugin
github.com/hashicorp/terraform/flatmap
github.com/hashicorp/terraform/helper/customdiff
github.com/hashicorp/terraform/helper/encryption
github.com/hashicorp/terraform/helper/hashcode
Expand All @@ -460,11 +459,11 @@ github.com/hashicorp/terraform/plugin/discovery
github.com/hashicorp/terraform/providers
github.com/hashicorp/terraform/provisioners
github.com/hashicorp/terraform/version
github.com/hashicorp/terraform/configs/hcl2shim
github.com/hashicorp/terraform/addrs
github.com/hashicorp/terraform/command/format
github.com/hashicorp/terraform/configs
github.com/hashicorp/terraform/configs/configload
github.com/hashicorp/terraform/configs/hcl2shim
github.com/hashicorp/terraform/helper/config
github.com/hashicorp/terraform/internal/initwd
github.com/hashicorp/terraform/plans
Expand All @@ -484,6 +483,7 @@ github.com/hashicorp/terraform/registry/regsrc
github.com/hashicorp/terraform/registry/response
github.com/hashicorp/terraform/svchost/disco
github.com/hashicorp/terraform/internal/modsdir
github.com/hashicorp/terraform/flatmap
github.com/hashicorp/terraform/internal/earlyconfig
github.com/hashicorp/terraform/helper/hilmapstructure
github.com/hashicorp/terraform/lang/blocktoattr
Expand Down
11 changes: 6 additions & 5 deletions website/docs/r/cloudfront_distribution.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,7 @@ of several sub-resources - these resources are laid out below.
CloudFront to route requests to when a request matches the path pattern
either for a cache behavior or for the default cache behavior.

* `trusted_signers` (Optional) - The AWS accounts, if any, that you want to
allow to create signed URLs for private content.
* `trusted_signers` (Optional) - List of AWS account IDs (or `self`) that you want to allow to create signed URLs for private content. See the [CloudFront User Guide]() for more information about this feature.

* `viewer_protocol_policy` (Required) - Use this element to specify the
protocol that users can use to access the files in the origin specified by
Expand Down Expand Up @@ -528,9 +527,11 @@ In addition to all arguments above, the following attributes are exported:
distribution's information is fully propagated throughout the Amazon
CloudFront system.

* `active_trusted_signers` - The key pair IDs that CloudFront is aware of for
each trusted signer, if the distribution is set up to serve private content
with signed URLs.
* `active_trusted_signers` - Nested attributes of trusted signers that CloudFront is aware, if the distribution is set up to serve private content with signed URLs.
* `enabled` - Enabled is `true` if any of the AWS accounts listed as trusted signers have active CloudFront key pairs.
* `items` - Nested attributes of each trusted signer.
* `aws_account_number` - AWS account ID or `self`
* `key_pair_ids` - Set of active CloudFront key pairs associated with the signer account.

* `domain_name` - The domain name corresponding to the distribution. For
example: `d604721fxaaqy9.cloudfront.net`.
Expand Down

0 comments on commit ebdc976

Please sign in to comment.