diff --git a/aws/cloudfront_distribution_configuration_structure.go b/aws/cloudfront_distribution_configuration_structure.go index 9927e98c9aa..68bdc6845a6 100644 --- a/aws/cloudfront_distribution_configuration_structure.go +++ b/aws/cloudfront_distribution_configuration_structure.go @@ -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" @@ -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 } diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index 0e28477e395..508ac127cd3 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -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, @@ -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 err := 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())) diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index 0bb6f2f3f6d..3b59c1d3d02 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -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" @@ -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(` diff --git a/vendor/modules.txt b/vendor/modules.txt index 7ea03a58039..e6483a96ad1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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 @@ -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 @@ -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 diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index a489e945e06..1373c164ad5 100644 --- a/website/docs/r/cloudfront_distribution.html.markdown +++ b/website/docs/r/cloudfront_distribution.html.markdown @@ -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 @@ -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 active trusted signers, if the distribution is set up to serve private content with signed URLs + * `enabled` - `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`.