From 1e07711e79d3e94a4248cd982bad044401dbe3d8 Mon Sep 17 00:00:00 2001 From: Bill Rich Date: Mon, 25 Jan 2021 16:13:07 -0800 Subject: [PATCH 01/13] Add cloudfront_cache_policy resource --- aws/cloudfront_cache_policy_structure.go | 230 ++++++++++++++++++ ...nt_distribution_configuration_structure.go | 25 +- aws/provider.go | 1 + aws/resource_aws_cloudfront_cache_policy.go | 223 +++++++++++++++++ ...source_aws_cloudfront_cache_policy_test.go | 208 ++++++++++++++++ aws/resource_aws_cloudfront_distribution.go | 21 +- ...source_aws_cloudfront_distribution_test.go | 113 +++++++++ .../r/cloudfront_cache_policy.html.markdown | 93 +++++++ .../r/cloudfront_distribution.html.markdown | 3 + 9 files changed, 910 insertions(+), 7 deletions(-) create mode 100644 aws/cloudfront_cache_policy_structure.go create mode 100644 aws/resource_aws_cloudfront_cache_policy.go create mode 100644 aws/resource_aws_cloudfront_cache_policy_test.go create mode 100644 website/docs/r/cloudfront_cache_policy.html.markdown diff --git a/aws/cloudfront_cache_policy_structure.go b/aws/cloudfront_cache_policy_structure.go new file mode 100644 index 00000000000..67e2c0cac78 --- /dev/null +++ b/aws/cloudfront_cache_policy_structure.go @@ -0,0 +1,230 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloudfront" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func expandCloudFrontCachePolicyCookieNames(cookieNamesFlat map[string]interface{}) *cloudfront.CookieNames { + cookieNames := &cloudfront.CookieNames{} + + var newCookieItems []*string + for _, cookie := range cookieNamesFlat["items"].(*schema.Set).List() { + newCookieItems = append(newCookieItems, aws.String(cookie.(string))) + } + cookieNames.Items = newCookieItems + cookieNames.Quantity = aws.Int64(int64(len(newCookieItems))) + + return cookieNames +} + +func expandCloudFrontCachePolicyCookiesConfig(cookiesConfigFlat map[string]interface{}) *cloudfront.CachePolicyCookiesConfig { + cookies := &cloudfront.CookieNames{ + Quantity: aws.Int64(int64(0)), + } + + if cookiesFlat, ok := cookiesConfigFlat["cookies"].([]interface{}); ok && len(cookiesFlat) == 1 { + cookies = expandCloudFrontCachePolicyCookieNames(cookiesFlat[0].(map[string]interface{})) + } else { + cookies = nil + } + + cookiesConfig := &cloudfront.CachePolicyCookiesConfig{ + CookieBehavior: aws.String(cookiesConfigFlat["cookie_behavior"].(string)), + Cookies: cookies, + } + + return cookiesConfig +} + +func expandCloudFrontCachePolicyHeaders(headerNamesFlat map[string]interface{}) *cloudfront.Headers { + headers := &cloudfront.Headers{} + + var newHeaderItems []*string + for _, header := range headerNamesFlat["items"].(*schema.Set).List() { + newHeaderItems = append(newHeaderItems, aws.String(header.(string))) + } + headers.Items = newHeaderItems + headers.Quantity = aws.Int64(int64(len(newHeaderItems))) + + return headers +} + +func expandCloudFrontCachePolicyHeadersConfig(headersConfigFlat map[string]interface{}) *cloudfront.CachePolicyHeadersConfig { + headers := &cloudfront.Headers{} + + if headersFlat, ok := headersConfigFlat["headers"].([]interface{}); ok && len(headersFlat) == 1 && headersConfigFlat["header_behavior"] != "none" { + headers = expandCloudFrontCachePolicyHeaders(headersFlat[0].(map[string]interface{})) + } else { + headers = nil + } + + headersConfig := &cloudfront.CachePolicyHeadersConfig{ + HeaderBehavior: aws.String(headersConfigFlat["header_behavior"].(string)), + Headers: headers, + } + + return headersConfig +} + +func expandCloudFrontCachePolicyQueryStringNames(queryStringNamesFlat map[string]interface{}) *cloudfront.QueryStringNames { + queryStringNames := &cloudfront.QueryStringNames{} + + var newQueryStringItems []*string + for _, queryString := range queryStringNamesFlat["items"].(*schema.Set).List() { + newQueryStringItems = append(newQueryStringItems, aws.String(queryString.(string))) + } + queryStringNames.Items = newQueryStringItems + queryStringNames.Quantity = aws.Int64(int64(len(newQueryStringItems))) + + return queryStringNames +} + +func expandCloudFrontCachePolicyQueryStringConfig(queryStringConfigFlat map[string]interface{}) *cloudfront.CachePolicyQueryStringsConfig { + queryStrings := &cloudfront.QueryStringNames{ + Quantity: aws.Int64(int64(0)), + } + + if queryStringFlat, ok := queryStringConfigFlat["query_strings"].([]interface{}); ok && len(queryStringFlat) == 1 { + queryStrings = expandCloudFrontCachePolicyQueryStringNames(queryStringFlat[0].(map[string]interface{})) + } else { + queryStrings = nil + } + + queryStringConfig := &cloudfront.CachePolicyQueryStringsConfig{ + QueryStringBehavior: aws.String(queryStringConfigFlat["query_string_behavior"].(string)), + QueryStrings: queryStrings, + } + + return queryStringConfig +} + +func expandCloudFrontCachePolicyParametersConfig(parameters map[string]interface{}) *cloudfront.ParametersInCacheKeyAndForwardedToOrigin { + var cookiesConfig *cloudfront.CachePolicyCookiesConfig + var headersConfig *cloudfront.CachePolicyHeadersConfig + var queryStringsConfig *cloudfront.CachePolicyQueryStringsConfig + + if cookiesFlat, ok := parameters["cookies_config"].([]interface{}); ok && len(cookiesFlat) == 1 { + cookiesConfig = expandCloudFrontCachePolicyCookiesConfig(cookiesFlat[0].(map[string]interface{})) + } + + if headersFlat, ok := parameters["headers_config"].([]interface{}); ok && len(headersFlat) == 1 { + headersConfig = expandCloudFrontCachePolicyHeadersConfig(headersFlat[0].(map[string]interface{})) + } + + if queryStringsFlat, ok := parameters["query_strings_config"].([]interface{}); ok && len(queryStringsFlat) == 1 { + queryStringsConfig = expandCloudFrontCachePolicyQueryStringConfig(queryStringsFlat[0].(map[string]interface{})) + } + + parametersConfig := &cloudfront.ParametersInCacheKeyAndForwardedToOrigin{ + CookiesConfig: cookiesConfig, + EnableAcceptEncodingBrotli: aws.Bool(parameters["enable_accept_encoding_brotli"].(bool)), + EnableAcceptEncodingGzip: aws.Bool(parameters["enable_accept_encoding_gzip"].(bool)), + HeadersConfig: headersConfig, + QueryStringsConfig: queryStringsConfig, + } + + return parametersConfig +} + +func expandCloudFrontCachePolicyConfig(d *schema.ResourceData) *cloudfront.CachePolicyConfig { + parametersConfig := &cloudfront.ParametersInCacheKeyAndForwardedToOrigin{} + + if parametersFlat, ok := d.GetOk("parameters_in_cache_key_and_forwarded_to_origin"); ok { + parametersConfig = expandCloudFrontCachePolicyParametersConfig(parametersFlat.([]interface{})[0].(map[string]interface{})) + } + cachePolicy := &cloudfront.CachePolicyConfig{ + Comment: aws.String(d.Get("comment").(string)), + DefaultTTL: aws.Int64(int64(d.Get("default_ttl").(int))), + MaxTTL: aws.Int64(int64(d.Get("max_ttl").(int))), + MinTTL: aws.Int64(int64(d.Get("min_ttl").(int))), + Name: aws.String(d.Get("name").(string)), + ParametersInCacheKeyAndForwardedToOrigin: parametersConfig, + } + + return cachePolicy +} + +func flattenCloudFrontCachePolicyCookiesConfig(cookiesConfig *cloudfront.CachePolicyCookiesConfig) []map[string]interface{} { + cookiesConfigFlat := map[string]interface{}{} + + cookies := []map[string]interface{}{} + if cookiesConfig.Cookies != nil { + cookies = []map[string]interface{}{ + { + "items": cookiesConfig.Cookies.Items, + }, + } + } + + cookiesConfigFlat["cookie_behavior"] = aws.StringValue(cookiesConfig.CookieBehavior) + cookiesConfigFlat["cookies"] = cookies + + return []map[string]interface{}{ + cookiesConfigFlat, + } +} + +func flattenCloudFrontCachePolicyHeadersConfig(headersConfig *cloudfront.CachePolicyHeadersConfig) []map[string]interface{} { + headersConfigFlat := map[string]interface{}{} + + headers := []map[string]interface{}{} + if headersConfig.Headers != nil { + headers = []map[string]interface{}{ + { + "items": headersConfig.Headers.Items, + }, + } + } + + headersConfigFlat["header_behavior"] = aws.StringValue(headersConfig.HeaderBehavior) + headersConfigFlat["headers"] = headers + + return []map[string]interface{}{ + headersConfigFlat, + } +} + +func flattenCloudFrontCachePolicyQueryStringsConfig(queryStringsConfig *cloudfront.CachePolicyQueryStringsConfig) []map[string]interface{} { + queryStringsConfigFlat := map[string]interface{}{} + + queryStrings := []map[string]interface{}{} + if queryStringsConfig.QueryStrings != nil { + queryStrings = []map[string]interface{}{ + { + "items": queryStringsConfig.QueryStrings.Items, + }, + } + } + + queryStringsConfigFlat["query_string_behavior"] = aws.StringValue(queryStringsConfig.QueryStringBehavior) + queryStringsConfigFlat["query_strings"] = queryStrings + + return []map[string]interface{}{ + queryStringsConfigFlat, + } +} + +func flattenParametersConfig(parametersConfig *cloudfront.ParametersInCacheKeyAndForwardedToOrigin) []map[string]interface{} { + parametersConfigFlat := map[string]interface{}{ + "enable_accept_encoding_brotli": aws.BoolValue(parametersConfig.EnableAcceptEncodingBrotli), + "enable_accept_encoding_gzip": aws.BoolValue(parametersConfig.EnableAcceptEncodingGzip), + "cookies_config": flattenCloudFrontCachePolicyCookiesConfig(parametersConfig.CookiesConfig), + "headers_config": flattenCloudFrontCachePolicyHeadersConfig(parametersConfig.HeadersConfig), + "query_strings_config": flattenCloudFrontCachePolicyQueryStringsConfig(parametersConfig.QueryStringsConfig), + } + + return []map[string]interface{}{ + parametersConfigFlat, + } +} + +func flattenCloudFrontCachePolicy(d *schema.ResourceData, cachePolicy *cloudfront.CachePolicyConfig) { + d.Set("comment", aws.StringValue(cachePolicy.Comment)) + d.Set("default_ttl", aws.Int64Value(cachePolicy.DefaultTTL)) + d.Set("max_ttl", aws.Int64Value(cachePolicy.MaxTTL)) + d.Set("min_ttl", aws.Int64Value(cachePolicy.MinTTL)) + d.Set("name", aws.StringValue(cachePolicy.Name)) + d.Set("parameters_in_cache_key_and_forwarded_to_origin", flattenParametersConfig(cachePolicy.ParametersInCacheKeyAndForwardedToOrigin)) +} diff --git a/aws/cloudfront_distribution_configuration_structure.go b/aws/cloudfront_distribution_configuration_structure.go index 6473b5ccef7..31c09f628b4 100644 --- a/aws/cloudfront_distribution_configuration_structure.go +++ b/aws/cloudfront_distribution_configuration_structure.go @@ -224,13 +224,28 @@ func expandCloudFrontDefaultCacheBehavior(m map[string]interface{}) *cloudfront. } func expandCacheBehavior(m map[string]interface{}) *cloudfront.CacheBehavior { + var forwardedValues *cloudfront.ForwardedValues + if forwardedValuesFlat, ok := m["forwarded_values"].([]interface{}); ok && len(forwardedValuesFlat) == 1 { + forwardedValues = expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})) + } + + minTTL := aws.Int64(int64(m["min_ttl"].(int))) + maxTTL := aws.Int64(int64(m["max_ttl"].(int))) + defaultTTL := aws.Int64(int64(m["default_ttl"].(int))) + if m["cache_policy_id"].(string) != "" { + minTTL = nil + maxTTL = nil + defaultTTL = nil + } + cb := &cloudfront.CacheBehavior{ + CachePolicyId: aws.String(m["cache_policy_id"].(string)), Compress: aws.Bool(m["compress"].(bool)), - DefaultTTL: aws.Int64(int64(m["default_ttl"].(int))), + DefaultTTL: defaultTTL, FieldLevelEncryptionId: aws.String(m["field_level_encryption_id"].(string)), - ForwardedValues: expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})), - MaxTTL: aws.Int64(int64(m["max_ttl"].(int))), - MinTTL: aws.Int64(int64(m["min_ttl"].(int))), + ForwardedValues: forwardedValues, + MaxTTL: maxTTL, + MinTTL: minTTL, OriginRequestPolicyId: aws.String(m["origin_request_policy_id"].(string)), TargetOriginId: aws.String(m["target_origin_id"].(string)), ViewerProtocolPolicy: aws.String(m["viewer_protocol_policy"].(string)), @@ -263,6 +278,7 @@ func expandCacheBehavior(m map[string]interface{}) *cloudfront.CacheBehavior { func flattenCloudFrontDefaultCacheBehavior(dcb *cloudfront.DefaultCacheBehavior) map[string]interface{} { m := map[string]interface{}{ + "cache_policy_id": aws.StringValue(dcb.CachePolicyId), "compress": aws.BoolValue(dcb.Compress), "field_level_encryption_id": aws.StringValue(dcb.FieldLevelEncryptionId), "viewer_protocol_policy": aws.StringValue(dcb.ViewerProtocolPolicy), @@ -302,6 +318,7 @@ func flattenCloudFrontDefaultCacheBehavior(dcb *cloudfront.DefaultCacheBehavior) func flattenCacheBehavior(cb *cloudfront.CacheBehavior) map[string]interface{} { m := make(map[string]interface{}) + m["cache_policy_id"] = aws.StringValue(cb.CachePolicyId) m["compress"] = aws.BoolValue(cb.Compress) m["field_level_encryption_id"] = aws.StringValue(cb.FieldLevelEncryptionId) m["viewer_protocol_policy"] = aws.StringValue(cb.ViewerProtocolPolicy) diff --git a/aws/provider.go b/aws/provider.go index 4b6f7ecf5b1..4b1c38dbc11 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -486,6 +486,7 @@ func Provider() *schema.Provider { "aws_cloudformation_stack": resourceAwsCloudFormationStack(), "aws_cloudformation_stack_set": resourceAwsCloudFormationStackSet(), "aws_cloudformation_stack_set_instance": resourceAwsCloudFormationStackSetInstance(), + "aws_cloudfront_cache_policy": resourceAwsCloudFrontCachePolicy(), "aws_cloudfront_distribution": resourceAwsCloudFrontDistribution(), "aws_cloudfront_origin_access_identity": resourceAwsCloudFrontOriginAccessIdentity(), "aws_cloudfront_origin_request_policy": resourceAwsCloudFrontOriginRequestPolicy(), diff --git a/aws/resource_aws_cloudfront_cache_policy.go b/aws/resource_aws_cloudfront_cache_policy.go new file mode 100644 index 00000000000..8ea69da67a1 --- /dev/null +++ b/aws/resource_aws_cloudfront_cache_policy.go @@ -0,0 +1,223 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloudfront" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceAwsCloudFrontCachePolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsCloudFrontCachePolicyCreate, + Read: resourceAwsCloudFrontCachePolicyRead, + Update: resourceAwsCloudFrontCachePolicyUpdate, + Delete: resourceAwsCloudFrontCachePolicyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "comment": { + Type: schema.TypeString, + Optional: true, + }, + "default_ttl": { + Type: schema.TypeInt, + Optional: true, + Default: 86400, + }, + "max_ttl": { + Type: schema.TypeInt, + Optional: true, + Default: 31536000, + }, + "min_ttl": { + Type: schema.TypeInt, + Optional: true, + Default: 0, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "etag": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "parameters_in_cache_key_and_forwarded_to_origin": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cookies_config": { + Type: schema.TypeList, + MaxItems: 1, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cookie_behavior": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"none", "whitelist", "allExcept", "all"}, false), + }, + "cookies": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "items": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + "enable_accept_encoding_brotli": { + Type: schema.TypeBool, + Optional: true, + }, + "enable_accept_encoding_gzip": { + Type: schema.TypeBool, + Optional: true, + }, + "headers_config": { + Type: schema.TypeList, + MaxItems: 1, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "header_behavior": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"none", "whitelist"}, false), + }, + "headers": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "items": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + "query_strings_config": { + Type: schema.TypeList, + MaxItems: 1, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "query_string_behavior": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"none", "whitelist", "allExcept", "all"}, false), + }, + "query_strings": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "items": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func resourceAwsCloudFrontCachePolicyCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + + request := &cloudfront.CreateCachePolicyInput{ + CachePolicyConfig: expandCloudFrontCachePolicyConfig(d), + } + + resp, err := conn.CreateCachePolicy(request) + + if err != nil { + return err + } + + d.SetId(aws.StringValue(resp.CachePolicy.Id)) + + return resourceAwsCloudFrontCachePolicyRead(d, meta) +} + +func resourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + request := &cloudfront.GetCachePolicyInput{ + Id: aws.String(d.Id()), + } + + resp, err := conn.GetCachePolicy(request) + if err != nil { + return err + } + d.Set("etag", aws.StringValue(resp.ETag)) + + flattenCloudFrontCachePolicy(d, resp.CachePolicy.CachePolicyConfig) + + return nil +} + +func resourceAwsCloudFrontCachePolicyUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + + request := &cloudfront.UpdateCachePolicyInput{ + CachePolicyConfig: expandCloudFrontCachePolicyConfig(d), + Id: aws.String(d.Id()), + IfMatch: aws.String(d.Get("etag").(string)), + } + + _, err := conn.UpdateCachePolicy(request) + if err != nil { + return err + } + + return resourceAwsCloudFrontCachePolicyRead(d, meta) +} + +func resourceAwsCloudFrontCachePolicyDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + + request := &cloudfront.DeleteCachePolicyInput{ + Id: aws.String(d.Id()), + IfMatch: aws.String(d.Get("etag").(string)), + } + + _, err := conn.DeleteCachePolicy(request) + if err != nil { + if isAWSErr(err, cloudfront.ErrCodeNoSuchCachePolicy, "") { + return nil + } + return err + } + + return nil +} diff --git a/aws/resource_aws_cloudfront_cache_policy_test.go b/aws/resource_aws_cloudfront_cache_policy_test.go new file mode 100644 index 00000000000..86f41e68ee1 --- /dev/null +++ b/aws/resource_aws_cloudfront_cache_policy_test.go @@ -0,0 +1,208 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/cloudfront" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccAWSCloudFrontCachePolicy_basic(t *testing.T) { + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontCachePolicyConfig(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "comment", "test comment"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "default_ttl", "50"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "min_ttl", "1"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "max_ttl", "100"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "whitelist"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "whitelist"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.0.items.0", "test"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "whitelist"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test"), + ), + }, + { + ResourceName: "aws_cloudfront_cache_policy.example", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func TestAccAWSCloudFrontCachePolicy_update(t *testing.T) { + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontCachePolicyConfig(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "comment", "test comment"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "default_ttl", "50"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "min_ttl", "1"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "max_ttl", "100"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "whitelist"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "whitelist"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.0.items.0", "test"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "whitelist"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test"), + ), + }, + { + Config: testAccAWSCloudFrontCachePolicyConfigUpdate(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "comment", "test comment updated"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "default_ttl", "51"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "min_ttl", "2"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "max_ttl", "101"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "allExcept"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test2"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "none"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.#", "0"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "allExcept"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test2"), + ), + }, + { + ResourceName: "aws_cloudfront_cache_policy.example", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func TestAccAWSCloudFrontCachePolicy_noneBehavior(t *testing.T) { + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontCachePolicyConfigNoneBehavior(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "comment", "test comment"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "default_ttl", "50"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "min_ttl", "1"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "max_ttl", "100"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "none"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.#", "0"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "none"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.#", "0"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "none"), + resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.#", "0"), + ), + }, + { + ResourceName: "aws_cloudfront_cache_policy.example", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func testAccAWSCloudFrontCachePolicyConfig(rInt int) string { + return fmt.Sprintf(` +resource "aws_cloudfront_cache_policy" "example" { + name = "test-policy%[1]d" + comment = "test comment" + default_ttl = 50 + max_ttl = 100 + min_ttl = 1 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "whitelist" + cookies { + items = ["test"] + } + } + headers_config { + header_behavior = "whitelist" + headers { + items = ["test"] + } + } + query_strings_config { + query_string_behavior = "whitelist" + query_strings { + items = ["test"] + } + } + } +} +`, rInt) +} + +func testAccAWSCloudFrontCachePolicyConfigUpdate(rInt int) string { + return fmt.Sprintf(` +resource "aws_cloudfront_cache_policy" "example" { + name = "test-policy-updated%[1]d" + comment = "test comment updated" + default_ttl = 51 + max_ttl = 101 + min_ttl = 2 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "allExcept" + cookies { + items = ["test2"] + } + } + headers_config { + header_behavior = "none" + } + query_strings_config { + query_string_behavior = "allExcept" + query_strings { + items = ["test2"] + } + } + } +} +`, rInt) +} + +func testAccAWSCloudFrontCachePolicyConfigNoneBehavior(rInt int) string { + return fmt.Sprintf(` +resource "aws_cloudfront_cache_policy" "example" { + name = "test-policy-updated%[1]d" + comment = "test comment" + default_ttl = 50 + max_ttl = 100 + min_ttl = 1 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "none" + } + headers_config { + header_behavior = "none" + } + query_strings_config { + query_string_behavior = "none" + } + } +} +`, rInt) +} diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index f63cfd2745e..2ab3c96aa17 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -58,6 +58,10 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "cache_policy_id": { + Type: schema.TypeString, + Optional: true, + }, "compress": { Type: schema.TypeBool, Optional: true, @@ -66,7 +70,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "default_ttl": { Type: schema.TypeInt, Optional: true, - Default: 86400, + Computed: true, }, "field_level_encryption_id": { Type: schema.TypeString, @@ -74,7 +78,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { }, "forwarded_values": { Type: schema.TypeList, - Required: true, + Optional: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -104,6 +108,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "headers": { Type: schema.TypeSet, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "query_string": { @@ -113,6 +118,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "query_string_cache_keys": { Type: schema.TypeList, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, }, @@ -144,7 +150,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "max_ttl": { Type: schema.TypeInt, Optional: true, - Default: 31536000, + Computed: true, }, "min_ttl": { Type: schema.TypeInt, @@ -224,6 +230,10 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Required: true, Elem: &schema.Schema{Type: schema.TypeString}, }, + "cache_policy_id": { + Type: schema.TypeString, + Optional: true, + }, "compress": { Type: schema.TypeBool, Optional: true, @@ -262,6 +272,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "whitelisted_names": { Type: schema.TypeSet, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, }, @@ -270,6 +281,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "headers": { Type: schema.TypeSet, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "query_string": { @@ -279,6 +291,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "query_string_cache_keys": { Type: schema.TypeList, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, }, @@ -332,6 +345,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "trusted_signers": { Type: schema.TypeList, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "viewer_protocol_policy": { @@ -529,6 +543,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "locations": { Type: schema.TypeSet, Optional: true, + Computed: true, Elem: &schema.Schema{Type: schema.TypeString}, }, "restriction_type": { diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index 29badfe2ce8..f412c40ee9d 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -310,6 +310,35 @@ func TestAccAWSCloudFrontDistribution_orderedCacheBehavior(t *testing.T) { }) } +func TestAccAWSCloudFrontDistribution_orderedCacheBehaviorCachePolicy(t *testing.T) { + var distribution cloudfront.Distribution + resourceName := "aws_cloudfront_distribution.main" + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontDistributionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontDistributionOrderedCacheBehaviorCachePolicy, + Check: resource.ComposeTestCheckFunc( + testAccCheckCloudFrontDistributionExists(resourceName, &distribution), + resource.TestCheckResourceAttr(resourceName, "ordered_cache_behavior.0.path_pattern", "images2/*.jpg"), + resource.TestMatchResourceAttr(resourceName, "ordered_cache_behavior.0.cache_policy_id", regexp.MustCompile(`^[a-z0-9]+`)), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "retain_on_delete", + "wait_for_deployment", + }, + }, + }, + }) +} + func TestAccAWSCloudFrontDistribution_Origin_EmptyDomainName(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, @@ -2053,6 +2082,90 @@ resource "aws_cloudfront_distribution" "main" { } `, acctest.RandInt(), testAccAWSCloudFrontDistributionRetainConfig()) +var testAccAWSCloudFrontDistributionOrderedCacheBehaviorCachePolicy = fmt.Sprintf(` +variable rand_id { + default = %d +} + +resource "aws_cloudfront_distribution" "main" { + origin { + domain_name = "www.hashicorp.com" + origin_id = "myCustomOrigin" + + custom_origin_config { + http_port = 80 + https_port = 443 + origin_protocol_policy = "http-only" + origin_ssl_protocols = ["SSLv3", "TLSv1"] + } + } + + enabled = true + comment = "Some comment" + + default_cache_behavior { + allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] + cached_methods = ["GET", "HEAD"] + target_origin_id = "myCustomOrigin" + smooth_streaming = true + + forwarded_values { + query_string = false + + cookies { + forward = "all" + } + } + + viewer_protocol_policy = "allow-all" + } + + ordered_cache_behavior { + allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] + cached_methods = ["GET", "HEAD"] + target_origin_id = "myCustomOrigin" + + cache_policy_id = aws_cloudfront_cache_policy.cache_policy.id + + viewer_protocol_policy = "allow-all" + path_pattern = "images2/*.jpg" + } + + price_class = "PriceClass_All" + + restrictions { + geo_restriction { + restriction_type = "none" + } + } + + viewer_certificate { + cloudfront_default_certificate = true + } + + %s +} + +resource "aws_cloudfront_cache_policy" "cache_policy" { + name = "test-policy%[1]d" + comment = "test comment" + default_ttl = 50 + max_ttl = 100 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "none" + } + headers_config { + header_behavior = "none" + } + query_strings_config { + query_string_behavior = "none" + } + } +} + +`, acctest.RandInt(), testAccAWSCloudFrontDistributionRetainConfig()) + var testAccAWSCloudFrontDistributionOriginGroupsConfig = ` variable rand_id { default = %d diff --git a/website/docs/r/cloudfront_cache_policy.html.markdown b/website/docs/r/cloudfront_cache_policy.html.markdown new file mode 100644 index 00000000000..2a8e0be984a --- /dev/null +++ b/website/docs/r/cloudfront_cache_policy.html.markdown @@ -0,0 +1,93 @@ +--- +subcategory: "CloudFront" +layout: "aws" +page_title: "AWS: aws_cloudfront_cache_policy" +description: |- + Provides a cache policy for a CloudFront ditribution. When it’s attached to a cache behavior, + the cache policy determines the the values that CloudFront includes in the cache key. These + values can include HTTP headers, cookies, and URL query strings. CloudFront uses the cache + key to find an object in its cache that it can return to the viewer. It also determines the + default, minimum, and maximum time to live (TTL) values that you want objects to stay in the + CloudFront cache. +--- + +# Resource: aws_cloudfront_cache_policy + +## Example Usage + +The following example below creates a CloudFront public key. + +```hcl +resource "aws_cloudfront_cache_policy" "example" { + name = "example-policy" + comment = "test comment" + default_ttl = 50 + max_ttl = 100 + min_ttl = 1 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "whitelist" + cookies { + items = [ "example" ] + } + } + headers_config { + header_behavior = "whitelist" + headers { + items = [ "example" ] + } + } + query_strings_config { + query_string_behavior = "whitelist" + query_strings { + items = [ "example" ] + } + } + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) A unique name to identify the cache policy. +* `min_ttl` - (Required) The minimum amount of time, in seconds, that you want objects to stay in the CloudFront cache before CloudFront sends another request to the origin to see if the object has been updated. +* `max_ttl` - (Optional) The maximum amount of time, in seconds, that objects stay in the CloudFront cache before CloudFront sends another request to the origin to see if the object has been updated. +* `default_ttl` - (Optional) The default amount of time, in seconds, that you want objects to stay in the CloudFront cache before CloudFront sends another request to the origin to see if the object has been updated. +* `comment` - (Optional) A comment to describe the cache policy. +* `parameters_in_cache_key_and_forwarded_to_origin` - (Optional) The HTTP headers, cookies, and URL query strings to include in the cache key. See [Parameters In Cache Key And Forwarded To Origin](#parameters-in-cache-key-and-forwarded-to-origin) for more information. + +### Parameters In Cache Key And Forwarded To Origin + +* `cookies_config` - (Required) An object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Cookies Config](#cookies-config) for more information. +* `cookies_config` - (Required) An object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. +* `cookies_config` - (Required) An object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. +* `enable_accept_encoding_brotli` - (Optional) A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. +* `enable_accept_encoding_gzip` - (Optional) A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. + +### Cookies Config + +`cookie_behavior` - (Required) Determines whether any cookies in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allExcept`, `all`. +`cookies` - (Optional) An object that contains a list of cookie names. See [Items](#items) for more information. + +### Headers Config + +`header_behavior` - (Required) Determines whether any HTTP headers are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`. +`headers` - (Optional) An object that contains a list of header names. See [Items](#items) for more information. + +### Query String Config + +`query_string_behavior` - (Required) Determines whether any URL query strings in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allExcept`, `all`. +`query_strings` - (Optional) An object that contains a list of query string names. See [Items](#items) for more information. + +### Items + +`items` - (Required) A list of item names (cookies, headers, or query strings). + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `etag` - The current version of the cache policy. +* `id` - The identifier for the cache policy. diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index 2c1b3b5eed3..1fcf48d7d19 100644 --- a/website/docs/r/cloudfront_distribution.html.markdown +++ b/website/docs/r/cloudfront_distribution.html.markdown @@ -271,6 +271,9 @@ of several sub-resources - these resources are laid out below. * `cached_methods` (Required) - Controls whether CloudFront caches the response to requests using the specified HTTP methods. +* `cache_policy_id` (Optional) - The unique identifier of the cache policy that + is attached to the cache behavior. + * `compress` (Optional) - Whether you want CloudFront to automatically compress content for web requests that include `Accept-Encoding: gzip` in the request header (default: `false`). From 921ffcb99319eb9dace2a69a47cacbb8817961af Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 27 Jan 2021 23:36:22 -0800 Subject: [PATCH 02/13] Fix copy and paste error --- website/docs/r/cloudfront_cache_policy.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/cloudfront_cache_policy.html.markdown b/website/docs/r/cloudfront_cache_policy.html.markdown index 2a8e0be984a..7612576e8f9 100644 --- a/website/docs/r/cloudfront_cache_policy.html.markdown +++ b/website/docs/r/cloudfront_cache_policy.html.markdown @@ -15,7 +15,7 @@ description: |- ## Example Usage -The following example below creates a CloudFront public key. +The following example below creates a CloudFront cache policy. ```hcl resource "aws_cloudfront_cache_policy" "example" { From 272c6b97988094b06342a7c36b485152ddd40ef2 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Thu, 28 Jan 2021 07:48:02 -0800 Subject: [PATCH 03/13] Fix formatting --- aws/cloudfront_cache_policy_structure.go | 10 +--- ...source_aws_cloudfront_distribution_test.go | 30 +++++----- .../r/cloudfront_cache_policy.html.markdown | 56 +++++++++---------- 3 files changed, 46 insertions(+), 50 deletions(-) diff --git a/aws/cloudfront_cache_policy_structure.go b/aws/cloudfront_cache_policy_structure.go index 67e2c0cac78..38f5d775d6d 100644 --- a/aws/cloudfront_cache_policy_structure.go +++ b/aws/cloudfront_cache_policy_structure.go @@ -20,9 +20,7 @@ func expandCloudFrontCachePolicyCookieNames(cookieNamesFlat map[string]interface } func expandCloudFrontCachePolicyCookiesConfig(cookiesConfigFlat map[string]interface{}) *cloudfront.CachePolicyCookiesConfig { - cookies := &cloudfront.CookieNames{ - Quantity: aws.Int64(int64(0)), - } + var cookies *cloudfront.CookieNames if cookiesFlat, ok := cookiesConfigFlat["cookies"].([]interface{}); ok && len(cookiesFlat) == 1 { cookies = expandCloudFrontCachePolicyCookieNames(cookiesFlat[0].(map[string]interface{})) @@ -52,7 +50,7 @@ func expandCloudFrontCachePolicyHeaders(headerNamesFlat map[string]interface{}) } func expandCloudFrontCachePolicyHeadersConfig(headersConfigFlat map[string]interface{}) *cloudfront.CachePolicyHeadersConfig { - headers := &cloudfront.Headers{} + var headers *cloudfront.Headers if headersFlat, ok := headersConfigFlat["headers"].([]interface{}); ok && len(headersFlat) == 1 && headersConfigFlat["header_behavior"] != "none" { headers = expandCloudFrontCachePolicyHeaders(headersFlat[0].(map[string]interface{})) @@ -82,9 +80,7 @@ func expandCloudFrontCachePolicyQueryStringNames(queryStringNamesFlat map[string } func expandCloudFrontCachePolicyQueryStringConfig(queryStringConfigFlat map[string]interface{}) *cloudfront.CachePolicyQueryStringsConfig { - queryStrings := &cloudfront.QueryStringNames{ - Quantity: aws.Int64(int64(0)), - } + var queryStrings *cloudfront.QueryStringNames if queryStringFlat, ok := queryStringConfigFlat["query_strings"].([]interface{}); ok && len(queryStringFlat) == 1 { queryStrings = expandCloudFrontCachePolicyQueryStringNames(queryStringFlat[0].(map[string]interface{})) diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index f412c40ee9d..8d210f69073 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -2147,21 +2147,21 @@ resource "aws_cloudfront_distribution" "main" { } resource "aws_cloudfront_cache_policy" "cache_policy" { - name = "test-policy%[1]d" - comment = "test comment" - default_ttl = 50 - max_ttl = 100 - parameters_in_cache_key_and_forwarded_to_origin { - cookies_config { - cookie_behavior = "none" - } - headers_config { - header_behavior = "none" - } - query_strings_config { - query_string_behavior = "none" - } - } + name = "test-policy%[1]d" + comment = "test comment" + default_ttl = 50 + max_ttl = 100 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "none" + } + headers_config { + header_behavior = "none" + } + query_strings_config { + query_string_behavior = "none" + } + } } `, acctest.RandInt(), testAccAWSCloudFrontDistributionRetainConfig()) diff --git a/website/docs/r/cloudfront_cache_policy.html.markdown b/website/docs/r/cloudfront_cache_policy.html.markdown index 7612576e8f9..811aa26d4ce 100644 --- a/website/docs/r/cloudfront_cache_policy.html.markdown +++ b/website/docs/r/cloudfront_cache_policy.html.markdown @@ -18,33 +18,33 @@ description: |- The following example below creates a CloudFront cache policy. ```hcl -resource "aws_cloudfront_cache_policy" "example" { - name = "example-policy" - comment = "test comment" - default_ttl = 50 - max_ttl = 100 - min_ttl = 1 - parameters_in_cache_key_and_forwarded_to_origin { - cookies_config { - cookie_behavior = "whitelist" - cookies { - items = [ "example" ] - } - } - headers_config { - header_behavior = "whitelist" - headers { - items = [ "example" ] - } - } - query_strings_config { - query_string_behavior = "whitelist" - query_strings { - items = [ "example" ] - } - } - } -} +resource "aws_cloudfront_cache_policy" "example" { + name = "example-policy" + comment = "test comment" + default_ttl = 50 + max_ttl = 100 + min_ttl = 1 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "whitelist" + cookies { + items = ["example"] + } + } + headers_config { + header_behavior = "whitelist" + headers { + items = ["example"] + } + } + query_strings_config { + query_string_behavior = "whitelist" + query_strings { + items = ["example"] + } + } + } +} ``` ## Argument Reference @@ -90,4 +90,4 @@ The following arguments are supported: In addition to all arguments above, the following attributes are exported: * `etag` - The current version of the cache policy. -* `id` - The identifier for the cache policy. +* `id` - The identifier for the cache policy. From b3cf9d5508fffde52abb90415ac1eb09cef47386 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Thu, 28 Jan 2021 09:41:44 -0800 Subject: [PATCH 04/13] Add cloudfront_cache_policy data source --- ...data_source_aws_cloudfront_cache_policy.go | 185 ++++++++++++++++++ ...source_aws_cloudfront_cache_policy_test.go | 79 ++++++++ aws/provider.go | 1 + .../d/cloudfront_cache_policy.html.markdown | 65 ++++++ 4 files changed, 330 insertions(+) create mode 100644 aws/data_source_aws_cloudfront_cache_policy.go create mode 100644 aws/data_source_aws_cloudfront_cache_policy_test.go create mode 100644 website/docs/d/cloudfront_cache_policy.html.markdown diff --git a/aws/data_source_aws_cloudfront_cache_policy.go b/aws/data_source_aws_cloudfront_cache_policy.go new file mode 100644 index 00000000000..47cc025f3ef --- /dev/null +++ b/aws/data_source_aws_cloudfront_cache_policy.go @@ -0,0 +1,185 @@ +package aws + +import ( + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/cloudfront" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func dataSourceAwsCloudFrontCachePolicy() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsCloudFrontCachePolicyRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + ConflictsWith: []string{"id"}, + Optional: true, + }, + "id": { + Type: schema.TypeString, + ConflictsWith: []string{"name"}, + Optional: true, + }, + "etag": { + Type: schema.TypeString, + Computed: true, + }, + "comment": { + Type: schema.TypeString, + Computed: true, + }, + "default_ttl": { + Type: schema.TypeInt, + Computed: true, + }, + "max_ttl": { + Type: schema.TypeInt, + Computed: true, + }, + "min_ttl": { + Type: schema.TypeInt, + Computed: true, + }, + "parameters_in_cache_key_and_forwarded_to_origin": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cookies_config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cookie_behavior": { + Type: schema.TypeString, + Computed: true, + }, + "cookies": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "items": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + "enable_accept_encoding_brotli": { + Type: schema.TypeBool, + Computed: true, + }, + "enable_accept_encoding_gzip": { + Type: schema.TypeBool, + Computed: true, + }, + "headers_config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "header_behavior": { + Type: schema.TypeString, + Computed: true, + }, + "headers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "items": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + "query_strings_config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "query_string_behavior": { + Type: schema.TypeString, + Computed: true, + }, + "query_strings": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "items": { + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func dataSourceAwsCloudFrontCachePolicyFindByName(d *schema.ResourceData, conn *cloudfront.CloudFront) error { + var cachePolicy *cloudfront.CachePolicy + request := &cloudfront.ListCachePoliciesInput{} + resp, err := conn.ListCachePolicies(request) + if err != nil { + return err + } + + for _, policySummary := range resp.CachePolicyList.Items { + if *policySummary.CachePolicy.CachePolicyConfig.Name == d.Get("name").(string) { + cachePolicy = policySummary.CachePolicy + break + } + } + + if cachePolicy != nil { + d.SetId(aws.StringValue(cachePolicy.Id)) + } + return nil +} + +func dataSourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + + if d.Id() == "" { + if err := dataSourceAwsCloudFrontCachePolicyFindByName(d, conn); err != nil { + return err + } + } + + if d.Id() != "" { + d.Set("id", d.Id()) + request := &cloudfront.GetCachePolicyInput{ + Id: aws.String(d.Id()), + } + + resp, err := conn.GetCachePolicy(request) + if err != nil { + return err + } + d.Set("etag", aws.StringValue(resp.ETag)) + + flattenCloudFrontCachePolicy(d, resp.CachePolicy.CachePolicyConfig) + } + + return nil +} diff --git a/aws/data_source_aws_cloudfront_cache_policy_test.go b/aws/data_source_aws_cloudfront_cache_policy_test.go new file mode 100644 index 00000000000..b32a77853f0 --- /dev/null +++ b/aws/data_source_aws_cloudfront_cache_policy_test.go @@ -0,0 +1,79 @@ +package aws + +import ( + "fmt" + "testing" + + "github.com/aws/aws-sdk-go/service/cloudfront" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccAWSCloudFrontDataSourceCachePolicy_basic(t *testing.T) { + rInt := acctest.RandInt() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontCachePolicyDataSourceNameConfig(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "comment", "test comment"), + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "default_ttl", "50"), + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "min_ttl", "1"), + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "max_ttl", "100"), + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "whitelist"), + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test"), + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "whitelist"), + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.0.items.0", "test"), + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "whitelist"), + resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test"), + ), + }, + { + ResourceName: "aws_cloudfront_cache_policy.example", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func testAccAWSCloudFrontCachePolicyDataSourceNameConfig(rInt int) string { + return fmt.Sprintf(` +data "aws_cloudfront_cache_policy" "example" { + name = aws_cloudfront_cache_policy.example.name +} + +resource "aws_cloudfront_cache_policy" "example" { + name = "test-policy%[1]d" + comment = "test comment" + default_ttl = 50 + max_ttl = 100 + min_ttl = 1 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "whitelist" + cookies { + items = ["test"] + } + } + headers_config { + header_behavior = "whitelist" + headers { + items = ["test"] + } + } + query_strings_config { + query_string_behavior = "whitelist" + query_strings { + items = ["test"] + } + } + } +} +`, rInt) +} diff --git a/aws/provider.go b/aws/provider.go index 4b1c38dbc11..f4ee772900e 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -190,6 +190,7 @@ func Provider() *schema.Provider { "aws_canonical_user_id": dataSourceAwsCanonicalUserId(), "aws_cloudformation_export": dataSourceAwsCloudFormationExport(), "aws_cloudformation_stack": dataSourceAwsCloudFormationStack(), + "aws_cloudfront_cache_policy": dataSourceAwsCloudFrontCachePolicy(), "aws_cloudfront_distribution": dataSourceAwsCloudFrontDistribution(), "aws_cloudfront_origin_request_policy": dataSourceAwsCloudFrontOriginRequestPolicy(), "aws_cloudhsm_v2_cluster": dataSourceCloudHsmV2Cluster(), diff --git a/website/docs/d/cloudfront_cache_policy.html.markdown b/website/docs/d/cloudfront_cache_policy.html.markdown new file mode 100644 index 00000000000..a39554ef6e4 --- /dev/null +++ b/website/docs/d/cloudfront_cache_policy.html.markdown @@ -0,0 +1,65 @@ +--- +subcategory: "CloudFront" +layout: "aws" +page_title: "AWS: aws_cloudfront_cache_policy" +description: |- + Use this data source to retrieve information about a CloudFront cache policy. +--- + +# Resource: aws_cloudfront_cache_policy + +## Example Usage + +The following example below creates a CloudFront cache policy. + +```hcl +data "aws_cloudfront_cache_policy" "example" { + name = "example-policy" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Optional) A unique name to identify the cache policy. +* `id` - (Optional) The identifier for the cache policy. + +## Attributes Reference + +* `etag` - The current version of the cache policy. +* `min_ttl` - The minimum amount of time, in seconds, that you want objects to stay in the CloudFront cache before CloudFront sends another request to the origin to see if the object has been updated. +* `max_ttl` - The maximum amount of time, in seconds, that objects stay in the CloudFront cache before CloudFront sends another request to the origin to see if the object has been updated. +* `default_ttl` - The default amount of time, in seconds, that you want objects to stay in the CloudFront cache before CloudFront sends another request to the origin to see if the object has been updated. +* `comment` - A comment to describe the cache policy. +* `parameters_in_cache_key_and_forwarded_to_origin` - The HTTP headers, cookies, and URL query strings to include in the cache key. See [Parameters In Cache Key And Forwarded To Origin](#parameters-in-cache-key-and-forwarded-to-origin) for more information. + +### Parameters In Cache Key And Forwarded To Origin + +* `cookies_config` - An object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Cookies Config](#cookies-config) for more information. +* `cookies_config` - An object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. +* `cookies_config` - An object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. +* `enable_accept_encoding_brotli` - A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. +* `enable_accept_encoding_gzip` - A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. + +### Cookies Config + +`cookie_behavior` - Determines whether any cookies in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allExcept`, `all`. +`cookies` - An object that contains a list of cookie names. See [Items](#items) for more information. + +### Headers Config + +`header_behavior` - Determines whether any HTTP headers are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`. +`headers` - An object that contains a list of header names. See [Items](#items) for more information. + +### Query String Config + +`query_string_behavior` - Determines whether any URL query strings in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allExcept`, `all`. +`query_strings` - An object that contains a list of query string names. See [Items](#items) for more information. + +### Items + +`items` - A list of item names (cookies, headers, or query strings). + + + From 1b32de5663437914faec1eb43ee2776cbca887f4 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 3 Feb 2021 15:56:49 -0800 Subject: [PATCH 05/13] Address feedback from cache_policy code review --- aws/cloudfront_cache_policy_structure.go | 45 ++++------ ...nt_distribution_configuration_structure.go | 28 +++---- ...data_source_aws_cloudfront_cache_policy.go | 8 +- ...source_aws_cloudfront_cache_policy_test.go | 21 ++--- aws/resource_aws_cloudfront_cache_policy.go | 2 +- ...source_aws_cloudfront_cache_policy_test.go | 83 ++++++++++--------- .../d/cloudfront_cache_policy.html.markdown | 4 +- .../r/cloudfront_cache_policy.html.markdown | 4 +- 8 files changed, 90 insertions(+), 105 deletions(-) diff --git a/aws/cloudfront_cache_policy_structure.go b/aws/cloudfront_cache_policy_structure.go index 38f5d775d6d..40d9c85d8c5 100644 --- a/aws/cloudfront_cache_policy_structure.go +++ b/aws/cloudfront_cache_policy_structure.go @@ -20,17 +20,12 @@ func expandCloudFrontCachePolicyCookieNames(cookieNamesFlat map[string]interface } func expandCloudFrontCachePolicyCookiesConfig(cookiesConfigFlat map[string]interface{}) *cloudfront.CachePolicyCookiesConfig { - var cookies *cloudfront.CookieNames - - if cookiesFlat, ok := cookiesConfigFlat["cookies"].([]interface{}); ok && len(cookiesFlat) == 1 { - cookies = expandCloudFrontCachePolicyCookieNames(cookiesFlat[0].(map[string]interface{})) - } else { - cookies = nil - } - cookiesConfig := &cloudfront.CachePolicyCookiesConfig{ CookieBehavior: aws.String(cookiesConfigFlat["cookie_behavior"].(string)), - Cookies: cookies, + } + + if cookiesFlat, ok := cookiesConfigFlat["cookies"].([]interface{}); ok && len(cookiesFlat) == 1 { + cookiesConfig.Cookies = expandCloudFrontCachePolicyCookieNames(cookiesFlat[0].(map[string]interface{})) } return cookiesConfig @@ -50,17 +45,12 @@ func expandCloudFrontCachePolicyHeaders(headerNamesFlat map[string]interface{}) } func expandCloudFrontCachePolicyHeadersConfig(headersConfigFlat map[string]interface{}) *cloudfront.CachePolicyHeadersConfig { - var headers *cloudfront.Headers - - if headersFlat, ok := headersConfigFlat["headers"].([]interface{}); ok && len(headersFlat) == 1 && headersConfigFlat["header_behavior"] != "none" { - headers = expandCloudFrontCachePolicyHeaders(headersFlat[0].(map[string]interface{})) - } else { - headers = nil - } - headersConfig := &cloudfront.CachePolicyHeadersConfig{ HeaderBehavior: aws.String(headersConfigFlat["header_behavior"].(string)), - Headers: headers, + } + + if headersFlat, ok := headersConfigFlat["headers"].([]interface{}); ok && len(headersFlat) == 1 && headersConfigFlat["header_behavior"] != "none" { + headersConfig.Headers = expandCloudFrontCachePolicyHeaders(headersFlat[0].(map[string]interface{})) } return headersConfig @@ -80,17 +70,12 @@ func expandCloudFrontCachePolicyQueryStringNames(queryStringNamesFlat map[string } func expandCloudFrontCachePolicyQueryStringConfig(queryStringConfigFlat map[string]interface{}) *cloudfront.CachePolicyQueryStringsConfig { - var queryStrings *cloudfront.QueryStringNames - - if queryStringFlat, ok := queryStringConfigFlat["query_strings"].([]interface{}); ok && len(queryStringFlat) == 1 { - queryStrings = expandCloudFrontCachePolicyQueryStringNames(queryStringFlat[0].(map[string]interface{})) - } else { - queryStrings = nil - } - queryStringConfig := &cloudfront.CachePolicyQueryStringsConfig{ QueryStringBehavior: aws.String(queryStringConfigFlat["query_string_behavior"].(string)), - QueryStrings: queryStrings, + } + + if queryStringFlat, ok := queryStringConfigFlat["query_strings"].([]interface{}); ok && len(queryStringFlat) == 1 { + queryStringConfig.QueryStrings = expandCloudFrontCachePolicyQueryStringNames(queryStringFlat[0].(map[string]interface{})) } return queryStringConfig @@ -202,7 +187,7 @@ func flattenCloudFrontCachePolicyQueryStringsConfig(queryStringsConfig *cloudfro } } -func flattenParametersConfig(parametersConfig *cloudfront.ParametersInCacheKeyAndForwardedToOrigin) []map[string]interface{} { +func setParametersConfig(parametersConfig *cloudfront.ParametersInCacheKeyAndForwardedToOrigin) []map[string]interface{} { parametersConfigFlat := map[string]interface{}{ "enable_accept_encoding_brotli": aws.BoolValue(parametersConfig.EnableAcceptEncodingBrotli), "enable_accept_encoding_gzip": aws.BoolValue(parametersConfig.EnableAcceptEncodingGzip), @@ -216,11 +201,11 @@ func flattenParametersConfig(parametersConfig *cloudfront.ParametersInCacheKeyAn } } -func flattenCloudFrontCachePolicy(d *schema.ResourceData, cachePolicy *cloudfront.CachePolicyConfig) { +func setCloudFrontCachePolicy(d *schema.ResourceData, cachePolicy *cloudfront.CachePolicyConfig) { d.Set("comment", aws.StringValue(cachePolicy.Comment)) d.Set("default_ttl", aws.Int64Value(cachePolicy.DefaultTTL)) d.Set("max_ttl", aws.Int64Value(cachePolicy.MaxTTL)) d.Set("min_ttl", aws.Int64Value(cachePolicy.MinTTL)) d.Set("name", aws.StringValue(cachePolicy.Name)) - d.Set("parameters_in_cache_key_and_forwarded_to_origin", flattenParametersConfig(cachePolicy.ParametersInCacheKeyAndForwardedToOrigin)) + d.Set("parameters_in_cache_key_and_forwarded_to_origin", setParametersConfig(cachePolicy.ParametersInCacheKeyAndForwardedToOrigin)) } diff --git a/aws/cloudfront_distribution_configuration_structure.go b/aws/cloudfront_distribution_configuration_structure.go index 31c09f628b4..acd31d9e627 100644 --- a/aws/cloudfront_distribution_configuration_structure.go +++ b/aws/cloudfront_distribution_configuration_structure.go @@ -224,33 +224,23 @@ func expandCloudFrontDefaultCacheBehavior(m map[string]interface{}) *cloudfront. } func expandCacheBehavior(m map[string]interface{}) *cloudfront.CacheBehavior { - var forwardedValues *cloudfront.ForwardedValues - if forwardedValuesFlat, ok := m["forwarded_values"].([]interface{}); ok && len(forwardedValuesFlat) == 1 { - forwardedValues = expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})) - } - - minTTL := aws.Int64(int64(m["min_ttl"].(int))) - maxTTL := aws.Int64(int64(m["max_ttl"].(int))) - defaultTTL := aws.Int64(int64(m["default_ttl"].(int))) - if m["cache_policy_id"].(string) != "" { - minTTL = nil - maxTTL = nil - defaultTTL = nil - } - cb := &cloudfront.CacheBehavior{ CachePolicyId: aws.String(m["cache_policy_id"].(string)), Compress: aws.Bool(m["compress"].(bool)), DefaultTTL: defaultTTL, FieldLevelEncryptionId: aws.String(m["field_level_encryption_id"].(string)), - ForwardedValues: forwardedValues, - MaxTTL: maxTTL, - MinTTL: minTTL, + ForwardedValues: expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})), OriginRequestPolicyId: aws.String(m["origin_request_policy_id"].(string)), TargetOriginId: aws.String(m["target_origin_id"].(string)), ViewerProtocolPolicy: aws.String(m["viewer_protocol_policy"].(string)), } + if m["cache_policy_id"].(string) != "" { + cb.MinTTL = aws.Int64(int64(m["min_ttl"].(int))) + cb.MaxTTL = aws.Int64(int64(m["max_ttl"].(int))) + cb.DefaultTTL = aws.Int64(int64(m["default_ttl"].(int))) + } + if v, ok := m["trusted_signers"]; ok { cb.TrustedSigners = expandTrustedSigners(v.([]interface{})) } else { @@ -435,6 +425,10 @@ func flattenLambdaFunctionAssociation(lfa *cloudfront.LambdaFunctionAssociation) } func expandForwardedValues(m map[string]interface{}) *cloudfront.ForwardedValues { + if len(m) < 1 { + return nil + } + fv := &cloudfront.ForwardedValues{ QueryString: aws.Bool(m["query_string"].(bool)), } diff --git a/aws/data_source_aws_cloudfront_cache_policy.go b/aws/data_source_aws_cloudfront_cache_policy.go index 47cc025f3ef..f78c5225c29 100644 --- a/aws/data_source_aws_cloudfront_cache_policy.go +++ b/aws/data_source_aws_cloudfront_cache_policy.go @@ -1,6 +1,8 @@ package aws import ( + "fmt" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloudfront" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -162,7 +164,7 @@ func dataSourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interfa if d.Id() == "" { if err := dataSourceAwsCloudFrontCachePolicyFindByName(d, conn); err != nil { - return err + return fmt.Errorf("Unable to locate cache policy by name: %s", err.Error()) } } @@ -174,11 +176,11 @@ func dataSourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interfa resp, err := conn.GetCachePolicy(request) if err != nil { - return err + return fmt.Errorf("Unable to retrieve cache policy with ID %s: %s", d.Id(), err.Error()) } d.Set("etag", aws.StringValue(resp.ETag)) - flattenCloudFrontCachePolicy(d, resp.CachePolicy.CachePolicyConfig) + setCloudFrontCachePolicy(d, resp.CachePolicy.CachePolicyConfig) } return nil diff --git a/aws/data_source_aws_cloudfront_cache_policy_test.go b/aws/data_source_aws_cloudfront_cache_policy_test.go index b32a77853f0..4b8f20f9300 100644 --- a/aws/data_source_aws_cloudfront_cache_policy_test.go +++ b/aws/data_source_aws_cloudfront_cache_policy_test.go @@ -11,6 +11,7 @@ import ( func TestAccAWSCloudFrontDataSourceCachePolicy_basic(t *testing.T) { rInt := acctest.RandInt() + dataSourceName := "data.aws_cloudfront_cache_policy.example" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, @@ -20,16 +21,16 @@ func TestAccAWSCloudFrontDataSourceCachePolicy_basic(t *testing.T) { { Config: testAccAWSCloudFrontCachePolicyDataSourceNameConfig(rInt), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "comment", "test comment"), - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "default_ttl", "50"), - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "min_ttl", "1"), - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "max_ttl", "100"), - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "whitelist"), - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test"), - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "whitelist"), - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.0.items.0", "test"), - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "whitelist"), - resource.TestCheckResourceAttr("data.aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test"), + resource.TestCheckResourceAttr(dataSourceName, "comment", "test comment"), + resource.TestCheckResourceAttr(dataSourceName, "default_ttl", "50"), + resource.TestCheckResourceAttr(dataSourceName, "min_ttl", "1"), + resource.TestCheckResourceAttr(dataSourceName, "max_ttl", "100"), + resource.TestCheckResourceAttr(dataSourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "whitelist"), + resource.TestCheckResourceAttr(dataSourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test"), + resource.TestCheckResourceAttr(dataSourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "whitelist"), + resource.TestCheckResourceAttr(dataSourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.0.items.0", "test"), + resource.TestCheckResourceAttr(dataSourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "whitelist"), + resource.TestCheckResourceAttr(dataSourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test"), ), }, { diff --git a/aws/resource_aws_cloudfront_cache_policy.go b/aws/resource_aws_cloudfront_cache_policy.go index 8ea69da67a1..2e9da7785bd 100644 --- a/aws/resource_aws_cloudfront_cache_policy.go +++ b/aws/resource_aws_cloudfront_cache_policy.go @@ -181,7 +181,7 @@ func resourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interface } d.Set("etag", aws.StringValue(resp.ETag)) - flattenCloudFrontCachePolicy(d, resp.CachePolicy.CachePolicyConfig) + setCloudFrontCachePolicy(d, resp.CachePolicy.CachePolicyConfig) return nil } diff --git a/aws/resource_aws_cloudfront_cache_policy_test.go b/aws/resource_aws_cloudfront_cache_policy_test.go index 86f41e68ee1..6c3649ca202 100644 --- a/aws/resource_aws_cloudfront_cache_policy_test.go +++ b/aws/resource_aws_cloudfront_cache_policy_test.go @@ -11,6 +11,7 @@ import ( func TestAccAWSCloudFrontCachePolicy_basic(t *testing.T) { rInt := acctest.RandInt() + resourceName := "aws_cloudfront_cache_policy.example" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, @@ -20,16 +21,16 @@ func TestAccAWSCloudFrontCachePolicy_basic(t *testing.T) { { Config: testAccAWSCloudFrontCachePolicyConfig(rInt), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "comment", "test comment"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "default_ttl", "50"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "min_ttl", "1"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "max_ttl", "100"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "whitelist"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "whitelist"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.0.items.0", "test"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "whitelist"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "comment", "test comment"), + resource.TestCheckResourceAttr(resourceName, "default_ttl", "50"), + resource.TestCheckResourceAttr(resourceName, "min_ttl", "1"), + resource.TestCheckResourceAttr(resourceName, "max_ttl", "100"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test"), ), }, { @@ -44,6 +45,7 @@ func TestAccAWSCloudFrontCachePolicy_basic(t *testing.T) { func TestAccAWSCloudFrontCachePolicy_update(t *testing.T) { rInt := acctest.RandInt() + resourceName := "aws_cloudfront_cache_policy.example" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, @@ -53,31 +55,31 @@ func TestAccAWSCloudFrontCachePolicy_update(t *testing.T) { { Config: testAccAWSCloudFrontCachePolicyConfig(rInt), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "comment", "test comment"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "default_ttl", "50"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "min_ttl", "1"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "max_ttl", "100"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "whitelist"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "whitelist"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.0.items.0", "test"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "whitelist"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "comment", "test comment"), + resource.TestCheckResourceAttr(resourceName, "default_ttl", "50"), + resource.TestCheckResourceAttr(resourceName, "min_ttl", "1"), + resource.TestCheckResourceAttr(resourceName, "max_ttl", "100"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test"), ), }, { Config: testAccAWSCloudFrontCachePolicyConfigUpdate(rInt), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "comment", "test comment updated"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "default_ttl", "51"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "min_ttl", "2"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "max_ttl", "101"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "allExcept"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test2"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "none"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.#", "0"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "allExcept"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test2"), + resource.TestCheckResourceAttr(resourceName, "comment", "test comment updated"), + resource.TestCheckResourceAttr(resourceName, "default_ttl", "51"), + resource.TestCheckResourceAttr(resourceName, "min_ttl", "2"), + resource.TestCheckResourceAttr(resourceName, "max_ttl", "101"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "allExcept"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.0.items.0", "test2"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "none"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.#", "0"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "allExcept"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.0.items.0", "test2"), ), }, { @@ -92,6 +94,7 @@ func TestAccAWSCloudFrontCachePolicy_update(t *testing.T) { func TestAccAWSCloudFrontCachePolicy_noneBehavior(t *testing.T) { rInt := acctest.RandInt() + resourceName := "aws_cloudfront_cache_policy.example" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, @@ -101,16 +104,16 @@ func TestAccAWSCloudFrontCachePolicy_noneBehavior(t *testing.T) { { Config: testAccAWSCloudFrontCachePolicyConfigNoneBehavior(rInt), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "comment", "test comment"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "default_ttl", "50"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "min_ttl", "1"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "max_ttl", "100"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "none"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.#", "0"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "none"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.#", "0"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "none"), - resource.TestCheckResourceAttr("aws_cloudfront_cache_policy.example", "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.#", "0"), + resource.TestCheckResourceAttr(resourceName, "comment", "test comment"), + resource.TestCheckResourceAttr(resourceName, "default_ttl", "50"), + resource.TestCheckResourceAttr(resourceName, "min_ttl", "1"), + resource.TestCheckResourceAttr(resourceName, "max_ttl", "100"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookie_behavior", "none"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.cookies_config.0.cookies.#", "0"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.header_behavior", "none"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.headers_config.0.headers.#", "0"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_string_behavior", "none"), + resource.TestCheckResourceAttr(resourceName, "parameters_in_cache_key_and_forwarded_to_origin.0.query_strings_config.0.query_strings.#", "0"), ), }, { diff --git a/website/docs/d/cloudfront_cache_policy.html.markdown b/website/docs/d/cloudfront_cache_policy.html.markdown index a39554ef6e4..71e100472dc 100644 --- a/website/docs/d/cloudfront_cache_policy.html.markdown +++ b/website/docs/d/cloudfront_cache_policy.html.markdown @@ -37,8 +37,8 @@ The following arguments are supported: ### Parameters In Cache Key And Forwarded To Origin * `cookies_config` - An object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Cookies Config](#cookies-config) for more information. -* `cookies_config` - An object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. -* `cookies_config` - An object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. +* `headers_config` - An object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. +* `query_strings_config` - An object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. * `enable_accept_encoding_brotli` - A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. * `enable_accept_encoding_gzip` - A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. diff --git a/website/docs/r/cloudfront_cache_policy.html.markdown b/website/docs/r/cloudfront_cache_policy.html.markdown index 811aa26d4ce..ea485f3d054 100644 --- a/website/docs/r/cloudfront_cache_policy.html.markdown +++ b/website/docs/r/cloudfront_cache_policy.html.markdown @@ -61,8 +61,8 @@ The following arguments are supported: ### Parameters In Cache Key And Forwarded To Origin * `cookies_config` - (Required) An object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Cookies Config](#cookies-config) for more information. -* `cookies_config` - (Required) An object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. -* `cookies_config` - (Required) An object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. +* `headers_config` - (Required) An object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. +* `query_strings_config` - (Required) An object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. * `enable_accept_encoding_brotli` - (Optional) A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. * `enable_accept_encoding_gzip` - (Optional) A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. From 66e407fd8bcff7b10333639c62b701cdf1b5b226 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 3 Feb 2021 16:19:12 -0800 Subject: [PATCH 06/13] Include feedback from origin_request_policy --- aws/cloudfront_cache_policy_structure.go | 127 +++++++++++------- ...data_source_aws_cloudfront_cache_policy.go | 71 +++++----- aws/resource_aws_cloudfront_cache_policy.go | 10 +- .../d/cloudfront_cache_policy.html.markdown | 12 +- .../r/cloudfront_cache_policy.html.markdown | 12 +- 5 files changed, 131 insertions(+), 101 deletions(-) diff --git a/aws/cloudfront_cache_policy_structure.go b/aws/cloudfront_cache_policy_structure.go index 40d9c85d8c5..dc80b3ea090 100644 --- a/aws/cloudfront_cache_policy_structure.go +++ b/aws/cloudfront_cache_policy_structure.go @@ -6,102 +6,133 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" ) -func expandCloudFrontCachePolicyCookieNames(cookieNamesFlat map[string]interface{}) *cloudfront.CookieNames { - cookieNames := &cloudfront.CookieNames{} +func expandCloudFrontCachePolicyCookieNames(tfMap map[string]interface{}) *cloudfront.CookieNames { + if tfMap == nil { + return nil + } + + var items []*string + for _, item := range tfMap["items"].(*schema.Set).List() { + items = append(items, aws.String(item.(string))) + } - var newCookieItems []*string - for _, cookie := range cookieNamesFlat["items"].(*schema.Set).List() { - newCookieItems = append(newCookieItems, aws.String(cookie.(string))) + apiObject := &cloudfront.CookieNames{ + Items: items, + Quantity: aws.Int64(int64(len(items))), } - cookieNames.Items = newCookieItems - cookieNames.Quantity = aws.Int64(int64(len(newCookieItems))) - return cookieNames + return apiObject } -func expandCloudFrontCachePolicyCookiesConfig(cookiesConfigFlat map[string]interface{}) *cloudfront.CachePolicyCookiesConfig { - cookiesConfig := &cloudfront.CachePolicyCookiesConfig{ - CookieBehavior: aws.String(cookiesConfigFlat["cookie_behavior"].(string)), +func expandCloudFrontCachePolicyCookiesConfig(tfMap map[string]interface{}) *cloudfront.CachePolicyCookiesConfig { + if tfMap == nil { + return nil + } + + apiObject := &cloudfront.CachePolicyCookiesConfig{ + CookieBehavior: aws.String(tfMap["cookie_behavior"].(string)), } - if cookiesFlat, ok := cookiesConfigFlat["cookies"].([]interface{}); ok && len(cookiesFlat) == 1 { - cookiesConfig.Cookies = expandCloudFrontCachePolicyCookieNames(cookiesFlat[0].(map[string]interface{})) + if items, ok := tfMap["cookies"].([]interface{}); ok && len(items) == 1 { + apiObject.Cookies = expandCloudFrontCachePolicyCookieNames(items[0].(map[string]interface{})) } - return cookiesConfig + return apiObject } -func expandCloudFrontCachePolicyHeaders(headerNamesFlat map[string]interface{}) *cloudfront.Headers { - headers := &cloudfront.Headers{} +func expandCloudFrontCachePolicyHeaders(tfMap map[string]interface{}) *cloudfront.Headers { + if tfMap == nil { + return nil + } + + var items []*string + for _, item := range tfMap["items"].(*schema.Set).List() { + items = append(items, aws.String(item.(string))) + } - var newHeaderItems []*string - for _, header := range headerNamesFlat["items"].(*schema.Set).List() { - newHeaderItems = append(newHeaderItems, aws.String(header.(string))) + apiObject := &cloudfront.Headers{ + Items: items, + Quantity: aws.Int64(int64(len(items))), } - headers.Items = newHeaderItems - headers.Quantity = aws.Int64(int64(len(newHeaderItems))) - return headers + return apiObject } -func expandCloudFrontCachePolicyHeadersConfig(headersConfigFlat map[string]interface{}) *cloudfront.CachePolicyHeadersConfig { - headersConfig := &cloudfront.CachePolicyHeadersConfig{ - HeaderBehavior: aws.String(headersConfigFlat["header_behavior"].(string)), +func expandCloudFrontCachePolicyHeadersConfig(tfMap map[string]interface{}) *cloudfront.CachePolicyHeadersConfig { + if tfMap == nil { + return nil } - if headersFlat, ok := headersConfigFlat["headers"].([]interface{}); ok && len(headersFlat) == 1 && headersConfigFlat["header_behavior"] != "none" { - headersConfig.Headers = expandCloudFrontCachePolicyHeaders(headersFlat[0].(map[string]interface{})) + apiObject := &cloudfront.CachePolicyHeadersConfig{ + HeaderBehavior: aws.String(tfMap["header_behavior"].(string)), } - return headersConfig + if items, ok := tfMap["headers"].([]interface{}); ok && len(items) == 1 && tfMap["header_behavior"] != "none" { + apiObject.Headers = expandCloudFrontCachePolicyHeaders(items[0].(map[string]interface{})) + } + + return apiObject } -func expandCloudFrontCachePolicyQueryStringNames(queryStringNamesFlat map[string]interface{}) *cloudfront.QueryStringNames { - queryStringNames := &cloudfront.QueryStringNames{} +func expandCloudFrontCachePolicyQueryStringNames(tfMap map[string]interface{}) *cloudfront.QueryStringNames { + if tfMap == nil { + return nil + } + + var items []*string + for _, queryStringitesm := range tfMap["items"].(*schema.Set).List() { + items = append(items, aws.String(queryStringitesm.(string))) + } - var newQueryStringItems []*string - for _, queryString := range queryStringNamesFlat["items"].(*schema.Set).List() { - newQueryStringItems = append(newQueryStringItems, aws.String(queryString.(string))) + apiObject := &cloudfront.QueryStringNames{ + Items: items, + Quantity: aws.Int64(int64(len(items))), } - queryStringNames.Items = newQueryStringItems - queryStringNames.Quantity = aws.Int64(int64(len(newQueryStringItems))) - return queryStringNames + return apiObject } -func expandCloudFrontCachePolicyQueryStringConfig(queryStringConfigFlat map[string]interface{}) *cloudfront.CachePolicyQueryStringsConfig { - queryStringConfig := &cloudfront.CachePolicyQueryStringsConfig{ - QueryStringBehavior: aws.String(queryStringConfigFlat["query_string_behavior"].(string)), +func expandCloudFrontCachePolicyQueryStringConfig(tfMap map[string]interface{}) *cloudfront.CachePolicyQueryStringsConfig { + if tfMap == nil { + return nil } - if queryStringFlat, ok := queryStringConfigFlat["query_strings"].([]interface{}); ok && len(queryStringFlat) == 1 { - queryStringConfig.QueryStrings = expandCloudFrontCachePolicyQueryStringNames(queryStringFlat[0].(map[string]interface{})) + apiObject := &cloudfront.CachePolicyQueryStringsConfig{ + QueryStringBehavior: aws.String(tfMap["query_string_behavior"].(string)), } - return queryStringConfig + if items, ok := tfMap["query_strings"].([]interface{}); ok && len(items) == 1 { + apiObject.QueryStrings = expandCloudFrontCachePolicyQueryStringNames(items[0].(map[string]interface{})) + } + + return apiObject } -func expandCloudFrontCachePolicyParametersConfig(parameters map[string]interface{}) *cloudfront.ParametersInCacheKeyAndForwardedToOrigin { +func expandCloudFrontCachePolicyParametersConfig(tfMap map[string]interface{}) *cloudfront.ParametersInCacheKeyAndForwardedToOrigin { + if tfMap == nil { + return nil + } + var cookiesConfig *cloudfront.CachePolicyCookiesConfig var headersConfig *cloudfront.CachePolicyHeadersConfig var queryStringsConfig *cloudfront.CachePolicyQueryStringsConfig - if cookiesFlat, ok := parameters["cookies_config"].([]interface{}); ok && len(cookiesFlat) == 1 { + if cookiesFlat, ok := tfMap["cookies_config"].([]interface{}); ok && len(cookiesFlat) == 1 { cookiesConfig = expandCloudFrontCachePolicyCookiesConfig(cookiesFlat[0].(map[string]interface{})) } - if headersFlat, ok := parameters["headers_config"].([]interface{}); ok && len(headersFlat) == 1 { + if headersFlat, ok := tfMap["headers_config"].([]interface{}); ok && len(headersFlat) == 1 { headersConfig = expandCloudFrontCachePolicyHeadersConfig(headersFlat[0].(map[string]interface{})) } - if queryStringsFlat, ok := parameters["query_strings_config"].([]interface{}); ok && len(queryStringsFlat) == 1 { + if queryStringsFlat, ok := tfMap["query_strings_config"].([]interface{}); ok && len(queryStringsFlat) == 1 { queryStringsConfig = expandCloudFrontCachePolicyQueryStringConfig(queryStringsFlat[0].(map[string]interface{})) } parametersConfig := &cloudfront.ParametersInCacheKeyAndForwardedToOrigin{ CookiesConfig: cookiesConfig, - EnableAcceptEncodingBrotli: aws.Bool(parameters["enable_accept_encoding_brotli"].(bool)), - EnableAcceptEncodingGzip: aws.Bool(parameters["enable_accept_encoding_gzip"].(bool)), + EnableAcceptEncodingBrotli: aws.Bool(tfMap["enable_accept_encoding_brotli"].(bool)), + EnableAcceptEncodingGzip: aws.Bool(tfMap["enable_accept_encoding_gzip"].(bool)), HeadersConfig: headersConfig, QueryStringsConfig: queryStringsConfig, } diff --git a/aws/data_source_aws_cloudfront_cache_policy.go b/aws/data_source_aws_cloudfront_cache_policy.go index f78c5225c29..da876f93472 100644 --- a/aws/data_source_aws_cloudfront_cache_policy.go +++ b/aws/data_source_aws_cloudfront_cache_policy.go @@ -13,20 +13,6 @@ func dataSourceAwsCloudFrontCachePolicy() *schema.Resource { Read: dataSourceAwsCloudFrontCachePolicyRead, Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - ConflictsWith: []string{"id"}, - Optional: true, - }, - "id": { - Type: schema.TypeString, - ConflictsWith: []string{"name"}, - Optional: true, - }, - "etag": { - Type: schema.TypeString, - Computed: true, - }, "comment": { Type: schema.TypeString, Computed: true, @@ -35,6 +21,15 @@ func dataSourceAwsCloudFrontCachePolicy() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + "etag": { + Type: schema.TypeString, + Computed: true, + }, + "id": { + Type: schema.TypeString, + ConflictsWith: []string{"name"}, + Optional: true, + }, "max_ttl": { Type: schema.TypeInt, Computed: true, @@ -43,6 +38,11 @@ func dataSourceAwsCloudFrontCachePolicy() *schema.Resource { Type: schema.TypeInt, Computed: true, }, + "name": { + Type: schema.TypeString, + ConflictsWith: []string{"id"}, + Optional: true, + }, "parameters_in_cache_key_and_forwarded_to_origin": { Type: schema.TypeList, Computed: true, @@ -137,28 +137,6 @@ func dataSourceAwsCloudFrontCachePolicy() *schema.Resource { }, } } - -func dataSourceAwsCloudFrontCachePolicyFindByName(d *schema.ResourceData, conn *cloudfront.CloudFront) error { - var cachePolicy *cloudfront.CachePolicy - request := &cloudfront.ListCachePoliciesInput{} - resp, err := conn.ListCachePolicies(request) - if err != nil { - return err - } - - for _, policySummary := range resp.CachePolicyList.Items { - if *policySummary.CachePolicy.CachePolicyConfig.Name == d.Get("name").(string) { - cachePolicy = policySummary.CachePolicy - break - } - } - - if cachePolicy != nil { - d.SetId(aws.StringValue(cachePolicy.Id)) - } - return nil -} - func dataSourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interface{}) error { conn := meta.(*AWSClient).cloudfrontconn @@ -185,3 +163,24 @@ func dataSourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interfa return nil } + +func dataSourceAwsCloudFrontCachePolicyFindByName(d *schema.ResourceData, conn *cloudfront.CloudFront) error { + var cachePolicy *cloudfront.CachePolicy + request := &cloudfront.ListCachePoliciesInput{} + resp, err := conn.ListCachePolicies(request) + if err != nil { + return err + } + + for _, policySummary := range resp.CachePolicyList.Items { + if *policySummary.CachePolicy.CachePolicyConfig.Name == d.Get("name").(string) { + cachePolicy = policySummary.CachePolicy + break + } + } + + if cachePolicy != nil { + d.SetId(aws.StringValue(cachePolicy.Id)) + } + return nil +} diff --git a/aws/resource_aws_cloudfront_cache_policy.go b/aws/resource_aws_cloudfront_cache_policy.go index 2e9da7785bd..6e090c8e35c 100644 --- a/aws/resource_aws_cloudfront_cache_policy.go +++ b/aws/resource_aws_cloudfront_cache_policy.go @@ -27,6 +27,11 @@ func resourceAwsCloudFrontCachePolicy() *schema.Resource { Optional: true, Default: 86400, }, + "etag": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, "max_ttl": { Type: schema.TypeInt, Optional: true, @@ -41,11 +46,6 @@ func resourceAwsCloudFrontCachePolicy() *schema.Resource { Type: schema.TypeString, Required: true, }, - "etag": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, "parameters_in_cache_key_and_forwarded_to_origin": { Type: schema.TypeList, MaxItems: 1, diff --git a/website/docs/d/cloudfront_cache_policy.html.markdown b/website/docs/d/cloudfront_cache_policy.html.markdown index 71e100472dc..007bf54878f 100644 --- a/website/docs/d/cloudfront_cache_policy.html.markdown +++ b/website/docs/d/cloudfront_cache_policy.html.markdown @@ -36,26 +36,26 @@ The following arguments are supported: ### Parameters In Cache Key And Forwarded To Origin -* `cookies_config` - An object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Cookies Config](#cookies-config) for more information. -* `headers_config` - An object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. -* `query_strings_config` - An object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. +* `cookies_config` - Object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Cookies Config](#cookies-config) for more information. +* `headers_config` - Object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. +* `query_strings_config` - Object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. * `enable_accept_encoding_brotli` - A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. * `enable_accept_encoding_gzip` - A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. ### Cookies Config `cookie_behavior` - Determines whether any cookies in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allExcept`, `all`. -`cookies` - An object that contains a list of cookie names. See [Items](#items) for more information. +`cookies` - Object that contains a list of cookie names. See [Items](#items) for more information. ### Headers Config `header_behavior` - Determines whether any HTTP headers are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`. -`headers` - An object that contains a list of header names. See [Items](#items) for more information. +`headers` - Object that contains a list of header names. See [Items](#items) for more information. ### Query String Config `query_string_behavior` - Determines whether any URL query strings in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allExcept`, `all`. -`query_strings` - An object that contains a list of query string names. See [Items](#items) for more information. +`query_strings` - Object that contains a list of query string names. See [Items](#items) for more information. ### Items diff --git a/website/docs/r/cloudfront_cache_policy.html.markdown b/website/docs/r/cloudfront_cache_policy.html.markdown index ea485f3d054..df94af0e340 100644 --- a/website/docs/r/cloudfront_cache_policy.html.markdown +++ b/website/docs/r/cloudfront_cache_policy.html.markdown @@ -60,26 +60,26 @@ The following arguments are supported: ### Parameters In Cache Key And Forwarded To Origin -* `cookies_config` - (Required) An object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Cookies Config](#cookies-config) for more information. -* `headers_config` - (Required) An object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. -* `query_strings_config` - (Required) An object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. +* `cookies_config` - (Required) Object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Cookies Config](#cookies-config) for more information. +* `headers_config` - (Required) Object that determines whether any HTTP headers (and if so, which headers) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Headers Config](#headers-config) for more information. +* `query_strings_config` - (Required) Object that determines whether any URL query strings in viewer requests (and if so, which query strings) are included in the cache key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. * `enable_accept_encoding_brotli` - (Optional) A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. * `enable_accept_encoding_gzip` - (Optional) A flag that can affect whether the Accept-Encoding HTTP header is included in the cache key and included in requests that CloudFront sends to the origin. ### Cookies Config `cookie_behavior` - (Required) Determines whether any cookies in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allExcept`, `all`. -`cookies` - (Optional) An object that contains a list of cookie names. See [Items](#items) for more information. +`cookies` - (Optional) Object that contains a list of cookie names. See [Items](#items) for more information. ### Headers Config `header_behavior` - (Required) Determines whether any HTTP headers are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`. -`headers` - (Optional) An object that contains a list of header names. See [Items](#items) for more information. +`headers` - (Optional) Object that contains a list of header names. See [Items](#items) for more information. ### Query String Config `query_string_behavior` - (Required) Determines whether any URL query strings in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allExcept`, `all`. -`query_strings` - (Optional) An object that contains a list of query string names. See [Items](#items) for more information. +`query_strings` - (Optional) Object that contains a list of query string names. See [Items](#items) for more information. ### Items From 79133b3233f8ea86358dc54337d5ecded870ccce Mon Sep 17 00:00:00 2001 From: bill-rich Date: Thu, 4 Feb 2021 09:53:14 -0800 Subject: [PATCH 07/13] Revert part of CF distribution changes --- aws/cloudfront_distribution_configuration_structure.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/aws/cloudfront_distribution_configuration_structure.go b/aws/cloudfront_distribution_configuration_structure.go index acd31d9e627..91f2a85f67e 100644 --- a/aws/cloudfront_distribution_configuration_structure.go +++ b/aws/cloudfront_distribution_configuration_structure.go @@ -224,18 +224,22 @@ func expandCloudFrontDefaultCacheBehavior(m map[string]interface{}) *cloudfront. } func expandCacheBehavior(m map[string]interface{}) *cloudfront.CacheBehavior { + var forwardedValues *cloudfront.ForwardedValues + if forwardedValuesFlat, ok := m["forwarded_values"].([]interface{}); ok && len(forwardedValuesFlat) == 1 { + forwardedValues = expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})) + } + cb := &cloudfront.CacheBehavior{ CachePolicyId: aws.String(m["cache_policy_id"].(string)), Compress: aws.Bool(m["compress"].(bool)), - DefaultTTL: defaultTTL, FieldLevelEncryptionId: aws.String(m["field_level_encryption_id"].(string)), - ForwardedValues: expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})), + ForwardedValues: forwardedValues, OriginRequestPolicyId: aws.String(m["origin_request_policy_id"].(string)), TargetOriginId: aws.String(m["target_origin_id"].(string)), ViewerProtocolPolicy: aws.String(m["viewer_protocol_policy"].(string)), } - if m["cache_policy_id"].(string) != "" { + if m["cache_policy_id"].(string) == "" { cb.MinTTL = aws.Int64(int64(m["min_ttl"].(int))) cb.MaxTTL = aws.Int64(int64(m["max_ttl"].(int))) cb.DefaultTTL = aws.Int64(int64(m["default_ttl"].(int))) From ffad98ce3c72c04aa89bd4a067a7a7efad39d454 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Thu, 4 Feb 2021 10:00:06 -0800 Subject: [PATCH 08/13] Fix error message capitalization --- aws/data_source_aws_cloudfront_cache_policy.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/data_source_aws_cloudfront_cache_policy.go b/aws/data_source_aws_cloudfront_cache_policy.go index da876f93472..a60434125f2 100644 --- a/aws/data_source_aws_cloudfront_cache_policy.go +++ b/aws/data_source_aws_cloudfront_cache_policy.go @@ -142,7 +142,7 @@ func dataSourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interfa if d.Id() == "" { if err := dataSourceAwsCloudFrontCachePolicyFindByName(d, conn); err != nil { - return fmt.Errorf("Unable to locate cache policy by name: %s", err.Error()) + return fmt.Errorf("unable to locate cache policy by name: %s", err.Error()) } } @@ -154,7 +154,7 @@ func dataSourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interfa resp, err := conn.GetCachePolicy(request) if err != nil { - return fmt.Errorf("Unable to retrieve cache policy with ID %s: %s", d.Id(), err.Error()) + return fmt.Errorf("unable to retrieve cache policy with ID %s: %s", d.Id(), err.Error()) } d.Set("etag", aws.StringValue(resp.ETag)) From 1b2174edbdf29035aa032f0236d0a7ee8e7c5480 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Thu, 4 Feb 2021 10:08:34 -0800 Subject: [PATCH 09/13] Add IsNewResource check --- aws/resource_aws_cloudfront_cache_policy.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/aws/resource_aws_cloudfront_cache_policy.go b/aws/resource_aws_cloudfront_cache_policy.go index 6e090c8e35c..d8a215f457d 100644 --- a/aws/resource_aws_cloudfront_cache_policy.go +++ b/aws/resource_aws_cloudfront_cache_policy.go @@ -176,6 +176,13 @@ func resourceAwsCloudFrontCachePolicyRead(d *schema.ResourceData, meta interface } resp, err := conn.GetCachePolicy(request) + + if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, "ResourceNotFoundException") { + log.Printf("[WARN] CloudFront Cache Policy (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + if err != nil { return err } From b6d0d33d3acd286e0e2453873fb27cbd23c02c79 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Thu, 4 Feb 2021 12:11:50 -0800 Subject: [PATCH 10/13] Fix imports --- aws/resource_aws_cloudfront_cache_policy.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aws/resource_aws_cloudfront_cache_policy.go b/aws/resource_aws_cloudfront_cache_policy.go index d8a215f457d..334271f12ec 100644 --- a/aws/resource_aws_cloudfront_cache_policy.go +++ b/aws/resource_aws_cloudfront_cache_policy.go @@ -1,8 +1,11 @@ package aws import ( + "log" + "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/cloudfront" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) From 672902f61026b2d3c9167b70f237fee9f0df17f4 Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 10 Feb 2021 12:04:25 -0800 Subject: [PATCH 11/13] Use expandStringSet --- aws/cloudfront_cache_policy_structure.go | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/aws/cloudfront_cache_policy_structure.go b/aws/cloudfront_cache_policy_structure.go index dc80b3ea090..7412bb16cd9 100644 --- a/aws/cloudfront_cache_policy_structure.go +++ b/aws/cloudfront_cache_policy_structure.go @@ -11,10 +11,7 @@ func expandCloudFrontCachePolicyCookieNames(tfMap map[string]interface{}) *cloud return nil } - var items []*string - for _, item := range tfMap["items"].(*schema.Set).List() { - items = append(items, aws.String(item.(string))) - } + items := expandStringSet(tfMap["items"].(*schema.Set)) apiObject := &cloudfront.CookieNames{ Items: items, @@ -45,10 +42,7 @@ func expandCloudFrontCachePolicyHeaders(tfMap map[string]interface{}) *cloudfron return nil } - var items []*string - for _, item := range tfMap["items"].(*schema.Set).List() { - items = append(items, aws.String(item.(string))) - } + items := expandStringSet(tfMap["items"].(*schema.Set)) apiObject := &cloudfront.Headers{ Items: items, @@ -79,10 +73,7 @@ func expandCloudFrontCachePolicyQueryStringNames(tfMap map[string]interface{}) * return nil } - var items []*string - for _, queryStringitesm := range tfMap["items"].(*schema.Set).List() { - items = append(items, aws.String(queryStringitesm.(string))) - } + items := expandStringSet(tfMap["items"].(*schema.Set)) apiObject := &cloudfront.QueryStringNames{ Items: items, From cc460944520af86daab54041e7c4e968f9f3cd8d Mon Sep 17 00:00:00 2001 From: bill-rich Date: Wed, 10 Feb 2021 15:14:50 -0800 Subject: [PATCH 12/13] Add default and ordered policy tests --- ...nt_distribution_configuration_structure.go | 15 +- ...stribution_configuration_structure_test.go | 1 + aws/resource_aws_cloudfront_distribution.go | 8 +- ...source_aws_cloudfront_distribution_test.go | 155 +++++++++++++++++- .../r/cloudfront_distribution.html.markdown | 5 +- 5 files changed, 166 insertions(+), 18 deletions(-) diff --git a/aws/cloudfront_distribution_configuration_structure.go b/aws/cloudfront_distribution_configuration_structure.go index 91f2a85f67e..59203dc1697 100644 --- a/aws/cloudfront_distribution_configuration_structure.go +++ b/aws/cloudfront_distribution_configuration_structure.go @@ -189,17 +189,24 @@ func flattenCacheBehaviors(cbs *cloudfront.CacheBehaviors) []interface{} { func expandCloudFrontDefaultCacheBehavior(m map[string]interface{}) *cloudfront.DefaultCacheBehavior { dcb := &cloudfront.DefaultCacheBehavior{ + CachePolicyId: aws.String(m["cache_policy_id"].(string)), Compress: aws.Bool(m["compress"].(bool)), - DefaultTTL: aws.Int64(int64(m["default_ttl"].(int))), FieldLevelEncryptionId: aws.String(m["field_level_encryption_id"].(string)), - ForwardedValues: expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})), - MaxTTL: aws.Int64(int64(m["max_ttl"].(int))), - MinTTL: aws.Int64(int64(m["min_ttl"].(int))), OriginRequestPolicyId: aws.String(m["origin_request_policy_id"].(string)), TargetOriginId: aws.String(m["target_origin_id"].(string)), ViewerProtocolPolicy: aws.String(m["viewer_protocol_policy"].(string)), } + if forwardedValuesFlat, ok := m["forwarded_values"].([]interface{}); ok && len(forwardedValuesFlat) == 1 { + dcb.ForwardedValues = expandForwardedValues(m["forwarded_values"].([]interface{})[0].(map[string]interface{})) + } + + if m["cache_policy_id"].(string) == "" { + dcb.MinTTL = aws.Int64(int64(m["min_ttl"].(int))) + dcb.MaxTTL = aws.Int64(int64(m["max_ttl"].(int))) + dcb.DefaultTTL = aws.Int64(int64(m["default_ttl"].(int))) + } + if v, ok := m["trusted_signers"]; ok { dcb.TrustedSigners = expandTrustedSigners(v.([]interface{})) } else { diff --git a/aws/cloudfront_distribution_configuration_structure_test.go b/aws/cloudfront_distribution_configuration_structure_test.go index 61659ef7577..481a7a7e14e 100644 --- a/aws/cloudfront_distribution_configuration_structure_test.go +++ b/aws/cloudfront_distribution_configuration_structure_test.go @@ -12,6 +12,7 @@ import ( func defaultCacheBehaviorConf() map[string]interface{} { return map[string]interface{}{ "viewer_protocol_policy": "allow-all", + "cache_policy_id": "", "target_origin_id": "myS3Origin", "forwarded_values": []interface{}{forwardedValuesConf()}, "min_ttl": 0, diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index 2ab3c96aa17..42ea527548c 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -80,6 +80,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Type: schema.TypeList, Optional: true, MaxItems: 1, + Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "cookies": { @@ -242,7 +243,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "default_ttl": { Type: schema.TypeInt, Optional: true, - Default: 86400, + Computed: true, }, "field_level_encryption_id": { Type: schema.TypeString, @@ -250,7 +251,8 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { }, "forwarded_values": { Type: schema.TypeList, - Required: true, + Optional: true, + Computed: true, MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -323,7 +325,7 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { "max_ttl": { Type: schema.TypeInt, Optional: true, - Default: 31536000, + Computed: true, }, "min_ttl": { Type: schema.TypeInt, diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index 8d210f69073..e53a97c15ef 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -212,14 +212,14 @@ func TestAccAWSCloudFrontDistribution_customOrigin(t *testing.T) { }) } -func TestAccAWSCloudFrontDistribution_originPolicy(t *testing.T) { +func TestAccAWSCloudFrontDistribution_originPolicyDefault(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, Providers: testAccProviders, CheckDestroy: testAccCheckCloudFrontDistributionDestroy, Steps: []resource.TestStep{ { - Config: testAccAWSCloudFrontDistributionOriginRequestPolicyConfig, + Config: testAccAWSCloudFrontDistributionOriginRequestPolicyConfigDefault, Check: resource.ComposeTestCheckFunc( resource.TestMatchResourceAttr("aws_cloudfront_distribution.custom_distribution", "default_cache_behavior.0.origin_request_policy_id", regexp.MustCompile("[A-z0-9]+")), ), @@ -237,6 +237,31 @@ func TestAccAWSCloudFrontDistribution_originPolicy(t *testing.T) { }) } +func TestAccAWSCloudFrontDistribution_originPolicyOrdered(t *testing.T) { + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontDistributionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontDistributionOriginRequestPolicyConfigOrdered, + Check: resource.ComposeTestCheckFunc( + resource.TestMatchResourceAttr("aws_cloudfront_distribution.custom_distribution", "ordered_cache_behavior.0.origin_request_policy_id", regexp.MustCompile("[A-z0-9]+")), + ), + }, + { + ResourceName: "aws_cloudfront_distribution.custom_distribution", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{ + "retain_on_delete", + "wait_for_deployment", + }, + }, + }, + }) +} + // TestAccAWSCloudFrontDistribution_multiOrigin runs an // aws_cloudfront_distribution acceptance test with multiple origins. // @@ -391,7 +416,6 @@ func TestAccAWSCloudFrontDistribution_noOptionalItemsConfig(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.allowed_methods.#", "7"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.cached_methods.#", "2"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.compress", "false"), - resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.default_ttl", "86400"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.forwarded_values.#", "1"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.forwarded_values.0.cookies.#", "1"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.forwarded_values.0.cookies.0.forward", "all"), @@ -400,7 +424,6 @@ func TestAccAWSCloudFrontDistribution_noOptionalItemsConfig(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.forwarded_values.0.query_string", "false"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.forwarded_values.0.query_string_cache_keys.#", "0"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.lambda_function_association.#", "0"), - resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.max_ttl", "31536000"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.min_ttl", "0"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.smooth_streaming", "false"), resource.TestCheckResourceAttr(resourceName, "default_cache_behavior.0.target_origin_id", "myCustomOrigin"), @@ -1417,7 +1440,7 @@ resource "aws_cloudfront_distribution" "custom_distribution" { } `, acctest.RandInt(), logBucket, testAccAWSCloudFrontDistributionRetainConfig()) -var testAccAWSCloudFrontDistributionOriginRequestPolicyConfig = fmt.Sprintf(` +var testAccAWSCloudFrontDistributionOriginRequestPolicyConfigDefault = fmt.Sprintf(` variable rand_id { default = %[1]d } @@ -1510,13 +1533,129 @@ resource "aws_cloudfront_distribution" "custom_distribution" { origin_request_policy_id = aws_cloudfront_origin_request_policy.test_policy.id cache_policy_id = aws_cloudfront_cache_policy.example.id - forwarded_values { - query_string = false + viewer_protocol_policy = "allow-all" + } + + price_class = "PriceClass_200" + restrictions { + geo_restriction { + restriction_type = "whitelist" + locations = ["US", "CA", "GB", "DE"] + } + } + + viewer_certificate { + cloudfront_default_certificate = true + } +} +`, acctest.RandInt(), logBucket, testAccAWSCloudFrontDistributionRetainConfig()) + +var testAccAWSCloudFrontDistributionOriginRequestPolicyConfigOrdered = fmt.Sprintf(` +variable rand_id { + default = %[1]d +} + +# log bucket +%[2]s + +resource "aws_cloudfront_cache_policy" "example" { + name = "test-policy%[1]d" + comment = "test comment" + default_ttl = 50 + max_ttl = 100 + min_ttl = 1 + parameters_in_cache_key_and_forwarded_to_origin { + cookies_config { + cookie_behavior = "whitelist" cookies { - forward = "all" + items = ["test"] + } + } + headers_config { + header_behavior = "whitelist" + headers { + items = ["test"] + } + } + query_strings_config { + query_string_behavior = "whitelist" + query_strings { + items = ["test"] } } + } +} + +resource "aws_cloudfront_origin_request_policy" "test_policy" { + name = "test-policy%[1]d" + comment = "test comment" + cookies_config { + cookie_behavior = "whitelist" + cookies { + items = ["test"] + } + } + headers_config { + header_behavior = "whitelist" + headers { + items = ["test"] + } + } + query_strings_config { + query_string_behavior = "whitelist" + query_strings { + items = ["test"] + } + } +} + +resource "aws_cloudfront_distribution" "custom_distribution" { + origin { + domain_name = "www.example.com" + origin_id = "myCustomOrigin" + + custom_origin_config { + http_port = 80 + https_port = 443 + origin_protocol_policy = "http-only" + origin_ssl_protocols = ["SSLv3", "TLSv1"] + origin_read_timeout = 30 + origin_keepalive_timeout = 5 + } + } + + enabled = true + comment = "Some comment" + default_root_object = "index.html" + + logging_config { + include_cookies = false + bucket = "${aws_s3_bucket.s3_bucket_logs.id}.s3.amazonaws.com" + prefix = "myprefix" + } + + default_cache_behavior { + allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] + cached_methods = ["GET", "HEAD"] + target_origin_id = "myCustomOrigin" + smooth_streaming = false + + origin_request_policy_id = aws_cloudfront_origin_request_policy.test_policy.id + cache_policy_id = aws_cloudfront_cache_policy.example.id + + viewer_protocol_policy = "allow-all" + } + + ordered_cache_behavior { + allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] + cached_methods = ["GET", "HEAD"] + target_origin_id = "myCustomOrigin" + smooth_streaming = false + path_pattern = "/*" + + origin_request_policy_id = aws_cloudfront_origin_request_policy.test_policy.id + cache_policy_id = aws_cloudfront_cache_policy.example.id viewer_protocol_policy = "allow-all" } diff --git a/website/docs/r/cloudfront_distribution.html.markdown b/website/docs/r/cloudfront_distribution.html.markdown index 1fcf48d7d19..084362a2221 100644 --- a/website/docs/r/cloudfront_distribution.html.markdown +++ b/website/docs/r/cloudfront_distribution.html.markdown @@ -280,8 +280,7 @@ of several sub-resources - these resources are laid out below. * `default_ttl` (Optional) - The default amount of time (in seconds) that an object is in a CloudFront cache before CloudFront forwards another request - in the absence of an `Cache-Control max-age` or `Expires` header. Defaults to - 1 day. + in the absence of an `Cache-Control max-age` or `Expires` header. * `field_level_encryption_id` (Optional) - Field level encryption configuration ID @@ -295,7 +294,7 @@ of several sub-resources - these resources are laid out below. object is in a CloudFront cache before CloudFront forwards another request to your origin to determine whether the object has been updated. Only effective in the presence of `Cache-Control max-age`, `Cache-Control - s-maxage`, and `Expires` headers. Defaults to 365 days. + s-maxage`, and `Expires` headers. * `min_ttl` (Optional) - The minimum amount of time that you want objects to stay in CloudFront caches before CloudFront queries your origin to see From 976ec8e85a9c90c14d9d42431316d953a3097b4a Mon Sep 17 00:00:00 2001 From: bill-rich Date: Thu, 11 Feb 2021 15:24:58 -0800 Subject: [PATCH 13/13] Add CHANGELOG entry --- .changelog/17336.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .changelog/17336.txt diff --git a/.changelog/17336.txt b/.changelog/17336.txt new file mode 100644 index 00000000000..b7df7acc0c2 --- /dev/null +++ b/.changelog/17336.txt @@ -0,0 +1,11 @@ +```release-note:new-data-source +aws_cloudfront_cache_policy +``` + +```release-note:new-resource +aws_cloudfront_cache_policy +``` + +```release-note:enhancement +resource/aws_cloudfront_distribution: Add `cache_policy_id` attribute +```