diff --git a/aws/cloudfront_distribution_configuration_structure.go b/aws/cloudfront_distribution_configuration_structure.go index 71ca5c39316..6473b5ccef7 100644 --- a/aws/cloudfront_distribution_configuration_structure.go +++ b/aws/cloudfront_distribution_configuration_structure.go @@ -195,6 +195,7 @@ func expandCloudFrontDefaultCacheBehavior(m map[string]interface{}) *cloudfront. 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)), } @@ -230,6 +231,7 @@ func expandCacheBehavior(m map[string]interface{}) *cloudfront.CacheBehavior { 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)), } @@ -266,6 +268,7 @@ func flattenCloudFrontDefaultCacheBehavior(dcb *cloudfront.DefaultCacheBehavior) "viewer_protocol_policy": aws.StringValue(dcb.ViewerProtocolPolicy), "target_origin_id": aws.StringValue(dcb.TargetOriginId), "min_ttl": aws.Int64Value(dcb.MinTTL), + "origin_request_policy_id": aws.StringValue(dcb.OriginRequestPolicyId), } if dcb.ForwardedValues != nil { @@ -304,6 +307,7 @@ func flattenCacheBehavior(cb *cloudfront.CacheBehavior) map[string]interface{} { m["viewer_protocol_policy"] = aws.StringValue(cb.ViewerProtocolPolicy) m["target_origin_id"] = aws.StringValue(cb.TargetOriginId) m["min_ttl"] = int(aws.Int64Value(cb.MinTTL)) + m["origin_request_policy_id"] = aws.StringValue(cb.OriginRequestPolicyId) if cb.ForwardedValues != nil { m["forwarded_values"] = []interface{}{flattenForwardedValues(cb.ForwardedValues)} diff --git a/aws/cloudfront_distribution_configuration_structure_test.go b/aws/cloudfront_distribution_configuration_structure_test.go index c3e38114616..61659ef7577 100644 --- a/aws/cloudfront_distribution_configuration_structure_test.go +++ b/aws/cloudfront_distribution_configuration_structure_test.go @@ -21,6 +21,7 @@ func defaultCacheBehaviorConf() map[string]interface{} { "smooth_streaming": false, "default_ttl": 86400, "allowed_methods": allowedMethodsConf(), + "origin_request_policy_id": "ABCD1234", "cached_methods": cachedMethodsConf(), "compress": true, "field_level_encryption_id": "", diff --git a/aws/cloudfront_origin_request_policy_structure.go b/aws/cloudfront_origin_request_policy_structure.go new file mode 100644 index 00000000000..f6faf8176a3 --- /dev/null +++ b/aws/cloudfront_origin_request_policy_structure.go @@ -0,0 +1,180 @@ +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 expandCloudFrontOriginRequestPolicyCookieNames(tfMap map[string]interface{}) *cloudfront.CookieNames { + if tfMap == nil { + return nil + } + + apiObject := &cloudfront.CookieNames{} + + var items []*string + for _, item := range tfMap["items"].(*schema.Set).List() { + items = append(items, aws.String(item.(string))) + } + apiObject.Items = items + apiObject.Quantity = aws.Int64(int64(len(items))) + + return apiObject +} + +func expandCloudFrontOriginRequestPolicyCookiesConfig(tfMap map[string]interface{}) *cloudfront.OriginRequestPolicyCookiesConfig { + if tfMap == nil { + return nil + } + + apiObject := &cloudfront.OriginRequestPolicyCookiesConfig{ + CookieBehavior: aws.String(tfMap["cookie_behavior"].(string)), + } + + if items, ok := tfMap["cookies"].([]interface{}); ok && len(items) == 1 { + apiObject.Cookies = expandCloudFrontOriginRequestPolicyCookieNames(items[0].(map[string]interface{})) + } + + return apiObject +} + +func expandCloudFrontOriginRequestPolicyHeaders(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))) + } + + apiObject := &cloudfront.Headers{ + Items: items, + Quantity: aws.Int64(int64(len(items))), + } + + return apiObject +} + +func expandCloudFrontOriginRequestPolicyHeadersConfig(tfMap map[string]interface{}) *cloudfront.OriginRequestPolicyHeadersConfig { + if tfMap == nil { + return nil + } + + apiObject := &cloudfront.OriginRequestPolicyHeadersConfig{ + HeaderBehavior: aws.String(tfMap["header_behavior"].(string)), + } + + if items, ok := tfMap["headers"].([]interface{}); ok && len(items) == 1 && tfMap["header_behavior"] != "none" { + apiObject.Headers = expandCloudFrontOriginRequestPolicyHeaders(items[0].(map[string]interface{})) + } + + return apiObject +} + +func expandCloudFrontOriginRequestPolicyQueryStringNames(tfMap map[string]interface{}) *cloudfront.QueryStringNames { + if tfMap == nil { + return nil + } + + var items []*string + for _, item := range tfMap["items"].(*schema.Set).List() { + items = append(items, aws.String(item.(string))) + } + + apiObject := &cloudfront.QueryStringNames{ + Items: items, + Quantity: aws.Int64(int64(len(items))), + } + + return apiObject +} + +func expandCloudFrontOriginRequestPolicyQueryStringsConfig(tfMap map[string]interface{}) *cloudfront.OriginRequestPolicyQueryStringsConfig { + if tfMap == nil { + return nil + } + + apiObject := &cloudfront.OriginRequestPolicyQueryStringsConfig{ + QueryStringBehavior: aws.String(tfMap["query_string_behavior"].(string)), + } + + if items, ok := tfMap["query_strings"].([]interface{}); ok && len(items) == 1 { + apiObject.QueryStrings = expandCloudFrontOriginRequestPolicyQueryStringNames(items[0].(map[string]interface{})) + } + + return apiObject +} + +func expandCloudFrontOriginRequestPolicyConfig(d *schema.ResourceData) *cloudfront.OriginRequestPolicyConfig { + apiObject := &cloudfront.OriginRequestPolicyConfig{ + Comment: aws.String(d.Get("comment").(string)), + Name: aws.String(d.Get("name").(string)), + CookiesConfig: expandCloudFrontOriginRequestPolicyCookiesConfig(d.Get("cookies_config").([]interface{})[0].(map[string]interface{})), + HeadersConfig: expandCloudFrontOriginRequestPolicyHeadersConfig(d.Get("headers_config").([]interface{})[0].(map[string]interface{})), + QueryStringsConfig: expandCloudFrontOriginRequestPolicyQueryStringsConfig(d.Get("query_strings_config").([]interface{})[0].(map[string]interface{})), + } + + return apiObject +} + +func flattenCloudFrontOriginRequestPolicyCookiesConfig(cookiesConfig *cloudfront.OriginRequestPolicyCookiesConfig) []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 flattenCloudFrontOriginRequestPolicyHeadersConfig(headersConfig *cloudfront.OriginRequestPolicyHeadersConfig) []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 flattenCloudFrontOriginRequestPolicyQueryStringsConfig(queryStringsConfig *cloudfront.OriginRequestPolicyQueryStringsConfig) []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, + } +} diff --git a/aws/data_source_aws_cloudfront_origin_request_policy.go b/aws/data_source_aws_cloudfront_origin_request_policy.go new file mode 100644 index 00000000000..2656c832b0d --- /dev/null +++ b/aws/data_source_aws_cloudfront_origin_request_policy.go @@ -0,0 +1,161 @@ +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" +) + +func dataSourceAwsCloudFrontOriginRequestPolicy() *schema.Resource { + return &schema.Resource{ + Read: dataSourceAwsCloudFrontOriginRequestPolicyRead, + + Schema: map[string]*schema.Schema{ + "comment": { + Type: schema.TypeString, + Computed: true, + }, + "cookies_config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "cookie_behavior": { + Computed: true, + Type: schema.TypeString, + }, + "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}, + }, + }, + }, + }, + }, + }, + }, + "etag": { + Type: schema.TypeString, + Computed: true, + }, + "headers_config": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "header_behavior": { + Computed: true, + Type: schema.TypeString, + }, + "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}, + }, + }, + }, + }, + }, + }, + }, + "id": { + Type: schema.TypeString, + Optional: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + }, + "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 dataSourceAwsCloudFrontOriginRequestPolicyRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + + if d.Get("id").(string) == "" { + if err := dataSourceAwsCloudFrontOriginRequestPolicyFindByName(d, conn); err != nil { + return fmt.Errorf("Unable to find origin request policy by name: %s", err.Error()) + } + } + + if d.Id() != "" { + request := &cloudfront.GetOriginRequestPolicyInput{ + Id: aws.String(d.Id()), + } + + resp, err := conn.GetOriginRequestPolicy(request) + if err != nil { + return fmt.Errorf("Unable to retrieve origin request policy with ID %s: %s", d.Id(), err.Error()) + } + d.Set("etag", aws.StringValue(resp.ETag)) + + originRequestPolicy := *resp.OriginRequestPolicy.OriginRequestPolicyConfig + d.Set("comment", aws.StringValue(originRequestPolicy.Comment)) + d.Set("name", aws.StringValue(originRequestPolicy.Name)) + d.Set("cookies_config", flattenCloudFrontOriginRequestPolicyCookiesConfig(originRequestPolicy.CookiesConfig)) + d.Set("headers_config", flattenCloudFrontOriginRequestPolicyHeadersConfig(originRequestPolicy.HeadersConfig)) + d.Set("query_strings_config", flattenCloudFrontOriginRequestPolicyQueryStringsConfig(originRequestPolicy.QueryStringsConfig)) + } + + return nil +} + +func dataSourceAwsCloudFrontOriginRequestPolicyFindByName(d *schema.ResourceData, conn *cloudfront.CloudFront) error { + var originRequestPolicy *cloudfront.OriginRequestPolicy + request := &cloudfront.ListOriginRequestPoliciesInput{} + resp, err := conn.ListOriginRequestPolicies(request) + if err != nil { + return err + } + + for _, policySummary := range resp.OriginRequestPolicyList.Items { + if *policySummary.OriginRequestPolicy.OriginRequestPolicyConfig.Name == d.Get("name").(string) { + originRequestPolicy = policySummary.OriginRequestPolicy + break + } + } + + if originRequestPolicy != nil { + d.SetId(aws.StringValue(originRequestPolicy.Id)) + } + return nil +} diff --git a/aws/data_source_aws_cloudfront_origin_request_policy_test.go b/aws/data_source_aws_cloudfront_origin_request_policy_test.go new file mode 100644 index 00000000000..10b55921ba3 --- /dev/null +++ b/aws/data_source_aws_cloudfront_origin_request_policy_test.go @@ -0,0 +1,65 @@ +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 TestAccAWSCloudFrontDataSourceOriginRequestPolicy_basic(t *testing.T) { + rInt := acctest.RandInt() + dataSourceName := "data.aws_cloudfront_origin_request_policy.example" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontDataSourceOriginRequestPolicyConfig(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(dataSourceName, "comment", "test comment"), + resource.TestCheckResourceAttr(dataSourceName, "cookies_config.0.cookie_behavior", "whitelist"), + resource.TestCheckResourceAttr(dataSourceName, "cookies_config.0.cookies.0.items.0", "test"), + resource.TestCheckResourceAttr(dataSourceName, "headers_config.0.header_behavior", "whitelist"), + resource.TestCheckResourceAttr(dataSourceName, "headers_config.0.headers.0.items.0", "test"), + resource.TestCheckResourceAttr(dataSourceName, "query_strings_config.0.query_string_behavior", "whitelist"), + resource.TestCheckResourceAttr(dataSourceName, "query_strings_config.0.query_strings.0.items.0", "test"), + ), + }, + }, + }) +} +func testAccAWSCloudFrontDataSourceOriginRequestPolicyConfig(rInt int) string { + return fmt.Sprintf(` +data "aws_cloudfront_origin_request_policy" "example" { + name = aws_cloudfront_origin_request_policy.example.name +} + +resource "aws_cloudfront_origin_request_policy" "example" { + 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"] + } + } +} +`, rInt) +} diff --git a/aws/provider.go b/aws/provider.go index 14740ee83be..be2f297a3ad 100644 --- a/aws/provider.go +++ b/aws/provider.go @@ -191,6 +191,7 @@ func Provider() *schema.Provider { "aws_cloudformation_export": dataSourceAwsCloudFormationExport(), "aws_cloudformation_stack": dataSourceAwsCloudFormationStack(), "aws_cloudfront_distribution": dataSourceAwsCloudFrontDistribution(), + "aws_cloudfront_origin_request_policy": dataSourceAwsCloudFrontOriginRequestPolicy(), "aws_cloudhsm_v2_cluster": dataSourceCloudHsmV2Cluster(), "aws_cloudtrail_service_account": dataSourceAwsCloudTrailServiceAccount(), "aws_cloudwatch_log_group": dataSourceAwsCloudwatchLogGroup(), @@ -487,6 +488,7 @@ func Provider() *schema.Provider { "aws_cloudformation_stack_set_instance": resourceAwsCloudFormationStackSetInstance(), "aws_cloudfront_distribution": resourceAwsCloudFrontDistribution(), "aws_cloudfront_origin_access_identity": resourceAwsCloudFrontOriginAccessIdentity(), + "aws_cloudfront_origin_request_policy": resourceAwsCloudFrontOriginRequestPolicy(), "aws_cloudfront_public_key": resourceAwsCloudFrontPublicKey(), "aws_cloudtrail": resourceAwsCloudTrail(), "aws_cloudwatch_event_bus": resourceAwsCloudWatchEventBus(), diff --git a/aws/resource_aws_cloudfront_distribution.go b/aws/resource_aws_cloudfront_distribution.go index 68e900ef6d3..f63cfd2745e 100644 --- a/aws/resource_aws_cloudfront_distribution.go +++ b/aws/resource_aws_cloudfront_distribution.go @@ -151,6 +151,10 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Optional: true, Default: 0, }, + "origin_request_policy_id": { + Type: schema.TypeString, + Optional: true, + }, "path_pattern": { Type: schema.TypeString, Required: true, @@ -313,6 +317,10 @@ func resourceAwsCloudFrontDistribution() *schema.Resource { Optional: true, Default: 0, }, + "origin_request_policy_id": { + Type: schema.TypeString, + Optional: true, + }, "smooth_streaming": { Type: schema.TypeBool, Optional: true, diff --git a/aws/resource_aws_cloudfront_distribution_test.go b/aws/resource_aws_cloudfront_distribution_test.go index 0f1fa7964eb..29badfe2ce8 100644 --- a/aws/resource_aws_cloudfront_distribution_test.go +++ b/aws/resource_aws_cloudfront_distribution_test.go @@ -212,6 +212,31 @@ func TestAccAWSCloudFrontDistribution_customOrigin(t *testing.T) { }) } +func TestAccAWSCloudFrontDistribution_originPolicy(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, + Check: resource.ComposeTestCheckFunc( + resource.TestMatchResourceAttr("aws_cloudfront_distribution.custom_distribution", "default_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. // @@ -1363,6 +1388,125 @@ resource "aws_cloudfront_distribution" "custom_distribution" { } `, acctest.RandInt(), logBucket, testAccAWSCloudFrontDistributionRetainConfig()) +var testAccAWSCloudFrontDistributionOriginRequestPolicyConfig = 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 { + 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 + + forwarded_values { + query_string = false + + cookies { + forward = "all" + } + } + + 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 testAccAWSCloudFrontDistributionMultiOriginConfig = fmt.Sprintf(` variable rand_id { default = %d diff --git a/aws/resource_aws_cloudfront_origin_request_policy.go b/aws/resource_aws_cloudfront_origin_request_policy.go new file mode 100644 index 00000000000..0b5b295302a --- /dev/null +++ b/aws/resource_aws_cloudfront_origin_request_policy.go @@ -0,0 +1,205 @@ +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" +) + +func resourceAwsCloudFrontOriginRequestPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsCloudFrontOriginRequestPolicyCreate, + Read: resourceAwsCloudFrontOriginRequestPolicyRead, + Update: resourceAwsCloudFrontOriginRequestPolicyUpdate, + Delete: resourceAwsCloudFrontOriginRequestPolicyDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "comment": { + Type: schema.TypeString, + Optional: true, + }, + "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", "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}, + }, + }, + }, + }, + }, + }, + }, + "etag": { + Type: schema.TypeString, + Optional: true, + Computed: 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", "allViewer", "allViewerAndWhitelistCloudFront"}, 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}, + }, + }, + }, + }, + }, + }, + }, + "name": { + Type: schema.TypeString, + Required: true, + }, + "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 resourceAwsCloudFrontOriginRequestPolicyCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + + request := &cloudfront.CreateOriginRequestPolicyInput{ + OriginRequestPolicyConfig: expandCloudFrontOriginRequestPolicyConfig(d), + } + + resp, err := conn.CreateOriginRequestPolicy(request) + + if err != nil { + return err + } + + d.SetId(aws.StringValue(resp.OriginRequestPolicy.Id)) + + return resourceAwsCloudFrontOriginRequestPolicyRead(d, meta) +} + +func resourceAwsCloudFrontOriginRequestPolicyRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + request := &cloudfront.GetOriginRequestPolicyInput{ + Id: aws.String(d.Id()), + } + + resp, err := conn.GetOriginRequestPolicy(request) + if !d.IsNewResource() && tfawserr.ErrCodeEquals(err, "ResourceNotFoundException") { + log.Printf("[WARN] CloudFront Origin Request Policy (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return err + } + d.Set("etag", aws.StringValue(resp.ETag)) + + originRequestPolicy := *resp.OriginRequestPolicy.OriginRequestPolicyConfig + d.Set("comment", aws.StringValue(originRequestPolicy.Comment)) + d.Set("name", aws.StringValue(originRequestPolicy.Name)) + d.Set("cookies_config", flattenCloudFrontOriginRequestPolicyCookiesConfig(originRequestPolicy.CookiesConfig)) + d.Set("headers_config", flattenCloudFrontOriginRequestPolicyHeadersConfig(originRequestPolicy.HeadersConfig)) + d.Set("query_strings_config", flattenCloudFrontOriginRequestPolicyQueryStringsConfig(originRequestPolicy.QueryStringsConfig)) + + return nil +} + +func resourceAwsCloudFrontOriginRequestPolicyUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + + request := &cloudfront.UpdateOriginRequestPolicyInput{ + OriginRequestPolicyConfig: expandCloudFrontOriginRequestPolicyConfig(d), + Id: aws.String(d.Id()), + IfMatch: aws.String(d.Get("etag").(string)), + } + + _, err := conn.UpdateOriginRequestPolicy(request) + if err != nil { + return err + } + + return resourceAwsCloudFrontOriginRequestPolicyRead(d, meta) +} + +func resourceAwsCloudFrontOriginRequestPolicyDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).cloudfrontconn + + request := &cloudfront.DeleteOriginRequestPolicyInput{ + Id: aws.String(d.Id()), + IfMatch: aws.String(d.Get("etag").(string)), + } + + _, err := conn.DeleteOriginRequestPolicy(request) + if err != nil { + if isAWSErr(err, cloudfront.ErrCodeNoSuchOriginRequestPolicy, "") { + return nil + } + return err + } + + return nil +} diff --git a/aws/resource_aws_cloudfront_origin_request_policy_test.go b/aws/resource_aws_cloudfront_origin_request_policy_test.go new file mode 100644 index 00000000000..e9bf7d1619f --- /dev/null +++ b/aws/resource_aws_cloudfront_origin_request_policy_test.go @@ -0,0 +1,182 @@ +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 TestAccAWSCloudFrontOriginRequestPolicy_basic(t *testing.T) { + rInt := acctest.RandInt() + resourceName := "aws_cloudfront_origin_request_policy.example" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontOriginRequestPolicyConfig(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "comment", "test comment"), + resource.TestCheckResourceAttr(resourceName, "cookies_config.0.cookie_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "cookies_config.0.cookies.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "headers_config.0.header_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "headers_config.0.headers.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "query_strings_config.0.query_string_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "query_strings_config.0.query_strings.0.items.0", "test"), + ), + }, + { + ResourceName: "aws_cloudfront_origin_request_policy.example", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func TestAccAWSCloudFrontOriginRequestPolicy_update(t *testing.T) { + rInt := acctest.RandInt() + resourceName := "aws_cloudfront_origin_request_policy.example" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontOriginRequestPolicyConfig(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "comment", "test comment"), + resource.TestCheckResourceAttr(resourceName, "cookies_config.0.cookie_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "cookies_config.0.cookies.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "headers_config.0.header_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "headers_config.0.headers.0.items.0", "test"), + resource.TestCheckResourceAttr(resourceName, "query_strings_config.0.query_string_behavior", "whitelist"), + resource.TestCheckResourceAttr(resourceName, "query_strings_config.0.query_strings.0.items.0", "test"), + ), + }, + { + Config: testAccAWSCloudFrontOriginRequestPolicyConfigUpdate(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "comment", "test comment updated"), + resource.TestCheckResourceAttr(resourceName, "cookies_config.0.cookies.0.items.0", "test2"), + resource.TestCheckResourceAttr(resourceName, "headers_config.0.header_behavior", "none"), + resource.TestCheckResourceAttr(resourceName, "headers_config.0.headers.#", "0"), + resource.TestCheckResourceAttr(resourceName, "query_strings_config.0.query_strings.0.items.0", "test2"), + ), + }, + { + ResourceName: "aws_cloudfront_origin_request_policy.example", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func TestAccAWSCloudFrontOriginRequestPolicy_noneBehavior(t *testing.T) { + rInt := acctest.RandInt() + resourceName := "aws_cloudfront_origin_request_policy.example" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t); testAccPartitionHasServicePreCheck(cloudfront.EndpointsID, t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckCloudFrontPublicKeyDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAWSCloudFrontOriginRequestPolicyConfigNoneBehavior(rInt), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(resourceName, "comment", "test comment"), + resource.TestCheckResourceAttr(resourceName, "cookies_config.0.cookie_behavior", "none"), + resource.TestCheckResourceAttr(resourceName, "cookies_config.0.cookies.#", "0"), + resource.TestCheckResourceAttr(resourceName, "headers_config.0.header_behavior", "none"), + resource.TestCheckResourceAttr(resourceName, "headers_config.0.headers.#", "0"), + resource.TestCheckResourceAttr(resourceName, "query_strings_config.0.query_string_behavior", "none"), + resource.TestCheckResourceAttr(resourceName, "query_strings_config.0.query_strings.#", "0"), + ), + }, + { + ResourceName: "aws_cloudfront_origin_request_policy.example", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{}, + }, + }, + }) +} + +func testAccAWSCloudFrontOriginRequestPolicyConfig(rInt int) string { + return fmt.Sprintf(` +resource "aws_cloudfront_origin_request_policy" "example" { + 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"] + } + } +} +`, rInt) +} + +func testAccAWSCloudFrontOriginRequestPolicyConfigUpdate(rInt int) string { + return fmt.Sprintf(` +resource "aws_cloudfront_origin_request_policy" "example" { + name = "test-policy-updated%[1]d" + comment = "test comment updated" + cookies_config { + cookie_behavior = "whitelist" + cookies { + items = ["test2"] + } + } + headers_config { + header_behavior = "none" + } + query_strings_config { + query_string_behavior = "whitelist" + query_strings { + items = ["test2"] + } + } +} +`, rInt) +} + +func testAccAWSCloudFrontOriginRequestPolicyConfigNoneBehavior(rInt int) string { + return fmt.Sprintf(` +resource "aws_cloudfront_origin_request_policy" "example" { + name = "test-policy-updated%[1]d" + comment = "test comment" + cookies_config { + cookie_behavior = "none" + } + headers_config { + header_behavior = "none" + } + query_strings_config { + query_string_behavior = "none" + } +} +`, rInt) +} diff --git a/website/docs/d/cloudfront_origin_request_policy.html.markdown b/website/docs/d/cloudfront_origin_request_policy.html.markdown new file mode 100644 index 00000000000..4e25a4ea5a1 --- /dev/null +++ b/website/docs/d/cloudfront_origin_request_policy.html.markdown @@ -0,0 +1,54 @@ +--- +subcategory: "CloudFront" +layout: "aws" +page_title: "AWS: aws_cloudfront_origin_request_policy" +description: |- + Determines the values that CloudFront includes in requests that it sends to the origin. +--- + +# Data Source: aws_cloudfront_origin_request_policy + +## Example Usage + +The following example below creates a CloudFront origin request policy. + +```hcl +data "aws_cloudfront_origin_request_policy" "example" { + name = "example-policy" +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - Unique name to identify the origin request policy. +* `id` - The identifier for the origin request policy. + +## Attributes Reference + +* `comment` - Comment to describe the origin request policy. +* `cookies_config` - Object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the origin request key and automatically included in requests that CloudFront sends to the origin. See [Cookies Config](#cookies-config) for more information. +* `etag` - The current version of the origin request policy. +* `headers_config` - Object that determines whether any HTTP headers (and if so, which headers) are included in the origin request 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 origin request key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. + +### Cookies Config + +`cookie_behavior` - Determines whether any cookies in viewer requests are included in the origin request key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist` `all`. +`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 origin request key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allViewer`, `allViewerAndWhitelistCloudFront`. +`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 origin request key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `all`. +`query_strings` - Object that contains a list of query string names. See [Items](#items) for more information. + +### Items + +`items` - List of item names (cookies, headers, or query strings). diff --git a/website/docs/r/cloudfront_origin_request_policy.html.markdown b/website/docs/r/cloudfront_origin_request_policy.html.markdown new file mode 100644 index 00000000000..e92e370dcd2 --- /dev/null +++ b/website/docs/r/cloudfront_origin_request_policy.html.markdown @@ -0,0 +1,75 @@ +--- +subcategory: "CloudFront" +layout: "aws" +page_title: "AWS: aws_cloudfront_origin_request_policy" +description: |- + Determines the values that CloudFront includes in requests that it sends to the origin. +--- + +# Resource: aws_cloudfront_origin_request_policy + +## Example Usage + +The following example below creates a CloudFront origin request policy. + +```hcl +resource "aws_cloudfront_origin_request_policy" "example" { + name = "example-policy" + comment = "example comment" + 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) Unique name to identify the origin request policy. +* `comment` - (Optional) Comment to describe the origin request policy. +* `cookies_config` - (Required) Object that determines whether any cookies in viewer requests (and if so, which cookies) are included in the origin request 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 origin request 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 origin request key and automatically included in requests that CloudFront sends to the origin. See [Query Strings Config](#query-strings-config) for more information. + +### Cookies Config + +`cookie_behavior` - (Required) Determines whether any cookies in viewer requests are included in the origin request key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist` `all`. +`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 origin request key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `allViewer`, `allViewerAndWhitelistCloudFront`. +`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 origin request key and automatically included in requests that CloudFront sends to the origin. Valid values are `none`, `whitelist`, `all`. +`query_strings` - (Optional) Object that contains a list of query string names. See [Items](#items) for more information. + +### Items + +`items` - (Required) 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 origin request policy. +* `id` - The identifier for the origin request policy.