From eb9772fbc9e4fc64a4342cc7652a5de58531de11 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 5 Sep 2019 15:48:45 -0400 Subject: [PATCH 1/9] resource/aws_cloudfront_distribution: Fix `active_trusted_signers` attribute for Terraform 0.12 Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/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) ``` (cherry picked from commit ebdc976ec075ce924a580207b62502c418f26156) --- ...nt_distribution_configuration_structure.go | 39 ++++++++++++------- aws/resource_aws_cloudfront_distribution.go | 35 ++++++++++++++--- ...source_aws_cloudfront_distribution_test.go | 12 ++++-- .../r/cloudfront_distribution.html.markdown | 11 +++--- 4 files changed, 69 insertions(+), 28 deletions(-) diff --git a/aws/cloudfront_distribution_configuration_structure.go b/aws/cloudfront_distribution_configuration_structure.go index a9e94e883bf..5f8ec07e12e 100644 --- a/aws/cloudfront_distribution_configuration_structure.go +++ b/aws/cloudfront_distribution_configuration_structure.go @@ -17,7 +17,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/helper/hashcode" "github.com/hashicorp/terraform-plugin-sdk/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/flatmap" ) // cloudFrontRoute53ZoneID defines the route 53 zone ID for CloudFront. This @@ -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 c7b7bcfe63b..93ec5b0407b 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -581,9 +581,33 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Computed: true, }, "active_trusted_signers": { - Type: schema.TypeMap, + Type: schema.TypeList, Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, + 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, @@ -705,10 +729,11 @@ func resourceAwsCloudFrontDistributionRead(d *schema.ResourceData, meta interfac } // 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())) diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index f099d0722e6..3e5e021e59e 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -581,9 +581,8 @@ func TestAccAWSCloudFrontDistribution_DefaultCacheBehavior_TrustedSigners(t *tes Config: testAccAWSCloudFrontDistributionConfigDefaultCacheBehaviorTrustedSignersSelf(retainOnDelete), Check: resource.ComposeTestCheckFunc( testAccCheckCloudFrontDistributionExists(resourceName, &distribution), - resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.%", "6"), - resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.items.#", "1"), - resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.items.0.aws_account_number", "self"), + 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"), ), @@ -2358,22 +2357,27 @@ resource "aws_cloudfront_distribution" "test" { 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 @@ -2381,11 +2385,13 @@ resource "aws_cloudfront_distribution" "test" { origin_ssl_protocols = ["TLSv1.2"] } } + restrictions { geo_restriction { restriction_type = "none" } } + viewer_certificate { cloudfront_default_certificate = true } diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index 75d20ccd7b3..daa7acee5ad 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 @@ -529,9 +528,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`. From bae48834285a6009e0ae89c1b3e538b915cf7968 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 5 Sep 2019 16:02:47 -0400 Subject: [PATCH 2/9] resource/aws_cloudfront_distribution: go fmt and minor documentation fixes (cherry picked from commit cad90e6bcd6781c23217122002246363526c222e) --- website/docs/r/cloudfront_distribution.html.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index daa7acee5ad..0d7af012ccc 100644 --- a/website/docs/r/cloudfront_distribution.html.markdown +++ b/website/docs/r/cloudfront_distribution.html.markdown @@ -528,11 +528,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` - 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. + * `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. + * `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`. From 366d637f0870420446fd1e1076edf93bcd325211 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Thu, 5 Sep 2019 17:07:47 -0400 Subject: [PATCH 3/9] resource/aws_cloudfront_distribution: Ensure we are catching d.Set("active_trusted_signers", ...) error Output from acceptance testing: ``` --- PASS: TestAccAWSCloudFrontDistribution_DefaultCacheBehavior_TrustedSigners ``` (cherry picked from commit 1c2b6f44d23a9af6986786f2b35783a3ee34c41d) --- aws/resource_aws_cloudfront_distribution.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index 93ec5b0407b..61073169134 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -730,7 +730,7 @@ func resourceAwsCloudFrontDistributionRead(d *schema.ResourceData, meta interfac // Update other attributes outside of DistributionConfig - if d.Set("active_trusted_signers", flattenCloudfrontActiveTrustedSigners(resp.Distribution.ActiveTrustedSigners)); err != nil { + if err := d.Set("active_trusted_signers", flattenCloudfrontActiveTrustedSigners(resp.Distribution.ActiveTrustedSigners)); err != nil { return fmt.Errorf("error setting active_trusted_signers: %s", err) } From 5599f7e72301a9afbc5d11f5852160c8dc080af1 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Fri, 24 Jul 2020 18:58:48 -0400 Subject: [PATCH 4/9] add cloudfront section to upgrade guide --- aws/resource_aws_cloudfront_distribution.go | 4 +--- website/docs/guides/version-3-upgrade.html.md | 24 +++++++++++++++++++ .../r/cloudfront_distribution.html.markdown | 9 +++---- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index 61073169134..7ed1168344a 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -729,11 +729,9 @@ func resourceAwsCloudFrontDistributionRead(d *schema.ResourceData, meta interfac } // Update other attributes outside of DistributionConfig - if err := d.Set("active_trusted_signers", flattenCloudfrontActiveTrustedSigners(resp.Distribution.ActiveTrustedSigners)); err != nil { - return fmt.Errorf("error setting active_trusted_signers: %s", err) + return fmt.Errorf("error setting active_trusted_signers: %w", 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/website/docs/guides/version-3-upgrade.html.md b/website/docs/guides/version-3-upgrade.html.md index 7b2f870e184..8a3fcf12a9b 100644 --- a/website/docs/guides/version-3-upgrade.html.md +++ b/website/docs/guides/version-3-upgrade.html.md @@ -26,6 +26,7 @@ Upgrade topics: - [Resource: aws_acm_certificate](#resource-aws_acm_certificate) - [Resource: aws_api_gateway_method_settings](#resource-aws_api_gateway_method_settings) - [Resource: aws_autoscaling_group](#resource-aws_autoscaling_group) +- [Resource: aws_cloudfront_distribution](#resource-aws_cloudfront_distribution) - [Resource: aws_cognito_user_pool](#resource-aws_cognito_user_pool) - [Resource: aws_dx_gateway](#resource-aws_dx_gateway) - [Resource: aws_ebs_volume](#resource-aws_ebs_volume) @@ -615,6 +616,29 @@ resource "aws_autoscaling_group" "example"{ } ``` +## Resource: aws_cloudfront_distribution + +### active_trusted_signers Attribute Type Change + +Previously, the `active_trusted_signers` computed attribute was implemented with a Map that did not support accessing its computed `items` attribute in Terraform 0.12. +To address this, the `active_trusted_signers` is now implemented as a List with a computed `items` List attribute and computed `enabled` boolean attribute. +The nested `items` attribute includes computed `aws_account_number` and `key_pair_ids` sub-fields, with the latter implemented as a List. +Thus, user configurations referencing the `active_trusted_signers` nested attributes will need to be changed to include an index e.g. + +Given these previous references: + +``` +aws_cloudfront_distribution.example.active_trusted_signers.enabled +aws_cloudfront_distribution.example.active_trusted_signers.items +``` + +Updated references: + +``` +aws_cloudfront_distribution.example.active_trusted_signers.0.enabled +aws_cloudfront_distribution.example.active_trusted_signers.0.items +``` + ## Resource: aws_cognito_user_pool ### Removal of admin_create_user_config.unused_account_validity_days Argument diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index 0d7af012ccc..6f9245df05c 100644 --- a/website/docs/r/cloudfront_distribution.html.markdown +++ b/website/docs/r/cloudfront_distribution.html.markdown @@ -307,7 +307,8 @@ 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) - 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. +* `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](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html) 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,11 +529,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` - Nested attributes of active trusted signers, 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 + * `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`. From d328003ba290661066695d8405f1241cf7b2c195 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 27 Jul 2020 16:23:52 -0400 Subject: [PATCH 5/9] rename field to workaround state migration --- aws/cloudfront_distribution_configuration_structure.go | 2 +- aws/resource_aws_cloudfront_distribution.go | 2 +- aws/resource_aws_cloudfront_distribution_test.go | 2 +- website/docs/guides/version-3-upgrade.html.md | 8 ++++---- website/docs/r/cloudfront_distribution.html.markdown | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aws/cloudfront_distribution_configuration_structure.go b/aws/cloudfront_distribution_configuration_structure.go index 5f8ec07e12e..ab0ec7df154 100644 --- a/aws/cloudfront_distribution_configuration_structure.go +++ b/aws/cloudfront_distribution_configuration_structure.go @@ -1103,7 +1103,7 @@ func flattenCloudfrontActiveTrustedSigners(ats *cloudfront.ActiveTrustedSigners) m := map[string]interface{}{ "enabled": aws.BoolValue(ats.Enabled), - "items": flattenCloudfrontSigners(ats.Items), + "signers": flattenCloudfrontSigners(ats.Items), } return []interface{}{m} diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index 7ed1168344a..c16b79213ea 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -589,7 +589,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Type: schema.TypeBool, Computed: true, }, - "items": { + "signers": { Type: schema.TypeList, Computed: true, Elem: &schema.Resource{ diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index 3e5e021e59e..c5a9032040a 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -582,7 +582,7 @@ func TestAccAWSCloudFrontDistribution_DefaultCacheBehavior_TrustedSigners(t *tes 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, "active_trusted_signers.0.signers.#", "1"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.#", "1"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.trusted_signers.#", "1"), ), diff --git a/website/docs/guides/version-3-upgrade.html.md b/website/docs/guides/version-3-upgrade.html.md index 8a3fcf12a9b..d86eb426f75 100644 --- a/website/docs/guides/version-3-upgrade.html.md +++ b/website/docs/guides/version-3-upgrade.html.md @@ -621,9 +621,9 @@ resource "aws_autoscaling_group" "example"{ ### active_trusted_signers Attribute Type Change Previously, the `active_trusted_signers` computed attribute was implemented with a Map that did not support accessing its computed `items` attribute in Terraform 0.12. -To address this, the `active_trusted_signers` is now implemented as a List with a computed `items` List attribute and computed `enabled` boolean attribute. -The nested `items` attribute includes computed `aws_account_number` and `key_pair_ids` sub-fields, with the latter implemented as a List. -Thus, user configurations referencing the `active_trusted_signers` nested attributes will need to be changed to include an index e.g. +To address this, the `active_trusted_signers` attribute is now implemented as a List with a computed `signers` List attribute and computed `enabled` boolean attribute. +The nested `signers` attribute includes computed `aws_account_number` and `key_pair_ids` sub-fields, with the latter implemented as a List. +Thus, user configurations referencing the `active_trusted_signers` nested attributes will need to be changed as follows. Given these previous references: @@ -636,7 +636,7 @@ Updated references: ``` aws_cloudfront_distribution.example.active_trusted_signers.0.enabled -aws_cloudfront_distribution.example.active_trusted_signers.0.items +aws_cloudfront_distribution.example.active_trusted_signers.0.signers ``` ## Resource: aws_cognito_user_pool diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index 6f9245df05c..36585015320 100644 --- a/website/docs/r/cloudfront_distribution.html.markdown +++ b/website/docs/r/cloudfront_distribution.html.markdown @@ -531,7 +531,7 @@ In addition to all arguments above, the following attributes are exported: * `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 + * `signers` - 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 From a031363fbbe690299a8fc45cf696f210ba092bb5 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Mon, 27 Jul 2020 16:29:23 -0400 Subject: [PATCH 6/9] re-add check step --- aws/resource_aws_cloudfront_distribution_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index c5a9032040a..854916ad76f 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -583,6 +583,7 @@ func TestAccAWSCloudFrontDistribution_DefaultCacheBehavior_TrustedSigners(t *tes testAccCheckCloudFrontDistributionExists(resourceName, &distribution), resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.#", "1"), resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.0.signers.#", "1"), + resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.0.signers.0.aws_account_number", "self"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.#", "1"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.trusted_signers.#", "1"), ), From d4526805a1280321ee6866a61d7819ccaec24073 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Wed, 29 Jul 2020 13:47:12 -0400 Subject: [PATCH 7/9] update computed field naming and removal of internal/flatmap --- ...nt_distribution_configuration_structure.go | 2 +- aws/internal/flatmap/README.md | 3 - aws/internal/flatmap/flatten.go | 71 ----------- aws/internal/flatmap/flatten_test.go | 88 ------------- aws/internal/flatmap/map.go | 82 ------------ aws/internal/flatmap/map_test.go | 120 ------------------ aws/resource_aws_cloudfront_distribution.go | 11 +- ...source_aws_cloudfront_distribution_test.go | 6 +- .../r/cloudfront_distribution.html.markdown | 4 +- 9 files changed, 13 insertions(+), 374 deletions(-) delete mode 100644 aws/internal/flatmap/README.md delete mode 100644 aws/internal/flatmap/flatten.go delete mode 100644 aws/internal/flatmap/flatten_test.go delete mode 100644 aws/internal/flatmap/map.go delete mode 100644 aws/internal/flatmap/map_test.go diff --git a/aws/cloudfront_distribution_configuration_structure.go b/aws/cloudfront_distribution_configuration_structure.go index ab0ec7df154..5f8ec07e12e 100644 --- a/aws/cloudfront_distribution_configuration_structure.go +++ b/aws/cloudfront_distribution_configuration_structure.go @@ -1103,7 +1103,7 @@ func flattenCloudfrontActiveTrustedSigners(ats *cloudfront.ActiveTrustedSigners) m := map[string]interface{}{ "enabled": aws.BoolValue(ats.Enabled), - "signers": flattenCloudfrontSigners(ats.Items), + "items": flattenCloudfrontSigners(ats.Items), } return []interface{}{m} diff --git a/aws/internal/flatmap/README.md b/aws/internal/flatmap/README.md deleted file mode 100644 index 45c85d8c8d0..00000000000 --- a/aws/internal/flatmap/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# flatmap - -This package contains legacy code from `github.com/hashicorp/terraform/flatmap@v0.12.9`. The types and functions within this package should not be used in any future implementations. diff --git a/aws/internal/flatmap/flatten.go b/aws/internal/flatmap/flatten.go deleted file mode 100644 index 9ff6e426526..00000000000 --- a/aws/internal/flatmap/flatten.go +++ /dev/null @@ -1,71 +0,0 @@ -package flatmap - -import ( - "fmt" - "reflect" -) - -// Flatten takes a structure and turns into a flat map[string]string. -// -// Within the "thing" parameter, only primitive values are allowed. Structs are -// not supported. Therefore, it can only be slices, maps, primitives, and -// any combination of those together. -// -// See the tests for examples of what inputs are turned into. -func Flatten(thing map[string]interface{}) Map { - result := make(map[string]string) - - for k, raw := range thing { - flatten(result, k, reflect.ValueOf(raw)) - } - - return Map(result) -} - -func flatten(result map[string]string, prefix string, v reflect.Value) { - if v.Kind() == reflect.Interface { - v = v.Elem() - } - - switch v.Kind() { - case reflect.Bool: - if v.Bool() { - result[prefix] = "true" - } else { - result[prefix] = "false" - } - case reflect.Int: - result[prefix] = fmt.Sprintf("%d", v.Int()) - case reflect.Map: - flattenMap(result, prefix, v) - case reflect.Slice: - flattenSlice(result, prefix, v) - case reflect.String: - result[prefix] = v.String() - default: - panic(fmt.Sprintf("Unknown: %s", v)) - } -} - -func flattenMap(result map[string]string, prefix string, v reflect.Value) { - for _, k := range v.MapKeys() { - if k.Kind() == reflect.Interface { - k = k.Elem() - } - - if k.Kind() != reflect.String { - panic(fmt.Sprintf("%s: map key is not string: %s", prefix, k)) - } - - flatten(result, fmt.Sprintf("%s.%s", prefix, k.String()), v.MapIndex(k)) - } -} - -func flattenSlice(result map[string]string, prefix string, v reflect.Value) { - prefix = prefix + "." - - result[prefix+"#"] = fmt.Sprintf("%d", v.Len()) - for i := 0; i < v.Len(); i++ { - flatten(result, fmt.Sprintf("%s%d", prefix, i), v.Index(i)) - } -} diff --git a/aws/internal/flatmap/flatten_test.go b/aws/internal/flatmap/flatten_test.go deleted file mode 100644 index 9abd22dee9b..00000000000 --- a/aws/internal/flatmap/flatten_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package flatmap - -import ( - "reflect" - "testing" -) - -func TestFlatten(t *testing.T) { - cases := []struct { - Input map[string]interface{} - Output map[string]string - }{ - { - Input: map[string]interface{}{ - "foo": "bar", - "bar": "baz", - }, - Output: map[string]string{ - "foo": "bar", - "bar": "baz", - }, - }, - - { - Input: map[string]interface{}{ - "foo": []string{ - "one", - "two", - }, - }, - Output: map[string]string{ - "foo.#": "2", - "foo.0": "one", - "foo.1": "two", - }, - }, - - { - Input: map[string]interface{}{ - "foo": []map[interface{}]interface{}{ - { - "name": "bar", - "port": 3000, - "enabled": true, - }, - }, - }, - Output: map[string]string{ - "foo.#": "1", - "foo.0.name": "bar", - "foo.0.port": "3000", - "foo.0.enabled": "true", - }, - }, - - { - Input: map[string]interface{}{ - "foo": []map[interface{}]interface{}{ - { - "name": "bar", - "ports": []string{ - "1", - "2", - }, - }, - }, - }, - Output: map[string]string{ - "foo.#": "1", - "foo.0.name": "bar", - "foo.0.ports.#": "2", - "foo.0.ports.0": "1", - "foo.0.ports.1": "2", - }, - }, - } - - for _, tc := range cases { - actual := Flatten(tc.Input) - if !reflect.DeepEqual(actual, Map(tc.Output)) { - t.Fatalf( - "Input:\n\n%#v\n\nOutput:\n\n%#v\n\nExpected:\n\n%#v\n", - tc.Input, - actual, - tc.Output) - } - } -} diff --git a/aws/internal/flatmap/map.go b/aws/internal/flatmap/map.go deleted file mode 100644 index 435e04a39db..00000000000 --- a/aws/internal/flatmap/map.go +++ /dev/null @@ -1,82 +0,0 @@ -package flatmap - -import ( - "strings" -) - -// Map is a wrapper around map[string]string that provides some helpers -// above it that assume the map is in the format that flatmap expects -// (the result of Flatten). -// -// All modifying functions such as Delete are done in-place unless -// otherwise noted. -type Map map[string]string - -// Contains returns true if the map contains the given key. -func (m Map) Contains(key string) bool { - for _, k := range m.Keys() { - if k == key { - return true - } - } - - return false -} - -// Delete deletes a key out of the map with the given prefix. -func (m Map) Delete(prefix string) { - for k := range m { - match := k == prefix - if !match { - if !strings.HasPrefix(k, prefix) { - continue - } - - if k[len(prefix):len(prefix)+1] != "." { - continue - } - } - - delete(m, k) - } -} - -// Keys returns all of the top-level keys in this map -func (m Map) Keys() []string { - ks := make(map[string]struct{}) - for k := range m { - idx := strings.Index(k, ".") - if idx == -1 { - idx = len(k) - } - - ks[k[:idx]] = struct{}{} - } - - result := make([]string, 0, len(ks)) - for k := range ks { - result = append(result, k) - } - - return result -} - -// Merge merges the contents of the other Map into this one. -// -// This merge is smarter than a simple map iteration because it -// will fully replace arrays and other complex structures that -// are present in this map with the other map's. For example, if -// this map has a 3 element "foo" list, and m2 has a 2 element "foo" -// list, then the result will be that m has a 2 element "foo" -// list. -func (m Map) Merge(m2 Map) { - for _, prefix := range m2.Keys() { - m.Delete(prefix) - - for k, v := range m2 { - if strings.HasPrefix(k, prefix) { - m[k] = v - } - } - } -} diff --git a/aws/internal/flatmap/map_test.go b/aws/internal/flatmap/map_test.go deleted file mode 100644 index ea767d54fd5..00000000000 --- a/aws/internal/flatmap/map_test.go +++ /dev/null @@ -1,120 +0,0 @@ -package flatmap - -import ( - "reflect" - "sort" - "testing" -) - -func TestMapContains(t *testing.T) { - cases := []struct { - Input map[string]string - Key string - Result bool - }{ - { - Input: map[string]string{ - "foo": "bar", - "bar": "nope", - }, - Key: "foo", - Result: true, - }, - - { - Input: map[string]string{ - "foo": "bar", - "bar": "nope", - }, - Key: "baz", - Result: false, - }, - } - - for i, tc := range cases { - actual := Map(tc.Input).Contains(tc.Key) - if actual != tc.Result { - t.Fatalf("case %d bad: %#v", i, tc.Input) - } - } -} - -func TestMapDelete(t *testing.T) { - m := Flatten(map[string]interface{}{ - "foo": "bar", - "routes": []map[string]string{ - { - "foo": "bar", - }, - }, - }) - - m.Delete("routes") - - expected := Map(map[string]string{"foo": "bar"}) - if !reflect.DeepEqual(m, expected) { - t.Fatalf("bad: %#v", m) - } -} - -func TestMapKeys(t *testing.T) { - cases := []struct { - Input map[string]string - Output []string - }{ - { - Input: map[string]string{ - "foo": "bar", - "bar.#": "bar", - "bar.0.foo": "bar", - "bar.0.baz": "bar", - }, - Output: []string{ - "bar", - "foo", - }, - }, - } - - for _, tc := range cases { - actual := Map(tc.Input).Keys() - - // Sort so we have a consistent view of the output - sort.Strings(actual) - - if !reflect.DeepEqual(actual, tc.Output) { - t.Fatalf("input: %#v\n\nbad: %#v", tc.Input, actual) - } - } -} - -func TestMapMerge(t *testing.T) { - cases := []struct { - One map[string]string - Two map[string]string - Result map[string]string - }{ - { - One: map[string]string{ - "foo": "bar", - "bar": "nope", - }, - Two: map[string]string{ - "bar": "baz", - "baz": "buz", - }, - Result: map[string]string{ - "foo": "bar", - "bar": "baz", - "baz": "buz", - }, - }, - } - - for i, tc := range cases { - Map(tc.One).Merge(Map(tc.Two)) - if !reflect.DeepEqual(tc.One, tc.Result) { - t.Fatalf("case %d bad: %#v", i, tc.One) - } - } -} diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index c16b79213ea..fe908a77943 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -580,7 +580,10 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "active_trusted_signers": { + // Terraform AWS Provider 3.0 name change: + // enables TF Plugin SDK to ignore pre-existing attribute state + // associated with previous naming i.e. active_trusted_signers + "trusted_signers": { Type: schema.TypeList, Computed: true, Elem: &schema.Resource{ @@ -589,7 +592,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Type: schema.TypeBool, Computed: true, }, - "signers": { + "items": { Type: schema.TypeList, Computed: true, Elem: &schema.Resource{ @@ -729,8 +732,8 @@ func resourceAwsCloudFrontDistributionRead(d *schema.ResourceData, meta interfac } // Update other attributes outside of DistributionConfig - if err := d.Set("active_trusted_signers", flattenCloudfrontActiveTrustedSigners(resp.Distribution.ActiveTrustedSigners)); err != nil { - return fmt.Errorf("error setting active_trusted_signers: %w", err) + if err := d.Set("trusted_signers", flattenCloudfrontActiveTrustedSigners(resp.Distribution.ActiveTrustedSigners)); err != nil { + return fmt.Errorf("error setting trusted_signers: %w", err) } d.Set("status", resp.Distribution.Status) d.Set("domain_name", resp.Distribution.DomainName) diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index 854916ad76f..7f3fecb3f11 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -581,9 +581,9 @@ func TestAccAWSCloudFrontDistribution_DefaultCacheBehavior_TrustedSigners(t *tes Config: testAccAWSCloudFrontDistributionConfigDefaultCacheBehaviorTrustedSignersSelf(retainOnDelete), Check: resource.ComposeTestCheckFunc( testAccCheckCloudFrontDistributionExists(resourceName, &distribution), - resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.#", "1"), - resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.0.signers.#", "1"), - resource.TestCheckResourceAttr(resourceName, "active_trusted_signers.0.signers.0.aws_account_number", "self"), + resource.TestCheckResourceAttr(resourceName, "trusted_signers.#", "1"), + resource.TestCheckResourceAttr(resourceName, "trusted_signers.0.items.#", "1"), + resource.TestCheckResourceAttr(resourceName, "trusted_signers.0.items.0.aws_account_number", "self"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.#", "1"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.trusted_signers.#", "1"), ), diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index 36585015320..fa473c9c742 100644 --- a/website/docs/r/cloudfront_distribution.html.markdown +++ b/website/docs/r/cloudfront_distribution.html.markdown @@ -529,9 +529,9 @@ 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` - Nested attributes of active trusted signers, if the distribution is set up to serve private content with signed URLs +* `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 - * `signers` - Nested attributes of each trusted signer + * `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 From 55db5f5f7077c26a8823ec820ff8958dbc728c17 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Wed, 29 Jul 2020 14:19:55 -0400 Subject: [PATCH 8/9] update upgrade guide with attribute change --- website/docs/guides/version-3-upgrade.html.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/website/docs/guides/version-3-upgrade.html.md b/website/docs/guides/version-3-upgrade.html.md index d86eb426f75..8a079dbf604 100644 --- a/website/docs/guides/version-3-upgrade.html.md +++ b/website/docs/guides/version-3-upgrade.html.md @@ -618,12 +618,12 @@ resource "aws_autoscaling_group" "example"{ ## Resource: aws_cloudfront_distribution -### active_trusted_signers Attribute Type Change +### active_trusted_signers Attribute Name and Type Change Previously, the `active_trusted_signers` computed attribute was implemented with a Map that did not support accessing its computed `items` attribute in Terraform 0.12. -To address this, the `active_trusted_signers` attribute is now implemented as a List with a computed `signers` List attribute and computed `enabled` boolean attribute. -The nested `signers` attribute includes computed `aws_account_number` and `key_pair_ids` sub-fields, with the latter implemented as a List. -Thus, user configurations referencing the `active_trusted_signers` nested attributes will need to be changed as follows. +To address this, while also enabling access to this data without a state migration, the `active_trusted_signers` attribute has been renamed to `trusted_signers` and is now implemented as a List with a computed `items` List attribute and computed `enabled` boolean attribute. +The nested `items` attribute includes computed `aws_account_number` and `key_pair_ids` sub-fields, with the latter implemented as a List. +Thus, user configurations referencing the `active_trusted_signers` attribute and its sub-fields will need to be changed as follows. Given these previous references: @@ -635,8 +635,8 @@ aws_cloudfront_distribution.example.active_trusted_signers.items Updated references: ``` -aws_cloudfront_distribution.example.active_trusted_signers.0.enabled -aws_cloudfront_distribution.example.active_trusted_signers.0.signers +aws_cloudfront_distribution.example.trusted_signers.0.enabled +aws_cloudfront_distribution.example.trusted_signers.0.items ``` ## Resource: aws_cognito_user_pool From d7099d24af3c26153be6fead2723e15685410c46 Mon Sep 17 00:00:00 2001 From: Angie Pinilla Date: Wed, 29 Jul 2020 14:59:27 -0400 Subject: [PATCH 9/9] update documentation wording --- website/docs/guides/version-3-upgrade.html.md | 4 ++-- website/docs/r/cloudfront_distribution.html.markdown | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/website/docs/guides/version-3-upgrade.html.md b/website/docs/guides/version-3-upgrade.html.md index 8a079dbf604..56d8b4ce4d4 100644 --- a/website/docs/guides/version-3-upgrade.html.md +++ b/website/docs/guides/version-3-upgrade.html.md @@ -620,8 +620,8 @@ resource "aws_autoscaling_group" "example"{ ### active_trusted_signers Attribute Name and Type Change -Previously, the `active_trusted_signers` computed attribute was implemented with a Map that did not support accessing its computed `items` attribute in Terraform 0.12. -To address this, while also enabling access to this data without a state migration, the `active_trusted_signers` attribute has been renamed to `trusted_signers` and is now implemented as a List with a computed `items` List attribute and computed `enabled` boolean attribute. +Previously, the `active_trusted_signers` computed attribute was implemented with a Map that did not support accessing its computed `items` attribute in Terraform 0.12 correctly. +To address this, the `active_trusted_signers` attribute has been renamed to `trusted_signers` and is now implemented as a List with a computed `items` List attribute and computed `enabled` boolean attribute. The nested `items` attribute includes computed `aws_account_number` and `key_pair_ids` sub-fields, with the latter implemented as a List. Thus, user configurations referencing the `active_trusted_signers` attribute and its sub-fields will need to be changed as follows. diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index fa473c9c742..38487066639 100644 --- a/website/docs/r/cloudfront_distribution.html.markdown +++ b/website/docs/r/cloudfront_distribution.html.markdown @@ -529,9 +529,9 @@ In addition to all arguments above, the following attributes are exported: distribution's information is fully propagated throughout the Amazon CloudFront system. -* `trusted_signers` - Nested attributes of active trusted signers, if the distribution is set up to serve private content with signed URLs +* `trusted_signers` - List of nested attributes for 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 + * `items` - List of nested attributes for 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