From 84216dc87fcecc2c91397f2c3b0de8b43f7b31e8 Mon Sep 17 00:00:00 2001 From: jhsinger-klotho <111291520+jhsinger-klotho@users.noreply.github.com> Date: Fri, 26 Jan 2024 16:25:45 -0500 Subject: [PATCH] Cdn behaviors (#899) --- pkg/engine2/solution_context.go | 20 +++- .../testdata/cf_distribution.expect.yaml | 4 +- .../same_path_multiple_methods.expect.yaml | 8 ++ .../same_path_multiple_methods.iac-viz.yaml | 44 ++++---- pkg/engine2/testdata/static_site.expect.yaml | 3 +- .../aws/cloudfront_distribution/factory.ts | 16 ++- pkg/knowledge_base2/dynamic_value.go | 14 +++ pkg/knowledge_base2/edge_template.go | 4 + pkg/knowledge_base2/graph.go | 2 + .../properties/int_property.go | 17 +++ .../properties/int_property_test.go | 40 +++++++ .../properties/map_property.go | 10 ++ .../properties/map_property_test.go | 37 +++++++ .../aws/edges/api_deployment-rest_api.yaml | 1 + .../cloudfront_distribution-api_stage.yaml | 58 ++++++++++ .../resources/cloudfront_distribution.yaml | 103 +++++++++++++++++- 16 files changed, 351 insertions(+), 30 deletions(-) diff --git a/pkg/engine2/solution_context.go b/pkg/engine2/solution_context.go index 29aa04c2e..909676390 100644 --- a/pkg/engine2/solution_context.go +++ b/pkg/engine2/solution_context.go @@ -2,6 +2,7 @@ package engine2 import ( "errors" + "fmt" construct "github.com/klothoplatform/klotho/pkg/construct2" "github.com/klothoplatform/klotho/pkg/engine2/constraints" @@ -90,9 +91,26 @@ func (ctx solutionContext) LoadGraph(graph construct.Graph) error { if err := op.AddVerticesFrom(graph); err != nil { return err } - if err := raw.AddEdgesFrom(graph); err != nil { + + edges, err := graph.Edges() + if err != nil { return err } + for _, edge := range edges { + edgeTemplate := ctx.KB.GetEdgeTemplate(edge.Source, edge.Target) + if edgeTemplate == nil { + return fmt.Errorf("edge template %s -> %s not found", edge.Source, edge.Target) + } + if edgeTemplate.AlwaysProcess { + if err := op.AddEdge(edge.Source, edge.Target); err != nil { + return err + } + } else { + if err := raw.AddEdge(edge.Source, edge.Target); err != nil { + return err + } + } + } // ensure any deployment dependencies due to properties are in place return construct.WalkGraph(ctx.RawView(), func(id construct.ResourceId, resource *construct.Resource, nerr error) error { diff --git a/pkg/engine2/testdata/cf_distribution.expect.yaml b/pkg/engine2/testdata/cf_distribution.expect.yaml index ce7203951..6382a5a96 100755 --- a/pkg/engine2/testdata/cf_distribution.expect.yaml +++ b/pkg/engine2/testdata/cf_distribution.expect.yaml @@ -1,6 +1,8 @@ resources: aws:cloudfront_distribution:cloudfront_distribution_2: - CloudfrontDefaultCertificate: true + ViewerCertificate: + CloudfrontDefaultCertificate: true + CacheBehaviors: [] DefaultCacheBehavior: AllowedMethods: - DELETE diff --git a/pkg/engine2/testdata/same_path_multiple_methods.expect.yaml b/pkg/engine2/testdata/same_path_multiple_methods.expect.yaml index ed24188f1..4c30f82aa 100644 --- a/pkg/engine2/testdata/same_path_multiple_methods.expect.yaml +++ b/pkg/engine2/testdata/same_path_multiple_methods.expect.yaml @@ -8,6 +8,10 @@ resources: Triggers: rest_api_0_integration_0: rest_api_0_integration_0 rest_api_0_integration_0_method: rest_api_0_integration_0_method + rest_api_0_integration_1: rest_api_0_integration_1 + rest_api_0_integration_1_method: rest_api_0_integration_1_method + rest_api_0_integration_2: rest_api_0_integration_2 + rest_api_0_integration_2_method: rest_api_0_integration_2_method aws:rest_api:rest_api_0: BinaryMediaTypes: - application/octet-stream @@ -64,7 +68,11 @@ edges: aws:api_stage:rest_api_0:api_stage-0 -> aws:api_deployment:rest_api_0:api_deployment-0: aws:api_stage:rest_api_0:api_stage-0 -> aws:rest_api:rest_api_0: aws:api_deployment:rest_api_0:api_deployment-0 -> aws:api_integration:rest_api_0:rest_api_0_integration_0: + aws:api_deployment:rest_api_0:api_deployment-0 -> aws:api_integration:rest_api_0:rest_api_0_integration_1: + aws:api_deployment:rest_api_0:api_deployment-0 -> aws:api_integration:rest_api_0:rest_api_0_integration_2: aws:api_deployment:rest_api_0:api_deployment-0 -> aws:api_method:rest_api_0:rest_api_0_integration_0_method: + aws:api_deployment:rest_api_0:api_deployment-0 -> aws:api_method:rest_api_0:rest_api_0_integration_1_method: + aws:api_deployment:rest_api_0:api_deployment-0 -> aws:api_method:rest_api_0:rest_api_0_integration_2_method: aws:api_deployment:rest_api_0:api_deployment-0 -> aws:rest_api:rest_api_0: aws:rest_api:rest_api_0 -> aws:api_integration:rest_api_0:rest_api_0_integration_0: aws:rest_api:rest_api_0 -> aws:api_integration:rest_api_0:rest_api_0_integration_1: diff --git a/pkg/engine2/testdata/same_path_multiple_methods.iac-viz.yaml b/pkg/engine2/testdata/same_path_multiple_methods.iac-viz.yaml index fdeb48c3c..7a70ea924 100644 --- a/pkg/engine2/testdata/same_path_multiple_methods.iac-viz.yaml +++ b/pkg/engine2/testdata/same_path_multiple_methods.iac-viz.yaml @@ -5,42 +5,46 @@ resources: aws:api_resource:rest_api_0/api_resource-1: aws:api_resource:rest_api_0/api_resource-1 -> rest_api/rest_api_0: + aws:api_resource:rest_api_0/api_resource-2: + + aws:api_resource:rest_api_0/api_resource-2 -> rest_api/rest_api_0: aws:api_method:rest_api_0/rest_api_0_integration_0_method: aws:api_method:rest_api_0/rest_api_0_integration_0_method -> aws:api_resource:rest_api_0/api_resource-1: aws:api_method:rest_api_0/rest_api_0_integration_0_method -> rest_api/rest_api_0: + aws:api_method:rest_api_0/rest_api_0_integration_1_method: + + aws:api_method:rest_api_0/rest_api_0_integration_1_method -> aws:api_resource:rest_api_0/api_resource-2: + aws:api_method:rest_api_0/rest_api_0_integration_1_method -> rest_api/rest_api_0: + aws:api_method:rest_api_0/rest_api_0_integration_2_method: + + aws:api_method:rest_api_0/rest_api_0_integration_2_method -> aws:api_resource:rest_api_0/api_resource-2: + aws:api_method:rest_api_0/rest_api_0_integration_2_method -> rest_api/rest_api_0: aws:api_integration:rest_api_0/rest_api_0_integration_0: aws:api_integration:rest_api_0/rest_api_0_integration_0 -> aws:api_method:rest_api_0/rest_api_0_integration_0_method: aws:api_integration:rest_api_0/rest_api_0_integration_0 -> aws:api_resource:rest_api_0/api_resource-1: aws:api_integration:rest_api_0/rest_api_0_integration_0 -> rest_api/rest_api_0: - aws:api_resource:rest_api_0/api_resource-2: + aws:api_integration:rest_api_0/rest_api_0_integration_1: - aws:api_resource:rest_api_0/api_resource-2 -> rest_api/rest_api_0: + aws:api_integration:rest_api_0/rest_api_0_integration_1 -> aws:api_method:rest_api_0/rest_api_0_integration_1_method: + aws:api_integration:rest_api_0/rest_api_0_integration_1 -> aws:api_resource:rest_api_0/api_resource-2: + aws:api_integration:rest_api_0/rest_api_0_integration_1 -> rest_api/rest_api_0: + aws:api_integration:rest_api_0/rest_api_0_integration_2: + + aws:api_integration:rest_api_0/rest_api_0_integration_2 -> aws:api_method:rest_api_0/rest_api_0_integration_2_method: + aws:api_integration:rest_api_0/rest_api_0_integration_2 -> aws:api_resource:rest_api_0/api_resource-2: + aws:api_integration:rest_api_0/rest_api_0_integration_2 -> rest_api/rest_api_0: aws:api_deployment:rest_api_0/api_deployment-0: aws:api_deployment:rest_api_0/api_deployment-0 -> aws:api_integration:rest_api_0/rest_api_0_integration_0: + aws:api_deployment:rest_api_0/api_deployment-0 -> aws:api_integration:rest_api_0/rest_api_0_integration_1: + aws:api_deployment:rest_api_0/api_deployment-0 -> aws:api_integration:rest_api_0/rest_api_0_integration_2: aws:api_deployment:rest_api_0/api_deployment-0 -> aws:api_method:rest_api_0/rest_api_0_integration_0_method: + aws:api_deployment:rest_api_0/api_deployment-0 -> aws:api_method:rest_api_0/rest_api_0_integration_1_method: + aws:api_deployment:rest_api_0/api_deployment-0 -> aws:api_method:rest_api_0/rest_api_0_integration_2_method: aws:api_deployment:rest_api_0/api_deployment-0 -> rest_api/rest_api_0: - aws:api_method:rest_api_0/rest_api_0_integration_2_method: - - aws:api_method:rest_api_0/rest_api_0_integration_2_method -> aws:api_resource:rest_api_0/api_resource-2: - aws:api_method:rest_api_0/rest_api_0_integration_2_method -> rest_api/rest_api_0: - aws:api_method:rest_api_0/rest_api_0_integration_1_method: - - aws:api_method:rest_api_0/rest_api_0_integration_1_method -> aws:api_resource:rest_api_0/api_resource-2: - aws:api_method:rest_api_0/rest_api_0_integration_1_method -> rest_api/rest_api_0: aws:api_stage:rest_api_0/api_stage-0: aws:api_stage:rest_api_0/api_stage-0 -> aws:api_deployment:rest_api_0/api_deployment-0: aws:api_stage:rest_api_0/api_stage-0 -> rest_api/rest_api_0: - aws:api_integration:rest_api_0/rest_api_0_integration_2: - - aws:api_integration:rest_api_0/rest_api_0_integration_2 -> aws:api_method:rest_api_0/rest_api_0_integration_2_method: - aws:api_integration:rest_api_0/rest_api_0_integration_2 -> aws:api_resource:rest_api_0/api_resource-2: - aws:api_integration:rest_api_0/rest_api_0_integration_2 -> rest_api/rest_api_0: - aws:api_integration:rest_api_0/rest_api_0_integration_1: - - aws:api_integration:rest_api_0/rest_api_0_integration_1 -> aws:api_method:rest_api_0/rest_api_0_integration_1_method: - aws:api_integration:rest_api_0/rest_api_0_integration_1 -> aws:api_resource:rest_api_0/api_resource-2: - aws:api_integration:rest_api_0/rest_api_0_integration_1 -> rest_api/rest_api_0: diff --git a/pkg/engine2/testdata/static_site.expect.yaml b/pkg/engine2/testdata/static_site.expect.yaml index b9f8e2917..c0b92a69e 100755 --- a/pkg/engine2/testdata/static_site.expect.yaml +++ b/pkg/engine2/testdata/static_site.expect.yaml @@ -1,6 +1,7 @@ resources: aws:cloudfront_distribution:cloudfront_distribution_1: - CloudfrontDefaultCertificate: true + ViewerCertificate: + CloudfrontDefaultCertificate: true DefaultCacheBehavior: AllowedMethods: - DELETE diff --git a/pkg/infra/iac3/templates/aws/cloudfront_distribution/factory.ts b/pkg/infra/iac3/templates/aws/cloudfront_distribution/factory.ts index 5692f3b6c..e80a7c574 100644 --- a/pkg/infra/iac3/templates/aws/cloudfront_distribution/factory.ts +++ b/pkg/infra/iac3/templates/aws/cloudfront_distribution/factory.ts @@ -4,11 +4,14 @@ import * as pulumi from '@pulumi/pulumi' interface Args { Name: string Origins: aws.types.input.cloudfront.DistributionOrigin[] - CloudfrontDefaultCertificate: boolean + ViewerCertificate: aws.types.input.cloudfront.DistributionViewerCertificate Enabled: boolean DefaultCacheBehavior: aws.types.input.cloudfront.DistributionDefaultCacheBehavior + CacheBehaviors: aws.types.input.cloudfront.DistributionCacheBehavior[] Restrictions: aws.types.input.cloudfront.DistributionRestrictions DefaultRootObject: string + CNAMEs: string[] + CustomErrorResponses: aws.types.input.cloudfront.DistributionCustomErrorResponse[] } // noinspection JSUnusedLocalSymbols @@ -16,9 +19,14 @@ function create(args: Args): aws.cloudfront.Distribution { return new aws.cloudfront.Distribution(args.Name, { origins: args.Origins, enabled: args.Enabled, - viewerCertificate: { - cloudfrontDefaultCertificate: args.CloudfrontDefaultCertificate, - }, + viewerCertificate: args.ViewerCertificate, + orderedCacheBehaviors: args.CacheBehaviors, + //TMPL {{- if .CNAMEs }} + aliases: args.CNAMEs, + //TMPL {{- end }} + //TMPL {{- if .CustomErrorResponses }} + customErrorResponses: args.CustomErrorResponses, + //TMPL {{- end }} //TMPL {{- if (index .DefaultCacheBehavior "targetOriginId") }} defaultCacheBehavior: args.DefaultCacheBehavior, //TMPL {{- else }} diff --git a/pkg/knowledge_base2/dynamic_value.go b/pkg/knowledge_base2/dynamic_value.go index 0878337f2..052be5657 100644 --- a/pkg/knowledge_base2/dynamic_value.go +++ b/pkg/knowledge_base2/dynamic_value.go @@ -90,6 +90,20 @@ func (ctx DynamicValueContext) TemplateFunctions() template.FuncMap { "add": add, "sub": sub, "last": last, + "makeSlice": func() []any { + return []any{} + }, + "appendSlice": func(slice []any, value any) []any { + return append(slice, value) + }, + "sliceContains": func(slice []any, value any) bool { + for _, v := range slice { + if v == value { + return true + } + } + return false + }, } } diff --git a/pkg/knowledge_base2/edge_template.go b/pkg/knowledge_base2/edge_template.go index ab073888b..afbdbcc05 100644 --- a/pkg/knowledge_base2/edge_template.go +++ b/pkg/knowledge_base2/edge_template.go @@ -12,6 +12,10 @@ type ( Source construct.ResourceId `yaml:"source"` Target construct.ResourceId `yaml:"target"` + // AlwaysProcess signals that the edge should always be processed even if the source and target exist in the input graph + // currently we dont check edges for operational rules if they previously existed and this flag is set to false + AlwaysProcess bool `yaml:"always_process"` + // DirectEdgeOnly signals that the edge cannot be used within constructing other paths // and can only be used as a direct edge DirectEdgeOnly bool `yaml:"direct_edge_only"` diff --git a/pkg/knowledge_base2/graph.go b/pkg/knowledge_base2/graph.go index b899d4f99..1409e37f9 100644 --- a/pkg/knowledge_base2/graph.go +++ b/pkg/knowledge_base2/graph.go @@ -112,11 +112,13 @@ func firstFunctional( func allDeps( ids set.Set[construct.ResourceId], ) graph_addons.WalkGraphFunc[construct.ResourceId] { + resourceSet := set.Set[construct.ResourceId]{} return func(path graph_addons.Path[construct.ResourceId], nerr error) error { id := path[len(path)-1] if ids != nil { ids.Add(id) } + resourceSet.Add(id) return nil } } diff --git a/pkg/knowledge_base2/properties/int_property.go b/pkg/knowledge_base2/properties/int_property.go index c8d18ae44..79abbced1 100644 --- a/pkg/knowledge_base2/properties/int_property.go +++ b/pkg/knowledge_base2/properties/int_property.go @@ -2,6 +2,7 @@ package properties import ( "fmt" + "math" construct "github.com/klothoplatform/klotho/pkg/construct2" knowledgebase "github.com/klothoplatform/klotho/pkg/knowledge_base2" @@ -57,6 +58,7 @@ func (i *IntProperty) GetDefaultValue(ctx knowledgebase.DynamicContext, data kno } func (i *IntProperty) Parse(value any, ctx knowledgebase.DynamicContext, data knowledgebase.DynamicValueData) (any, error) { + if val, ok := value.(string); ok { var result int err := ctx.ExecuteDecode(val, data, &result) @@ -65,6 +67,21 @@ func (i *IntProperty) Parse(value any, ctx knowledgebase.DynamicContext, data kn if val, ok := value.(int); ok { return val, nil } + EPSILON := 0.0000001 + if val, ok := value.(float32); ok { + ival := int(val) + if math.Abs(float64(val)-float64(ival)) > EPSILON { + return 0, fmt.Errorf("cannot convert non-integral float to int: %f", val) + } + return int(val), nil + + } else if val, ok := value.(float64); ok { + ival := int(val) + if math.Abs(val-float64(ival)) > EPSILON { + return 0, fmt.Errorf("cannot convert non-integral float to int: %f", val) + } + return int(val), nil + } val, err := ParsePropertyRef(value, ctx, data) if err == nil { return val, nil diff --git a/pkg/knowledge_base2/properties/int_property_test.go b/pkg/knowledge_base2/properties/int_property_test.go index 1f95eb94d..6fcf90065 100644 --- a/pkg/knowledge_base2/properties/int_property_test.go +++ b/pkg/knowledge_base2/properties/int_property_test.go @@ -157,6 +157,46 @@ func Test_IntProperty_Parse(t *testing.T) { value: "{{ 1 }}", expected: 1, }, + { + name: "valid float32 property", + property: &IntProperty{ + PropertyDetails: knowledgebase2.PropertyDetails{ + Path: "test", + }, + }, + value: float32(1.0), + expected: 1, + }, + { + name: "invalid float32 property", + property: &IntProperty{ + PropertyDetails: knowledgebase2.PropertyDetails{ + Path: "test", + }, + }, + value: float32(1.1), + wantErr: true, + }, + { + name: "valid float64 property", + property: &IntProperty{ + PropertyDetails: knowledgebase2.PropertyDetails{ + Path: "test", + }, + }, + value: float64(1.0), + expected: 1, + }, + { + name: "invalid float64 property", + property: &IntProperty{ + PropertyDetails: knowledgebase2.PropertyDetails{ + Path: "test", + }, + }, + value: float64(1.1), + wantErr: true, + }, { name: "non int property", property: &IntProperty{ diff --git a/pkg/knowledge_base2/properties/map_property.go b/pkg/knowledge_base2/properties/map_property.go index 7a3fe8a98..0cfd3dabf 100644 --- a/pkg/knowledge_base2/properties/map_property.go +++ b/pkg/knowledge_base2/properties/map_property.go @@ -112,6 +112,16 @@ func (m *MapProperty) Parse(value any, ctx knowledgebase.DynamicContext, data kn continue } result[key] = val + } else { + val, err := prop.GetDefaultValue(ctx, data) + if err != nil { + errs = errors.Join(errs, fmt.Errorf("unable to get default value for sub property %s: %w", key, err)) + continue + } + if val == nil { + continue + } + result[key] = val } } } diff --git a/pkg/knowledge_base2/properties/map_property_test.go b/pkg/knowledge_base2/properties/map_property_test.go index 31f0a5ea9..ff696d058 100644 --- a/pkg/knowledge_base2/properties/map_property_test.go +++ b/pkg/knowledge_base2/properties/map_property_test.go @@ -399,6 +399,43 @@ func Test_MapProperty_Parse(t *testing.T) { "value": "Name", }, }, + { + name: "parses sub properties", + property: &MapProperty{ + Properties: knowledgebase2.Properties{ + "key": &StringProperty{}, + "value": &StringProperty{}, + }, + }, + value: map[string]interface{}{ + "key": "test", + "value": "test", + }, + want: map[string]interface{}{ + "key": "test", + "value": "test", + }, + }, + { + name: "parses sub properties with default values if they dont exist", + property: &MapProperty{ + Properties: knowledgebase2.Properties{ + "key": &StringProperty{}, + "value": &StringProperty{ + SharedPropertyFields: SharedPropertyFields{ + DefaultValue: "test", + }, + }, + }, + }, + value: map[string]interface{}{ + "key": "test", + }, + want: map[string]interface{}{ + "key": "test", + "value": "test", + }, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/pkg/templates/aws/edges/api_deployment-rest_api.yaml b/pkg/templates/aws/edges/api_deployment-rest_api.yaml index 5a4cb3e88..4deea2bf6 100644 --- a/pkg/templates/aws/edges/api_deployment-rest_api.yaml +++ b/pkg/templates/aws/edges/api_deployment-rest_api.yaml @@ -1,5 +1,6 @@ source: aws:api_deployment target: aws:rest_api +always_process: true operational_rules: - if: '{{ hasDownstream "aws:api_integration" .Target }}' steps: diff --git a/pkg/templates/aws/edges/cloudfront_distribution-api_stage.yaml b/pkg/templates/aws/edges/cloudfront_distribution-api_stage.yaml index 06e7ce7ff..5cce453e8 100644 --- a/pkg/templates/aws/edges/cloudfront_distribution-api_stage.yaml +++ b/pkg/templates/aws/edges/cloudfront_distribution-api_stage.yaml @@ -1,5 +1,6 @@ source: aws:cloudfront_distribution target: aws:api_stage +always_process: true operational_rules: - configuration_rules: - resource: '{{ .Source }}' @@ -18,3 +19,60 @@ operational_rules: DomainName: '{{ .Target }}#StageInvokeUrl' OriginId: '{{ .Target.Name }}' OriginPath: '/{{ fieldValue "StageName" .Target }}' + - resource: '{{ .Source }}' + configuration: + field: CacheBehaviors + value: | + [ + + {{ $targetOriginId := .Target.Name }} + {{ $routes := makeSlice }} + {{ $integrations := allDownstream "aws:api_integration" .Target }} + {{ range $i, $integ := $integrations }} + {{- if not (sliceContains $routes (fieldValue "Route" $integ)) }} + {{ $routes = appendSlice $routes (fieldValue "Route" $integ) }} + {{- end }} + {{ end }} + {{ range $i, $route := $routes }} + {{ $methods := makeSlice }} + {{ range $i, $integ := $integrations }} + {{- if eq (fieldValue "Route" $integ) $route }} + {{ $methods = appendSlice $methods (fieldValue "HttpMethod" (fieldValue "Method" $integ)) }} + {{- end }} + {{ end }} + { + "AllowedMethods": [ + {{- if or (sliceContains $methods "PATCH") (sliceContains $methods "POST") (sliceContains $methods "PUT") (sliceContains $methods "DELETE") }} + "DELETE", + "GET", + "HEAD", + "OPTIONS", + "PATCH", + "POST", + "PUT" + {{- else }} + "HEAD", + "GET", + "OPTIONS" + {{- end }} + ], + "ForwardedValues": { + "Cookies": { + "Forward": "none" + }, + "QueryString": true + }, + "CachedMethods": [ + "HEAD", + "GET" + ], + "DefaultTtl": 0, + "MaxTtl": 0, + "MinTtl": 0, + "SmoothStreaming": false, + "PathPattern": "{{ replace `\/\{proxy\+\}` "*" $route }}", + "TargetOriginId": "{{ $targetOriginId }}", + "ViewerProtocolPolicy": "redirect-to-https" + }{{ if ne $i (sub (len $routes) 1) }},{{ end }} + {{ end }} + ] diff --git a/pkg/templates/aws/resources/cloudfront_distribution.yaml b/pkg/templates/aws/resources/cloudfront_distribution.yaml index ae71a6eb7..7aa344307 100644 --- a/pkg/templates/aws/resources/cloudfront_distribution.yaml +++ b/pkg/templates/aws/resources/cloudfront_distribution.yaml @@ -27,9 +27,106 @@ properties: type: string OriginSslProtocols: type: list(string) - CloudfrontDefaultCertificate: - type: bool - default_value: true + CacheBehaviors: + type: set + properties: + AllowedMethods: + type: set(string) + item_property: + type: string + allowed_values: + - DELETE + - GET + - HEAD + - OPTIONS + - PATCH + - POST + - PUT + default_value: + - DELETE + - GET + - HEAD + - OPTIONS + - PATCH + - POST + - PUT + CachedMethods: + type: set(string) + item_property: + type: string + allowed_values: + - DELETE + - GET + - HEAD + - OPTIONS + - PATCH + - POST + - PUT + default_value: + - HEAD + - GET + TargetOriginId: + type: string + ForwardedValues: + type: map + properties: + QueryString: + type: bool + default_value: true + Cookies: + type: map + properties: + Forward: + type: string + default_value: none + MinTtl: + type: int + default_value: 0 + MaxTtl: + type: int + default_value: 86400 + DefaultTtl: + type: int + default_value: 3600 + ViewerProtocolPolicy: + type: string + default_value: allow-all + PathPattern: + type: string + SmoothStreaming: + type: bool + default_value: false + ViewerCertificate: + type: map + default_value: + CloudfrontDefaultCertificate: true + properties: + ACMCertificateArn: + type: string + SSLSupportMethod: + type: string + MinimumProtocolVersion: + type: string + CloudfrontDefaultCertificate: + type: bool + IAMCertificateId: + type: string + CNAMEs: + type: list(string) + description: | + A list of CNAMEs (aliases) that you want CloudFront to use for this + distribution. You can have up to 10 CNAMEs in this list. + CustomErrorResponses: + type: list + properties: + ErrorCachingMinTTL: + type: int + ErrorCode: + type: int + ResponseCode: + type: int + ResponsePagePath: + type: string Enabled: type: bool default_value: true