'''
# Amazon CloudFront Construct Library

<!--BEGIN STABILITY BANNER-->---


![cfn-resources: Stable](https://img.shields.io/badge/cfn--resources-stable-success.svg?style=for-the-badge)

![cdk-constructs: Stable](https://img.shields.io/badge/cdk--constructs-stable-success.svg?style=for-the-badge)

---
<!--END STABILITY BANNER-->

Amazon CloudFront is a web service that speeds up distribution of your static and dynamic web content, such as .html, .css, .js, and image files, to
your users. CloudFront delivers your content through a worldwide network of data centers called edge locations. When a user requests content that
you're serving with CloudFront, the user is routed to the edge location that provides the lowest latency, so that content is delivered with the best
possible performance.

## Distribution API

The `Distribution` API is currently being built to replace the existing `CloudFrontWebDistribution` API. The `Distribution` API is optimized for the
most common use cases of CloudFront distributions (e.g., single origin and behavior, few customizations) while still providing the ability for more
advanced use cases. The API focuses on simplicity for the common use cases, and convenience methods for creating the behaviors and origins necessary
for more complex use cases.

### Creating a distribution

CloudFront distributions deliver your content from one or more origins; an origin is the location where you store the original version of your
content. Origins can be created from S3 buckets or a custom origin (HTTP server). Constructs to define origins are in the `@aws-cdk/aws-cloudfront-origins` module.

Each distribution has a default behavior which applies to all requests to that distribution, and routes requests to a primary origin.
Additional behaviors may be specified for an origin with a given URL path pattern. Behaviors allow routing with multiple origins,
controlling which HTTP methods to support, whether to require users to use HTTPS, and what query strings or cookies to forward to your origin,
among other settings.

#### From an S3 Bucket

An S3 bucket can be added as an origin. If the bucket is configured as a website endpoint, the distribution can use S3 redirects and S3 custom error
documents.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
import aws_cdk.aws_cloudfront as cloudfront
import aws_cdk.aws_cloudfront_origins as origins

# Creates a distribution for a S3 bucket.
my_bucket = s3.Bucket(self, "myBucket")
cloudfront.Distribution(self, "myDist",
    default_behavior=BehaviorOptions(origin=origins.S3Origin(my_bucket))
)
```

The above will treat the bucket differently based on if `IBucket.isWebsite` is set or not. If the bucket is configured as a website, the bucket is
treated as an HTTP origin, and the built-in S3 redirects and error pages can be used. Otherwise, the bucket is handled as a bucket origin and
CloudFront's redirect and error handling will be used. In the latter case, the Origin will create an origin access identity and grant it access to the
underlying bucket. This can be used in conjunction with a bucket that is not public to require that your users access your content using CloudFront
URLs and not S3 URLs directly.

#### ELBv2 Load Balancer

An Elastic Load Balancing (ELB) v2 load balancer may be used as an origin. In order for a load balancer to serve as an origin, it must be publicly
accessible (`internetFacing` is true). Both Application and Network load balancers are supported.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
import aws_cdk.aws_ec2 as ec2
import aws_cdk.aws_elasticloadbalancingv2 as elbv2

vpc = ec2.Vpc(...)
# Create an application load balancer in a VPC. 'internetFacing' must be 'true'
# for CloudFront to access the load balancer and use it as an origin.
lb = elbv2.ApplicationLoadBalancer(self, "LB",
    vpc=vpc,
    internet_facing=True
)
cloudfront.Distribution(self, "myDist",
    default_behavior={"origin": origins.LoadBalancerV2Origin(lb)}
)
```

#### From an HTTP endpoint

Origins can also be created from any other HTTP endpoint, given the domain name, and optionally, other origin properties.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
cloudfront.Distribution(self, "myDist",
    default_behavior={"origin": origins.HttpOrigin("www.example.com")}
)
```

### Domain Names and Certificates

When you create a distribution, CloudFront assigns a domain name for the distribution, for example: `d111111abcdef8.cloudfront.net`; this value can
be retrieved from `distribution.distributionDomainName`. CloudFront distributions use a default certificate (`*.cloudfront.net`) to support HTTPS by
default. If you want to use your own domain name, such as `www.example.com`, you must associate a certificate with your distribution that contains
your domain name, and provide one (or more) domain names from the certificate for the distribution.

The certificate must be present in the AWS Certificate Manager (ACM) service in the US East (N. Virginia) region; the certificate
may either be created by ACM, or created elsewhere and imported into ACM. When a certificate is used, the distribution will support HTTPS connections
from SNI only and a minimum protocol version of TLSv1.2_2021 if the '@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021' feature flag is set, and TLSv1.2_2019 otherwise.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_certificate = acm.DnsValidatedCertificate(self, "mySiteCert",
    domain_name="www.example.com",
    hosted_zone=hosted_zone
)
cloudfront.Distribution(self, "myDist",
    default_behavior={"origin": origins.S3Origin(my_bucket)},
    domain_names=["www.example.com"],
    certificate=my_certificate
)
```

However, you can customize the minimum protocol version for the certificate while creating the distribution using `minimumProtocolVersion` property.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
cloudfront.Distribution(self, "myDist",
    default_behavior={"origin": origins.S3Origin(my_bucket)},
    domain_names=["www.example.com"],
    minimum_protocol_version=SecurityPolicyProtocol.TLS_V1_2016
)
```

### Multiple Behaviors & Origins

Each distribution has a default behavior which applies to all requests to that distribution; additional behaviors may be specified for a
given URL path pattern. Behaviors allow routing with multiple origins, controlling which HTTP methods to support, whether to require users to
use HTTPS, and what query strings or cookies to forward to your origin, among others.

The properties of the default behavior can be adjusted as part of the distribution creation. The following example shows configuring the HTTP
methods and viewer protocol policy of the cache.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_web_distribution = cloudfront.Distribution(self, "myDist",
    default_behavior={
        "origin": origins.S3Origin(my_bucket),
        "allowed_methods": AllowedMethods.ALLOW_ALL,
        "viewer_protocol_policy": ViewerProtocolPolicy.REDIRECT_TO_HTTPS
    }
)
```

Additional behaviors can be specified at creation, or added after the initial creation. Each additional behavior is associated with an origin,
and enable customization for a specific set of resources based on a URL path pattern. For example, we can add a behavior to `myWebDistribution` to
override the default viewer protocol policy for all of the images.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_web_distribution.add_behavior("/images/*.jpg", origins.S3Origin(my_bucket),
    viewer_protocol_policy=ViewerProtocolPolicy.REDIRECT_TO_HTTPS
)
```

These behaviors can also be specified at distribution creation time.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
bucket_origin = origins.S3Origin(my_bucket)
cloudfront.Distribution(self, "myDist",
    default_behavior={
        "origin": bucket_origin,
        "allowed_methods": AllowedMethods.ALLOW_ALL,
        "viewer_protocol_policy": ViewerProtocolPolicy.REDIRECT_TO_HTTPS
    },
    additional_behaviors={
        "/images/*.jpg": {
            "origin": bucket_origin,
            "viewer_protocol_policy": ViewerProtocolPolicy.REDIRECT_TO_HTTPS
        }
    }
)
```

### Customizing Cache Keys and TTLs with Cache Policies

You can use a cache policy to improve your cache hit ratio by controlling the values (URL query strings, HTTP headers, and cookies)
that are included in the cache key, and/or adjusting how long items remain in the cache via the time-to-live (TTL) settings.
CloudFront provides some predefined cache policies, known as managed policies, for common use cases. You can use these managed policies,
or you can create your own cache policy that’s specific to your needs.
See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-the-cache-key.html for more details.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
# Using an existing cache policy
cloudfront.Distribution(self, "myDistManagedPolicy",
    default_behavior={
        "origin": bucket_origin,
        "cache_policy": cloudfront.CachePolicy.CACHING_OPTIMIZED
    }
)

# Creating a custom cache policy  -- all parameters optional
my_cache_policy = cloudfront.CachePolicy(self, "myCachePolicy",
    cache_policy_name="MyPolicy",
    comment="A default policy",
    default_ttl=Duration.days(2),
    min_ttl=Duration.minutes(1),
    max_ttl=Duration.days(10),
    cookie_behavior=cloudfront.CacheCookieBehavior.all(),
    header_behavior=cloudfront.CacheHeaderBehavior.allow_list("X-CustomHeader"),
    query_string_behavior=cloudfront.CacheQueryStringBehavior.deny_list("username"),
    enable_accept_encoding_gzip=True,
    enable_accept_encoding_brotli=True
)
cloudfront.Distribution(self, "myDistCustomPolicy",
    default_behavior={
        "origin": bucket_origin,
        "cache_policy": my_cache_policy
    }
)
```

### Customizing Origin Requests with Origin Request Policies

When CloudFront makes a request to an origin, the URL path, request body (if present), and a few standard headers are included.
Other information from the viewer request, such as URL query strings, HTTP headers, and cookies, is not included in the origin request by default.
You can use an origin request policy to control the information that’s included in an origin request.
CloudFront provides some predefined origin request policies, known as managed policies, for common use cases. You can use these managed policies,
or you can create your own origin request policy that’s specific to your needs.
See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-origin-requests.html for more details.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
# Using an existing origin request policy
cloudfront.Distribution(self, "myDistManagedPolicy",
    default_behavior={
        "origin": bucket_origin,
        "origin_request_policy": cloudfront.OriginRequestPolicy.CORS_S3_ORIGIN
    }
)
# Creating a custom origin request policy -- all parameters optional
my_origin_request_policy = cloudfront.OriginRequestPolicy(stack, "OriginRequestPolicy",
    origin_request_policy_name="MyPolicy",
    comment="A default policy",
    cookie_behavior=cloudfront.OriginRequestCookieBehavior.none(),
    header_behavior=cloudfront.OriginRequestHeaderBehavior.all("CloudFront-Is-Android-Viewer"),
    query_string_behavior=cloudfront.OriginRequestQueryStringBehavior.allow_list("username")
)
cloudfront.Distribution(self, "myDistCustomPolicy",
    default_behavior={
        "origin": bucket_origin,
        "cache_policy": my_cache_policy,
        "origin_request_policy": my_origin_request_policy
    }
)
```

### Validating signed URLs or signed cookies with Trusted Key Groups

CloudFront Distribution now supports validating signed URLs or signed cookies using key groups. When a cache behavior contains trusted key groups, CloudFront requires signed URLs or signed cookies for all requests that match the cache behavior.

Example:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
# public key in PEM format
pub_key = PublicKey(stack, "MyPubKey",
    encoded_key=public_key
)

key_group = KeyGroup(stack, "MyKeyGroup",
    items=[pub_key
    ]
)

cloudfront.Distribution(stack, "Dist",
    default_behavior={
        "origin": origins.HttpOrigin("www.example.com"),
        "trusted_key_groups": [key_group
        ]
    }
)
```

### Lambda@Edge

Lambda@Edge is an extension of AWS Lambda, a compute service that lets you execute functions that customize the content that CloudFront delivers.
You can author Node.js or Python functions in the US East (N. Virginia) region,
and then execute them in AWS locations globally that are closer to the viewer,
without provisioning or managing servers.
Lambda@Edge functions are associated with a specific behavior and event type.
Lambda@Edge can be used to rewrite URLs,
alter responses based on headers or cookies,
or authorize requests based on headers or authorization tokens.

The following shows a Lambda@Edge function added to the default behavior and triggered on every request:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_func = cloudfront.experimental.EdgeFunction(self, "MyFunction",
    runtime=lambda_.Runtime.NODEJS_12_X,
    handler="index.handler",
    code=lambda_.Code.from_asset(path.join(__dirname, "lambda-handler"))
)
cloudfront.Distribution(self, "myDist",
    default_behavior={
        "origin": origins.S3Origin(my_bucket),
        "edge_lambdas": [{
            "function_version": my_func.current_version,
            "event_type": cloudfront.LambdaEdgeEventType.VIEWER_REQUEST
        }
        ]
    }
)
```

> **Note:** Lambda@Edge functions must be created in the `us-east-1` region, regardless of the region of the CloudFront distribution and stack.
> To make it easier to request functions for Lambda@Edge, the `EdgeFunction` construct can be used.
> The `EdgeFunction` construct will automatically request a function in `us-east-1`, regardless of the region of the current stack.
> `EdgeFunction` has the same interface as `Function` and can be created and used interchangeably.
> Please note that using `EdgeFunction` requires that the `us-east-1` region has been bootstrapped.
> See https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html for more about bootstrapping regions.

If the stack is in `us-east-1`, a "normal" `lambda.Function` can be used instead of an `EdgeFunction`.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_func = lambda_.Function(self, "MyFunction",
    runtime=lambda_.Runtime.NODEJS_12_X,
    handler="index.handler",
    code=lambda_.Code.from_asset(path.join(__dirname, "lambda-handler"))
)
```

If the stack is not in `us-east-1`, and you need references from different applications on the same account,
you can also set a specific stack ID for each Lambda@Edge.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
my_func1 = cloudfront.experimental.EdgeFunction(self, "MyFunction1",
    runtime=lambda_.Runtime.NODEJS_12_X,
    handler="index.handler",
    code=lambda_.Code.from_asset(path.join(__dirname, "lambda-handler1")),
    stack_id="edge-lambda-stack-id-1"
)

my_func2 = cloudfront.experimental.EdgeFunction(self, "MyFunction2",
    runtime=lambda_.Runtime.NODEJS_12_X,
    handler="index.handler",
    code=lambda_.Code.from_asset(path.join(__dirname, "lambda-handler2")),
    stack_id="edge-lambda-stack-id-2"
)
```

Lambda@Edge functions can also be associated with additional behaviors,
either at or after Distribution creation time.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
# assigning at Distribution creation
my_origin = origins.S3Origin(my_bucket)
cloudfront.Distribution(self, "myDist",
    default_behavior={"origin": my_origin},
    additional_behaviors={
        "images/*": {
            "origin": my_origin,
            "edge_lambdas": [{
                "function_version": my_func.current_version,
                "event_type": cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
                "include_body": True
            }
            ]
        }
    }
)

# assigning after creation
my_distribution.add_behavior("images/*", my_origin,
    edge_lambdas=[{
        "function_version": my_func.current_version,
        "event_type": cloudfront.LambdaEdgeEventType.VIEWER_RESPONSE
    }
    ]
)
```

Adding an existing Lambda@Edge function created in a different stack to a CloudFront distribution.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
function_version = lambda_.Version.from_version_arn(self, "Version", "arn:aws:lambda:us-east-1:123456789012:function:functionName:1")

cloudfront.Distribution(self, "distro",
    default_behavior={
        "origin": origins.S3Origin(s3_bucket),
        "edge_lambdas": [{
            "function_version": function_version,
            "event_type": cloudfront.LambdaEdgeEventType.VIEWER_REQUEST
        }
        ]
    }
)
```

### CloudFront Function

You can also deploy CloudFront functions and add them to a CloudFront distribution.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
cf_function = cloudfront.Function(stack, "Function",
    code=cloudfront.FunctionCode.from_inline("function handler(event) { return event.request }")
)

cloudfront.Distribution(stack, "distro",
    default_behavior={
        "origin": origins.S3Origin(s3_bucket),
        "function_associations": [{
            "function": cf_function,
            "event_type": cloudfront.FunctionEventType.VIEWER_REQUEST
        }]
    }
)
```

It will auto-generate the name of the function and deploy it to the `live` stage.

Additionally, you can load the function's code from a file using the `FunctionCode.fromFile()` method.

### Logging

You can configure CloudFront to create log files that contain detailed information about every user request that CloudFront receives.
The logs can go to either an existing bucket, or a bucket will be created for you.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
# Simplest form - creates a new bucket and logs to it.
cloudfront.Distribution(self, "myDist",
    default_behavior={"origin": origins.HttpOrigin("www.example.com")},
    enable_logging=True
)

# You can optionally log to a specific bucket, configure whether cookies are logged, and give the log files a prefix.
cloudfront.Distribution(self, "myDist",
    default_behavior={"origin": origins.HttpOrigin("www.example.com")},
    enable_logging=True,  # Optional, this is implied if logBucket is specified
    log_bucket=s3.Bucket(self, "LogBucket"),
    log_file_prefix="distribution-access-logs/",
    log_includes_cookies=True
)
```

### Importing Distributions

Existing distributions can be imported as well; note that like most imported constructs, an imported distribution cannot be modified.
However, it can be used as a reference for other higher-level constructs.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
distribution = cloudfront.Distribution.from_distribution_attributes(scope, "ImportedDist",
    domain_name="d111111abcdef8.cloudfront.net",
    distribution_id="012345ABCDEF"
)
```

## CloudFrontWebDistribution API

> The `CloudFrontWebDistribution` construct is the original construct written for working with CloudFront distributions.
> Users are encouraged to use the newer `Distribution` instead, as it has a simpler interface and receives new features faster.

Example usage:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
source_bucket = Bucket(self, "Bucket")

distribution = CloudFrontWebDistribution(self, "MyDistribution",
    origin_configs=[{
        "s3_origin_source": {
            "s3_bucket_source": source_bucket
        },
        "behaviors": [{"is_default_behavior": True}]
    }
    ]
)
```

### Viewer certificate

By default, CloudFront Web Distributions will answer HTTPS requests with CloudFront's default certificate, only containing the distribution `domainName` (e.g. d111111abcdef8.cloudfront.net).
You can customize the viewer certificate property to provide a custom certificate and/or list of domain name aliases to fit your needs.

See [Using Alternate Domain Names and HTTPS](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-https-alternate-domain-names.html) in the CloudFront User Guide.

#### Default certificate

You can customize the default certificate aliases. This is intended to be used in combination with CNAME records in your DNS zone.

Example:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
s3_bucket_source = s3.Bucket(self, "Bucket")

distribution = cloudfront.CloudFrontWebDistribution(self, "AnAmazingWebsiteProbably",
    origin_configs=[SourceConfiguration(
        s3_origin_source=S3OriginConfig(s3_bucket_source=s3_bucket_source),
        behaviors=[Behavior(is_default_behavior=True)]
    )],
    viewer_certificate=cloudfront.ViewerCertificate.from_cloud_front_default_certificate("www.example.com")
)
```

#### ACM certificate

You can change the default certificate by one stored AWS Certificate Manager, or ACM.
Those certificate can either be generated by AWS, or purchased by another CA imported into ACM.

For more information, see [the aws-certificatemanager module documentation](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-certificatemanager-readme.html) or [Importing Certificates into AWS Certificate Manager](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate.html) in the AWS Certificate Manager User Guide.

Example:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
s3_bucket_source = s3.Bucket(self, "Bucket")

certificate = certificatemanager.Certificate(self, "Certificate",
    domain_name="example.com",
    subject_alternative_names=["*.example.com"]
)

distribution = cloudfront.CloudFrontWebDistribution(self, "AnAmazingWebsiteProbably",
    origin_configs=[SourceConfiguration(
        s3_origin_source=S3OriginConfig(s3_bucket_source=s3_bucket_source),
        behaviors=[Behavior(is_default_behavior=True)]
    )],
    viewer_certificate=cloudfront.ViewerCertificate.from_acm_certificate(certificate,
        aliases=["example.com", "www.example.com"],
        security_policy=cloudfront.SecurityPolicyProtocol.TLS_V1,  # default
        ssl_method=cloudfront.SSLMethod.SNI
    )
)
```

#### IAM certificate

You can also import a certificate into the IAM certificate store.

See [Importing an SSL/TLS Certificate](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/cnames-and-https-procedures.html#cnames-and-https-uploading-certificates) in the CloudFront User Guide.

Example:

```python
# Example automatically generated. See https://github.com/aws/jsii/issues/826
s3_bucket_source = s3.Bucket(self, "Bucket")

distribution = cloudfront.CloudFrontWebDistribution(self, "AnAmazingWebsiteProbably",
    origin_configs=[SourceConfiguration(
        s3_origin_source=S3OriginConfig(s3_bucket_source=s3_bucket_source),
        behaviors=[Behavior(is_default_behavior=True)]
    )],
    viewer_certificate=cloudfront.ViewerCertificate.from_iam_certificate("certificateId",
        aliases=["example.com"],
        security_policy=cloudfront.SecurityPolicyProtocol.SSL_V3,  # default
        ssl_method=cloudfront.SSLMethod.SNI
    )
)
```

### Trusted Key Groups

CloudFront Web Distributions supports validating signed URLs or signed cookies using key groups. When a cache behavior contains trusted key groups, CloudFront requires signed URLs or signed cookies for all requests that match the cache behavior.

Example:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
pub_key = PublicKey(stack, "MyPubKey",
    encoded_key=public_key
)

key_group = KeyGroup(stack, "MyKeyGroup",
    items=[pub_key
    ]
)

CloudFrontWebDistribution(stack, "AnAmazingWebsiteProbably",
    origin_configs=[{
        "s3_origin_source": {
            "s3_bucket_source": source_bucket
        },
        "behaviors": [{
            "is_default_behavior": True,
            "trusted_key_groups": [key_group
            ]
        }
        ]
    }
    ]
)
```

### Restrictions

CloudFront supports adding restrictions to your distribution.

See [Restricting the Geographic Distribution of Your Content](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/georestrictions.html) in the CloudFront User Guide.

Example:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
cloudfront.CloudFrontWebDistribution(stack, "MyDistribution",
    # ...
    geo_restriction=GeoRestriction.whitelist("US", "UK")
)
```

### Connection behaviors between CloudFront and your origin

CloudFront provides you even more control over the connection behaviors between CloudFront and your origin. You can now configure the number of connection attempts CloudFront will make to your origin and the origin connection timeout for each attempt.

See [Origin Connection Attempts](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#origin-connection-attempts)

See [Origin Connection Timeout](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#origin-connection-timeout)

Example usage:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
distribution = CloudFrontWebDistribution(self, "MyDistribution",
    origin_configs=[{...,
        "connection_attempts": 3,
        "connection_timeout": cdk.Duration.seconds(10)
    }
    ]
)
```

#### Origin Fallback

In case the origin source is not available and answers with one of the
specified status code the failover origin source will be used.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
CloudFrontWebDistribution(stack, "ADistribution",
    origin_configs=[{
        "s3_origin_source": {
            "s3_bucket_source": s3.Bucket.from_bucket_name(stack, "aBucket", "myoriginbucket"),
            "origin_path": "/",
            "origin_headers": {
                "my_header": "42"
            },
            "origin_shield_region": "us-west-2"
        },
        "failover_s3_origin_source": {
            "s3_bucket_source": s3.Bucket.from_bucket_name(stack, "aBucketFallback", "myoriginbucketfallback"),
            "origin_path": "/somewhere",
            "origin_headers": {
                "my_header2": "21"
            },
            "origin_shield_region": "us-east-1"
        },
        "failover_criteria_status_codes": [FailoverStatusCode.INTERNAL_SERVER_ERROR],
        "behaviors": [{
            "is_default_behavior": True
        }
        ]
    }
    ]
)
```

## KeyGroup & PublicKey API

Now you can create a key group to use with CloudFront signed URLs and signed cookies. You can add public keys to use with CloudFront features such as signed URLs, signed cookies, and field-level encryption.

The following example command uses OpenSSL to generate an RSA key pair with a length of 2048 bits and save to the file named `private_key.pem`.

```bash
openssl genrsa -out private_key.pem 2048
```

The resulting file contains both the public and the private key. The following example command extracts the public key from the file named `private_key.pem` and stores it in `public_key.pem`.

```bash
openssl rsa -pubout -in private_key.pem -out public_key.pem
```

Note: Don't forget to copy/paste the contents of `public_key.pem` file including `-----BEGIN PUBLIC KEY-----` and `-----END PUBLIC KEY-----` lines into `encodedKey` parameter when creating a `PublicKey`.

Example:

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
cloudfront.KeyGroup(stack, "MyKeyGroup",
    items=[
        cloudfront.PublicKey(stack, "MyPublicKey",
            encoded_key="..."
        )
    ]
)
```

See:

* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html
'''
import abc
import builtins
import datetime
import enum
import typing

import jsii
import publication
import typing_extensions

from ._jsii import *

import aws_cdk.aws_certificatemanager
import aws_cdk.aws_iam
import aws_cdk.aws_lambda
import aws_cdk.aws_s3
import aws_cdk.core
import constructs


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.AddBehaviorOptions",
    jsii_struct_bases=[],
    name_mapping={
        "allowed_methods": "allowedMethods",
        "cached_methods": "cachedMethods",
        "cache_policy": "cachePolicy",
        "compress": "compress",
        "edge_lambdas": "edgeLambdas",
        "function_associations": "functionAssociations",
        "origin_request_policy": "originRequestPolicy",
        "smooth_streaming": "smoothStreaming",
        "trusted_key_groups": "trustedKeyGroups",
        "viewer_protocol_policy": "viewerProtocolPolicy",
    },
)
class AddBehaviorOptions:
    def __init__(
        self,
        *,
        allowed_methods: typing.Optional["AllowedMethods"] = None,
        cached_methods: typing.Optional["CachedMethods"] = None,
        cache_policy: typing.Optional["ICachePolicy"] = None,
        compress: typing.Optional[builtins.bool] = None,
        edge_lambdas: typing.Optional[typing.Sequence["EdgeLambda"]] = None,
        function_associations: typing.Optional[typing.Sequence["FunctionAssociation"]] = None,
        origin_request_policy: typing.Optional["IOriginRequestPolicy"] = None,
        smooth_streaming: typing.Optional[builtins.bool] = None,
        trusted_key_groups: typing.Optional[typing.Sequence["IKeyGroup"]] = None,
        viewer_protocol_policy: typing.Optional["ViewerProtocolPolicy"] = None,
    ) -> None:
        '''Options for adding a new behavior to a Distribution.

        :param allowed_methods: HTTP methods to allow for this behavior. Default: AllowedMethods.ALLOW_GET_HEAD
        :param cached_methods: HTTP methods to cache for this behavior. Default: CachedMethods.CACHE_GET_HEAD
        :param cache_policy: The cache policy for this behavior. The cache policy determines what values are included in the cache key, and the time-to-live (TTL) values for the cache. Default: CachePolicy.CACHING_OPTIMIZED
        :param compress: Whether you want CloudFront to automatically compress certain files for this cache behavior. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types for file types CloudFront will compress. Default: true
        :param edge_lambdas: The Lambda@Edge functions to invoke before serving the contents. Default: - no Lambda functions will be invoked
        :param function_associations: The CloudFront functions to invoke before serving the contents. Default: - no functions will be invoked
        :param origin_request_policy: The origin request policy for this behavior. The origin request policy determines which values (e.g., headers, cookies) are included in requests that CloudFront sends to the origin. Default: - none
        :param smooth_streaming: Set this to true to indicate you want to distribute media files in the Microsoft Smooth Streaming format using this behavior. Default: false
        :param trusted_key_groups: A list of Key Groups that CloudFront can use to validate signed URLs or signed cookies. Default: - no KeyGroups are associated with cache behavior
        :param viewer_protocol_policy: The protocol that viewers can use to access the files controlled by this behavior. Default: ViewerProtocolPolicy.ALLOW_ALL
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if allowed_methods is not None:
            self._values["allowed_methods"] = allowed_methods
        if cached_methods is not None:
            self._values["cached_methods"] = cached_methods
        if cache_policy is not None:
            self._values["cache_policy"] = cache_policy
        if compress is not None:
            self._values["compress"] = compress
        if edge_lambdas is not None:
            self._values["edge_lambdas"] = edge_lambdas
        if function_associations is not None:
            self._values["function_associations"] = function_associations
        if origin_request_policy is not None:
            self._values["origin_request_policy"] = origin_request_policy
        if smooth_streaming is not None:
            self._values["smooth_streaming"] = smooth_streaming
        if trusted_key_groups is not None:
            self._values["trusted_key_groups"] = trusted_key_groups
        if viewer_protocol_policy is not None:
            self._values["viewer_protocol_policy"] = viewer_protocol_policy

    @builtins.property
    def allowed_methods(self) -> typing.Optional["AllowedMethods"]:
        '''HTTP methods to allow for this behavior.

        :default: AllowedMethods.ALLOW_GET_HEAD
        '''
        result = self._values.get("allowed_methods")
        return typing.cast(typing.Optional["AllowedMethods"], result)

    @builtins.property
    def cached_methods(self) -> typing.Optional["CachedMethods"]:
        '''HTTP methods to cache for this behavior.

        :default: CachedMethods.CACHE_GET_HEAD
        '''
        result = self._values.get("cached_methods")
        return typing.cast(typing.Optional["CachedMethods"], result)

    @builtins.property
    def cache_policy(self) -> typing.Optional["ICachePolicy"]:
        '''The cache policy for this behavior.

        The cache policy determines what values are included in the cache key,
        and the time-to-live (TTL) values for the cache.

        :default: CachePolicy.CACHING_OPTIMIZED

        :see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-the-cache-key.html.
        '''
        result = self._values.get("cache_policy")
        return typing.cast(typing.Optional["ICachePolicy"], result)

    @builtins.property
    def compress(self) -> typing.Optional[builtins.bool]:
        '''Whether you want CloudFront to automatically compress certain files for this cache behavior.

        See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types
        for file types CloudFront will compress.

        :default: true
        '''
        result = self._values.get("compress")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def edge_lambdas(self) -> typing.Optional[typing.List["EdgeLambda"]]:
        '''The Lambda@Edge functions to invoke before serving the contents.

        :default: - no Lambda functions will be invoked

        :see: https://aws.amazon.com/lambda/edge
        '''
        result = self._values.get("edge_lambdas")
        return typing.cast(typing.Optional[typing.List["EdgeLambda"]], result)

    @builtins.property
    def function_associations(
        self,
    ) -> typing.Optional[typing.List["FunctionAssociation"]]:
        '''The CloudFront functions to invoke before serving the contents.

        :default: - no functions will be invoked
        '''
        result = self._values.get("function_associations")
        return typing.cast(typing.Optional[typing.List["FunctionAssociation"]], result)

    @builtins.property
    def origin_request_policy(self) -> typing.Optional["IOriginRequestPolicy"]:
        '''The origin request policy for this behavior.

        The origin request policy determines which values (e.g., headers, cookies)
        are included in requests that CloudFront sends to the origin.

        :default: - none
        '''
        result = self._values.get("origin_request_policy")
        return typing.cast(typing.Optional["IOriginRequestPolicy"], result)

    @builtins.property
    def smooth_streaming(self) -> typing.Optional[builtins.bool]:
        '''Set this to true to indicate you want to distribute media files in the Microsoft Smooth Streaming format using this behavior.

        :default: false
        '''
        result = self._values.get("smooth_streaming")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def trusted_key_groups(self) -> typing.Optional[typing.List["IKeyGroup"]]:
        '''A list of Key Groups that CloudFront can use to validate signed URLs or signed cookies.

        :default: - no KeyGroups are associated with cache behavior

        :see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html
        '''
        result = self._values.get("trusted_key_groups")
        return typing.cast(typing.Optional[typing.List["IKeyGroup"]], result)

    @builtins.property
    def viewer_protocol_policy(self) -> typing.Optional["ViewerProtocolPolicy"]:
        '''The protocol that viewers can use to access the files controlled by this behavior.

        :default: ViewerProtocolPolicy.ALLOW_ALL
        '''
        result = self._values.get("viewer_protocol_policy")
        return typing.cast(typing.Optional["ViewerProtocolPolicy"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AddBehaviorOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.AliasConfiguration",
    jsii_struct_bases=[],
    name_mapping={
        "acm_cert_ref": "acmCertRef",
        "names": "names",
        "security_policy": "securityPolicy",
        "ssl_method": "sslMethod",
    },
)
class AliasConfiguration:
    def __init__(
        self,
        *,
        acm_cert_ref: builtins.str,
        names: typing.Sequence[builtins.str],
        security_policy: typing.Optional["SecurityPolicyProtocol"] = None,
        ssl_method: typing.Optional["SSLMethod"] = None,
    ) -> None:
        '''(deprecated) Configuration for custom domain names.

        CloudFront can use a custom domain that you provide instead of a
        "cloudfront.net" domain. To use this feature you must provide the list of
        additional domains, and the ACM Certificate that CloudFront should use for
        these additional domains.

        :param acm_cert_ref: (deprecated) ARN of an AWS Certificate Manager (ACM) certificate.
        :param names: (deprecated) Domain names on the certificate. Both main domain name and Subject Alternative Names.
        :param security_policy: (deprecated) The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify. Default: - SSLv3 if sslMethod VIP, TLSv1 if sslMethod SNI
        :param ssl_method: (deprecated) How CloudFront should serve HTTPS requests. See the notes on SSLMethod if you wish to use other SSL termination types. Default: SSLMethod.SNI

        :deprecated: see {@link CloudFrontWebDistributionProps#viewerCertificate} with {@link ViewerCertificate#acmCertificate}

        :stability: deprecated
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "acm_cert_ref": acm_cert_ref,
            "names": names,
        }
        if security_policy is not None:
            self._values["security_policy"] = security_policy
        if ssl_method is not None:
            self._values["ssl_method"] = ssl_method

    @builtins.property
    def acm_cert_ref(self) -> builtins.str:
        '''(deprecated) ARN of an AWS Certificate Manager (ACM) certificate.

        :stability: deprecated
        '''
        result = self._values.get("acm_cert_ref")
        assert result is not None, "Required property 'acm_cert_ref' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def names(self) -> typing.List[builtins.str]:
        '''(deprecated) Domain names on the certificate.

        Both main domain name and Subject Alternative Names.

        :stability: deprecated
        '''
        result = self._values.get("names")
        assert result is not None, "Required property 'names' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def security_policy(self) -> typing.Optional["SecurityPolicyProtocol"]:
        '''(deprecated) The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections.

        CloudFront serves your objects only to browsers or devices that support at
        least the SSL version that you specify.

        :default: - SSLv3 if sslMethod VIP, TLSv1 if sslMethod SNI

        :stability: deprecated
        '''
        result = self._values.get("security_policy")
        return typing.cast(typing.Optional["SecurityPolicyProtocol"], result)

    @builtins.property
    def ssl_method(self) -> typing.Optional["SSLMethod"]:
        '''(deprecated) How CloudFront should serve HTTPS requests.

        See the notes on SSLMethod if you wish to use other SSL termination types.

        :default: SSLMethod.SNI

        :see: https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ViewerCertificate.html
        :stability: deprecated
        '''
        result = self._values.get("ssl_method")
        return typing.cast(typing.Optional["SSLMethod"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "AliasConfiguration(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class AllowedMethods(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.AllowedMethods",
):
    '''The HTTP methods that the Behavior will accept requests on.'''

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ALLOW_ALL")
    def ALLOW_ALL(cls) -> "AllowedMethods":
        '''All supported HTTP methods.'''
        return typing.cast("AllowedMethods", jsii.sget(cls, "ALLOW_ALL"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ALLOW_GET_HEAD")
    def ALLOW_GET_HEAD(cls) -> "AllowedMethods":
        '''HEAD and GET.'''
        return typing.cast("AllowedMethods", jsii.sget(cls, "ALLOW_GET_HEAD"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ALLOW_GET_HEAD_OPTIONS")
    def ALLOW_GET_HEAD_OPTIONS(cls) -> "AllowedMethods":
        '''HEAD, GET, and OPTIONS.'''
        return typing.cast("AllowedMethods", jsii.sget(cls, "ALLOW_GET_HEAD_OPTIONS"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="methods")
    def methods(self) -> typing.List[builtins.str]:
        '''HTTP methods supported.'''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "methods"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.Behavior",
    jsii_struct_bases=[],
    name_mapping={
        "allowed_methods": "allowedMethods",
        "cached_methods": "cachedMethods",
        "compress": "compress",
        "default_ttl": "defaultTtl",
        "forwarded_values": "forwardedValues",
        "function_associations": "functionAssociations",
        "is_default_behavior": "isDefaultBehavior",
        "lambda_function_associations": "lambdaFunctionAssociations",
        "max_ttl": "maxTtl",
        "min_ttl": "minTtl",
        "path_pattern": "pathPattern",
        "trusted_key_groups": "trustedKeyGroups",
        "trusted_signers": "trustedSigners",
        "viewer_protocol_policy": "viewerProtocolPolicy",
    },
)
class Behavior:
    def __init__(
        self,
        *,
        allowed_methods: typing.Optional["CloudFrontAllowedMethods"] = None,
        cached_methods: typing.Optional["CloudFrontAllowedCachedMethods"] = None,
        compress: typing.Optional[builtins.bool] = None,
        default_ttl: typing.Optional[aws_cdk.core.Duration] = None,
        forwarded_values: typing.Optional["CfnDistribution.ForwardedValuesProperty"] = None,
        function_associations: typing.Optional[typing.Sequence["FunctionAssociation"]] = None,
        is_default_behavior: typing.Optional[builtins.bool] = None,
        lambda_function_associations: typing.Optional[typing.Sequence["LambdaFunctionAssociation"]] = None,
        max_ttl: typing.Optional[aws_cdk.core.Duration] = None,
        min_ttl: typing.Optional[aws_cdk.core.Duration] = None,
        path_pattern: typing.Optional[builtins.str] = None,
        trusted_key_groups: typing.Optional[typing.Sequence["IKeyGroup"]] = None,
        trusted_signers: typing.Optional[typing.Sequence[builtins.str]] = None,
        viewer_protocol_policy: typing.Optional["ViewerProtocolPolicy"] = None,
    ) -> None:
        '''A CloudFront behavior wrapper.

        :param allowed_methods: The method this CloudFront distribution responds do. Default: GET_HEAD
        :param cached_methods: Which methods are cached by CloudFront by default. Default: GET_HEAD
        :param compress: If CloudFront should automatically compress some content types. Default: true
        :param default_ttl: The default amount of time CloudFront will cache an object. This value applies only when your custom origin does not add HTTP headers, such as Cache-Control max-age, Cache-Control s-maxage, and Expires to objects. Default: 86400 (1 day)
        :param forwarded_values: The values CloudFront will forward to the origin when making a request. Default: none (no cookies - no headers)
        :param function_associations: The CloudFront functions to invoke before serving the contents. Default: - no functions will be invoked
        :param is_default_behavior: If this behavior is the default behavior for the distribution. You must specify exactly one default distribution per CloudFront distribution. The default behavior is allowed to omit the "path" property.
        :param lambda_function_associations: Declares associated lambda@edge functions for this distribution behaviour. Default: No lambda function associated
        :param max_ttl: The max amount of time you want objects to stay in the cache before CloudFront queries your origin. Default: Duration.seconds(31536000) (one year)
        :param min_ttl: The minimum amount of time that you want objects to stay in the cache before CloudFront queries your origin.
        :param path_pattern: The path this behavior responds to. Required for all non-default behaviors. (The default behavior implicitly has "*" as the path pattern. )
        :param trusted_key_groups: A list of Key Groups that CloudFront can use to validate signed URLs or signed cookies. Default: - no KeyGroups are associated with cache behavior
        :param trusted_signers: (deprecated) Trusted signers is how CloudFront allows you to serve private content. The signers are the account IDs that are allowed to sign cookies/presigned URLs for this distribution. If you pass a non empty value, all requests for this behavior must be signed (no public access will be allowed)
        :param viewer_protocol_policy: The viewer policy for this behavior. Default: - the distribution wide viewer protocol policy will be used
        '''
        if isinstance(forwarded_values, dict):
            forwarded_values = CfnDistribution.ForwardedValuesProperty(**forwarded_values)
        self._values: typing.Dict[str, typing.Any] = {}
        if allowed_methods is not None:
            self._values["allowed_methods"] = allowed_methods
        if cached_methods is not None:
            self._values["cached_methods"] = cached_methods
        if compress is not None:
            self._values["compress"] = compress
        if default_ttl is not None:
            self._values["default_ttl"] = default_ttl
        if forwarded_values is not None:
            self._values["forwarded_values"] = forwarded_values
        if function_associations is not None:
            self._values["function_associations"] = function_associations
        if is_default_behavior is not None:
            self._values["is_default_behavior"] = is_default_behavior
        if lambda_function_associations is not None:
            self._values["lambda_function_associations"] = lambda_function_associations
        if max_ttl is not None:
            self._values["max_ttl"] = max_ttl
        if min_ttl is not None:
            self._values["min_ttl"] = min_ttl
        if path_pattern is not None:
            self._values["path_pattern"] = path_pattern
        if trusted_key_groups is not None:
            self._values["trusted_key_groups"] = trusted_key_groups
        if trusted_signers is not None:
            self._values["trusted_signers"] = trusted_signers
        if viewer_protocol_policy is not None:
            self._values["viewer_protocol_policy"] = viewer_protocol_policy

    @builtins.property
    def allowed_methods(self) -> typing.Optional["CloudFrontAllowedMethods"]:
        '''The method this CloudFront distribution responds do.

        :default: GET_HEAD
        '''
        result = self._values.get("allowed_methods")
        return typing.cast(typing.Optional["CloudFrontAllowedMethods"], result)

    @builtins.property
    def cached_methods(self) -> typing.Optional["CloudFrontAllowedCachedMethods"]:
        '''Which methods are cached by CloudFront by default.

        :default: GET_HEAD
        '''
        result = self._values.get("cached_methods")
        return typing.cast(typing.Optional["CloudFrontAllowedCachedMethods"], result)

    @builtins.property
    def compress(self) -> typing.Optional[builtins.bool]:
        '''If CloudFront should automatically compress some content types.

        :default: true
        '''
        result = self._values.get("compress")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def default_ttl(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The default amount of time CloudFront will cache an object.

        This value applies only when your custom origin does not add HTTP headers,
        such as Cache-Control max-age, Cache-Control s-maxage, and Expires to objects.

        :default: 86400 (1 day)
        '''
        result = self._values.get("default_ttl")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def forwarded_values(
        self,
    ) -> typing.Optional["CfnDistribution.ForwardedValuesProperty"]:
        '''The values CloudFront will forward to the origin when making a request.

        :default: none (no cookies - no headers)
        '''
        result = self._values.get("forwarded_values")
        return typing.cast(typing.Optional["CfnDistribution.ForwardedValuesProperty"], result)

    @builtins.property
    def function_associations(
        self,
    ) -> typing.Optional[typing.List["FunctionAssociation"]]:
        '''The CloudFront functions to invoke before serving the contents.

        :default: - no functions will be invoked
        '''
        result = self._values.get("function_associations")
        return typing.cast(typing.Optional[typing.List["FunctionAssociation"]], result)

    @builtins.property
    def is_default_behavior(self) -> typing.Optional[builtins.bool]:
        '''If this behavior is the default behavior for the distribution.

        You must specify exactly one default distribution per CloudFront distribution.
        The default behavior is allowed to omit the "path" property.
        '''
        result = self._values.get("is_default_behavior")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def lambda_function_associations(
        self,
    ) -> typing.Optional[typing.List["LambdaFunctionAssociation"]]:
        '''Declares associated lambda@edge functions for this distribution behaviour.

        :default: No lambda function associated
        '''
        result = self._values.get("lambda_function_associations")
        return typing.cast(typing.Optional[typing.List["LambdaFunctionAssociation"]], result)

    @builtins.property
    def max_ttl(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The max amount of time you want objects to stay in the cache before CloudFront queries your origin.

        :default: Duration.seconds(31536000) (one year)
        '''
        result = self._values.get("max_ttl")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def min_ttl(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The minimum amount of time that you want objects to stay in the cache before CloudFront queries your origin.'''
        result = self._values.get("min_ttl")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def path_pattern(self) -> typing.Optional[builtins.str]:
        '''The path this behavior responds to.

        Required for all non-default behaviors. (The default behavior implicitly has "*" as the path pattern. )
        '''
        result = self._values.get("path_pattern")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def trusted_key_groups(self) -> typing.Optional[typing.List["IKeyGroup"]]:
        '''A list of Key Groups that CloudFront can use to validate signed URLs or signed cookies.

        :default: - no KeyGroups are associated with cache behavior

        :see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html
        '''
        result = self._values.get("trusted_key_groups")
        return typing.cast(typing.Optional[typing.List["IKeyGroup"]], result)

    @builtins.property
    def trusted_signers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''(deprecated) Trusted signers is how CloudFront allows you to serve private content.

        The signers are the account IDs that are allowed to sign cookies/presigned URLs for this distribution.

        If you pass a non empty value, all requests for this behavior must be signed (no public access will be allowed)

        :deprecated: - We recommend using trustedKeyGroups instead of trustedSigners.

        :stability: deprecated
        '''
        result = self._values.get("trusted_signers")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def viewer_protocol_policy(self) -> typing.Optional["ViewerProtocolPolicy"]:
        '''The viewer policy for this behavior.

        :default: - the distribution wide viewer protocol policy will be used
        '''
        result = self._values.get("viewer_protocol_policy")
        return typing.cast(typing.Optional["ViewerProtocolPolicy"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "Behavior(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.BehaviorOptions",
    jsii_struct_bases=[AddBehaviorOptions],
    name_mapping={
        "allowed_methods": "allowedMethods",
        "cached_methods": "cachedMethods",
        "cache_policy": "cachePolicy",
        "compress": "compress",
        "edge_lambdas": "edgeLambdas",
        "function_associations": "functionAssociations",
        "origin_request_policy": "originRequestPolicy",
        "smooth_streaming": "smoothStreaming",
        "trusted_key_groups": "trustedKeyGroups",
        "viewer_protocol_policy": "viewerProtocolPolicy",
        "origin": "origin",
    },
)
class BehaviorOptions(AddBehaviorOptions):
    def __init__(
        self,
        *,
        allowed_methods: typing.Optional[AllowedMethods] = None,
        cached_methods: typing.Optional["CachedMethods"] = None,
        cache_policy: typing.Optional["ICachePolicy"] = None,
        compress: typing.Optional[builtins.bool] = None,
        edge_lambdas: typing.Optional[typing.Sequence["EdgeLambda"]] = None,
        function_associations: typing.Optional[typing.Sequence["FunctionAssociation"]] = None,
        origin_request_policy: typing.Optional["IOriginRequestPolicy"] = None,
        smooth_streaming: typing.Optional[builtins.bool] = None,
        trusted_key_groups: typing.Optional[typing.Sequence["IKeyGroup"]] = None,
        viewer_protocol_policy: typing.Optional["ViewerProtocolPolicy"] = None,
        origin: "IOrigin",
    ) -> None:
        '''Options for creating a new behavior.

        :param allowed_methods: HTTP methods to allow for this behavior. Default: AllowedMethods.ALLOW_GET_HEAD
        :param cached_methods: HTTP methods to cache for this behavior. Default: CachedMethods.CACHE_GET_HEAD
        :param cache_policy: The cache policy for this behavior. The cache policy determines what values are included in the cache key, and the time-to-live (TTL) values for the cache. Default: CachePolicy.CACHING_OPTIMIZED
        :param compress: Whether you want CloudFront to automatically compress certain files for this cache behavior. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types for file types CloudFront will compress. Default: true
        :param edge_lambdas: The Lambda@Edge functions to invoke before serving the contents. Default: - no Lambda functions will be invoked
        :param function_associations: The CloudFront functions to invoke before serving the contents. Default: - no functions will be invoked
        :param origin_request_policy: The origin request policy for this behavior. The origin request policy determines which values (e.g., headers, cookies) are included in requests that CloudFront sends to the origin. Default: - none
        :param smooth_streaming: Set this to true to indicate you want to distribute media files in the Microsoft Smooth Streaming format using this behavior. Default: false
        :param trusted_key_groups: A list of Key Groups that CloudFront can use to validate signed URLs or signed cookies. Default: - no KeyGroups are associated with cache behavior
        :param viewer_protocol_policy: The protocol that viewers can use to access the files controlled by this behavior. Default: ViewerProtocolPolicy.ALLOW_ALL
        :param origin: The origin that you want CloudFront to route requests to when they match this behavior.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "origin": origin,
        }
        if allowed_methods is not None:
            self._values["allowed_methods"] = allowed_methods
        if cached_methods is not None:
            self._values["cached_methods"] = cached_methods
        if cache_policy is not None:
            self._values["cache_policy"] = cache_policy
        if compress is not None:
            self._values["compress"] = compress
        if edge_lambdas is not None:
            self._values["edge_lambdas"] = edge_lambdas
        if function_associations is not None:
            self._values["function_associations"] = function_associations
        if origin_request_policy is not None:
            self._values["origin_request_policy"] = origin_request_policy
        if smooth_streaming is not None:
            self._values["smooth_streaming"] = smooth_streaming
        if trusted_key_groups is not None:
            self._values["trusted_key_groups"] = trusted_key_groups
        if viewer_protocol_policy is not None:
            self._values["viewer_protocol_policy"] = viewer_protocol_policy

    @builtins.property
    def allowed_methods(self) -> typing.Optional[AllowedMethods]:
        '''HTTP methods to allow for this behavior.

        :default: AllowedMethods.ALLOW_GET_HEAD
        '''
        result = self._values.get("allowed_methods")
        return typing.cast(typing.Optional[AllowedMethods], result)

    @builtins.property
    def cached_methods(self) -> typing.Optional["CachedMethods"]:
        '''HTTP methods to cache for this behavior.

        :default: CachedMethods.CACHE_GET_HEAD
        '''
        result = self._values.get("cached_methods")
        return typing.cast(typing.Optional["CachedMethods"], result)

    @builtins.property
    def cache_policy(self) -> typing.Optional["ICachePolicy"]:
        '''The cache policy for this behavior.

        The cache policy determines what values are included in the cache key,
        and the time-to-live (TTL) values for the cache.

        :default: CachePolicy.CACHING_OPTIMIZED

        :see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-the-cache-key.html.
        '''
        result = self._values.get("cache_policy")
        return typing.cast(typing.Optional["ICachePolicy"], result)

    @builtins.property
    def compress(self) -> typing.Optional[builtins.bool]:
        '''Whether you want CloudFront to automatically compress certain files for this cache behavior.

        See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types
        for file types CloudFront will compress.

        :default: true
        '''
        result = self._values.get("compress")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def edge_lambdas(self) -> typing.Optional[typing.List["EdgeLambda"]]:
        '''The Lambda@Edge functions to invoke before serving the contents.

        :default: - no Lambda functions will be invoked

        :see: https://aws.amazon.com/lambda/edge
        '''
        result = self._values.get("edge_lambdas")
        return typing.cast(typing.Optional[typing.List["EdgeLambda"]], result)

    @builtins.property
    def function_associations(
        self,
    ) -> typing.Optional[typing.List["FunctionAssociation"]]:
        '''The CloudFront functions to invoke before serving the contents.

        :default: - no functions will be invoked
        '''
        result = self._values.get("function_associations")
        return typing.cast(typing.Optional[typing.List["FunctionAssociation"]], result)

    @builtins.property
    def origin_request_policy(self) -> typing.Optional["IOriginRequestPolicy"]:
        '''The origin request policy for this behavior.

        The origin request policy determines which values (e.g., headers, cookies)
        are included in requests that CloudFront sends to the origin.

        :default: - none
        '''
        result = self._values.get("origin_request_policy")
        return typing.cast(typing.Optional["IOriginRequestPolicy"], result)

    @builtins.property
    def smooth_streaming(self) -> typing.Optional[builtins.bool]:
        '''Set this to true to indicate you want to distribute media files in the Microsoft Smooth Streaming format using this behavior.

        :default: false
        '''
        result = self._values.get("smooth_streaming")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def trusted_key_groups(self) -> typing.Optional[typing.List["IKeyGroup"]]:
        '''A list of Key Groups that CloudFront can use to validate signed URLs or signed cookies.

        :default: - no KeyGroups are associated with cache behavior

        :see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PrivateContent.html
        '''
        result = self._values.get("trusted_key_groups")
        return typing.cast(typing.Optional[typing.List["IKeyGroup"]], result)

    @builtins.property
    def viewer_protocol_policy(self) -> typing.Optional["ViewerProtocolPolicy"]:
        '''The protocol that viewers can use to access the files controlled by this behavior.

        :default: ViewerProtocolPolicy.ALLOW_ALL
        '''
        result = self._values.get("viewer_protocol_policy")
        return typing.cast(typing.Optional["ViewerProtocolPolicy"], result)

    @builtins.property
    def origin(self) -> "IOrigin":
        '''The origin that you want CloudFront to route requests to when they match this behavior.'''
        result = self._values.get("origin")
        assert result is not None, "Required property 'origin' is missing"
        return typing.cast("IOrigin", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "BehaviorOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class CacheCookieBehavior(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CacheCookieBehavior",
):
    '''Determines whether any cookies in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin.'''

    @jsii.member(jsii_name="all") # type: ignore[misc]
    @builtins.classmethod
    def all(cls) -> "CacheCookieBehavior":
        '''All cookies in viewer requests are included in the cache key and are automatically included in requests that CloudFront sends to the origin.'''
        return typing.cast("CacheCookieBehavior", jsii.sinvoke(cls, "all", []))

    @jsii.member(jsii_name="allowList") # type: ignore[misc]
    @builtins.classmethod
    def allow_list(cls, *cookies: builtins.str) -> "CacheCookieBehavior":
        '''Only the provided ``cookies`` are included in the cache key and automatically included in requests that CloudFront sends to the origin.

        :param cookies: -
        '''
        return typing.cast("CacheCookieBehavior", jsii.sinvoke(cls, "allowList", [*cookies]))

    @jsii.member(jsii_name="denyList") # type: ignore[misc]
    @builtins.classmethod
    def deny_list(cls, *cookies: builtins.str) -> "CacheCookieBehavior":
        '''All cookies except the provided ``cookies`` are included in the cache key and automatically included in requests that CloudFront sends to the origin.

        :param cookies: -
        '''
        return typing.cast("CacheCookieBehavior", jsii.sinvoke(cls, "denyList", [*cookies]))

    @jsii.member(jsii_name="none") # type: ignore[misc]
    @builtins.classmethod
    def none(cls) -> "CacheCookieBehavior":
        '''Cookies in viewer requests are not included in the cache key and are not automatically included in requests that CloudFront sends to the origin.'''
        return typing.cast("CacheCookieBehavior", jsii.sinvoke(cls, "none", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="behavior")
    def behavior(self) -> builtins.str:
        '''The behavior of cookies: allow all, none, an allow list, or a deny list.'''
        return typing.cast(builtins.str, jsii.get(self, "behavior"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cookies")
    def cookies(self) -> typing.Optional[typing.List[builtins.str]]:
        '''The cookies to allow or deny, if the behavior is an allow or deny list.'''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "cookies"))


class CacheHeaderBehavior(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CacheHeaderBehavior",
):
    '''Determines whether any HTTP headers are included in the cache key and automatically included in requests that CloudFront sends to the origin.'''

    @jsii.member(jsii_name="allowList") # type: ignore[misc]
    @builtins.classmethod
    def allow_list(cls, *headers: builtins.str) -> "CacheHeaderBehavior":
        '''Listed headers are included in the cache key and are automatically included in requests that CloudFront sends to the origin.

        :param headers: -
        '''
        return typing.cast("CacheHeaderBehavior", jsii.sinvoke(cls, "allowList", [*headers]))

    @jsii.member(jsii_name="none") # type: ignore[misc]
    @builtins.classmethod
    def none(cls) -> "CacheHeaderBehavior":
        '''HTTP headers are not included in the cache key and are not automatically included in requests that CloudFront sends to the origin.'''
        return typing.cast("CacheHeaderBehavior", jsii.sinvoke(cls, "none", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="behavior")
    def behavior(self) -> builtins.str:
        '''If no headers will be passed, or an allow list of headers.'''
        return typing.cast(builtins.str, jsii.get(self, "behavior"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="headers")
    def headers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''The headers for the allow/deny list, if applicable.'''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "headers"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CachePolicyProps",
    jsii_struct_bases=[],
    name_mapping={
        "cache_policy_name": "cachePolicyName",
        "comment": "comment",
        "cookie_behavior": "cookieBehavior",
        "default_ttl": "defaultTtl",
        "enable_accept_encoding_brotli": "enableAcceptEncodingBrotli",
        "enable_accept_encoding_gzip": "enableAcceptEncodingGzip",
        "header_behavior": "headerBehavior",
        "max_ttl": "maxTtl",
        "min_ttl": "minTtl",
        "query_string_behavior": "queryStringBehavior",
    },
)
class CachePolicyProps:
    def __init__(
        self,
        *,
        cache_policy_name: typing.Optional[builtins.str] = None,
        comment: typing.Optional[builtins.str] = None,
        cookie_behavior: typing.Optional[CacheCookieBehavior] = None,
        default_ttl: typing.Optional[aws_cdk.core.Duration] = None,
        enable_accept_encoding_brotli: typing.Optional[builtins.bool] = None,
        enable_accept_encoding_gzip: typing.Optional[builtins.bool] = None,
        header_behavior: typing.Optional[CacheHeaderBehavior] = None,
        max_ttl: typing.Optional[aws_cdk.core.Duration] = None,
        min_ttl: typing.Optional[aws_cdk.core.Duration] = None,
        query_string_behavior: typing.Optional["CacheQueryStringBehavior"] = None,
    ) -> None:
        '''Properties for creating a Cache Policy.

        :param cache_policy_name: A unique name to identify the cache policy. The name must only include '-', '_', or alphanumeric characters. Default: - generated from the ``id``
        :param comment: A comment to describe the cache policy. Default: - no comment
        :param 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. Default: CacheCookieBehavior.none()
        :param default_ttl: The default amount of time for objects to stay in the CloudFront cache. Only used when the origin does not send Cache-Control or Expires headers with the object. Default: - The greater of 1 day and ``minTtl``
        :param enable_accept_encoding_brotli: Whether to normalize and include the ``Accept-Encoding`` header in the cache key when the ``Accept-Encoding`` header is 'br'. Default: false
        :param enable_accept_encoding_gzip: Whether to normalize and include the ``Accept-Encoding`` header in the cache key when the ``Accept-Encoding`` header is 'gzip'. Default: false
        :param header_behavior: Determines whether any HTTP headers are included in the cache key and automatically included in requests that CloudFront sends to the origin. Default: CacheHeaderBehavior.none()
        :param max_ttl: The maximum amount of time for objects to stay in the CloudFront cache. CloudFront uses this value only when the origin sends Cache-Control or Expires headers with the object. Default: - The greater of 1 year and ``defaultTtl``
        :param min_ttl: The minimum amount of time for objects to stay in the CloudFront cache. Default: Duration.seconds(0)
        :param query_string_behavior: Determines whether any query strings are included in the cache key and automatically included in requests that CloudFront sends to the origin. Default: CacheQueryStringBehavior.none()
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if cache_policy_name is not None:
            self._values["cache_policy_name"] = cache_policy_name
        if comment is not None:
            self._values["comment"] = comment
        if cookie_behavior is not None:
            self._values["cookie_behavior"] = cookie_behavior
        if default_ttl is not None:
            self._values["default_ttl"] = default_ttl
        if enable_accept_encoding_brotli is not None:
            self._values["enable_accept_encoding_brotli"] = enable_accept_encoding_brotli
        if enable_accept_encoding_gzip is not None:
            self._values["enable_accept_encoding_gzip"] = enable_accept_encoding_gzip
        if header_behavior is not None:
            self._values["header_behavior"] = header_behavior
        if max_ttl is not None:
            self._values["max_ttl"] = max_ttl
        if min_ttl is not None:
            self._values["min_ttl"] = min_ttl
        if query_string_behavior is not None:
            self._values["query_string_behavior"] = query_string_behavior

    @builtins.property
    def cache_policy_name(self) -> typing.Optional[builtins.str]:
        '''A unique name to identify the cache policy.

        The name must only include '-', '_', or alphanumeric characters.

        :default: - generated from the ``id``
        '''
        result = self._values.get("cache_policy_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def comment(self) -> typing.Optional[builtins.str]:
        '''A comment to describe the cache policy.

        :default: - no comment
        '''
        result = self._values.get("comment")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cookie_behavior(self) -> typing.Optional[CacheCookieBehavior]:
        '''Determines whether any cookies in viewer requests are included in the cache key and automatically included in requests that CloudFront sends to the origin.

        :default: CacheCookieBehavior.none()
        '''
        result = self._values.get("cookie_behavior")
        return typing.cast(typing.Optional[CacheCookieBehavior], result)

    @builtins.property
    def default_ttl(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The default amount of time for objects to stay in the CloudFront cache.

        Only used when the origin does not send Cache-Control or Expires headers with the object.

        :default: - The greater of 1 day and ``minTtl``
        '''
        result = self._values.get("default_ttl")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def enable_accept_encoding_brotli(self) -> typing.Optional[builtins.bool]:
        '''Whether to normalize and include the ``Accept-Encoding`` header in the cache key when the ``Accept-Encoding`` header is 'br'.

        :default: false
        '''
        result = self._values.get("enable_accept_encoding_brotli")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def enable_accept_encoding_gzip(self) -> typing.Optional[builtins.bool]:
        '''Whether to normalize and include the ``Accept-Encoding`` header in the cache key when the ``Accept-Encoding`` header is 'gzip'.

        :default: false
        '''
        result = self._values.get("enable_accept_encoding_gzip")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def header_behavior(self) -> typing.Optional[CacheHeaderBehavior]:
        '''Determines whether any HTTP headers are included in the cache key and automatically included in requests that CloudFront sends to the origin.

        :default: CacheHeaderBehavior.none()
        '''
        result = self._values.get("header_behavior")
        return typing.cast(typing.Optional[CacheHeaderBehavior], result)

    @builtins.property
    def max_ttl(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The maximum amount of time for objects to stay in the CloudFront cache.

        CloudFront uses this value only when the origin sends Cache-Control or Expires headers with the object.

        :default: - The greater of 1 year and ``defaultTtl``
        '''
        result = self._values.get("max_ttl")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def min_ttl(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The minimum amount of time for objects to stay in the CloudFront cache.

        :default: Duration.seconds(0)
        '''
        result = self._values.get("min_ttl")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def query_string_behavior(self) -> typing.Optional["CacheQueryStringBehavior"]:
        '''Determines whether any query strings are included in the cache key and automatically included in requests that CloudFront sends to the origin.

        :default: CacheQueryStringBehavior.none()
        '''
        result = self._values.get("query_string_behavior")
        return typing.cast(typing.Optional["CacheQueryStringBehavior"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CachePolicyProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class CacheQueryStringBehavior(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CacheQueryStringBehavior",
):
    '''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.'''

    @jsii.member(jsii_name="all") # type: ignore[misc]
    @builtins.classmethod
    def all(cls) -> "CacheQueryStringBehavior":
        '''All query strings in viewer requests are included in the cache key and are automatically included in requests that CloudFront sends to the origin.'''
        return typing.cast("CacheQueryStringBehavior", jsii.sinvoke(cls, "all", []))

    @jsii.member(jsii_name="allowList") # type: ignore[misc]
    @builtins.classmethod
    def allow_list(cls, *query_strings: builtins.str) -> "CacheQueryStringBehavior":
        '''Only the provided ``queryStrings`` are included in the cache key and automatically included in requests that CloudFront sends to the origin.

        :param query_strings: -
        '''
        return typing.cast("CacheQueryStringBehavior", jsii.sinvoke(cls, "allowList", [*query_strings]))

    @jsii.member(jsii_name="denyList") # type: ignore[misc]
    @builtins.classmethod
    def deny_list(cls, *query_strings: builtins.str) -> "CacheQueryStringBehavior":
        '''All query strings except the provided ``queryStrings`` are included in the cache key and automatically included in requests that CloudFront sends to the origin.

        :param query_strings: -
        '''
        return typing.cast("CacheQueryStringBehavior", jsii.sinvoke(cls, "denyList", [*query_strings]))

    @jsii.member(jsii_name="none") # type: ignore[misc]
    @builtins.classmethod
    def none(cls) -> "CacheQueryStringBehavior":
        '''Query strings in viewer requests are not included in the cache key and are not automatically included in requests that CloudFront sends to the origin.'''
        return typing.cast("CacheQueryStringBehavior", jsii.sinvoke(cls, "none", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="behavior")
    def behavior(self) -> builtins.str:
        '''The behavior of query strings -- allow all, none, only an allow list, or a deny list.'''
        return typing.cast(builtins.str, jsii.get(self, "behavior"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="queryStrings")
    def query_strings(self) -> typing.Optional[typing.List[builtins.str]]:
        '''The query strings to allow or deny, if the behavior is an allow or deny list.'''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "queryStrings"))


class CachedMethods(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CachedMethods",
):
    '''The HTTP methods that the Behavior will cache requests on.'''

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CACHE_GET_HEAD")
    def CACHE_GET_HEAD(cls) -> "CachedMethods":
        '''HEAD and GET.'''
        return typing.cast("CachedMethods", jsii.sget(cls, "CACHE_GET_HEAD"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CACHE_GET_HEAD_OPTIONS")
    def CACHE_GET_HEAD_OPTIONS(cls) -> "CachedMethods":
        '''HEAD, GET, and OPTIONS.'''
        return typing.cast("CachedMethods", jsii.sget(cls, "CACHE_GET_HEAD_OPTIONS"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="methods")
    def methods(self) -> typing.List[builtins.str]:
        '''HTTP methods supported.'''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "methods"))


@jsii.implements(aws_cdk.core.IInspectable)
class CfnCachePolicy(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CfnCachePolicy",
):
    '''A CloudFormation ``AWS::CloudFront::CachePolicy``.

    :cloudformationResource: AWS::CloudFront::CachePolicy
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-cachepolicy.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        cache_policy_config: typing.Union["CfnCachePolicy.CachePolicyConfigProperty", aws_cdk.core.IResolvable],
    ) -> None:
        '''Create a new ``AWS::CloudFront::CachePolicy``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param cache_policy_config: ``AWS::CloudFront::CachePolicy.CachePolicyConfig``.
        '''
        props = CfnCachePolicyProps(cache_policy_config=cache_policy_config)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrId")
    def attr_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: Id
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrLastModifiedTime")
    def attr_last_modified_time(self) -> builtins.str:
        '''
        :cloudformationAttribute: LastModifiedTime
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrLastModifiedTime"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cachePolicyConfig")
    def cache_policy_config(
        self,
    ) -> typing.Union["CfnCachePolicy.CachePolicyConfigProperty", aws_cdk.core.IResolvable]:
        '''``AWS::CloudFront::CachePolicy.CachePolicyConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-cachepolicy.html#cfn-cloudfront-cachepolicy-cachepolicyconfig
        '''
        return typing.cast(typing.Union["CfnCachePolicy.CachePolicyConfigProperty", aws_cdk.core.IResolvable], jsii.get(self, "cachePolicyConfig"))

    @cache_policy_config.setter
    def cache_policy_config(
        self,
        value: typing.Union["CfnCachePolicy.CachePolicyConfigProperty", aws_cdk.core.IResolvable],
    ) -> None:
        jsii.set(self, "cachePolicyConfig", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnCachePolicy.CachePolicyConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "default_ttl": "defaultTtl",
            "max_ttl": "maxTtl",
            "min_ttl": "minTtl",
            "name": "name",
            "parameters_in_cache_key_and_forwarded_to_origin": "parametersInCacheKeyAndForwardedToOrigin",
            "comment": "comment",
        },
    )
    class CachePolicyConfigProperty:
        def __init__(
            self,
            *,
            default_ttl: jsii.Number,
            max_ttl: jsii.Number,
            min_ttl: jsii.Number,
            name: builtins.str,
            parameters_in_cache_key_and_forwarded_to_origin: typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty"],
            comment: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param default_ttl: ``CfnCachePolicy.CachePolicyConfigProperty.DefaultTTL``.
            :param max_ttl: ``CfnCachePolicy.CachePolicyConfigProperty.MaxTTL``.
            :param min_ttl: ``CfnCachePolicy.CachePolicyConfigProperty.MinTTL``.
            :param name: ``CfnCachePolicy.CachePolicyConfigProperty.Name``.
            :param parameters_in_cache_key_and_forwarded_to_origin: ``CfnCachePolicy.CachePolicyConfigProperty.ParametersInCacheKeyAndForwardedToOrigin``.
            :param comment: ``CfnCachePolicy.CachePolicyConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cachepolicyconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "default_ttl": default_ttl,
                "max_ttl": max_ttl,
                "min_ttl": min_ttl,
                "name": name,
                "parameters_in_cache_key_and_forwarded_to_origin": parameters_in_cache_key_and_forwarded_to_origin,
            }
            if comment is not None:
                self._values["comment"] = comment

        @builtins.property
        def default_ttl(self) -> jsii.Number:
            '''``CfnCachePolicy.CachePolicyConfigProperty.DefaultTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cachepolicyconfig.html#cfn-cloudfront-cachepolicy-cachepolicyconfig-defaultttl
            '''
            result = self._values.get("default_ttl")
            assert result is not None, "Required property 'default_ttl' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def max_ttl(self) -> jsii.Number:
            '''``CfnCachePolicy.CachePolicyConfigProperty.MaxTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cachepolicyconfig.html#cfn-cloudfront-cachepolicy-cachepolicyconfig-maxttl
            '''
            result = self._values.get("max_ttl")
            assert result is not None, "Required property 'max_ttl' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def min_ttl(self) -> jsii.Number:
            '''``CfnCachePolicy.CachePolicyConfigProperty.MinTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cachepolicyconfig.html#cfn-cloudfront-cachepolicy-cachepolicyconfig-minttl
            '''
            result = self._values.get("min_ttl")
            assert result is not None, "Required property 'min_ttl' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def name(self) -> builtins.str:
            '''``CfnCachePolicy.CachePolicyConfigProperty.Name``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cachepolicyconfig.html#cfn-cloudfront-cachepolicy-cachepolicyconfig-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def parameters_in_cache_key_and_forwarded_to_origin(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty"]:
            '''``CfnCachePolicy.CachePolicyConfigProperty.ParametersInCacheKeyAndForwardedToOrigin``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cachepolicyconfig.html#cfn-cloudfront-cachepolicy-cachepolicyconfig-parametersincachekeyandforwardedtoorigin
            '''
            result = self._values.get("parameters_in_cache_key_and_forwarded_to_origin")
            assert result is not None, "Required property 'parameters_in_cache_key_and_forwarded_to_origin' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty"], result)

        @builtins.property
        def comment(self) -> typing.Optional[builtins.str]:
            '''``CfnCachePolicy.CachePolicyConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cachepolicyconfig.html#cfn-cloudfront-cachepolicy-cachepolicyconfig-comment
            '''
            result = self._values.get("comment")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CachePolicyConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnCachePolicy.CookiesConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"cookie_behavior": "cookieBehavior", "cookies": "cookies"},
    )
    class CookiesConfigProperty:
        def __init__(
            self,
            *,
            cookie_behavior: builtins.str,
            cookies: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param cookie_behavior: ``CfnCachePolicy.CookiesConfigProperty.CookieBehavior``.
            :param cookies: ``CfnCachePolicy.CookiesConfigProperty.Cookies``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cookiesconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "cookie_behavior": cookie_behavior,
            }
            if cookies is not None:
                self._values["cookies"] = cookies

        @builtins.property
        def cookie_behavior(self) -> builtins.str:
            '''``CfnCachePolicy.CookiesConfigProperty.CookieBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cookiesconfig.html#cfn-cloudfront-cachepolicy-cookiesconfig-cookiebehavior
            '''
            result = self._values.get("cookie_behavior")
            assert result is not None, "Required property 'cookie_behavior' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def cookies(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnCachePolicy.CookiesConfigProperty.Cookies``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-cookiesconfig.html#cfn-cloudfront-cachepolicy-cookiesconfig-cookies
            '''
            result = self._values.get("cookies")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CookiesConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnCachePolicy.HeadersConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"header_behavior": "headerBehavior", "headers": "headers"},
    )
    class HeadersConfigProperty:
        def __init__(
            self,
            *,
            header_behavior: builtins.str,
            headers: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param header_behavior: ``CfnCachePolicy.HeadersConfigProperty.HeaderBehavior``.
            :param headers: ``CfnCachePolicy.HeadersConfigProperty.Headers``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-headersconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "header_behavior": header_behavior,
            }
            if headers is not None:
                self._values["headers"] = headers

        @builtins.property
        def header_behavior(self) -> builtins.str:
            '''``CfnCachePolicy.HeadersConfigProperty.HeaderBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-headersconfig.html#cfn-cloudfront-cachepolicy-headersconfig-headerbehavior
            '''
            result = self._values.get("header_behavior")
            assert result is not None, "Required property 'header_behavior' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def headers(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnCachePolicy.HeadersConfigProperty.Headers``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-headersconfig.html#cfn-cloudfront-cachepolicy-headersconfig-headers
            '''
            result = self._values.get("headers")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HeadersConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty",
        jsii_struct_bases=[],
        name_mapping={
            "cookies_config": "cookiesConfig",
            "enable_accept_encoding_gzip": "enableAcceptEncodingGzip",
            "headers_config": "headersConfig",
            "query_strings_config": "queryStringsConfig",
            "enable_accept_encoding_brotli": "enableAcceptEncodingBrotli",
        },
    )
    class ParametersInCacheKeyAndForwardedToOriginProperty:
        def __init__(
            self,
            *,
            cookies_config: typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.CookiesConfigProperty"],
            enable_accept_encoding_gzip: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            headers_config: typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.HeadersConfigProperty"],
            query_strings_config: typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.QueryStringsConfigProperty"],
            enable_accept_encoding_brotli: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        ) -> None:
            '''
            :param cookies_config: ``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.CookiesConfig``.
            :param enable_accept_encoding_gzip: ``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.EnableAcceptEncodingGzip``.
            :param headers_config: ``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.HeadersConfig``.
            :param query_strings_config: ``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.QueryStringsConfig``.
            :param enable_accept_encoding_brotli: ``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.EnableAcceptEncodingBrotli``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "cookies_config": cookies_config,
                "enable_accept_encoding_gzip": enable_accept_encoding_gzip,
                "headers_config": headers_config,
                "query_strings_config": query_strings_config,
            }
            if enable_accept_encoding_brotli is not None:
                self._values["enable_accept_encoding_brotli"] = enable_accept_encoding_brotli

        @builtins.property
        def cookies_config(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.CookiesConfigProperty"]:
            '''``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.CookiesConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin.html#cfn-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin-cookiesconfig
            '''
            result = self._values.get("cookies_config")
            assert result is not None, "Required property 'cookies_config' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.CookiesConfigProperty"], result)

        @builtins.property
        def enable_accept_encoding_gzip(
            self,
        ) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.EnableAcceptEncodingGzip``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin.html#cfn-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin-enableacceptencodinggzip
            '''
            result = self._values.get("enable_accept_encoding_gzip")
            assert result is not None, "Required property 'enable_accept_encoding_gzip' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def headers_config(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.HeadersConfigProperty"]:
            '''``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.HeadersConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin.html#cfn-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin-headersconfig
            '''
            result = self._values.get("headers_config")
            assert result is not None, "Required property 'headers_config' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.HeadersConfigProperty"], result)

        @builtins.property
        def query_strings_config(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.QueryStringsConfigProperty"]:
            '''``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.QueryStringsConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin.html#cfn-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin-querystringsconfig
            '''
            result = self._values.get("query_strings_config")
            assert result is not None, "Required property 'query_strings_config' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnCachePolicy.QueryStringsConfigProperty"], result)

        @builtins.property
        def enable_accept_encoding_brotli(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnCachePolicy.ParametersInCacheKeyAndForwardedToOriginProperty.EnableAcceptEncodingBrotli``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin.html#cfn-cloudfront-cachepolicy-parametersincachekeyandforwardedtoorigin-enableacceptencodingbrotli
            '''
            result = self._values.get("enable_accept_encoding_brotli")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ParametersInCacheKeyAndForwardedToOriginProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnCachePolicy.QueryStringsConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "query_string_behavior": "queryStringBehavior",
            "query_strings": "queryStrings",
        },
    )
    class QueryStringsConfigProperty:
        def __init__(
            self,
            *,
            query_string_behavior: builtins.str,
            query_strings: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param query_string_behavior: ``CfnCachePolicy.QueryStringsConfigProperty.QueryStringBehavior``.
            :param query_strings: ``CfnCachePolicy.QueryStringsConfigProperty.QueryStrings``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-querystringsconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "query_string_behavior": query_string_behavior,
            }
            if query_strings is not None:
                self._values["query_strings"] = query_strings

        @builtins.property
        def query_string_behavior(self) -> builtins.str:
            '''``CfnCachePolicy.QueryStringsConfigProperty.QueryStringBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-querystringsconfig.html#cfn-cloudfront-cachepolicy-querystringsconfig-querystringbehavior
            '''
            result = self._values.get("query_string_behavior")
            assert result is not None, "Required property 'query_string_behavior' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def query_strings(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnCachePolicy.QueryStringsConfigProperty.QueryStrings``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cachepolicy-querystringsconfig.html#cfn-cloudfront-cachepolicy-querystringsconfig-querystrings
            '''
            result = self._values.get("query_strings")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "QueryStringsConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CfnCachePolicyProps",
    jsii_struct_bases=[],
    name_mapping={"cache_policy_config": "cachePolicyConfig"},
)
class CfnCachePolicyProps:
    def __init__(
        self,
        *,
        cache_policy_config: typing.Union[CfnCachePolicy.CachePolicyConfigProperty, aws_cdk.core.IResolvable],
    ) -> None:
        '''Properties for defining a ``AWS::CloudFront::CachePolicy``.

        :param cache_policy_config: ``AWS::CloudFront::CachePolicy.CachePolicyConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-cachepolicy.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cache_policy_config": cache_policy_config,
        }

    @builtins.property
    def cache_policy_config(
        self,
    ) -> typing.Union[CfnCachePolicy.CachePolicyConfigProperty, aws_cdk.core.IResolvable]:
        '''``AWS::CloudFront::CachePolicy.CachePolicyConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-cachepolicy.html#cfn-cloudfront-cachepolicy-cachepolicyconfig
        '''
        result = self._values.get("cache_policy_config")
        assert result is not None, "Required property 'cache_policy_config' is missing"
        return typing.cast(typing.Union[CfnCachePolicy.CachePolicyConfigProperty, aws_cdk.core.IResolvable], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnCachePolicyProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnCloudFrontOriginAccessIdentity(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CfnCloudFrontOriginAccessIdentity",
):
    '''A CloudFormation ``AWS::CloudFront::CloudFrontOriginAccessIdentity``.

    :cloudformationResource: AWS::CloudFront::CloudFrontOriginAccessIdentity
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-cloudfrontoriginaccessidentity.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        cloud_front_origin_access_identity_config: typing.Union[aws_cdk.core.IResolvable, "CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty"],
    ) -> None:
        '''Create a new ``AWS::CloudFront::CloudFrontOriginAccessIdentity``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param cloud_front_origin_access_identity_config: ``AWS::CloudFront::CloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfig``.
        '''
        props = CfnCloudFrontOriginAccessIdentityProps(
            cloud_front_origin_access_identity_config=cloud_front_origin_access_identity_config,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrId")
    def attr_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: Id
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrS3CanonicalUserId")
    def attr_s3_canonical_user_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: S3CanonicalUserId
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrS3CanonicalUserId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cloudFrontOriginAccessIdentityConfig")
    def cloud_front_origin_access_identity_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty"]:
        '''``AWS::CloudFront::CloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-cloudfrontoriginaccessidentity.html#cfn-cloudfront-cloudfrontoriginaccessidentity-cloudfrontoriginaccessidentityconfig
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty"], jsii.get(self, "cloudFrontOriginAccessIdentityConfig"))

    @cloud_front_origin_access_identity_config.setter
    def cloud_front_origin_access_identity_config(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty"],
    ) -> None:
        jsii.set(self, "cloudFrontOriginAccessIdentityConfig", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"comment": "comment"},
    )
    class CloudFrontOriginAccessIdentityConfigProperty:
        def __init__(self, *, comment: builtins.str) -> None:
            '''
            :param comment: ``CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cloudfrontoriginaccessidentity-cloudfrontoriginaccessidentityconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "comment": comment,
            }

        @builtins.property
        def comment(self) -> builtins.str:
            '''``CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-cloudfrontoriginaccessidentity-cloudfrontoriginaccessidentityconfig.html#cfn-cloudfront-cloudfrontoriginaccessidentity-cloudfrontoriginaccessidentityconfig-comment
            '''
            result = self._values.get("comment")
            assert result is not None, "Required property 'comment' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CloudFrontOriginAccessIdentityConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CfnCloudFrontOriginAccessIdentityProps",
    jsii_struct_bases=[],
    name_mapping={
        "cloud_front_origin_access_identity_config": "cloudFrontOriginAccessIdentityConfig",
    },
)
class CfnCloudFrontOriginAccessIdentityProps:
    def __init__(
        self,
        *,
        cloud_front_origin_access_identity_config: typing.Union[aws_cdk.core.IResolvable, CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty],
    ) -> None:
        '''Properties for defining a ``AWS::CloudFront::CloudFrontOriginAccessIdentity``.

        :param cloud_front_origin_access_identity_config: ``AWS::CloudFront::CloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-cloudfrontoriginaccessidentity.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "cloud_front_origin_access_identity_config": cloud_front_origin_access_identity_config,
        }

    @builtins.property
    def cloud_front_origin_access_identity_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty]:
        '''``AWS::CloudFront::CloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-cloudfrontoriginaccessidentity.html#cfn-cloudfront-cloudfrontoriginaccessidentity-cloudfrontoriginaccessidentityconfig
        '''
        result = self._values.get("cloud_front_origin_access_identity_config")
        assert result is not None, "Required property 'cloud_front_origin_access_identity_config' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnCloudFrontOriginAccessIdentity.CloudFrontOriginAccessIdentityConfigProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnCloudFrontOriginAccessIdentityProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnDistribution(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution",
):
    '''A CloudFormation ``AWS::CloudFront::Distribution``.

    :cloudformationResource: AWS::CloudFront::Distribution
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-distribution.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        distribution_config: typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.DistributionConfigProperty"],
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Create a new ``AWS::CloudFront::Distribution``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param distribution_config: ``AWS::CloudFront::Distribution.DistributionConfig``.
        :param tags: ``AWS::CloudFront::Distribution.Tags``.
        '''
        props = CfnDistributionProps(
            distribution_config=distribution_config, tags=tags
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrDomainName")
    def attr_domain_name(self) -> builtins.str:
        '''
        :cloudformationAttribute: DomainName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrDomainName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrId")
    def attr_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: Id
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::CloudFront::Distribution.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-distribution.html#cfn-cloudfront-distribution-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="distributionConfig")
    def distribution_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.DistributionConfigProperty"]:
        '''``AWS::CloudFront::Distribution.DistributionConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-distribution.html#cfn-cloudfront-distribution-distributionconfig
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.DistributionConfigProperty"], jsii.get(self, "distributionConfig"))

    @distribution_config.setter
    def distribution_config(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.DistributionConfigProperty"],
    ) -> None:
        jsii.set(self, "distributionConfig", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.CacheBehaviorProperty",
        jsii_struct_bases=[],
        name_mapping={
            "path_pattern": "pathPattern",
            "target_origin_id": "targetOriginId",
            "viewer_protocol_policy": "viewerProtocolPolicy",
            "allowed_methods": "allowedMethods",
            "cached_methods": "cachedMethods",
            "cache_policy_id": "cachePolicyId",
            "compress": "compress",
            "default_ttl": "defaultTtl",
            "field_level_encryption_id": "fieldLevelEncryptionId",
            "forwarded_values": "forwardedValues",
            "function_associations": "functionAssociations",
            "lambda_function_associations": "lambdaFunctionAssociations",
            "max_ttl": "maxTtl",
            "min_ttl": "minTtl",
            "origin_request_policy_id": "originRequestPolicyId",
            "realtime_log_config_arn": "realtimeLogConfigArn",
            "smooth_streaming": "smoothStreaming",
            "trusted_key_groups": "trustedKeyGroups",
            "trusted_signers": "trustedSigners",
        },
    )
    class CacheBehaviorProperty:
        def __init__(
            self,
            *,
            path_pattern: builtins.str,
            target_origin_id: builtins.str,
            viewer_protocol_policy: builtins.str,
            allowed_methods: typing.Optional[typing.Sequence[builtins.str]] = None,
            cached_methods: typing.Optional[typing.Sequence[builtins.str]] = None,
            cache_policy_id: typing.Optional[builtins.str] = None,
            compress: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            default_ttl: typing.Optional[jsii.Number] = None,
            field_level_encryption_id: typing.Optional[builtins.str] = None,
            forwarded_values: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.ForwardedValuesProperty"]] = None,
            function_associations: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.FunctionAssociationProperty"]]]] = None,
            lambda_function_associations: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LambdaFunctionAssociationProperty"]]]] = None,
            max_ttl: typing.Optional[jsii.Number] = None,
            min_ttl: typing.Optional[jsii.Number] = None,
            origin_request_policy_id: typing.Optional[builtins.str] = None,
            realtime_log_config_arn: typing.Optional[builtins.str] = None,
            smooth_streaming: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            trusted_key_groups: typing.Optional[typing.Sequence[builtins.str]] = None,
            trusted_signers: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param path_pattern: ``CfnDistribution.CacheBehaviorProperty.PathPattern``.
            :param target_origin_id: ``CfnDistribution.CacheBehaviorProperty.TargetOriginId``.
            :param viewer_protocol_policy: ``CfnDistribution.CacheBehaviorProperty.ViewerProtocolPolicy``.
            :param allowed_methods: ``CfnDistribution.CacheBehaviorProperty.AllowedMethods``.
            :param cached_methods: ``CfnDistribution.CacheBehaviorProperty.CachedMethods``.
            :param cache_policy_id: ``CfnDistribution.CacheBehaviorProperty.CachePolicyId``.
            :param compress: ``CfnDistribution.CacheBehaviorProperty.Compress``.
            :param default_ttl: ``CfnDistribution.CacheBehaviorProperty.DefaultTTL``.
            :param field_level_encryption_id: ``CfnDistribution.CacheBehaviorProperty.FieldLevelEncryptionId``.
            :param forwarded_values: ``CfnDistribution.CacheBehaviorProperty.ForwardedValues``.
            :param function_associations: ``CfnDistribution.CacheBehaviorProperty.FunctionAssociations``.
            :param lambda_function_associations: ``CfnDistribution.CacheBehaviorProperty.LambdaFunctionAssociations``.
            :param max_ttl: ``CfnDistribution.CacheBehaviorProperty.MaxTTL``.
            :param min_ttl: ``CfnDistribution.CacheBehaviorProperty.MinTTL``.
            :param origin_request_policy_id: ``CfnDistribution.CacheBehaviorProperty.OriginRequestPolicyId``.
            :param realtime_log_config_arn: ``CfnDistribution.CacheBehaviorProperty.RealtimeLogConfigArn``.
            :param smooth_streaming: ``CfnDistribution.CacheBehaviorProperty.SmoothStreaming``.
            :param trusted_key_groups: ``CfnDistribution.CacheBehaviorProperty.TrustedKeyGroups``.
            :param trusted_signers: ``CfnDistribution.CacheBehaviorProperty.TrustedSigners``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "path_pattern": path_pattern,
                "target_origin_id": target_origin_id,
                "viewer_protocol_policy": viewer_protocol_policy,
            }
            if allowed_methods is not None:
                self._values["allowed_methods"] = allowed_methods
            if cached_methods is not None:
                self._values["cached_methods"] = cached_methods
            if cache_policy_id is not None:
                self._values["cache_policy_id"] = cache_policy_id
            if compress is not None:
                self._values["compress"] = compress
            if default_ttl is not None:
                self._values["default_ttl"] = default_ttl
            if field_level_encryption_id is not None:
                self._values["field_level_encryption_id"] = field_level_encryption_id
            if forwarded_values is not None:
                self._values["forwarded_values"] = forwarded_values
            if function_associations is not None:
                self._values["function_associations"] = function_associations
            if lambda_function_associations is not None:
                self._values["lambda_function_associations"] = lambda_function_associations
            if max_ttl is not None:
                self._values["max_ttl"] = max_ttl
            if min_ttl is not None:
                self._values["min_ttl"] = min_ttl
            if origin_request_policy_id is not None:
                self._values["origin_request_policy_id"] = origin_request_policy_id
            if realtime_log_config_arn is not None:
                self._values["realtime_log_config_arn"] = realtime_log_config_arn
            if smooth_streaming is not None:
                self._values["smooth_streaming"] = smooth_streaming
            if trusted_key_groups is not None:
                self._values["trusted_key_groups"] = trusted_key_groups
            if trusted_signers is not None:
                self._values["trusted_signers"] = trusted_signers

        @builtins.property
        def path_pattern(self) -> builtins.str:
            '''``CfnDistribution.CacheBehaviorProperty.PathPattern``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-pathpattern
            '''
            result = self._values.get("path_pattern")
            assert result is not None, "Required property 'path_pattern' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def target_origin_id(self) -> builtins.str:
            '''``CfnDistribution.CacheBehaviorProperty.TargetOriginId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-targetoriginid
            '''
            result = self._values.get("target_origin_id")
            assert result is not None, "Required property 'target_origin_id' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def viewer_protocol_policy(self) -> builtins.str:
            '''``CfnDistribution.CacheBehaviorProperty.ViewerProtocolPolicy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-viewerprotocolpolicy
            '''
            result = self._values.get("viewer_protocol_policy")
            assert result is not None, "Required property 'viewer_protocol_policy' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def allowed_methods(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.CacheBehaviorProperty.AllowedMethods``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-allowedmethods
            '''
            result = self._values.get("allowed_methods")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def cached_methods(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.CacheBehaviorProperty.CachedMethods``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-cachedmethods
            '''
            result = self._values.get("cached_methods")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def cache_policy_id(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.CacheBehaviorProperty.CachePolicyId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-cachepolicyid
            '''
            result = self._values.get("cache_policy_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def compress(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnDistribution.CacheBehaviorProperty.Compress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-compress
            '''
            result = self._values.get("compress")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def default_ttl(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.CacheBehaviorProperty.DefaultTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-defaultttl
            '''
            result = self._values.get("default_ttl")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def field_level_encryption_id(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.CacheBehaviorProperty.FieldLevelEncryptionId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-fieldlevelencryptionid
            '''
            result = self._values.get("field_level_encryption_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def forwarded_values(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.ForwardedValuesProperty"]]:
            '''``CfnDistribution.CacheBehaviorProperty.ForwardedValues``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-forwardedvalues
            '''
            result = self._values.get("forwarded_values")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.ForwardedValuesProperty"]], result)

        @builtins.property
        def function_associations(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.FunctionAssociationProperty"]]]]:
            '''``CfnDistribution.CacheBehaviorProperty.FunctionAssociations``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-functionassociations
            '''
            result = self._values.get("function_associations")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.FunctionAssociationProperty"]]]], result)

        @builtins.property
        def lambda_function_associations(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LambdaFunctionAssociationProperty"]]]]:
            '''``CfnDistribution.CacheBehaviorProperty.LambdaFunctionAssociations``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-lambdafunctionassociations
            '''
            result = self._values.get("lambda_function_associations")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LambdaFunctionAssociationProperty"]]]], result)

        @builtins.property
        def max_ttl(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.CacheBehaviorProperty.MaxTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-maxttl
            '''
            result = self._values.get("max_ttl")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def min_ttl(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.CacheBehaviorProperty.MinTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-minttl
            '''
            result = self._values.get("min_ttl")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def origin_request_policy_id(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.CacheBehaviorProperty.OriginRequestPolicyId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-originrequestpolicyid
            '''
            result = self._values.get("origin_request_policy_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def realtime_log_config_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.CacheBehaviorProperty.RealtimeLogConfigArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-realtimelogconfigarn
            '''
            result = self._values.get("realtime_log_config_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def smooth_streaming(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnDistribution.CacheBehaviorProperty.SmoothStreaming``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-smoothstreaming
            '''
            result = self._values.get("smooth_streaming")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def trusted_key_groups(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.CacheBehaviorProperty.TrustedKeyGroups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-trustedkeygroups
            '''
            result = self._values.get("trusted_key_groups")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def trusted_signers(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.CacheBehaviorProperty.TrustedSigners``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html#cfn-cloudfront-distribution-cachebehavior-trustedsigners
            '''
            result = self._values.get("trusted_signers")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CacheBehaviorProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.CookiesProperty",
        jsii_struct_bases=[],
        name_mapping={"forward": "forward", "whitelisted_names": "whitelistedNames"},
    )
    class CookiesProperty:
        def __init__(
            self,
            *,
            forward: builtins.str,
            whitelisted_names: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param forward: ``CfnDistribution.CookiesProperty.Forward``.
            :param whitelisted_names: ``CfnDistribution.CookiesProperty.WhitelistedNames``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cookies.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "forward": forward,
            }
            if whitelisted_names is not None:
                self._values["whitelisted_names"] = whitelisted_names

        @builtins.property
        def forward(self) -> builtins.str:
            '''``CfnDistribution.CookiesProperty.Forward``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cookies.html#cfn-cloudfront-distribution-cookies-forward
            '''
            result = self._values.get("forward")
            assert result is not None, "Required property 'forward' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def whitelisted_names(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.CookiesProperty.WhitelistedNames``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cookies.html#cfn-cloudfront-distribution-cookies-whitelistednames
            '''
            result = self._values.get("whitelisted_names")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CookiesProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.CustomErrorResponseProperty",
        jsii_struct_bases=[],
        name_mapping={
            "error_code": "errorCode",
            "error_caching_min_ttl": "errorCachingMinTtl",
            "response_code": "responseCode",
            "response_page_path": "responsePagePath",
        },
    )
    class CustomErrorResponseProperty:
        def __init__(
            self,
            *,
            error_code: jsii.Number,
            error_caching_min_ttl: typing.Optional[jsii.Number] = None,
            response_code: typing.Optional[jsii.Number] = None,
            response_page_path: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param error_code: ``CfnDistribution.CustomErrorResponseProperty.ErrorCode``.
            :param error_caching_min_ttl: ``CfnDistribution.CustomErrorResponseProperty.ErrorCachingMinTTL``.
            :param response_code: ``CfnDistribution.CustomErrorResponseProperty.ResponseCode``.
            :param response_page_path: ``CfnDistribution.CustomErrorResponseProperty.ResponsePagePath``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customerrorresponse.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "error_code": error_code,
            }
            if error_caching_min_ttl is not None:
                self._values["error_caching_min_ttl"] = error_caching_min_ttl
            if response_code is not None:
                self._values["response_code"] = response_code
            if response_page_path is not None:
                self._values["response_page_path"] = response_page_path

        @builtins.property
        def error_code(self) -> jsii.Number:
            '''``CfnDistribution.CustomErrorResponseProperty.ErrorCode``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customerrorresponse.html#cfn-cloudfront-distribution-customerrorresponse-errorcode
            '''
            result = self._values.get("error_code")
            assert result is not None, "Required property 'error_code' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def error_caching_min_ttl(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.CustomErrorResponseProperty.ErrorCachingMinTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customerrorresponse.html#cfn-cloudfront-distribution-customerrorresponse-errorcachingminttl
            '''
            result = self._values.get("error_caching_min_ttl")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def response_code(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.CustomErrorResponseProperty.ResponseCode``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customerrorresponse.html#cfn-cloudfront-distribution-customerrorresponse-responsecode
            '''
            result = self._values.get("response_code")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def response_page_path(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.CustomErrorResponseProperty.ResponsePagePath``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customerrorresponse.html#cfn-cloudfront-distribution-customerrorresponse-responsepagepath
            '''
            result = self._values.get("response_page_path")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CustomErrorResponseProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.CustomOriginConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "origin_protocol_policy": "originProtocolPolicy",
            "http_port": "httpPort",
            "https_port": "httpsPort",
            "origin_keepalive_timeout": "originKeepaliveTimeout",
            "origin_read_timeout": "originReadTimeout",
            "origin_ssl_protocols": "originSslProtocols",
        },
    )
    class CustomOriginConfigProperty:
        def __init__(
            self,
            *,
            origin_protocol_policy: builtins.str,
            http_port: typing.Optional[jsii.Number] = None,
            https_port: typing.Optional[jsii.Number] = None,
            origin_keepalive_timeout: typing.Optional[jsii.Number] = None,
            origin_read_timeout: typing.Optional[jsii.Number] = None,
            origin_ssl_protocols: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param origin_protocol_policy: ``CfnDistribution.CustomOriginConfigProperty.OriginProtocolPolicy``.
            :param http_port: ``CfnDistribution.CustomOriginConfigProperty.HTTPPort``.
            :param https_port: ``CfnDistribution.CustomOriginConfigProperty.HTTPSPort``.
            :param origin_keepalive_timeout: ``CfnDistribution.CustomOriginConfigProperty.OriginKeepaliveTimeout``.
            :param origin_read_timeout: ``CfnDistribution.CustomOriginConfigProperty.OriginReadTimeout``.
            :param origin_ssl_protocols: ``CfnDistribution.CustomOriginConfigProperty.OriginSSLProtocols``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customoriginconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "origin_protocol_policy": origin_protocol_policy,
            }
            if http_port is not None:
                self._values["http_port"] = http_port
            if https_port is not None:
                self._values["https_port"] = https_port
            if origin_keepalive_timeout is not None:
                self._values["origin_keepalive_timeout"] = origin_keepalive_timeout
            if origin_read_timeout is not None:
                self._values["origin_read_timeout"] = origin_read_timeout
            if origin_ssl_protocols is not None:
                self._values["origin_ssl_protocols"] = origin_ssl_protocols

        @builtins.property
        def origin_protocol_policy(self) -> builtins.str:
            '''``CfnDistribution.CustomOriginConfigProperty.OriginProtocolPolicy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customoriginconfig.html#cfn-cloudfront-distribution-customoriginconfig-originprotocolpolicy
            '''
            result = self._values.get("origin_protocol_policy")
            assert result is not None, "Required property 'origin_protocol_policy' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def http_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.CustomOriginConfigProperty.HTTPPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customoriginconfig.html#cfn-cloudfront-distribution-customoriginconfig-httpport
            '''
            result = self._values.get("http_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def https_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.CustomOriginConfigProperty.HTTPSPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customoriginconfig.html#cfn-cloudfront-distribution-customoriginconfig-httpsport
            '''
            result = self._values.get("https_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def origin_keepalive_timeout(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.CustomOriginConfigProperty.OriginKeepaliveTimeout``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customoriginconfig.html#cfn-cloudfront-distribution-customoriginconfig-originkeepalivetimeout
            '''
            result = self._values.get("origin_keepalive_timeout")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def origin_read_timeout(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.CustomOriginConfigProperty.OriginReadTimeout``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customoriginconfig.html#cfn-cloudfront-distribution-customoriginconfig-originreadtimeout
            '''
            result = self._values.get("origin_read_timeout")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def origin_ssl_protocols(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.CustomOriginConfigProperty.OriginSSLProtocols``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-customoriginconfig.html#cfn-cloudfront-distribution-customoriginconfig-originsslprotocols
            '''
            result = self._values.get("origin_ssl_protocols")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CustomOriginConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.DefaultCacheBehaviorProperty",
        jsii_struct_bases=[],
        name_mapping={
            "target_origin_id": "targetOriginId",
            "viewer_protocol_policy": "viewerProtocolPolicy",
            "allowed_methods": "allowedMethods",
            "cached_methods": "cachedMethods",
            "cache_policy_id": "cachePolicyId",
            "compress": "compress",
            "default_ttl": "defaultTtl",
            "field_level_encryption_id": "fieldLevelEncryptionId",
            "forwarded_values": "forwardedValues",
            "function_associations": "functionAssociations",
            "lambda_function_associations": "lambdaFunctionAssociations",
            "max_ttl": "maxTtl",
            "min_ttl": "minTtl",
            "origin_request_policy_id": "originRequestPolicyId",
            "realtime_log_config_arn": "realtimeLogConfigArn",
            "smooth_streaming": "smoothStreaming",
            "trusted_key_groups": "trustedKeyGroups",
            "trusted_signers": "trustedSigners",
        },
    )
    class DefaultCacheBehaviorProperty:
        def __init__(
            self,
            *,
            target_origin_id: builtins.str,
            viewer_protocol_policy: builtins.str,
            allowed_methods: typing.Optional[typing.Sequence[builtins.str]] = None,
            cached_methods: typing.Optional[typing.Sequence[builtins.str]] = None,
            cache_policy_id: typing.Optional[builtins.str] = None,
            compress: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            default_ttl: typing.Optional[jsii.Number] = None,
            field_level_encryption_id: typing.Optional[builtins.str] = None,
            forwarded_values: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.ForwardedValuesProperty"]] = None,
            function_associations: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.FunctionAssociationProperty"]]]] = None,
            lambda_function_associations: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LambdaFunctionAssociationProperty"]]]] = None,
            max_ttl: typing.Optional[jsii.Number] = None,
            min_ttl: typing.Optional[jsii.Number] = None,
            origin_request_policy_id: typing.Optional[builtins.str] = None,
            realtime_log_config_arn: typing.Optional[builtins.str] = None,
            smooth_streaming: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            trusted_key_groups: typing.Optional[typing.Sequence[builtins.str]] = None,
            trusted_signers: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param target_origin_id: ``CfnDistribution.DefaultCacheBehaviorProperty.TargetOriginId``.
            :param viewer_protocol_policy: ``CfnDistribution.DefaultCacheBehaviorProperty.ViewerProtocolPolicy``.
            :param allowed_methods: ``CfnDistribution.DefaultCacheBehaviorProperty.AllowedMethods``.
            :param cached_methods: ``CfnDistribution.DefaultCacheBehaviorProperty.CachedMethods``.
            :param cache_policy_id: ``CfnDistribution.DefaultCacheBehaviorProperty.CachePolicyId``.
            :param compress: ``CfnDistribution.DefaultCacheBehaviorProperty.Compress``.
            :param default_ttl: ``CfnDistribution.DefaultCacheBehaviorProperty.DefaultTTL``.
            :param field_level_encryption_id: ``CfnDistribution.DefaultCacheBehaviorProperty.FieldLevelEncryptionId``.
            :param forwarded_values: ``CfnDistribution.DefaultCacheBehaviorProperty.ForwardedValues``.
            :param function_associations: ``CfnDistribution.DefaultCacheBehaviorProperty.FunctionAssociations``.
            :param lambda_function_associations: ``CfnDistribution.DefaultCacheBehaviorProperty.LambdaFunctionAssociations``.
            :param max_ttl: ``CfnDistribution.DefaultCacheBehaviorProperty.MaxTTL``.
            :param min_ttl: ``CfnDistribution.DefaultCacheBehaviorProperty.MinTTL``.
            :param origin_request_policy_id: ``CfnDistribution.DefaultCacheBehaviorProperty.OriginRequestPolicyId``.
            :param realtime_log_config_arn: ``CfnDistribution.DefaultCacheBehaviorProperty.RealtimeLogConfigArn``.
            :param smooth_streaming: ``CfnDistribution.DefaultCacheBehaviorProperty.SmoothStreaming``.
            :param trusted_key_groups: ``CfnDistribution.DefaultCacheBehaviorProperty.TrustedKeyGroups``.
            :param trusted_signers: ``CfnDistribution.DefaultCacheBehaviorProperty.TrustedSigners``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "target_origin_id": target_origin_id,
                "viewer_protocol_policy": viewer_protocol_policy,
            }
            if allowed_methods is not None:
                self._values["allowed_methods"] = allowed_methods
            if cached_methods is not None:
                self._values["cached_methods"] = cached_methods
            if cache_policy_id is not None:
                self._values["cache_policy_id"] = cache_policy_id
            if compress is not None:
                self._values["compress"] = compress
            if default_ttl is not None:
                self._values["default_ttl"] = default_ttl
            if field_level_encryption_id is not None:
                self._values["field_level_encryption_id"] = field_level_encryption_id
            if forwarded_values is not None:
                self._values["forwarded_values"] = forwarded_values
            if function_associations is not None:
                self._values["function_associations"] = function_associations
            if lambda_function_associations is not None:
                self._values["lambda_function_associations"] = lambda_function_associations
            if max_ttl is not None:
                self._values["max_ttl"] = max_ttl
            if min_ttl is not None:
                self._values["min_ttl"] = min_ttl
            if origin_request_policy_id is not None:
                self._values["origin_request_policy_id"] = origin_request_policy_id
            if realtime_log_config_arn is not None:
                self._values["realtime_log_config_arn"] = realtime_log_config_arn
            if smooth_streaming is not None:
                self._values["smooth_streaming"] = smooth_streaming
            if trusted_key_groups is not None:
                self._values["trusted_key_groups"] = trusted_key_groups
            if trusted_signers is not None:
                self._values["trusted_signers"] = trusted_signers

        @builtins.property
        def target_origin_id(self) -> builtins.str:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.TargetOriginId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-targetoriginid
            '''
            result = self._values.get("target_origin_id")
            assert result is not None, "Required property 'target_origin_id' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def viewer_protocol_policy(self) -> builtins.str:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.ViewerProtocolPolicy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-viewerprotocolpolicy
            '''
            result = self._values.get("viewer_protocol_policy")
            assert result is not None, "Required property 'viewer_protocol_policy' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def allowed_methods(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.AllowedMethods``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-allowedmethods
            '''
            result = self._values.get("allowed_methods")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def cached_methods(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.CachedMethods``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-cachedmethods
            '''
            result = self._values.get("cached_methods")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def cache_policy_id(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.CachePolicyId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-cachepolicyid
            '''
            result = self._values.get("cache_policy_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def compress(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.Compress``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-compress
            '''
            result = self._values.get("compress")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def default_ttl(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.DefaultTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-defaultttl
            '''
            result = self._values.get("default_ttl")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def field_level_encryption_id(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.FieldLevelEncryptionId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-fieldlevelencryptionid
            '''
            result = self._values.get("field_level_encryption_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def forwarded_values(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.ForwardedValuesProperty"]]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.ForwardedValues``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-forwardedvalues
            '''
            result = self._values.get("forwarded_values")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.ForwardedValuesProperty"]], result)

        @builtins.property
        def function_associations(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.FunctionAssociationProperty"]]]]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.FunctionAssociations``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-functionassociations
            '''
            result = self._values.get("function_associations")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.FunctionAssociationProperty"]]]], result)

        @builtins.property
        def lambda_function_associations(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LambdaFunctionAssociationProperty"]]]]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.LambdaFunctionAssociations``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-lambdafunctionassociations
            '''
            result = self._values.get("lambda_function_associations")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LambdaFunctionAssociationProperty"]]]], result)

        @builtins.property
        def max_ttl(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.MaxTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-maxttl
            '''
            result = self._values.get("max_ttl")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def min_ttl(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.MinTTL``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-minttl
            '''
            result = self._values.get("min_ttl")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def origin_request_policy_id(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.OriginRequestPolicyId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-originrequestpolicyid
            '''
            result = self._values.get("origin_request_policy_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def realtime_log_config_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.RealtimeLogConfigArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-realtimelogconfigarn
            '''
            result = self._values.get("realtime_log_config_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def smooth_streaming(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.SmoothStreaming``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-smoothstreaming
            '''
            result = self._values.get("smooth_streaming")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def trusted_key_groups(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.TrustedKeyGroups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-trustedkeygroups
            '''
            result = self._values.get("trusted_key_groups")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def trusted_signers(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.DefaultCacheBehaviorProperty.TrustedSigners``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-defaultcachebehavior.html#cfn-cloudfront-distribution-defaultcachebehavior-trustedsigners
            '''
            result = self._values.get("trusted_signers")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "DefaultCacheBehaviorProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.DistributionConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "enabled": "enabled",
            "aliases": "aliases",
            "cache_behaviors": "cacheBehaviors",
            "cnam_es": "cnamEs",
            "comment": "comment",
            "custom_error_responses": "customErrorResponses",
            "custom_origin": "customOrigin",
            "default_cache_behavior": "defaultCacheBehavior",
            "default_root_object": "defaultRootObject",
            "http_version": "httpVersion",
            "ipv6_enabled": "ipv6Enabled",
            "logging": "logging",
            "origin_groups": "originGroups",
            "origins": "origins",
            "price_class": "priceClass",
            "restrictions": "restrictions",
            "s3_origin": "s3Origin",
            "viewer_certificate": "viewerCertificate",
            "web_acl_id": "webAclId",
        },
    )
    class DistributionConfigProperty:
        def __init__(
            self,
            *,
            enabled: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            aliases: typing.Optional[typing.Sequence[builtins.str]] = None,
            cache_behaviors: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CacheBehaviorProperty"]]]] = None,
            cnam_es: typing.Optional[typing.Sequence[builtins.str]] = None,
            comment: typing.Optional[builtins.str] = None,
            custom_error_responses: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CustomErrorResponseProperty"]]]] = None,
            custom_origin: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LegacyCustomOriginProperty"]] = None,
            default_cache_behavior: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.DefaultCacheBehaviorProperty"]] = None,
            default_root_object: typing.Optional[builtins.str] = None,
            http_version: typing.Optional[builtins.str] = None,
            ipv6_enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            logging: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LoggingProperty"]] = None,
            origin_groups: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupsProperty"]] = None,
            origins: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union["CfnDistribution.OriginProperty", aws_cdk.core.IResolvable]]]] = None,
            price_class: typing.Optional[builtins.str] = None,
            restrictions: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.RestrictionsProperty"]] = None,
            s3_origin: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LegacyS3OriginProperty"]] = None,
            viewer_certificate: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.ViewerCertificateProperty"]] = None,
            web_acl_id: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param enabled: ``CfnDistribution.DistributionConfigProperty.Enabled``.
            :param aliases: ``CfnDistribution.DistributionConfigProperty.Aliases``.
            :param cache_behaviors: ``CfnDistribution.DistributionConfigProperty.CacheBehaviors``.
            :param cnam_es: ``CfnDistribution.DistributionConfigProperty.CNAMEs``.
            :param comment: ``CfnDistribution.DistributionConfigProperty.Comment``.
            :param custom_error_responses: ``CfnDistribution.DistributionConfigProperty.CustomErrorResponses``.
            :param custom_origin: ``CfnDistribution.DistributionConfigProperty.CustomOrigin``.
            :param default_cache_behavior: ``CfnDistribution.DistributionConfigProperty.DefaultCacheBehavior``.
            :param default_root_object: ``CfnDistribution.DistributionConfigProperty.DefaultRootObject``.
            :param http_version: ``CfnDistribution.DistributionConfigProperty.HttpVersion``.
            :param ipv6_enabled: ``CfnDistribution.DistributionConfigProperty.IPV6Enabled``.
            :param logging: ``CfnDistribution.DistributionConfigProperty.Logging``.
            :param origin_groups: ``CfnDistribution.DistributionConfigProperty.OriginGroups``.
            :param origins: ``CfnDistribution.DistributionConfigProperty.Origins``.
            :param price_class: ``CfnDistribution.DistributionConfigProperty.PriceClass``.
            :param restrictions: ``CfnDistribution.DistributionConfigProperty.Restrictions``.
            :param s3_origin: ``CfnDistribution.DistributionConfigProperty.S3Origin``.
            :param viewer_certificate: ``CfnDistribution.DistributionConfigProperty.ViewerCertificate``.
            :param web_acl_id: ``CfnDistribution.DistributionConfigProperty.WebACLId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "enabled": enabled,
            }
            if aliases is not None:
                self._values["aliases"] = aliases
            if cache_behaviors is not None:
                self._values["cache_behaviors"] = cache_behaviors
            if cnam_es is not None:
                self._values["cnam_es"] = cnam_es
            if comment is not None:
                self._values["comment"] = comment
            if custom_error_responses is not None:
                self._values["custom_error_responses"] = custom_error_responses
            if custom_origin is not None:
                self._values["custom_origin"] = custom_origin
            if default_cache_behavior is not None:
                self._values["default_cache_behavior"] = default_cache_behavior
            if default_root_object is not None:
                self._values["default_root_object"] = default_root_object
            if http_version is not None:
                self._values["http_version"] = http_version
            if ipv6_enabled is not None:
                self._values["ipv6_enabled"] = ipv6_enabled
            if logging is not None:
                self._values["logging"] = logging
            if origin_groups is not None:
                self._values["origin_groups"] = origin_groups
            if origins is not None:
                self._values["origins"] = origins
            if price_class is not None:
                self._values["price_class"] = price_class
            if restrictions is not None:
                self._values["restrictions"] = restrictions
            if s3_origin is not None:
                self._values["s3_origin"] = s3_origin
            if viewer_certificate is not None:
                self._values["viewer_certificate"] = viewer_certificate
            if web_acl_id is not None:
                self._values["web_acl_id"] = web_acl_id

        @builtins.property
        def enabled(self) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnDistribution.DistributionConfigProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-enabled
            '''
            result = self._values.get("enabled")
            assert result is not None, "Required property 'enabled' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def aliases(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.DistributionConfigProperty.Aliases``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-aliases
            '''
            result = self._values.get("aliases")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def cache_behaviors(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CacheBehaviorProperty"]]]]:
            '''``CfnDistribution.DistributionConfigProperty.CacheBehaviors``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-cachebehaviors
            '''
            result = self._values.get("cache_behaviors")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CacheBehaviorProperty"]]]], result)

        @builtins.property
        def cnam_es(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.DistributionConfigProperty.CNAMEs``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-cnames
            '''
            result = self._values.get("cnam_es")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def comment(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.DistributionConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-comment
            '''
            result = self._values.get("comment")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def custom_error_responses(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CustomErrorResponseProperty"]]]]:
            '''``CfnDistribution.DistributionConfigProperty.CustomErrorResponses``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-customerrorresponses
            '''
            result = self._values.get("custom_error_responses")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CustomErrorResponseProperty"]]]], result)

        @builtins.property
        def custom_origin(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LegacyCustomOriginProperty"]]:
            '''``CfnDistribution.DistributionConfigProperty.CustomOrigin``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-customorigin
            '''
            result = self._values.get("custom_origin")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LegacyCustomOriginProperty"]], result)

        @builtins.property
        def default_cache_behavior(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.DefaultCacheBehaviorProperty"]]:
            '''``CfnDistribution.DistributionConfigProperty.DefaultCacheBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-defaultcachebehavior
            '''
            result = self._values.get("default_cache_behavior")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.DefaultCacheBehaviorProperty"]], result)

        @builtins.property
        def default_root_object(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.DistributionConfigProperty.DefaultRootObject``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-defaultrootobject
            '''
            result = self._values.get("default_root_object")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def http_version(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.DistributionConfigProperty.HttpVersion``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-httpversion
            '''
            result = self._values.get("http_version")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def ipv6_enabled(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnDistribution.DistributionConfigProperty.IPV6Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-ipv6enabled
            '''
            result = self._values.get("ipv6_enabled")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def logging(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LoggingProperty"]]:
            '''``CfnDistribution.DistributionConfigProperty.Logging``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-logging
            '''
            result = self._values.get("logging")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LoggingProperty"]], result)

        @builtins.property
        def origin_groups(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupsProperty"]]:
            '''``CfnDistribution.DistributionConfigProperty.OriginGroups``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-origingroups
            '''
            result = self._values.get("origin_groups")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupsProperty"]], result)

        @builtins.property
        def origins(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union["CfnDistribution.OriginProperty", aws_cdk.core.IResolvable]]]]:
            '''``CfnDistribution.DistributionConfigProperty.Origins``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-origins
            '''
            result = self._values.get("origins")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union["CfnDistribution.OriginProperty", aws_cdk.core.IResolvable]]]], result)

        @builtins.property
        def price_class(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.DistributionConfigProperty.PriceClass``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-priceclass
            '''
            result = self._values.get("price_class")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def restrictions(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.RestrictionsProperty"]]:
            '''``CfnDistribution.DistributionConfigProperty.Restrictions``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-restrictions
            '''
            result = self._values.get("restrictions")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.RestrictionsProperty"]], result)

        @builtins.property
        def s3_origin(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LegacyS3OriginProperty"]]:
            '''``CfnDistribution.DistributionConfigProperty.S3Origin``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-s3origin
            '''
            result = self._values.get("s3_origin")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.LegacyS3OriginProperty"]], result)

        @builtins.property
        def viewer_certificate(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.ViewerCertificateProperty"]]:
            '''``CfnDistribution.DistributionConfigProperty.ViewerCertificate``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-viewercertificate
            '''
            result = self._values.get("viewer_certificate")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.ViewerCertificateProperty"]], result)

        @builtins.property
        def web_acl_id(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.DistributionConfigProperty.WebACLId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-distributionconfig.html#cfn-cloudfront-distribution-distributionconfig-webaclid
            '''
            result = self._values.get("web_acl_id")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "DistributionConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.ForwardedValuesProperty",
        jsii_struct_bases=[],
        name_mapping={
            "query_string": "queryString",
            "cookies": "cookies",
            "headers": "headers",
            "query_string_cache_keys": "queryStringCacheKeys",
        },
    )
    class ForwardedValuesProperty:
        def __init__(
            self,
            *,
            query_string: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            cookies: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CookiesProperty"]] = None,
            headers: typing.Optional[typing.Sequence[builtins.str]] = None,
            query_string_cache_keys: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param query_string: ``CfnDistribution.ForwardedValuesProperty.QueryString``.
            :param cookies: ``CfnDistribution.ForwardedValuesProperty.Cookies``.
            :param headers: ``CfnDistribution.ForwardedValuesProperty.Headers``.
            :param query_string_cache_keys: ``CfnDistribution.ForwardedValuesProperty.QueryStringCacheKeys``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-forwardedvalues.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "query_string": query_string,
            }
            if cookies is not None:
                self._values["cookies"] = cookies
            if headers is not None:
                self._values["headers"] = headers
            if query_string_cache_keys is not None:
                self._values["query_string_cache_keys"] = query_string_cache_keys

        @builtins.property
        def query_string(self) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnDistribution.ForwardedValuesProperty.QueryString``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-forwardedvalues.html#cfn-cloudfront-distribution-forwardedvalues-querystring
            '''
            result = self._values.get("query_string")
            assert result is not None, "Required property 'query_string' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def cookies(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CookiesProperty"]]:
            '''``CfnDistribution.ForwardedValuesProperty.Cookies``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-forwardedvalues.html#cfn-cloudfront-distribution-forwardedvalues-cookies
            '''
            result = self._values.get("cookies")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CookiesProperty"]], result)

        @builtins.property
        def headers(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.ForwardedValuesProperty.Headers``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-forwardedvalues.html#cfn-cloudfront-distribution-forwardedvalues-headers
            '''
            result = self._values.get("headers")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def query_string_cache_keys(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.ForwardedValuesProperty.QueryStringCacheKeys``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-forwardedvalues.html#cfn-cloudfront-distribution-forwardedvalues-querystringcachekeys
            '''
            result = self._values.get("query_string_cache_keys")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ForwardedValuesProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.FunctionAssociationProperty",
        jsii_struct_bases=[],
        name_mapping={"event_type": "eventType", "function_arn": "functionArn"},
    )
    class FunctionAssociationProperty:
        def __init__(
            self,
            *,
            event_type: typing.Optional[builtins.str] = None,
            function_arn: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param event_type: ``CfnDistribution.FunctionAssociationProperty.EventType``.
            :param function_arn: ``CfnDistribution.FunctionAssociationProperty.FunctionARN``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-functionassociation.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if event_type is not None:
                self._values["event_type"] = event_type
            if function_arn is not None:
                self._values["function_arn"] = function_arn

        @builtins.property
        def event_type(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.FunctionAssociationProperty.EventType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-functionassociation.html#cfn-cloudfront-distribution-functionassociation-eventtype
            '''
            result = self._values.get("event_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def function_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.FunctionAssociationProperty.FunctionARN``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-functionassociation.html#cfn-cloudfront-distribution-functionassociation-functionarn
            '''
            result = self._values.get("function_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "FunctionAssociationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.GeoRestrictionProperty",
        jsii_struct_bases=[],
        name_mapping={"restriction_type": "restrictionType", "locations": "locations"},
    )
    class GeoRestrictionProperty:
        def __init__(
            self,
            *,
            restriction_type: builtins.str,
            locations: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param restriction_type: ``CfnDistribution.GeoRestrictionProperty.RestrictionType``.
            :param locations: ``CfnDistribution.GeoRestrictionProperty.Locations``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-georestriction.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "restriction_type": restriction_type,
            }
            if locations is not None:
                self._values["locations"] = locations

        @builtins.property
        def restriction_type(self) -> builtins.str:
            '''``CfnDistribution.GeoRestrictionProperty.RestrictionType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-georestriction.html#cfn-cloudfront-distribution-georestriction-restrictiontype
            '''
            result = self._values.get("restriction_type")
            assert result is not None, "Required property 'restriction_type' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def locations(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnDistribution.GeoRestrictionProperty.Locations``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-georestriction.html#cfn-cloudfront-distribution-georestriction-locations
            '''
            result = self._values.get("locations")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "GeoRestrictionProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.LambdaFunctionAssociationProperty",
        jsii_struct_bases=[],
        name_mapping={
            "event_type": "eventType",
            "include_body": "includeBody",
            "lambda_function_arn": "lambdaFunctionArn",
        },
    )
    class LambdaFunctionAssociationProperty:
        def __init__(
            self,
            *,
            event_type: typing.Optional[builtins.str] = None,
            include_body: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            lambda_function_arn: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param event_type: ``CfnDistribution.LambdaFunctionAssociationProperty.EventType``.
            :param include_body: ``CfnDistribution.LambdaFunctionAssociationProperty.IncludeBody``.
            :param lambda_function_arn: ``CfnDistribution.LambdaFunctionAssociationProperty.LambdaFunctionARN``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-lambdafunctionassociation.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if event_type is not None:
                self._values["event_type"] = event_type
            if include_body is not None:
                self._values["include_body"] = include_body
            if lambda_function_arn is not None:
                self._values["lambda_function_arn"] = lambda_function_arn

        @builtins.property
        def event_type(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.LambdaFunctionAssociationProperty.EventType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-lambdafunctionassociation.html#cfn-cloudfront-distribution-lambdafunctionassociation-eventtype
            '''
            result = self._values.get("event_type")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def include_body(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnDistribution.LambdaFunctionAssociationProperty.IncludeBody``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-lambdafunctionassociation.html#cfn-cloudfront-distribution-lambdafunctionassociation-includebody
            '''
            result = self._values.get("include_body")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def lambda_function_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.LambdaFunctionAssociationProperty.LambdaFunctionARN``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-lambdafunctionassociation.html#cfn-cloudfront-distribution-lambdafunctionassociation-lambdafunctionarn
            '''
            result = self._values.get("lambda_function_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LambdaFunctionAssociationProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.LegacyCustomOriginProperty",
        jsii_struct_bases=[],
        name_mapping={
            "dns_name": "dnsName",
            "origin_protocol_policy": "originProtocolPolicy",
            "origin_ssl_protocols": "originSslProtocols",
            "http_port": "httpPort",
            "https_port": "httpsPort",
        },
    )
    class LegacyCustomOriginProperty:
        def __init__(
            self,
            *,
            dns_name: builtins.str,
            origin_protocol_policy: builtins.str,
            origin_ssl_protocols: typing.Sequence[builtins.str],
            http_port: typing.Optional[jsii.Number] = None,
            https_port: typing.Optional[jsii.Number] = None,
        ) -> None:
            '''
            :param dns_name: ``CfnDistribution.LegacyCustomOriginProperty.DNSName``.
            :param origin_protocol_policy: ``CfnDistribution.LegacyCustomOriginProperty.OriginProtocolPolicy``.
            :param origin_ssl_protocols: ``CfnDistribution.LegacyCustomOriginProperty.OriginSSLProtocols``.
            :param http_port: ``CfnDistribution.LegacyCustomOriginProperty.HTTPPort``.
            :param https_port: ``CfnDistribution.LegacyCustomOriginProperty.HTTPSPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "dns_name": dns_name,
                "origin_protocol_policy": origin_protocol_policy,
                "origin_ssl_protocols": origin_ssl_protocols,
            }
            if http_port is not None:
                self._values["http_port"] = http_port
            if https_port is not None:
                self._values["https_port"] = https_port

        @builtins.property
        def dns_name(self) -> builtins.str:
            '''``CfnDistribution.LegacyCustomOriginProperty.DNSName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-dnsname
            '''
            result = self._values.get("dns_name")
            assert result is not None, "Required property 'dns_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def origin_protocol_policy(self) -> builtins.str:
            '''``CfnDistribution.LegacyCustomOriginProperty.OriginProtocolPolicy``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-originprotocolpolicy
            '''
            result = self._values.get("origin_protocol_policy")
            assert result is not None, "Required property 'origin_protocol_policy' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def origin_ssl_protocols(self) -> typing.List[builtins.str]:
            '''``CfnDistribution.LegacyCustomOriginProperty.OriginSSLProtocols``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-originsslprotocols
            '''
            result = self._values.get("origin_ssl_protocols")
            assert result is not None, "Required property 'origin_ssl_protocols' is missing"
            return typing.cast(typing.List[builtins.str], result)

        @builtins.property
        def http_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.LegacyCustomOriginProperty.HTTPPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-httpport
            '''
            result = self._values.get("http_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def https_port(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.LegacyCustomOriginProperty.HTTPSPort``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacycustomorigin.html#cfn-cloudfront-distribution-legacycustomorigin-httpsport
            '''
            result = self._values.get("https_port")
            return typing.cast(typing.Optional[jsii.Number], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LegacyCustomOriginProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.LegacyS3OriginProperty",
        jsii_struct_bases=[],
        name_mapping={
            "dns_name": "dnsName",
            "origin_access_identity": "originAccessIdentity",
        },
    )
    class LegacyS3OriginProperty:
        def __init__(
            self,
            *,
            dns_name: builtins.str,
            origin_access_identity: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param dns_name: ``CfnDistribution.LegacyS3OriginProperty.DNSName``.
            :param origin_access_identity: ``CfnDistribution.LegacyS3OriginProperty.OriginAccessIdentity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacys3origin.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "dns_name": dns_name,
            }
            if origin_access_identity is not None:
                self._values["origin_access_identity"] = origin_access_identity

        @builtins.property
        def dns_name(self) -> builtins.str:
            '''``CfnDistribution.LegacyS3OriginProperty.DNSName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacys3origin.html#cfn-cloudfront-distribution-legacys3origin-dnsname
            '''
            result = self._values.get("dns_name")
            assert result is not None, "Required property 'dns_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def origin_access_identity(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.LegacyS3OriginProperty.OriginAccessIdentity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-legacys3origin.html#cfn-cloudfront-distribution-legacys3origin-originaccessidentity
            '''
            result = self._values.get("origin_access_identity")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LegacyS3OriginProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.LoggingProperty",
        jsii_struct_bases=[],
        name_mapping={
            "bucket": "bucket",
            "include_cookies": "includeCookies",
            "prefix": "prefix",
        },
    )
    class LoggingProperty:
        def __init__(
            self,
            *,
            bucket: builtins.str,
            include_cookies: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            prefix: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param bucket: ``CfnDistribution.LoggingProperty.Bucket``.
            :param include_cookies: ``CfnDistribution.LoggingProperty.IncludeCookies``.
            :param prefix: ``CfnDistribution.LoggingProperty.Prefix``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-logging.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "bucket": bucket,
            }
            if include_cookies is not None:
                self._values["include_cookies"] = include_cookies
            if prefix is not None:
                self._values["prefix"] = prefix

        @builtins.property
        def bucket(self) -> builtins.str:
            '''``CfnDistribution.LoggingProperty.Bucket``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-logging.html#cfn-cloudfront-distribution-logging-bucket
            '''
            result = self._values.get("bucket")
            assert result is not None, "Required property 'bucket' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def include_cookies(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnDistribution.LoggingProperty.IncludeCookies``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-logging.html#cfn-cloudfront-distribution-logging-includecookies
            '''
            result = self._values.get("include_cookies")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def prefix(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.LoggingProperty.Prefix``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-logging.html#cfn-cloudfront-distribution-logging-prefix
            '''
            result = self._values.get("prefix")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LoggingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.OriginCustomHeaderProperty",
        jsii_struct_bases=[],
        name_mapping={"header_name": "headerName", "header_value": "headerValue"},
    )
    class OriginCustomHeaderProperty:
        def __init__(
            self,
            *,
            header_name: builtins.str,
            header_value: builtins.str,
        ) -> None:
            '''
            :param header_name: ``CfnDistribution.OriginCustomHeaderProperty.HeaderName``.
            :param header_value: ``CfnDistribution.OriginCustomHeaderProperty.HeaderValue``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origincustomheader.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "header_name": header_name,
                "header_value": header_value,
            }

        @builtins.property
        def header_name(self) -> builtins.str:
            '''``CfnDistribution.OriginCustomHeaderProperty.HeaderName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origincustomheader.html#cfn-cloudfront-distribution-origincustomheader-headername
            '''
            result = self._values.get("header_name")
            assert result is not None, "Required property 'header_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def header_value(self) -> builtins.str:
            '''``CfnDistribution.OriginCustomHeaderProperty.HeaderValue``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origincustomheader.html#cfn-cloudfront-distribution-origincustomheader-headervalue
            '''
            result = self._values.get("header_value")
            assert result is not None, "Required property 'header_value' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OriginCustomHeaderProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.OriginGroupFailoverCriteriaProperty",
        jsii_struct_bases=[],
        name_mapping={"status_codes": "statusCodes"},
    )
    class OriginGroupFailoverCriteriaProperty:
        def __init__(
            self,
            *,
            status_codes: typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.StatusCodesProperty"],
        ) -> None:
            '''
            :param status_codes: ``CfnDistribution.OriginGroupFailoverCriteriaProperty.StatusCodes``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroupfailovercriteria.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "status_codes": status_codes,
            }

        @builtins.property
        def status_codes(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.StatusCodesProperty"]:
            '''``CfnDistribution.OriginGroupFailoverCriteriaProperty.StatusCodes``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroupfailovercriteria.html#cfn-cloudfront-distribution-origingroupfailovercriteria-statuscodes
            '''
            result = self._values.get("status_codes")
            assert result is not None, "Required property 'status_codes' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.StatusCodesProperty"], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OriginGroupFailoverCriteriaProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.OriginGroupMemberProperty",
        jsii_struct_bases=[],
        name_mapping={"origin_id": "originId"},
    )
    class OriginGroupMemberProperty:
        def __init__(self, *, origin_id: builtins.str) -> None:
            '''
            :param origin_id: ``CfnDistribution.OriginGroupMemberProperty.OriginId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroupmember.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "origin_id": origin_id,
            }

        @builtins.property
        def origin_id(self) -> builtins.str:
            '''``CfnDistribution.OriginGroupMemberProperty.OriginId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroupmember.html#cfn-cloudfront-distribution-origingroupmember-originid
            '''
            result = self._values.get("origin_id")
            assert result is not None, "Required property 'origin_id' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OriginGroupMemberProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.OriginGroupMembersProperty",
        jsii_struct_bases=[],
        name_mapping={"items": "items", "quantity": "quantity"},
    )
    class OriginGroupMembersProperty:
        def __init__(
            self,
            *,
            items: typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupMemberProperty"]]],
            quantity: jsii.Number,
        ) -> None:
            '''
            :param items: ``CfnDistribution.OriginGroupMembersProperty.Items``.
            :param quantity: ``CfnDistribution.OriginGroupMembersProperty.Quantity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroupmembers.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "items": items,
                "quantity": quantity,
            }

        @builtins.property
        def items(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupMemberProperty"]]]:
            '''``CfnDistribution.OriginGroupMembersProperty.Items``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroupmembers.html#cfn-cloudfront-distribution-origingroupmembers-items
            '''
            result = self._values.get("items")
            assert result is not None, "Required property 'items' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupMemberProperty"]]], result)

        @builtins.property
        def quantity(self) -> jsii.Number:
            '''``CfnDistribution.OriginGroupMembersProperty.Quantity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroupmembers.html#cfn-cloudfront-distribution-origingroupmembers-quantity
            '''
            result = self._values.get("quantity")
            assert result is not None, "Required property 'quantity' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OriginGroupMembersProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.OriginGroupProperty",
        jsii_struct_bases=[],
        name_mapping={
            "failover_criteria": "failoverCriteria",
            "id": "id",
            "members": "members",
        },
    )
    class OriginGroupProperty:
        def __init__(
            self,
            *,
            failover_criteria: typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupFailoverCriteriaProperty"],
            id: builtins.str,
            members: typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupMembersProperty"],
        ) -> None:
            '''
            :param failover_criteria: ``CfnDistribution.OriginGroupProperty.FailoverCriteria``.
            :param id: ``CfnDistribution.OriginGroupProperty.Id``.
            :param members: ``CfnDistribution.OriginGroupProperty.Members``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroup.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "failover_criteria": failover_criteria,
                "id": id,
                "members": members,
            }

        @builtins.property
        def failover_criteria(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupFailoverCriteriaProperty"]:
            '''``CfnDistribution.OriginGroupProperty.FailoverCriteria``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroup.html#cfn-cloudfront-distribution-origingroup-failovercriteria
            '''
            result = self._values.get("failover_criteria")
            assert result is not None, "Required property 'failover_criteria' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupFailoverCriteriaProperty"], result)

        @builtins.property
        def id(self) -> builtins.str:
            '''``CfnDistribution.OriginGroupProperty.Id``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroup.html#cfn-cloudfront-distribution-origingroup-id
            '''
            result = self._values.get("id")
            assert result is not None, "Required property 'id' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def members(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupMembersProperty"]:
            '''``CfnDistribution.OriginGroupProperty.Members``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroup.html#cfn-cloudfront-distribution-origingroup-members
            '''
            result = self._values.get("members")
            assert result is not None, "Required property 'members' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupMembersProperty"], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OriginGroupProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.OriginGroupsProperty",
        jsii_struct_bases=[],
        name_mapping={"quantity": "quantity", "items": "items"},
    )
    class OriginGroupsProperty:
        def __init__(
            self,
            *,
            quantity: jsii.Number,
            items: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupProperty"]]]] = None,
        ) -> None:
            '''
            :param quantity: ``CfnDistribution.OriginGroupsProperty.Quantity``.
            :param items: ``CfnDistribution.OriginGroupsProperty.Items``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroups.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "quantity": quantity,
            }
            if items is not None:
                self._values["items"] = items

        @builtins.property
        def quantity(self) -> jsii.Number:
            '''``CfnDistribution.OriginGroupsProperty.Quantity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroups.html#cfn-cloudfront-distribution-origingroups-quantity
            '''
            result = self._values.get("quantity")
            assert result is not None, "Required property 'quantity' is missing"
            return typing.cast(jsii.Number, result)

        @builtins.property
        def items(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupProperty"]]]]:
            '''``CfnDistribution.OriginGroupsProperty.Items``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origingroups.html#cfn-cloudfront-distribution-origingroups-items
            '''
            result = self._values.get("items")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginGroupProperty"]]]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OriginGroupsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.OriginProperty",
        jsii_struct_bases=[],
        name_mapping={
            "domain_name": "domainName",
            "id": "id",
            "connection_attempts": "connectionAttempts",
            "connection_timeout": "connectionTimeout",
            "custom_origin_config": "customOriginConfig",
            "origin_custom_headers": "originCustomHeaders",
            "origin_path": "originPath",
            "origin_shield": "originShield",
            "s3_origin_config": "s3OriginConfig",
        },
    )
    class OriginProperty:
        def __init__(
            self,
            *,
            domain_name: builtins.str,
            id: builtins.str,
            connection_attempts: typing.Optional[jsii.Number] = None,
            connection_timeout: typing.Optional[jsii.Number] = None,
            custom_origin_config: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CustomOriginConfigProperty"]] = None,
            origin_custom_headers: typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginCustomHeaderProperty"]]]] = None,
            origin_path: typing.Optional[builtins.str] = None,
            origin_shield: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginShieldProperty"]] = None,
            s3_origin_config: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.S3OriginConfigProperty"]] = None,
        ) -> None:
            '''
            :param domain_name: ``CfnDistribution.OriginProperty.DomainName``.
            :param id: ``CfnDistribution.OriginProperty.Id``.
            :param connection_attempts: ``CfnDistribution.OriginProperty.ConnectionAttempts``.
            :param connection_timeout: ``CfnDistribution.OriginProperty.ConnectionTimeout``.
            :param custom_origin_config: ``CfnDistribution.OriginProperty.CustomOriginConfig``.
            :param origin_custom_headers: ``CfnDistribution.OriginProperty.OriginCustomHeaders``.
            :param origin_path: ``CfnDistribution.OriginProperty.OriginPath``.
            :param origin_shield: ``CfnDistribution.OriginProperty.OriginShield``.
            :param s3_origin_config: ``CfnDistribution.OriginProperty.S3OriginConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "domain_name": domain_name,
                "id": id,
            }
            if connection_attempts is not None:
                self._values["connection_attempts"] = connection_attempts
            if connection_timeout is not None:
                self._values["connection_timeout"] = connection_timeout
            if custom_origin_config is not None:
                self._values["custom_origin_config"] = custom_origin_config
            if origin_custom_headers is not None:
                self._values["origin_custom_headers"] = origin_custom_headers
            if origin_path is not None:
                self._values["origin_path"] = origin_path
            if origin_shield is not None:
                self._values["origin_shield"] = origin_shield
            if s3_origin_config is not None:
                self._values["s3_origin_config"] = s3_origin_config

        @builtins.property
        def domain_name(self) -> builtins.str:
            '''``CfnDistribution.OriginProperty.DomainName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-domainname
            '''
            result = self._values.get("domain_name")
            assert result is not None, "Required property 'domain_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def id(self) -> builtins.str:
            '''``CfnDistribution.OriginProperty.Id``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-id
            '''
            result = self._values.get("id")
            assert result is not None, "Required property 'id' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def connection_attempts(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.OriginProperty.ConnectionAttempts``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-connectionattempts
            '''
            result = self._values.get("connection_attempts")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def connection_timeout(self) -> typing.Optional[jsii.Number]:
            '''``CfnDistribution.OriginProperty.ConnectionTimeout``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-connectiontimeout
            '''
            result = self._values.get("connection_timeout")
            return typing.cast(typing.Optional[jsii.Number], result)

        @builtins.property
        def custom_origin_config(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CustomOriginConfigProperty"]]:
            '''``CfnDistribution.OriginProperty.CustomOriginConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-customoriginconfig
            '''
            result = self._values.get("custom_origin_config")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.CustomOriginConfigProperty"]], result)

        @builtins.property
        def origin_custom_headers(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginCustomHeaderProperty"]]]]:
            '''``CfnDistribution.OriginProperty.OriginCustomHeaders``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-origincustomheaders
            '''
            result = self._values.get("origin_custom_headers")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginCustomHeaderProperty"]]]], result)

        @builtins.property
        def origin_path(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.OriginProperty.OriginPath``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-originpath
            '''
            result = self._values.get("origin_path")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def origin_shield(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginShieldProperty"]]:
            '''``CfnDistribution.OriginProperty.OriginShield``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-originshield
            '''
            result = self._values.get("origin_shield")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.OriginShieldProperty"]], result)

        @builtins.property
        def s3_origin_config(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.S3OriginConfigProperty"]]:
            '''``CfnDistribution.OriginProperty.S3OriginConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html#cfn-cloudfront-distribution-origin-s3originconfig
            '''
            result = self._values.get("s3_origin_config")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.S3OriginConfigProperty"]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OriginProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.OriginShieldProperty",
        jsii_struct_bases=[],
        name_mapping={
            "enabled": "enabled",
            "origin_shield_region": "originShieldRegion",
        },
    )
    class OriginShieldProperty:
        def __init__(
            self,
            *,
            enabled: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            origin_shield_region: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param enabled: ``CfnDistribution.OriginShieldProperty.Enabled``.
            :param origin_shield_region: ``CfnDistribution.OriginShieldProperty.OriginShieldRegion``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-originshield.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if enabled is not None:
                self._values["enabled"] = enabled
            if origin_shield_region is not None:
                self._values["origin_shield_region"] = origin_shield_region

        @builtins.property
        def enabled(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnDistribution.OriginShieldProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-originshield.html#cfn-cloudfront-distribution-originshield-enabled
            '''
            result = self._values.get("enabled")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def origin_shield_region(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.OriginShieldProperty.OriginShieldRegion``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-originshield.html#cfn-cloudfront-distribution-originshield-originshieldregion
            '''
            result = self._values.get("origin_shield_region")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OriginShieldProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.RestrictionsProperty",
        jsii_struct_bases=[],
        name_mapping={"geo_restriction": "geoRestriction"},
    )
    class RestrictionsProperty:
        def __init__(
            self,
            *,
            geo_restriction: typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.GeoRestrictionProperty"],
        ) -> None:
            '''
            :param geo_restriction: ``CfnDistribution.RestrictionsProperty.GeoRestriction``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-restrictions.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "geo_restriction": geo_restriction,
            }

        @builtins.property
        def geo_restriction(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.GeoRestrictionProperty"]:
            '''``CfnDistribution.RestrictionsProperty.GeoRestriction``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-restrictions.html#cfn-cloudfront-distribution-restrictions-georestriction
            '''
            result = self._values.get("geo_restriction")
            assert result is not None, "Required property 'geo_restriction' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnDistribution.GeoRestrictionProperty"], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "RestrictionsProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.S3OriginConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"origin_access_identity": "originAccessIdentity"},
    )
    class S3OriginConfigProperty:
        def __init__(
            self,
            *,
            origin_access_identity: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param origin_access_identity: ``CfnDistribution.S3OriginConfigProperty.OriginAccessIdentity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-s3originconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if origin_access_identity is not None:
                self._values["origin_access_identity"] = origin_access_identity

        @builtins.property
        def origin_access_identity(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.S3OriginConfigProperty.OriginAccessIdentity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-s3originconfig.html#cfn-cloudfront-distribution-s3originconfig-originaccessidentity
            '''
            result = self._values.get("origin_access_identity")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "S3OriginConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.StatusCodesProperty",
        jsii_struct_bases=[],
        name_mapping={"items": "items", "quantity": "quantity"},
    )
    class StatusCodesProperty:
        def __init__(
            self,
            *,
            items: typing.Union[aws_cdk.core.IResolvable, typing.Sequence[jsii.Number]],
            quantity: jsii.Number,
        ) -> None:
            '''
            :param items: ``CfnDistribution.StatusCodesProperty.Items``.
            :param quantity: ``CfnDistribution.StatusCodesProperty.Quantity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-statuscodes.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "items": items,
                "quantity": quantity,
            }

        @builtins.property
        def items(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[jsii.Number]]:
            '''``CfnDistribution.StatusCodesProperty.Items``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-statuscodes.html#cfn-cloudfront-distribution-statuscodes-items
            '''
            result = self._values.get("items")
            assert result is not None, "Required property 'items' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[jsii.Number]], result)

        @builtins.property
        def quantity(self) -> jsii.Number:
            '''``CfnDistribution.StatusCodesProperty.Quantity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-statuscodes.html#cfn-cloudfront-distribution-statuscodes-quantity
            '''
            result = self._values.get("quantity")
            assert result is not None, "Required property 'quantity' is missing"
            return typing.cast(jsii.Number, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "StatusCodesProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnDistribution.ViewerCertificateProperty",
        jsii_struct_bases=[],
        name_mapping={
            "acm_certificate_arn": "acmCertificateArn",
            "cloud_front_default_certificate": "cloudFrontDefaultCertificate",
            "iam_certificate_id": "iamCertificateId",
            "minimum_protocol_version": "minimumProtocolVersion",
            "ssl_support_method": "sslSupportMethod",
        },
    )
    class ViewerCertificateProperty:
        def __init__(
            self,
            *,
            acm_certificate_arn: typing.Optional[builtins.str] = None,
            cloud_front_default_certificate: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
            iam_certificate_id: typing.Optional[builtins.str] = None,
            minimum_protocol_version: typing.Optional[builtins.str] = None,
            ssl_support_method: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param acm_certificate_arn: ``CfnDistribution.ViewerCertificateProperty.AcmCertificateArn``.
            :param cloud_front_default_certificate: ``CfnDistribution.ViewerCertificateProperty.CloudFrontDefaultCertificate``.
            :param iam_certificate_id: ``CfnDistribution.ViewerCertificateProperty.IamCertificateId``.
            :param minimum_protocol_version: ``CfnDistribution.ViewerCertificateProperty.MinimumProtocolVersion``.
            :param ssl_support_method: ``CfnDistribution.ViewerCertificateProperty.SslSupportMethod``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-viewercertificate.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if acm_certificate_arn is not None:
                self._values["acm_certificate_arn"] = acm_certificate_arn
            if cloud_front_default_certificate is not None:
                self._values["cloud_front_default_certificate"] = cloud_front_default_certificate
            if iam_certificate_id is not None:
                self._values["iam_certificate_id"] = iam_certificate_id
            if minimum_protocol_version is not None:
                self._values["minimum_protocol_version"] = minimum_protocol_version
            if ssl_support_method is not None:
                self._values["ssl_support_method"] = ssl_support_method

        @builtins.property
        def acm_certificate_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.ViewerCertificateProperty.AcmCertificateArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-viewercertificate.html#cfn-cloudfront-distribution-viewercertificate-acmcertificatearn
            '''
            result = self._values.get("acm_certificate_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def cloud_front_default_certificate(
            self,
        ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
            '''``CfnDistribution.ViewerCertificateProperty.CloudFrontDefaultCertificate``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-viewercertificate.html#cfn-cloudfront-distribution-viewercertificate-cloudfrontdefaultcertificate
            '''
            result = self._values.get("cloud_front_default_certificate")
            return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

        @builtins.property
        def iam_certificate_id(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.ViewerCertificateProperty.IamCertificateId``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-viewercertificate.html#cfn-cloudfront-distribution-viewercertificate-iamcertificateid
            '''
            result = self._values.get("iam_certificate_id")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def minimum_protocol_version(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.ViewerCertificateProperty.MinimumProtocolVersion``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-viewercertificate.html#cfn-cloudfront-distribution-viewercertificate-minimumprotocolversion
            '''
            result = self._values.get("minimum_protocol_version")
            return typing.cast(typing.Optional[builtins.str], result)

        @builtins.property
        def ssl_support_method(self) -> typing.Optional[builtins.str]:
            '''``CfnDistribution.ViewerCertificateProperty.SslSupportMethod``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-viewercertificate.html#cfn-cloudfront-distribution-viewercertificate-sslsupportmethod
            '''
            result = self._values.get("ssl_support_method")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "ViewerCertificateProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CfnDistributionProps",
    jsii_struct_bases=[],
    name_mapping={"distribution_config": "distributionConfig", "tags": "tags"},
)
class CfnDistributionProps:
    def __init__(
        self,
        *,
        distribution_config: typing.Union[aws_cdk.core.IResolvable, CfnDistribution.DistributionConfigProperty],
        tags: typing.Optional[typing.Sequence[aws_cdk.core.CfnTag]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::CloudFront::Distribution``.

        :param distribution_config: ``AWS::CloudFront::Distribution.DistributionConfig``.
        :param tags: ``AWS::CloudFront::Distribution.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-distribution.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "distribution_config": distribution_config,
        }
        if tags is not None:
            self._values["tags"] = tags

    @builtins.property
    def distribution_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnDistribution.DistributionConfigProperty]:
        '''``AWS::CloudFront::Distribution.DistributionConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-distribution.html#cfn-cloudfront-distribution-distributionconfig
        '''
        result = self._values.get("distribution_config")
        assert result is not None, "Required property 'distribution_config' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnDistribution.DistributionConfigProperty], result)

    @builtins.property
    def tags(self) -> typing.Optional[typing.List[aws_cdk.core.CfnTag]]:
        '''``AWS::CloudFront::Distribution.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-distribution.html#cfn-cloudfront-distribution-tags
        '''
        result = self._values.get("tags")
        return typing.cast(typing.Optional[typing.List[aws_cdk.core.CfnTag]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnDistributionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnFunction(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CfnFunction",
):
    '''A CloudFormation ``AWS::CloudFront::Function``.

    :cloudformationResource: AWS::CloudFront::Function
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        name: builtins.str,
        auto_publish: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        function_code: typing.Optional[builtins.str] = None,
        function_config: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnFunction.FunctionConfigProperty"]] = None,
        function_metadata: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnFunction.FunctionMetadataProperty"]] = None,
    ) -> None:
        '''Create a new ``AWS::CloudFront::Function``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param name: ``AWS::CloudFront::Function.Name``.
        :param auto_publish: ``AWS::CloudFront::Function.AutoPublish``.
        :param function_code: ``AWS::CloudFront::Function.FunctionCode``.
        :param function_config: ``AWS::CloudFront::Function.FunctionConfig``.
        :param function_metadata: ``AWS::CloudFront::Function.FunctionMetadata``.
        '''
        props = CfnFunctionProps(
            name=name,
            auto_publish=auto_publish,
            function_code=function_code,
            function_config=function_config,
            function_metadata=function_metadata,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrFunctionArn")
    def attr_function_arn(self) -> builtins.str:
        '''
        :cloudformationAttribute: FunctionARN
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrFunctionArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrFunctionMetadataFunctionArn")
    def attr_function_metadata_function_arn(self) -> builtins.str:
        '''
        :cloudformationAttribute: FunctionMetadata.FunctionARN
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrFunctionMetadataFunctionArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrStage")
    def attr_stage(self) -> builtins.str:
        '''
        :cloudformationAttribute: Stage
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrStage"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="name")
    def name(self) -> builtins.str:
        '''``AWS::CloudFront::Function.Name``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-name
        '''
        return typing.cast(builtins.str, jsii.get(self, "name"))

    @name.setter
    def name(self, value: builtins.str) -> None:
        jsii.set(self, "name", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="autoPublish")
    def auto_publish(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::CloudFront::Function.AutoPublish``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-autopublish
        '''
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], jsii.get(self, "autoPublish"))

    @auto_publish.setter
    def auto_publish(
        self,
        value: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]],
    ) -> None:
        jsii.set(self, "autoPublish", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionCode")
    def function_code(self) -> typing.Optional[builtins.str]:
        '''``AWS::CloudFront::Function.FunctionCode``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functioncode
        '''
        return typing.cast(typing.Optional[builtins.str], jsii.get(self, "functionCode"))

    @function_code.setter
    def function_code(self, value: typing.Optional[builtins.str]) -> None:
        jsii.set(self, "functionCode", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionConfig")
    def function_config(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnFunction.FunctionConfigProperty"]]:
        '''``AWS::CloudFront::Function.FunctionConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functionconfig
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnFunction.FunctionConfigProperty"]], jsii.get(self, "functionConfig"))

    @function_config.setter
    def function_config(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnFunction.FunctionConfigProperty"]],
    ) -> None:
        jsii.set(self, "functionConfig", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionMetadata")
    def function_metadata(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnFunction.FunctionMetadataProperty"]]:
        '''``AWS::CloudFront::Function.FunctionMetadata``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functionmetadata
        '''
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnFunction.FunctionMetadataProperty"]], jsii.get(self, "functionMetadata"))

    @function_metadata.setter
    def function_metadata(
        self,
        value: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnFunction.FunctionMetadataProperty"]],
    ) -> None:
        jsii.set(self, "functionMetadata", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnFunction.FunctionConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"comment": "comment", "runtime": "runtime"},
    )
    class FunctionConfigProperty:
        def __init__(self, *, comment: builtins.str, runtime: builtins.str) -> None:
            '''
            :param comment: ``CfnFunction.FunctionConfigProperty.Comment``.
            :param runtime: ``CfnFunction.FunctionConfigProperty.Runtime``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "comment": comment,
                "runtime": runtime,
            }

        @builtins.property
        def comment(self) -> builtins.str:
            '''``CfnFunction.FunctionConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionconfig.html#cfn-cloudfront-function-functionconfig-comment
            '''
            result = self._values.get("comment")
            assert result is not None, "Required property 'comment' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def runtime(self) -> builtins.str:
            '''``CfnFunction.FunctionConfigProperty.Runtime``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionconfig.html#cfn-cloudfront-function-functionconfig-runtime
            '''
            result = self._values.get("runtime")
            assert result is not None, "Required property 'runtime' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "FunctionConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnFunction.FunctionMetadataProperty",
        jsii_struct_bases=[],
        name_mapping={"function_arn": "functionArn"},
    )
    class FunctionMetadataProperty:
        def __init__(
            self,
            *,
            function_arn: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param function_arn: ``CfnFunction.FunctionMetadataProperty.FunctionARN``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionmetadata.html
            '''
            self._values: typing.Dict[str, typing.Any] = {}
            if function_arn is not None:
                self._values["function_arn"] = function_arn

        @builtins.property
        def function_arn(self) -> typing.Optional[builtins.str]:
            '''``CfnFunction.FunctionMetadataProperty.FunctionARN``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-function-functionmetadata.html#cfn-cloudfront-function-functionmetadata-functionarn
            '''
            result = self._values.get("function_arn")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "FunctionMetadataProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CfnFunctionProps",
    jsii_struct_bases=[],
    name_mapping={
        "name": "name",
        "auto_publish": "autoPublish",
        "function_code": "functionCode",
        "function_config": "functionConfig",
        "function_metadata": "functionMetadata",
    },
)
class CfnFunctionProps:
    def __init__(
        self,
        *,
        name: builtins.str,
        auto_publish: typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]] = None,
        function_code: typing.Optional[builtins.str] = None,
        function_config: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnFunction.FunctionConfigProperty]] = None,
        function_metadata: typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnFunction.FunctionMetadataProperty]] = None,
    ) -> None:
        '''Properties for defining a ``AWS::CloudFront::Function``.

        :param name: ``AWS::CloudFront::Function.Name``.
        :param auto_publish: ``AWS::CloudFront::Function.AutoPublish``.
        :param function_code: ``AWS::CloudFront::Function.FunctionCode``.
        :param function_config: ``AWS::CloudFront::Function.FunctionConfig``.
        :param function_metadata: ``AWS::CloudFront::Function.FunctionMetadata``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "name": name,
        }
        if auto_publish is not None:
            self._values["auto_publish"] = auto_publish
        if function_code is not None:
            self._values["function_code"] = function_code
        if function_config is not None:
            self._values["function_config"] = function_config
        if function_metadata is not None:
            self._values["function_metadata"] = function_metadata

    @builtins.property
    def name(self) -> builtins.str:
        '''``AWS::CloudFront::Function.Name``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def auto_publish(
        self,
    ) -> typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]]:
        '''``AWS::CloudFront::Function.AutoPublish``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-autopublish
        '''
        result = self._values.get("auto_publish")
        return typing.cast(typing.Optional[typing.Union[builtins.bool, aws_cdk.core.IResolvable]], result)

    @builtins.property
    def function_code(self) -> typing.Optional[builtins.str]:
        '''``AWS::CloudFront::Function.FunctionCode``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functioncode
        '''
        result = self._values.get("function_code")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def function_config(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnFunction.FunctionConfigProperty]]:
        '''``AWS::CloudFront::Function.FunctionConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functionconfig
        '''
        result = self._values.get("function_config")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnFunction.FunctionConfigProperty]], result)

    @builtins.property
    def function_metadata(
        self,
    ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnFunction.FunctionMetadataProperty]]:
        '''``AWS::CloudFront::Function.FunctionMetadata``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-function.html#cfn-cloudfront-function-functionmetadata
        '''
        result = self._values.get("function_metadata")
        return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, CfnFunction.FunctionMetadataProperty]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnFunctionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnKeyGroup(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CfnKeyGroup",
):
    '''A CloudFormation ``AWS::CloudFront::KeyGroup``.

    :cloudformationResource: AWS::CloudFront::KeyGroup
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-keygroup.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        key_group_config: typing.Union[aws_cdk.core.IResolvable, "CfnKeyGroup.KeyGroupConfigProperty"],
    ) -> None:
        '''Create a new ``AWS::CloudFront::KeyGroup``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param key_group_config: ``AWS::CloudFront::KeyGroup.KeyGroupConfig``.
        '''
        props = CfnKeyGroupProps(key_group_config=key_group_config)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrId")
    def attr_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: Id
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrLastModifiedTime")
    def attr_last_modified_time(self) -> builtins.str:
        '''
        :cloudformationAttribute: LastModifiedTime
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrLastModifiedTime"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="keyGroupConfig")
    def key_group_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnKeyGroup.KeyGroupConfigProperty"]:
        '''``AWS::CloudFront::KeyGroup.KeyGroupConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-keygroup.html#cfn-cloudfront-keygroup-keygroupconfig
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnKeyGroup.KeyGroupConfigProperty"], jsii.get(self, "keyGroupConfig"))

    @key_group_config.setter
    def key_group_config(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnKeyGroup.KeyGroupConfigProperty"],
    ) -> None:
        jsii.set(self, "keyGroupConfig", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnKeyGroup.KeyGroupConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"items": "items", "name": "name", "comment": "comment"},
    )
    class KeyGroupConfigProperty:
        def __init__(
            self,
            *,
            items: typing.Sequence[builtins.str],
            name: builtins.str,
            comment: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param items: ``CfnKeyGroup.KeyGroupConfigProperty.Items``.
            :param name: ``CfnKeyGroup.KeyGroupConfigProperty.Name``.
            :param comment: ``CfnKeyGroup.KeyGroupConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-keygroup-keygroupconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "items": items,
                "name": name,
            }
            if comment is not None:
                self._values["comment"] = comment

        @builtins.property
        def items(self) -> typing.List[builtins.str]:
            '''``CfnKeyGroup.KeyGroupConfigProperty.Items``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-keygroup-keygroupconfig.html#cfn-cloudfront-keygroup-keygroupconfig-items
            '''
            result = self._values.get("items")
            assert result is not None, "Required property 'items' is missing"
            return typing.cast(typing.List[builtins.str], result)

        @builtins.property
        def name(self) -> builtins.str:
            '''``CfnKeyGroup.KeyGroupConfigProperty.Name``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-keygroup-keygroupconfig.html#cfn-cloudfront-keygroup-keygroupconfig-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def comment(self) -> typing.Optional[builtins.str]:
            '''``CfnKeyGroup.KeyGroupConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-keygroup-keygroupconfig.html#cfn-cloudfront-keygroup-keygroupconfig-comment
            '''
            result = self._values.get("comment")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "KeyGroupConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CfnKeyGroupProps",
    jsii_struct_bases=[],
    name_mapping={"key_group_config": "keyGroupConfig"},
)
class CfnKeyGroupProps:
    def __init__(
        self,
        *,
        key_group_config: typing.Union[aws_cdk.core.IResolvable, CfnKeyGroup.KeyGroupConfigProperty],
    ) -> None:
        '''Properties for defining a ``AWS::CloudFront::KeyGroup``.

        :param key_group_config: ``AWS::CloudFront::KeyGroup.KeyGroupConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-keygroup.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "key_group_config": key_group_config,
        }

    @builtins.property
    def key_group_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnKeyGroup.KeyGroupConfigProperty]:
        '''``AWS::CloudFront::KeyGroup.KeyGroupConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-keygroup.html#cfn-cloudfront-keygroup-keygroupconfig
        '''
        result = self._values.get("key_group_config")
        assert result is not None, "Required property 'key_group_config' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnKeyGroup.KeyGroupConfigProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnKeyGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnOriginRequestPolicy(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CfnOriginRequestPolicy",
):
    '''A CloudFormation ``AWS::CloudFront::OriginRequestPolicy``.

    :cloudformationResource: AWS::CloudFront::OriginRequestPolicy
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-originrequestpolicy.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        origin_request_policy_config: typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty"],
    ) -> None:
        '''Create a new ``AWS::CloudFront::OriginRequestPolicy``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param origin_request_policy_config: ``AWS::CloudFront::OriginRequestPolicy.OriginRequestPolicyConfig``.
        '''
        props = CfnOriginRequestPolicyProps(
            origin_request_policy_config=origin_request_policy_config
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrId")
    def attr_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: Id
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrLastModifiedTime")
    def attr_last_modified_time(self) -> builtins.str:
        '''
        :cloudformationAttribute: LastModifiedTime
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrLastModifiedTime"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="originRequestPolicyConfig")
    def origin_request_policy_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty"]:
        '''``AWS::CloudFront::OriginRequestPolicy.OriginRequestPolicyConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-originrequestpolicy.html#cfn-cloudfront-originrequestpolicy-originrequestpolicyconfig
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty"], jsii.get(self, "originRequestPolicyConfig"))

    @origin_request_policy_config.setter
    def origin_request_policy_config(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty"],
    ) -> None:
        jsii.set(self, "originRequestPolicyConfig", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnOriginRequestPolicy.CookiesConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"cookie_behavior": "cookieBehavior", "cookies": "cookies"},
    )
    class CookiesConfigProperty:
        def __init__(
            self,
            *,
            cookie_behavior: builtins.str,
            cookies: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param cookie_behavior: ``CfnOriginRequestPolicy.CookiesConfigProperty.CookieBehavior``.
            :param cookies: ``CfnOriginRequestPolicy.CookiesConfigProperty.Cookies``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-cookiesconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "cookie_behavior": cookie_behavior,
            }
            if cookies is not None:
                self._values["cookies"] = cookies

        @builtins.property
        def cookie_behavior(self) -> builtins.str:
            '''``CfnOriginRequestPolicy.CookiesConfigProperty.CookieBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-cookiesconfig.html#cfn-cloudfront-originrequestpolicy-cookiesconfig-cookiebehavior
            '''
            result = self._values.get("cookie_behavior")
            assert result is not None, "Required property 'cookie_behavior' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def cookies(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnOriginRequestPolicy.CookiesConfigProperty.Cookies``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-cookiesconfig.html#cfn-cloudfront-originrequestpolicy-cookiesconfig-cookies
            '''
            result = self._values.get("cookies")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "CookiesConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnOriginRequestPolicy.HeadersConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"header_behavior": "headerBehavior", "headers": "headers"},
    )
    class HeadersConfigProperty:
        def __init__(
            self,
            *,
            header_behavior: builtins.str,
            headers: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param header_behavior: ``CfnOriginRequestPolicy.HeadersConfigProperty.HeaderBehavior``.
            :param headers: ``CfnOriginRequestPolicy.HeadersConfigProperty.Headers``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-headersconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "header_behavior": header_behavior,
            }
            if headers is not None:
                self._values["headers"] = headers

        @builtins.property
        def header_behavior(self) -> builtins.str:
            '''``CfnOriginRequestPolicy.HeadersConfigProperty.HeaderBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-headersconfig.html#cfn-cloudfront-originrequestpolicy-headersconfig-headerbehavior
            '''
            result = self._values.get("header_behavior")
            assert result is not None, "Required property 'header_behavior' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def headers(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnOriginRequestPolicy.HeadersConfigProperty.Headers``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-headersconfig.html#cfn-cloudfront-originrequestpolicy-headersconfig-headers
            '''
            result = self._values.get("headers")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "HeadersConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "cookies_config": "cookiesConfig",
            "headers_config": "headersConfig",
            "name": "name",
            "query_strings_config": "queryStringsConfig",
            "comment": "comment",
        },
    )
    class OriginRequestPolicyConfigProperty:
        def __init__(
            self,
            *,
            cookies_config: typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.CookiesConfigProperty"],
            headers_config: typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.HeadersConfigProperty"],
            name: builtins.str,
            query_strings_config: typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.QueryStringsConfigProperty"],
            comment: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param cookies_config: ``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.CookiesConfig``.
            :param headers_config: ``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.HeadersConfig``.
            :param name: ``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.Name``.
            :param query_strings_config: ``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.QueryStringsConfig``.
            :param comment: ``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-originrequestpolicyconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "cookies_config": cookies_config,
                "headers_config": headers_config,
                "name": name,
                "query_strings_config": query_strings_config,
            }
            if comment is not None:
                self._values["comment"] = comment

        @builtins.property
        def cookies_config(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.CookiesConfigProperty"]:
            '''``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.CookiesConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-originrequestpolicyconfig.html#cfn-cloudfront-originrequestpolicy-originrequestpolicyconfig-cookiesconfig
            '''
            result = self._values.get("cookies_config")
            assert result is not None, "Required property 'cookies_config' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.CookiesConfigProperty"], result)

        @builtins.property
        def headers_config(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.HeadersConfigProperty"]:
            '''``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.HeadersConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-originrequestpolicyconfig.html#cfn-cloudfront-originrequestpolicy-originrequestpolicyconfig-headersconfig
            '''
            result = self._values.get("headers_config")
            assert result is not None, "Required property 'headers_config' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.HeadersConfigProperty"], result)

        @builtins.property
        def name(self) -> builtins.str:
            '''``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.Name``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-originrequestpolicyconfig.html#cfn-cloudfront-originrequestpolicy-originrequestpolicyconfig-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def query_strings_config(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.QueryStringsConfigProperty"]:
            '''``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.QueryStringsConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-originrequestpolicyconfig.html#cfn-cloudfront-originrequestpolicy-originrequestpolicyconfig-querystringsconfig
            '''
            result = self._values.get("query_strings_config")
            assert result is not None, "Required property 'query_strings_config' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnOriginRequestPolicy.QueryStringsConfigProperty"], result)

        @builtins.property
        def comment(self) -> typing.Optional[builtins.str]:
            '''``CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-originrequestpolicyconfig.html#cfn-cloudfront-originrequestpolicy-originrequestpolicyconfig-comment
            '''
            result = self._values.get("comment")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "OriginRequestPolicyConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnOriginRequestPolicy.QueryStringsConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "query_string_behavior": "queryStringBehavior",
            "query_strings": "queryStrings",
        },
    )
    class QueryStringsConfigProperty:
        def __init__(
            self,
            *,
            query_string_behavior: builtins.str,
            query_strings: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param query_string_behavior: ``CfnOriginRequestPolicy.QueryStringsConfigProperty.QueryStringBehavior``.
            :param query_strings: ``CfnOriginRequestPolicy.QueryStringsConfigProperty.QueryStrings``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-querystringsconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "query_string_behavior": query_string_behavior,
            }
            if query_strings is not None:
                self._values["query_strings"] = query_strings

        @builtins.property
        def query_string_behavior(self) -> builtins.str:
            '''``CfnOriginRequestPolicy.QueryStringsConfigProperty.QueryStringBehavior``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-querystringsconfig.html#cfn-cloudfront-originrequestpolicy-querystringsconfig-querystringbehavior
            '''
            result = self._values.get("query_string_behavior")
            assert result is not None, "Required property 'query_string_behavior' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def query_strings(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnOriginRequestPolicy.QueryStringsConfigProperty.QueryStrings``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-originrequestpolicy-querystringsconfig.html#cfn-cloudfront-originrequestpolicy-querystringsconfig-querystrings
            '''
            result = self._values.get("query_strings")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "QueryStringsConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CfnOriginRequestPolicyProps",
    jsii_struct_bases=[],
    name_mapping={"origin_request_policy_config": "originRequestPolicyConfig"},
)
class CfnOriginRequestPolicyProps:
    def __init__(
        self,
        *,
        origin_request_policy_config: typing.Union[aws_cdk.core.IResolvable, CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty],
    ) -> None:
        '''Properties for defining a ``AWS::CloudFront::OriginRequestPolicy``.

        :param origin_request_policy_config: ``AWS::CloudFront::OriginRequestPolicy.OriginRequestPolicyConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-originrequestpolicy.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "origin_request_policy_config": origin_request_policy_config,
        }

    @builtins.property
    def origin_request_policy_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty]:
        '''``AWS::CloudFront::OriginRequestPolicy.OriginRequestPolicyConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-originrequestpolicy.html#cfn-cloudfront-originrequestpolicy-originrequestpolicyconfig
        '''
        result = self._values.get("origin_request_policy_config")
        assert result is not None, "Required property 'origin_request_policy_config' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnOriginRequestPolicy.OriginRequestPolicyConfigProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnOriginRequestPolicyProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnPublicKey(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CfnPublicKey",
):
    '''A CloudFormation ``AWS::CloudFront::PublicKey``.

    :cloudformationResource: AWS::CloudFront::PublicKey
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-publickey.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        public_key_config: typing.Union[aws_cdk.core.IResolvable, "CfnPublicKey.PublicKeyConfigProperty"],
    ) -> None:
        '''Create a new ``AWS::CloudFront::PublicKey``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param public_key_config: ``AWS::CloudFront::PublicKey.PublicKeyConfig``.
        '''
        props = CfnPublicKeyProps(public_key_config=public_key_config)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrCreatedTime")
    def attr_created_time(self) -> builtins.str:
        '''
        :cloudformationAttribute: CreatedTime
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrCreatedTime"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrId")
    def attr_id(self) -> builtins.str:
        '''
        :cloudformationAttribute: Id
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="publicKeyConfig")
    def public_key_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnPublicKey.PublicKeyConfigProperty"]:
        '''``AWS::CloudFront::PublicKey.PublicKeyConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-publickey.html#cfn-cloudfront-publickey-publickeyconfig
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnPublicKey.PublicKeyConfigProperty"], jsii.get(self, "publicKeyConfig"))

    @public_key_config.setter
    def public_key_config(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnPublicKey.PublicKeyConfigProperty"],
    ) -> None:
        jsii.set(self, "publicKeyConfig", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnPublicKey.PublicKeyConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "caller_reference": "callerReference",
            "encoded_key": "encodedKey",
            "name": "name",
            "comment": "comment",
        },
    )
    class PublicKeyConfigProperty:
        def __init__(
            self,
            *,
            caller_reference: builtins.str,
            encoded_key: builtins.str,
            name: builtins.str,
            comment: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param caller_reference: ``CfnPublicKey.PublicKeyConfigProperty.CallerReference``.
            :param encoded_key: ``CfnPublicKey.PublicKeyConfigProperty.EncodedKey``.
            :param name: ``CfnPublicKey.PublicKeyConfigProperty.Name``.
            :param comment: ``CfnPublicKey.PublicKeyConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-publickey-publickeyconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "caller_reference": caller_reference,
                "encoded_key": encoded_key,
                "name": name,
            }
            if comment is not None:
                self._values["comment"] = comment

        @builtins.property
        def caller_reference(self) -> builtins.str:
            '''``CfnPublicKey.PublicKeyConfigProperty.CallerReference``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-publickey-publickeyconfig.html#cfn-cloudfront-publickey-publickeyconfig-callerreference
            '''
            result = self._values.get("caller_reference")
            assert result is not None, "Required property 'caller_reference' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def encoded_key(self) -> builtins.str:
            '''``CfnPublicKey.PublicKeyConfigProperty.EncodedKey``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-publickey-publickeyconfig.html#cfn-cloudfront-publickey-publickeyconfig-encodedkey
            '''
            result = self._values.get("encoded_key")
            assert result is not None, "Required property 'encoded_key' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def name(self) -> builtins.str:
            '''``CfnPublicKey.PublicKeyConfigProperty.Name``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-publickey-publickeyconfig.html#cfn-cloudfront-publickey-publickeyconfig-name
            '''
            result = self._values.get("name")
            assert result is not None, "Required property 'name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def comment(self) -> typing.Optional[builtins.str]:
            '''``CfnPublicKey.PublicKeyConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-publickey-publickeyconfig.html#cfn-cloudfront-publickey-publickeyconfig-comment
            '''
            result = self._values.get("comment")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "PublicKeyConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CfnPublicKeyProps",
    jsii_struct_bases=[],
    name_mapping={"public_key_config": "publicKeyConfig"},
)
class CfnPublicKeyProps:
    def __init__(
        self,
        *,
        public_key_config: typing.Union[aws_cdk.core.IResolvable, CfnPublicKey.PublicKeyConfigProperty],
    ) -> None:
        '''Properties for defining a ``AWS::CloudFront::PublicKey``.

        :param public_key_config: ``AWS::CloudFront::PublicKey.PublicKeyConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-publickey.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "public_key_config": public_key_config,
        }

    @builtins.property
    def public_key_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnPublicKey.PublicKeyConfigProperty]:
        '''``AWS::CloudFront::PublicKey.PublicKeyConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-publickey.html#cfn-cloudfront-publickey-publickeyconfig
        '''
        result = self._values.get("public_key_config")
        assert result is not None, "Required property 'public_key_config' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnPublicKey.PublicKeyConfigProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnPublicKeyProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnRealtimeLogConfig(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CfnRealtimeLogConfig",
):
    '''A CloudFormation ``AWS::CloudFront::RealtimeLogConfig``.

    :cloudformationResource: AWS::CloudFront::RealtimeLogConfig
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        end_points: typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, "CfnRealtimeLogConfig.EndPointProperty"]]],
        fields: typing.Sequence[builtins.str],
        name: builtins.str,
        sampling_rate: jsii.Number,
    ) -> None:
        '''Create a new ``AWS::CloudFront::RealtimeLogConfig``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param end_points: ``AWS::CloudFront::RealtimeLogConfig.EndPoints``.
        :param fields: ``AWS::CloudFront::RealtimeLogConfig.Fields``.
        :param name: ``AWS::CloudFront::RealtimeLogConfig.Name``.
        :param sampling_rate: ``AWS::CloudFront::RealtimeLogConfig.SamplingRate``.
        '''
        props = CfnRealtimeLogConfigProps(
            end_points=end_points,
            fields=fields,
            name=name,
            sampling_rate=sampling_rate,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrArn")
    def attr_arn(self) -> builtins.str:
        '''
        :cloudformationAttribute: Arn
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="endPoints")
    def end_points(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRealtimeLogConfig.EndPointProperty"]]]:
        '''``AWS::CloudFront::RealtimeLogConfig.EndPoints``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html#cfn-cloudfront-realtimelogconfig-endpoints
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRealtimeLogConfig.EndPointProperty"]]], jsii.get(self, "endPoints"))

    @end_points.setter
    def end_points(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, "CfnRealtimeLogConfig.EndPointProperty"]]],
    ) -> None:
        jsii.set(self, "endPoints", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="fields")
    def fields(self) -> typing.List[builtins.str]:
        '''``AWS::CloudFront::RealtimeLogConfig.Fields``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html#cfn-cloudfront-realtimelogconfig-fields
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "fields"))

    @fields.setter
    def fields(self, value: typing.List[builtins.str]) -> None:
        jsii.set(self, "fields", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="name")
    def name(self) -> builtins.str:
        '''``AWS::CloudFront::RealtimeLogConfig.Name``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html#cfn-cloudfront-realtimelogconfig-name
        '''
        return typing.cast(builtins.str, jsii.get(self, "name"))

    @name.setter
    def name(self, value: builtins.str) -> None:
        jsii.set(self, "name", value)

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="samplingRate")
    def sampling_rate(self) -> jsii.Number:
        '''``AWS::CloudFront::RealtimeLogConfig.SamplingRate``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html#cfn-cloudfront-realtimelogconfig-samplingrate
        '''
        return typing.cast(jsii.Number, jsii.get(self, "samplingRate"))

    @sampling_rate.setter
    def sampling_rate(self, value: jsii.Number) -> None:
        jsii.set(self, "samplingRate", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnRealtimeLogConfig.EndPointProperty",
        jsii_struct_bases=[],
        name_mapping={
            "kinesis_stream_config": "kinesisStreamConfig",
            "stream_type": "streamType",
        },
    )
    class EndPointProperty:
        def __init__(
            self,
            *,
            kinesis_stream_config: typing.Union[aws_cdk.core.IResolvable, "CfnRealtimeLogConfig.KinesisStreamConfigProperty"],
            stream_type: builtins.str,
        ) -> None:
            '''
            :param kinesis_stream_config: ``CfnRealtimeLogConfig.EndPointProperty.KinesisStreamConfig``.
            :param stream_type: ``CfnRealtimeLogConfig.EndPointProperty.StreamType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-realtimelogconfig-endpoint.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "kinesis_stream_config": kinesis_stream_config,
                "stream_type": stream_type,
            }

        @builtins.property
        def kinesis_stream_config(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnRealtimeLogConfig.KinesisStreamConfigProperty"]:
            '''``CfnRealtimeLogConfig.EndPointProperty.KinesisStreamConfig``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-realtimelogconfig-endpoint.html#cfn-cloudfront-realtimelogconfig-endpoint-kinesisstreamconfig
            '''
            result = self._values.get("kinesis_stream_config")
            assert result is not None, "Required property 'kinesis_stream_config' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnRealtimeLogConfig.KinesisStreamConfigProperty"], result)

        @builtins.property
        def stream_type(self) -> builtins.str:
            '''``CfnRealtimeLogConfig.EndPointProperty.StreamType``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-realtimelogconfig-endpoint.html#cfn-cloudfront-realtimelogconfig-endpoint-streamtype
            '''
            result = self._values.get("stream_type")
            assert result is not None, "Required property 'stream_type' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "EndPointProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnRealtimeLogConfig.KinesisStreamConfigProperty",
        jsii_struct_bases=[],
        name_mapping={"role_arn": "roleArn", "stream_arn": "streamArn"},
    )
    class KinesisStreamConfigProperty:
        def __init__(self, *, role_arn: builtins.str, stream_arn: builtins.str) -> None:
            '''
            :param role_arn: ``CfnRealtimeLogConfig.KinesisStreamConfigProperty.RoleArn``.
            :param stream_arn: ``CfnRealtimeLogConfig.KinesisStreamConfigProperty.StreamArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-realtimelogconfig-kinesisstreamconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "role_arn": role_arn,
                "stream_arn": stream_arn,
            }

        @builtins.property
        def role_arn(self) -> builtins.str:
            '''``CfnRealtimeLogConfig.KinesisStreamConfigProperty.RoleArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-realtimelogconfig-kinesisstreamconfig.html#cfn-cloudfront-realtimelogconfig-kinesisstreamconfig-rolearn
            '''
            result = self._values.get("role_arn")
            assert result is not None, "Required property 'role_arn' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def stream_arn(self) -> builtins.str:
            '''``CfnRealtimeLogConfig.KinesisStreamConfigProperty.StreamArn``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-realtimelogconfig-kinesisstreamconfig.html#cfn-cloudfront-realtimelogconfig-kinesisstreamconfig-streamarn
            '''
            result = self._values.get("stream_arn")
            assert result is not None, "Required property 'stream_arn' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "KinesisStreamConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CfnRealtimeLogConfigProps",
    jsii_struct_bases=[],
    name_mapping={
        "end_points": "endPoints",
        "fields": "fields",
        "name": "name",
        "sampling_rate": "samplingRate",
    },
)
class CfnRealtimeLogConfigProps:
    def __init__(
        self,
        *,
        end_points: typing.Union[aws_cdk.core.IResolvable, typing.Sequence[typing.Union[aws_cdk.core.IResolvable, CfnRealtimeLogConfig.EndPointProperty]]],
        fields: typing.Sequence[builtins.str],
        name: builtins.str,
        sampling_rate: jsii.Number,
    ) -> None:
        '''Properties for defining a ``AWS::CloudFront::RealtimeLogConfig``.

        :param end_points: ``AWS::CloudFront::RealtimeLogConfig.EndPoints``.
        :param fields: ``AWS::CloudFront::RealtimeLogConfig.Fields``.
        :param name: ``AWS::CloudFront::RealtimeLogConfig.Name``.
        :param sampling_rate: ``AWS::CloudFront::RealtimeLogConfig.SamplingRate``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "end_points": end_points,
            "fields": fields,
            "name": name,
            "sampling_rate": sampling_rate,
        }

    @builtins.property
    def end_points(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnRealtimeLogConfig.EndPointProperty]]]:
        '''``AWS::CloudFront::RealtimeLogConfig.EndPoints``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html#cfn-cloudfront-realtimelogconfig-endpoints
        '''
        result = self._values.get("end_points")
        assert result is not None, "Required property 'end_points' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, typing.List[typing.Union[aws_cdk.core.IResolvable, CfnRealtimeLogConfig.EndPointProperty]]], result)

    @builtins.property
    def fields(self) -> typing.List[builtins.str]:
        '''``AWS::CloudFront::RealtimeLogConfig.Fields``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html#cfn-cloudfront-realtimelogconfig-fields
        '''
        result = self._values.get("fields")
        assert result is not None, "Required property 'fields' is missing"
        return typing.cast(typing.List[builtins.str], result)

    @builtins.property
    def name(self) -> builtins.str:
        '''``AWS::CloudFront::RealtimeLogConfig.Name``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html#cfn-cloudfront-realtimelogconfig-name
        '''
        result = self._values.get("name")
        assert result is not None, "Required property 'name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def sampling_rate(self) -> jsii.Number:
        '''``AWS::CloudFront::RealtimeLogConfig.SamplingRate``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-realtimelogconfig.html#cfn-cloudfront-realtimelogconfig-samplingrate
        '''
        result = self._values.get("sampling_rate")
        assert result is not None, "Required property 'sampling_rate' is missing"
        return typing.cast(jsii.Number, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnRealtimeLogConfigProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(aws_cdk.core.IInspectable)
class CfnStreamingDistribution(
    aws_cdk.core.CfnResource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CfnStreamingDistribution",
):
    '''A CloudFormation ``AWS::CloudFront::StreamingDistribution``.

    :cloudformationResource: AWS::CloudFront::StreamingDistribution
    :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-streamingdistribution.html
    '''

    def __init__(
        self,
        scope: aws_cdk.core.Construct,
        id: builtins.str,
        *,
        streaming_distribution_config: typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.StreamingDistributionConfigProperty"],
        tags: typing.Sequence[aws_cdk.core.CfnTag],
    ) -> None:
        '''Create a new ``AWS::CloudFront::StreamingDistribution``.

        :param scope: - scope in which this resource is defined.
        :param id: - scoped id of the resource.
        :param streaming_distribution_config: ``AWS::CloudFront::StreamingDistribution.StreamingDistributionConfig``.
        :param tags: ``AWS::CloudFront::StreamingDistribution.Tags``.
        '''
        props = CfnStreamingDistributionProps(
            streaming_distribution_config=streaming_distribution_config, tags=tags
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="inspect")
    def inspect(self, inspector: aws_cdk.core.TreeInspector) -> None:
        '''Examines the CloudFormation resource and discloses attributes.

        :param inspector: - tree inspector to collect and process attributes.
        '''
        return typing.cast(None, jsii.invoke(self, "inspect", [inspector]))

    @jsii.member(jsii_name="renderProperties")
    def _render_properties(
        self,
        props: typing.Mapping[builtins.str, typing.Any],
    ) -> typing.Mapping[builtins.str, typing.Any]:
        '''
        :param props: -
        '''
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.invoke(self, "renderProperties", [props]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CFN_RESOURCE_TYPE_NAME")
    def CFN_RESOURCE_TYPE_NAME(cls) -> builtins.str:
        '''The CloudFormation resource type name for this resource class.'''
        return typing.cast(builtins.str, jsii.sget(cls, "CFN_RESOURCE_TYPE_NAME"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="attrDomainName")
    def attr_domain_name(self) -> builtins.str:
        '''
        :cloudformationAttribute: DomainName
        '''
        return typing.cast(builtins.str, jsii.get(self, "attrDomainName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cfnProperties")
    def _cfn_properties(self) -> typing.Mapping[builtins.str, typing.Any]:
        return typing.cast(typing.Mapping[builtins.str, typing.Any], jsii.get(self, "cfnProperties"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="tags")
    def tags(self) -> aws_cdk.core.TagManager:
        '''``AWS::CloudFront::StreamingDistribution.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-streamingdistribution.html#cfn-cloudfront-streamingdistribution-tags
        '''
        return typing.cast(aws_cdk.core.TagManager, jsii.get(self, "tags"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="streamingDistributionConfig")
    def streaming_distribution_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.StreamingDistributionConfigProperty"]:
        '''``AWS::CloudFront::StreamingDistribution.StreamingDistributionConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-streamingdistribution.html#cfn-cloudfront-streamingdistribution-streamingdistributionconfig
        '''
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.StreamingDistributionConfigProperty"], jsii.get(self, "streamingDistributionConfig"))

    @streaming_distribution_config.setter
    def streaming_distribution_config(
        self,
        value: typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.StreamingDistributionConfigProperty"],
    ) -> None:
        jsii.set(self, "streamingDistributionConfig", value)

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnStreamingDistribution.LoggingProperty",
        jsii_struct_bases=[],
        name_mapping={"bucket": "bucket", "enabled": "enabled", "prefix": "prefix"},
    )
    class LoggingProperty:
        def __init__(
            self,
            *,
            bucket: builtins.str,
            enabled: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            prefix: builtins.str,
        ) -> None:
            '''
            :param bucket: ``CfnStreamingDistribution.LoggingProperty.Bucket``.
            :param enabled: ``CfnStreamingDistribution.LoggingProperty.Enabled``.
            :param prefix: ``CfnStreamingDistribution.LoggingProperty.Prefix``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-logging.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "bucket": bucket,
                "enabled": enabled,
                "prefix": prefix,
            }

        @builtins.property
        def bucket(self) -> builtins.str:
            '''``CfnStreamingDistribution.LoggingProperty.Bucket``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-logging.html#cfn-cloudfront-streamingdistribution-logging-bucket
            '''
            result = self._values.get("bucket")
            assert result is not None, "Required property 'bucket' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def enabled(self) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnStreamingDistribution.LoggingProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-logging.html#cfn-cloudfront-streamingdistribution-logging-enabled
            '''
            result = self._values.get("enabled")
            assert result is not None, "Required property 'enabled' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def prefix(self) -> builtins.str:
            '''``CfnStreamingDistribution.LoggingProperty.Prefix``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-logging.html#cfn-cloudfront-streamingdistribution-logging-prefix
            '''
            result = self._values.get("prefix")
            assert result is not None, "Required property 'prefix' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "LoggingProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnStreamingDistribution.S3OriginProperty",
        jsii_struct_bases=[],
        name_mapping={
            "domain_name": "domainName",
            "origin_access_identity": "originAccessIdentity",
        },
    )
    class S3OriginProperty:
        def __init__(
            self,
            *,
            domain_name: builtins.str,
            origin_access_identity: builtins.str,
        ) -> None:
            '''
            :param domain_name: ``CfnStreamingDistribution.S3OriginProperty.DomainName``.
            :param origin_access_identity: ``CfnStreamingDistribution.S3OriginProperty.OriginAccessIdentity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-s3origin.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "domain_name": domain_name,
                "origin_access_identity": origin_access_identity,
            }

        @builtins.property
        def domain_name(self) -> builtins.str:
            '''``CfnStreamingDistribution.S3OriginProperty.DomainName``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-s3origin.html#cfn-cloudfront-streamingdistribution-s3origin-domainname
            '''
            result = self._values.get("domain_name")
            assert result is not None, "Required property 'domain_name' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def origin_access_identity(self) -> builtins.str:
            '''``CfnStreamingDistribution.S3OriginProperty.OriginAccessIdentity``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-s3origin.html#cfn-cloudfront-streamingdistribution-s3origin-originaccessidentity
            '''
            result = self._values.get("origin_access_identity")
            assert result is not None, "Required property 'origin_access_identity' is missing"
            return typing.cast(builtins.str, result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "S3OriginProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnStreamingDistribution.StreamingDistributionConfigProperty",
        jsii_struct_bases=[],
        name_mapping={
            "comment": "comment",
            "enabled": "enabled",
            "s3_origin": "s3Origin",
            "trusted_signers": "trustedSigners",
            "aliases": "aliases",
            "logging": "logging",
            "price_class": "priceClass",
        },
    )
    class StreamingDistributionConfigProperty:
        def __init__(
            self,
            *,
            comment: builtins.str,
            enabled: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            s3_origin: typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.S3OriginProperty"],
            trusted_signers: typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.TrustedSignersProperty"],
            aliases: typing.Optional[typing.Sequence[builtins.str]] = None,
            logging: typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.LoggingProperty"]] = None,
            price_class: typing.Optional[builtins.str] = None,
        ) -> None:
            '''
            :param comment: ``CfnStreamingDistribution.StreamingDistributionConfigProperty.Comment``.
            :param enabled: ``CfnStreamingDistribution.StreamingDistributionConfigProperty.Enabled``.
            :param s3_origin: ``CfnStreamingDistribution.StreamingDistributionConfigProperty.S3Origin``.
            :param trusted_signers: ``CfnStreamingDistribution.StreamingDistributionConfigProperty.TrustedSigners``.
            :param aliases: ``CfnStreamingDistribution.StreamingDistributionConfigProperty.Aliases``.
            :param logging: ``CfnStreamingDistribution.StreamingDistributionConfigProperty.Logging``.
            :param price_class: ``CfnStreamingDistribution.StreamingDistributionConfigProperty.PriceClass``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-streamingdistributionconfig.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "comment": comment,
                "enabled": enabled,
                "s3_origin": s3_origin,
                "trusted_signers": trusted_signers,
            }
            if aliases is not None:
                self._values["aliases"] = aliases
            if logging is not None:
                self._values["logging"] = logging
            if price_class is not None:
                self._values["price_class"] = price_class

        @builtins.property
        def comment(self) -> builtins.str:
            '''``CfnStreamingDistribution.StreamingDistributionConfigProperty.Comment``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-streamingdistributionconfig.html#cfn-cloudfront-streamingdistribution-streamingdistributionconfig-comment
            '''
            result = self._values.get("comment")
            assert result is not None, "Required property 'comment' is missing"
            return typing.cast(builtins.str, result)

        @builtins.property
        def enabled(self) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnStreamingDistribution.StreamingDistributionConfigProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-streamingdistributionconfig.html#cfn-cloudfront-streamingdistribution-streamingdistributionconfig-enabled
            '''
            result = self._values.get("enabled")
            assert result is not None, "Required property 'enabled' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def s3_origin(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.S3OriginProperty"]:
            '''``CfnStreamingDistribution.StreamingDistributionConfigProperty.S3Origin``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-streamingdistributionconfig.html#cfn-cloudfront-streamingdistribution-streamingdistributionconfig-s3origin
            '''
            result = self._values.get("s3_origin")
            assert result is not None, "Required property 's3_origin' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.S3OriginProperty"], result)

        @builtins.property
        def trusted_signers(
            self,
        ) -> typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.TrustedSignersProperty"]:
            '''``CfnStreamingDistribution.StreamingDistributionConfigProperty.TrustedSigners``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-streamingdistributionconfig.html#cfn-cloudfront-streamingdistribution-streamingdistributionconfig-trustedsigners
            '''
            result = self._values.get("trusted_signers")
            assert result is not None, "Required property 'trusted_signers' is missing"
            return typing.cast(typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.TrustedSignersProperty"], result)

        @builtins.property
        def aliases(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnStreamingDistribution.StreamingDistributionConfigProperty.Aliases``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-streamingdistributionconfig.html#cfn-cloudfront-streamingdistribution-streamingdistributionconfig-aliases
            '''
            result = self._values.get("aliases")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        @builtins.property
        def logging(
            self,
        ) -> typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.LoggingProperty"]]:
            '''``CfnStreamingDistribution.StreamingDistributionConfigProperty.Logging``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-streamingdistributionconfig.html#cfn-cloudfront-streamingdistribution-streamingdistributionconfig-logging
            '''
            result = self._values.get("logging")
            return typing.cast(typing.Optional[typing.Union[aws_cdk.core.IResolvable, "CfnStreamingDistribution.LoggingProperty"]], result)

        @builtins.property
        def price_class(self) -> typing.Optional[builtins.str]:
            '''``CfnStreamingDistribution.StreamingDistributionConfigProperty.PriceClass``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-streamingdistributionconfig.html#cfn-cloudfront-streamingdistribution-streamingdistributionconfig-priceclass
            '''
            result = self._values.get("price_class")
            return typing.cast(typing.Optional[builtins.str], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "StreamingDistributionConfigProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )

    @jsii.data_type(
        jsii_type="@aws-cdk/aws-cloudfront.CfnStreamingDistribution.TrustedSignersProperty",
        jsii_struct_bases=[],
        name_mapping={
            "enabled": "enabled",
            "aws_account_numbers": "awsAccountNumbers",
        },
    )
    class TrustedSignersProperty:
        def __init__(
            self,
            *,
            enabled: typing.Union[builtins.bool, aws_cdk.core.IResolvable],
            aws_account_numbers: typing.Optional[typing.Sequence[builtins.str]] = None,
        ) -> None:
            '''
            :param enabled: ``CfnStreamingDistribution.TrustedSignersProperty.Enabled``.
            :param aws_account_numbers: ``CfnStreamingDistribution.TrustedSignersProperty.AwsAccountNumbers``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-trustedsigners.html
            '''
            self._values: typing.Dict[str, typing.Any] = {
                "enabled": enabled,
            }
            if aws_account_numbers is not None:
                self._values["aws_account_numbers"] = aws_account_numbers

        @builtins.property
        def enabled(self) -> typing.Union[builtins.bool, aws_cdk.core.IResolvable]:
            '''``CfnStreamingDistribution.TrustedSignersProperty.Enabled``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-trustedsigners.html#cfn-cloudfront-streamingdistribution-trustedsigners-enabled
            '''
            result = self._values.get("enabled")
            assert result is not None, "Required property 'enabled' is missing"
            return typing.cast(typing.Union[builtins.bool, aws_cdk.core.IResolvable], result)

        @builtins.property
        def aws_account_numbers(self) -> typing.Optional[typing.List[builtins.str]]:
            '''``CfnStreamingDistribution.TrustedSignersProperty.AwsAccountNumbers``.

            :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-streamingdistribution-trustedsigners.html#cfn-cloudfront-streamingdistribution-trustedsigners-awsaccountnumbers
            '''
            result = self._values.get("aws_account_numbers")
            return typing.cast(typing.Optional[typing.List[builtins.str]], result)

        def __eq__(self, rhs: typing.Any) -> builtins.bool:
            return isinstance(rhs, self.__class__) and rhs._values == self._values

        def __ne__(self, rhs: typing.Any) -> builtins.bool:
            return not (rhs == self)

        def __repr__(self) -> str:
            return "TrustedSignersProperty(%s)" % ", ".join(
                k + "=" + repr(v) for k, v in self._values.items()
            )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CfnStreamingDistributionProps",
    jsii_struct_bases=[],
    name_mapping={
        "streaming_distribution_config": "streamingDistributionConfig",
        "tags": "tags",
    },
)
class CfnStreamingDistributionProps:
    def __init__(
        self,
        *,
        streaming_distribution_config: typing.Union[aws_cdk.core.IResolvable, CfnStreamingDistribution.StreamingDistributionConfigProperty],
        tags: typing.Sequence[aws_cdk.core.CfnTag],
    ) -> None:
        '''Properties for defining a ``AWS::CloudFront::StreamingDistribution``.

        :param streaming_distribution_config: ``AWS::CloudFront::StreamingDistribution.StreamingDistributionConfig``.
        :param tags: ``AWS::CloudFront::StreamingDistribution.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-streamingdistribution.html
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "streaming_distribution_config": streaming_distribution_config,
            "tags": tags,
        }

    @builtins.property
    def streaming_distribution_config(
        self,
    ) -> typing.Union[aws_cdk.core.IResolvable, CfnStreamingDistribution.StreamingDistributionConfigProperty]:
        '''``AWS::CloudFront::StreamingDistribution.StreamingDistributionConfig``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-streamingdistribution.html#cfn-cloudfront-streamingdistribution-streamingdistributionconfig
        '''
        result = self._values.get("streaming_distribution_config")
        assert result is not None, "Required property 'streaming_distribution_config' is missing"
        return typing.cast(typing.Union[aws_cdk.core.IResolvable, CfnStreamingDistribution.StreamingDistributionConfigProperty], result)

    @builtins.property
    def tags(self) -> typing.List[aws_cdk.core.CfnTag]:
        '''``AWS::CloudFront::StreamingDistribution.Tags``.

        :link: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-streamingdistribution.html#cfn-cloudfront-streamingdistribution-tags
        '''
        result = self._values.get("tags")
        assert result is not None, "Required property 'tags' is missing"
        return typing.cast(typing.List[aws_cdk.core.CfnTag], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CfnStreamingDistributionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.CloudFrontAllowedCachedMethods")
class CloudFrontAllowedCachedMethods(enum.Enum):
    '''Enums for the methods CloudFront can cache.'''

    GET_HEAD = "GET_HEAD"
    GET_HEAD_OPTIONS = "GET_HEAD_OPTIONS"


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.CloudFrontAllowedMethods")
class CloudFrontAllowedMethods(enum.Enum):
    '''An enum for the supported methods to a CloudFront distribution.'''

    GET_HEAD = "GET_HEAD"
    GET_HEAD_OPTIONS = "GET_HEAD_OPTIONS"
    ALL = "ALL"


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CloudFrontWebDistributionAttributes",
    jsii_struct_bases=[],
    name_mapping={"distribution_id": "distributionId", "domain_name": "domainName"},
)
class CloudFrontWebDistributionAttributes:
    def __init__(
        self,
        *,
        distribution_id: builtins.str,
        domain_name: builtins.str,
    ) -> None:
        '''Attributes used to import a Distribution.

        :param distribution_id: The distribution ID for this distribution.
        :param domain_name: The generated domain name of the Distribution, such as d111111abcdef8.cloudfront.net.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "distribution_id": distribution_id,
            "domain_name": domain_name,
        }

    @builtins.property
    def distribution_id(self) -> builtins.str:
        '''The distribution ID for this distribution.

        :attribute: true
        '''
        result = self._values.get("distribution_id")
        assert result is not None, "Required property 'distribution_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def domain_name(self) -> builtins.str:
        '''The generated domain name of the Distribution, such as d111111abcdef8.cloudfront.net.

        :attribute: true
        '''
        result = self._values.get("domain_name")
        assert result is not None, "Required property 'domain_name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CloudFrontWebDistributionAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CloudFrontWebDistributionProps",
    jsii_struct_bases=[],
    name_mapping={
        "origin_configs": "originConfigs",
        "alias_configuration": "aliasConfiguration",
        "comment": "comment",
        "default_root_object": "defaultRootObject",
        "enabled": "enabled",
        "enable_ip_v6": "enableIpV6",
        "error_configurations": "errorConfigurations",
        "geo_restriction": "geoRestriction",
        "http_version": "httpVersion",
        "logging_config": "loggingConfig",
        "price_class": "priceClass",
        "viewer_certificate": "viewerCertificate",
        "viewer_protocol_policy": "viewerProtocolPolicy",
        "web_acl_id": "webACLId",
    },
)
class CloudFrontWebDistributionProps:
    def __init__(
        self,
        *,
        origin_configs: typing.Sequence["SourceConfiguration"],
        alias_configuration: typing.Optional[AliasConfiguration] = None,
        comment: typing.Optional[builtins.str] = None,
        default_root_object: typing.Optional[builtins.str] = None,
        enabled: typing.Optional[builtins.bool] = None,
        enable_ip_v6: typing.Optional[builtins.bool] = None,
        error_configurations: typing.Optional[typing.Sequence[CfnDistribution.CustomErrorResponseProperty]] = None,
        geo_restriction: typing.Optional["GeoRestriction"] = None,
        http_version: typing.Optional["HttpVersion"] = None,
        logging_config: typing.Optional["LoggingConfiguration"] = None,
        price_class: typing.Optional["PriceClass"] = None,
        viewer_certificate: typing.Optional["ViewerCertificate"] = None,
        viewer_protocol_policy: typing.Optional["ViewerProtocolPolicy"] = None,
        web_acl_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param origin_configs: The origin configurations for this distribution. Behaviors are a part of the origin.
        :param alias_configuration: (deprecated) AliasConfiguration is used to configured CloudFront to respond to requests on custom domain names. Default: - None.
        :param comment: A comment for this distribution in the CloudFront console. Default: - No comment is added to distribution.
        :param default_root_object: The default object to serve. Default: - "index.html" is served.
        :param enabled: Enable or disable the distribution. Default: true
        :param enable_ip_v6: If your distribution should have IPv6 enabled. Default: true
        :param error_configurations: How CloudFront should handle requests that are not successful (eg PageNotFound). By default, CloudFront does not replace HTTP status codes in the 4xx and 5xx range with custom error messages. CloudFront does not cache HTTP status codes. Default: - No custom error configuration.
        :param geo_restriction: Controls the countries in which your content is distributed. Default: No geo restriction
        :param http_version: The max supported HTTP Versions. Default: HttpVersion.HTTP2
        :param logging_config: Optional - if we should enable logging. You can pass an empty object ({}) to have us auto create a bucket for logging. Omission of this property indicates no logging is to be enabled. Default: - no logging is enabled by default.
        :param price_class: The price class for the distribution (this impacts how many locations CloudFront uses for your distribution, and billing). Default: PriceClass.PRICE_CLASS_100 the cheapest option for CloudFront is picked by default.
        :param viewer_certificate: Specifies whether you want viewers to use HTTP or HTTPS to request your objects, whether you're using an alternate domain name with HTTPS, and if so, if you're using AWS Certificate Manager (ACM) or a third-party certificate authority. Default: ViewerCertificate.fromCloudFrontDefaultCertificate()
        :param viewer_protocol_policy: The default viewer policy for incoming clients. Default: RedirectToHTTPs
        :param web_acl_id: Unique identifier that specifies the AWS WAF web ACL to associate with this CloudFront distribution. To specify a web ACL created using the latest version of AWS WAF, use the ACL ARN, for example ``arn:aws:wafv2:us-east-1:123456789012:global/webacl/ExampleWebACL/473e64fd-f30b-4765-81a0-62ad96dd167a``. To specify a web ACL created using AWS WAF Classic, use the ACL ID, for example ``473e64fd-f30b-4765-81a0-62ad96dd167a``. Default: - No AWS Web Application Firewall web access control list (web ACL).
        '''
        if isinstance(alias_configuration, dict):
            alias_configuration = AliasConfiguration(**alias_configuration)
        if isinstance(logging_config, dict):
            logging_config = LoggingConfiguration(**logging_config)
        self._values: typing.Dict[str, typing.Any] = {
            "origin_configs": origin_configs,
        }
        if alias_configuration is not None:
            self._values["alias_configuration"] = alias_configuration
        if comment is not None:
            self._values["comment"] = comment
        if default_root_object is not None:
            self._values["default_root_object"] = default_root_object
        if enabled is not None:
            self._values["enabled"] = enabled
        if enable_ip_v6 is not None:
            self._values["enable_ip_v6"] = enable_ip_v6
        if error_configurations is not None:
            self._values["error_configurations"] = error_configurations
        if geo_restriction is not None:
            self._values["geo_restriction"] = geo_restriction
        if http_version is not None:
            self._values["http_version"] = http_version
        if logging_config is not None:
            self._values["logging_config"] = logging_config
        if price_class is not None:
            self._values["price_class"] = price_class
        if viewer_certificate is not None:
            self._values["viewer_certificate"] = viewer_certificate
        if viewer_protocol_policy is not None:
            self._values["viewer_protocol_policy"] = viewer_protocol_policy
        if web_acl_id is not None:
            self._values["web_acl_id"] = web_acl_id

    @builtins.property
    def origin_configs(self) -> typing.List["SourceConfiguration"]:
        '''The origin configurations for this distribution.

        Behaviors are a part of the origin.
        '''
        result = self._values.get("origin_configs")
        assert result is not None, "Required property 'origin_configs' is missing"
        return typing.cast(typing.List["SourceConfiguration"], result)

    @builtins.property
    def alias_configuration(self) -> typing.Optional[AliasConfiguration]:
        '''(deprecated) AliasConfiguration is used to configured CloudFront to respond to requests on custom domain names.

        :default: - None.

        :deprecated: see {@link CloudFrontWebDistributionProps#viewerCertificate} with {@link ViewerCertificate#acmCertificate}

        :stability: deprecated
        '''
        result = self._values.get("alias_configuration")
        return typing.cast(typing.Optional[AliasConfiguration], result)

    @builtins.property
    def comment(self) -> typing.Optional[builtins.str]:
        '''A comment for this distribution in the CloudFront console.

        :default: - No comment is added to distribution.
        '''
        result = self._values.get("comment")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def default_root_object(self) -> typing.Optional[builtins.str]:
        '''The default object to serve.

        :default: - "index.html" is served.
        '''
        result = self._values.get("default_root_object")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def enabled(self) -> typing.Optional[builtins.bool]:
        '''Enable or disable the distribution.

        :default: true
        '''
        result = self._values.get("enabled")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def enable_ip_v6(self) -> typing.Optional[builtins.bool]:
        '''If your distribution should have IPv6 enabled.

        :default: true
        '''
        result = self._values.get("enable_ip_v6")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def error_configurations(
        self,
    ) -> typing.Optional[typing.List[CfnDistribution.CustomErrorResponseProperty]]:
        '''How CloudFront should handle requests that are not successful (eg PageNotFound).

        By default, CloudFront does not replace HTTP status codes in the 4xx and 5xx range
        with custom error messages. CloudFront does not cache HTTP status codes.

        :default: - No custom error configuration.
        '''
        result = self._values.get("error_configurations")
        return typing.cast(typing.Optional[typing.List[CfnDistribution.CustomErrorResponseProperty]], result)

    @builtins.property
    def geo_restriction(self) -> typing.Optional["GeoRestriction"]:
        '''Controls the countries in which your content is distributed.

        :default: No geo restriction
        '''
        result = self._values.get("geo_restriction")
        return typing.cast(typing.Optional["GeoRestriction"], result)

    @builtins.property
    def http_version(self) -> typing.Optional["HttpVersion"]:
        '''The max supported HTTP Versions.

        :default: HttpVersion.HTTP2
        '''
        result = self._values.get("http_version")
        return typing.cast(typing.Optional["HttpVersion"], result)

    @builtins.property
    def logging_config(self) -> typing.Optional["LoggingConfiguration"]:
        '''Optional - if we should enable logging.

        You can pass an empty object ({}) to have us auto create a bucket for logging.
        Omission of this property indicates no logging is to be enabled.

        :default: - no logging is enabled by default.
        '''
        result = self._values.get("logging_config")
        return typing.cast(typing.Optional["LoggingConfiguration"], result)

    @builtins.property
    def price_class(self) -> typing.Optional["PriceClass"]:
        '''The price class for the distribution (this impacts how many locations CloudFront uses for your distribution, and billing).

        :default: PriceClass.PRICE_CLASS_100 the cheapest option for CloudFront is picked by default.
        '''
        result = self._values.get("price_class")
        return typing.cast(typing.Optional["PriceClass"], result)

    @builtins.property
    def viewer_certificate(self) -> typing.Optional["ViewerCertificate"]:
        '''Specifies whether you want viewers to use HTTP or HTTPS to request your objects, whether you're using an alternate domain name with HTTPS, and if so, if you're using AWS Certificate Manager (ACM) or a third-party certificate authority.

        :default: ViewerCertificate.fromCloudFrontDefaultCertificate()

        :see: https://aws.amazon.com/premiumsupport/knowledge-center/custom-ssl-certificate-cloudfront/
        '''
        result = self._values.get("viewer_certificate")
        return typing.cast(typing.Optional["ViewerCertificate"], result)

    @builtins.property
    def viewer_protocol_policy(self) -> typing.Optional["ViewerProtocolPolicy"]:
        '''The default viewer policy for incoming clients.

        :default: RedirectToHTTPs
        '''
        result = self._values.get("viewer_protocol_policy")
        return typing.cast(typing.Optional["ViewerProtocolPolicy"], result)

    @builtins.property
    def web_acl_id(self) -> typing.Optional[builtins.str]:
        '''Unique identifier that specifies the AWS WAF web ACL to associate with this CloudFront distribution.

        To specify a web ACL created using the latest version of AWS WAF, use the ACL ARN, for example
        ``arn:aws:wafv2:us-east-1:123456789012:global/webacl/ExampleWebACL/473e64fd-f30b-4765-81a0-62ad96dd167a``.

        To specify a web ACL created using AWS WAF Classic, use the ACL ID, for example ``473e64fd-f30b-4765-81a0-62ad96dd167a``.

        :default: - No AWS Web Application Firewall web access control list (web ACL).

        :see: https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateDistribution.html#API_CreateDistribution_RequestParameters.
        '''
        result = self._values.get("web_acl_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CloudFrontWebDistributionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.CustomOriginConfig",
    jsii_struct_bases=[],
    name_mapping={
        "domain_name": "domainName",
        "allowed_origin_ssl_versions": "allowedOriginSSLVersions",
        "http_port": "httpPort",
        "https_port": "httpsPort",
        "origin_headers": "originHeaders",
        "origin_keepalive_timeout": "originKeepaliveTimeout",
        "origin_path": "originPath",
        "origin_protocol_policy": "originProtocolPolicy",
        "origin_read_timeout": "originReadTimeout",
        "origin_shield_region": "originShieldRegion",
    },
)
class CustomOriginConfig:
    def __init__(
        self,
        *,
        domain_name: builtins.str,
        allowed_origin_ssl_versions: typing.Optional[typing.Sequence["OriginSslPolicy"]] = None,
        http_port: typing.Optional[jsii.Number] = None,
        https_port: typing.Optional[jsii.Number] = None,
        origin_headers: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        origin_keepalive_timeout: typing.Optional[aws_cdk.core.Duration] = None,
        origin_path: typing.Optional[builtins.str] = None,
        origin_protocol_policy: typing.Optional["OriginProtocolPolicy"] = None,
        origin_read_timeout: typing.Optional[aws_cdk.core.Duration] = None,
        origin_shield_region: typing.Optional[builtins.str] = None,
    ) -> None:
        '''A custom origin configuration.

        :param domain_name: The domain name of the custom origin. Should not include the path - that should be in the parent SourceConfiguration
        :param allowed_origin_ssl_versions: The SSL versions to use when interacting with the origin. Default: OriginSslPolicy.TLS_V1_2
        :param http_port: The origin HTTP port. Default: 80
        :param https_port: The origin HTTPS port. Default: 443
        :param origin_headers: Any additional headers to pass to the origin. Default: - No additional headers are passed.
        :param origin_keepalive_timeout: The keep alive timeout when making calls in seconds. Default: Duration.seconds(5)
        :param origin_path: The relative path to the origin root to use for sources. Default: /
        :param origin_protocol_policy: The protocol (http or https) policy to use when interacting with the origin. Default: OriginProtocolPolicy.HttpsOnly
        :param origin_read_timeout: The read timeout when calling the origin in seconds. Default: Duration.seconds(30)
        :param origin_shield_region: When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance. Default: - origin shield not enabled
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "domain_name": domain_name,
        }
        if allowed_origin_ssl_versions is not None:
            self._values["allowed_origin_ssl_versions"] = allowed_origin_ssl_versions
        if http_port is not None:
            self._values["http_port"] = http_port
        if https_port is not None:
            self._values["https_port"] = https_port
        if origin_headers is not None:
            self._values["origin_headers"] = origin_headers
        if origin_keepalive_timeout is not None:
            self._values["origin_keepalive_timeout"] = origin_keepalive_timeout
        if origin_path is not None:
            self._values["origin_path"] = origin_path
        if origin_protocol_policy is not None:
            self._values["origin_protocol_policy"] = origin_protocol_policy
        if origin_read_timeout is not None:
            self._values["origin_read_timeout"] = origin_read_timeout
        if origin_shield_region is not None:
            self._values["origin_shield_region"] = origin_shield_region

    @builtins.property
    def domain_name(self) -> builtins.str:
        '''The domain name of the custom origin.

        Should not include the path - that should be in the parent SourceConfiguration
        '''
        result = self._values.get("domain_name")
        assert result is not None, "Required property 'domain_name' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def allowed_origin_ssl_versions(
        self,
    ) -> typing.Optional[typing.List["OriginSslPolicy"]]:
        '''The SSL versions to use when interacting with the origin.

        :default: OriginSslPolicy.TLS_V1_2
        '''
        result = self._values.get("allowed_origin_ssl_versions")
        return typing.cast(typing.Optional[typing.List["OriginSslPolicy"]], result)

    @builtins.property
    def http_port(self) -> typing.Optional[jsii.Number]:
        '''The origin HTTP port.

        :default: 80
        '''
        result = self._values.get("http_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def https_port(self) -> typing.Optional[jsii.Number]:
        '''The origin HTTPS port.

        :default: 443
        '''
        result = self._values.get("https_port")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def origin_headers(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Any additional headers to pass to the origin.

        :default: - No additional headers are passed.
        '''
        result = self._values.get("origin_headers")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def origin_keepalive_timeout(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The keep alive timeout when making calls in seconds.

        :default: Duration.seconds(5)
        '''
        result = self._values.get("origin_keepalive_timeout")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def origin_path(self) -> typing.Optional[builtins.str]:
        '''The relative path to the origin root to use for sources.

        :default: /
        '''
        result = self._values.get("origin_path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def origin_protocol_policy(self) -> typing.Optional["OriginProtocolPolicy"]:
        '''The protocol (http or https) policy to use when interacting with the origin.

        :default: OriginProtocolPolicy.HttpsOnly
        '''
        result = self._values.get("origin_protocol_policy")
        return typing.cast(typing.Optional["OriginProtocolPolicy"], result)

    @builtins.property
    def origin_read_timeout(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The read timeout when calling the origin in seconds.

        :default: Duration.seconds(30)
        '''
        result = self._values.get("origin_read_timeout")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def origin_shield_region(self) -> typing.Optional[builtins.str]:
        '''When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance.

        :default: - origin shield not enabled
        '''
        result = self._values.get("origin_shield_region")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "CustomOriginConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.DistributionAttributes",
    jsii_struct_bases=[],
    name_mapping={"distribution_id": "distributionId", "domain_name": "domainName"},
)
class DistributionAttributes:
    def __init__(
        self,
        *,
        distribution_id: builtins.str,
        domain_name: builtins.str,
    ) -> None:
        '''Attributes used to import a Distribution.

        :param distribution_id: The distribution ID for this distribution.
        :param domain_name: The generated domain name of the Distribution, such as d111111abcdef8.cloudfront.net.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "distribution_id": distribution_id,
            "domain_name": domain_name,
        }

    @builtins.property
    def distribution_id(self) -> builtins.str:
        '''The distribution ID for this distribution.

        :attribute: true
        '''
        result = self._values.get("distribution_id")
        assert result is not None, "Required property 'distribution_id' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def domain_name(self) -> builtins.str:
        '''The generated domain name of the Distribution, such as d111111abcdef8.cloudfront.net.

        :attribute: true
        '''
        result = self._values.get("domain_name")
        assert result is not None, "Required property 'domain_name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DistributionAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.DistributionProps",
    jsii_struct_bases=[],
    name_mapping={
        "default_behavior": "defaultBehavior",
        "additional_behaviors": "additionalBehaviors",
        "certificate": "certificate",
        "comment": "comment",
        "default_root_object": "defaultRootObject",
        "domain_names": "domainNames",
        "enabled": "enabled",
        "enable_ipv6": "enableIpv6",
        "enable_logging": "enableLogging",
        "error_responses": "errorResponses",
        "geo_restriction": "geoRestriction",
        "http_version": "httpVersion",
        "log_bucket": "logBucket",
        "log_file_prefix": "logFilePrefix",
        "log_includes_cookies": "logIncludesCookies",
        "minimum_protocol_version": "minimumProtocolVersion",
        "price_class": "priceClass",
        "web_acl_id": "webAclId",
    },
)
class DistributionProps:
    def __init__(
        self,
        *,
        default_behavior: BehaviorOptions,
        additional_behaviors: typing.Optional[typing.Mapping[builtins.str, BehaviorOptions]] = None,
        certificate: typing.Optional[aws_cdk.aws_certificatemanager.ICertificate] = None,
        comment: typing.Optional[builtins.str] = None,
        default_root_object: typing.Optional[builtins.str] = None,
        domain_names: typing.Optional[typing.Sequence[builtins.str]] = None,
        enabled: typing.Optional[builtins.bool] = None,
        enable_ipv6: typing.Optional[builtins.bool] = None,
        enable_logging: typing.Optional[builtins.bool] = None,
        error_responses: typing.Optional[typing.Sequence["ErrorResponse"]] = None,
        geo_restriction: typing.Optional["GeoRestriction"] = None,
        http_version: typing.Optional["HttpVersion"] = None,
        log_bucket: typing.Optional[aws_cdk.aws_s3.IBucket] = None,
        log_file_prefix: typing.Optional[builtins.str] = None,
        log_includes_cookies: typing.Optional[builtins.bool] = None,
        minimum_protocol_version: typing.Optional["SecurityPolicyProtocol"] = None,
        price_class: typing.Optional["PriceClass"] = None,
        web_acl_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for a Distribution.

        :param default_behavior: The default behavior for the distribution.
        :param additional_behaviors: Additional behaviors for the distribution, mapped by the pathPattern that specifies which requests to apply the behavior to. Default: - no additional behaviors are added.
        :param certificate: A certificate to associate with the distribution. The certificate must be located in N. Virginia (us-east-1). Default: - the CloudFront wildcard certificate (*.cloudfront.net) will be used.
        :param comment: Any comments you want to include about the distribution. Default: - no comment
        :param default_root_object: The object that you want CloudFront to request from your origin (for example, index.html) when a viewer requests the root URL for your distribution. If no default object is set, the request goes to the origin's root (e.g., example.com/). Default: - no default root object
        :param domain_names: Alternative domain names for this distribution. If you want to use your own domain name, such as www.example.com, instead of the cloudfront.net domain name, you can add an alternate domain name to your distribution. If you attach a certificate to the distribution, you must add (at least one of) the domain names of the certificate to this list. Default: - The distribution will only support the default generated name (e.g., d111111abcdef8.cloudfront.net)
        :param enabled: Enable or disable the distribution. Default: true
        :param enable_ipv6: Whether CloudFront will respond to IPv6 DNS requests with an IPv6 address. If you specify false, CloudFront responds to IPv6 DNS requests with the DNS response code NOERROR and with no IP addresses. This allows viewers to submit a second request, for an IPv4 address for your distribution. Default: true
        :param enable_logging: Enable access logging for the distribution. Default: - false, unless ``logBucket`` is specified.
        :param error_responses: How CloudFront should handle requests that are not successful (e.g., PageNotFound). Default: - No custom error responses.
        :param geo_restriction: Controls the countries in which your content is distributed. Default: - No geographic restrictions
        :param http_version: Specify the maximum HTTP version that you want viewers to use to communicate with CloudFront. For viewers and CloudFront to use HTTP/2, viewers must support TLS 1.2 or later, and must support server name identification (SNI). Default: HttpVersion.HTTP2
        :param log_bucket: The Amazon S3 bucket to store the access logs in. Default: - A bucket is created if ``enableLogging`` is true
        :param log_file_prefix: An optional string that you want CloudFront to prefix to the access log filenames for this distribution. Default: - no prefix
        :param log_includes_cookies: Specifies whether you want CloudFront to include cookies in access logs. Default: false
        :param minimum_protocol_version: The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify. Default: - SecurityPolicyProtocol.TLS_V1_2_2021 if the '
        :param price_class: The price class that corresponds with the maximum price that you want to pay for CloudFront service. If you specify PriceClass_All, CloudFront responds to requests for your objects from all CloudFront edge locations. If you specify a price class other than PriceClass_All, CloudFront serves your objects from the CloudFront edge location that has the lowest latency among the edge locations in your price class. Default: PriceClass.PRICE_CLASS_ALL
        :param web_acl_id: Unique identifier that specifies the AWS WAF web ACL to associate with this CloudFront distribution. To specify a web ACL created using the latest version of AWS WAF, use the ACL ARN, for example ``arn:aws:wafv2:us-east-1:123456789012:global/webacl/ExampleWebACL/473e64fd-f30b-4765-81a0-62ad96dd167a``. To specify a web ACL created using AWS WAF Classic, use the ACL ID, for example ``473e64fd-f30b-4765-81a0-62ad96dd167a``. Default: - No AWS Web Application Firewall web access control list (web ACL).
        '''
        if isinstance(default_behavior, dict):
            default_behavior = BehaviorOptions(**default_behavior)
        self._values: typing.Dict[str, typing.Any] = {
            "default_behavior": default_behavior,
        }
        if additional_behaviors is not None:
            self._values["additional_behaviors"] = additional_behaviors
        if certificate is not None:
            self._values["certificate"] = certificate
        if comment is not None:
            self._values["comment"] = comment
        if default_root_object is not None:
            self._values["default_root_object"] = default_root_object
        if domain_names is not None:
            self._values["domain_names"] = domain_names
        if enabled is not None:
            self._values["enabled"] = enabled
        if enable_ipv6 is not None:
            self._values["enable_ipv6"] = enable_ipv6
        if enable_logging is not None:
            self._values["enable_logging"] = enable_logging
        if error_responses is not None:
            self._values["error_responses"] = error_responses
        if geo_restriction is not None:
            self._values["geo_restriction"] = geo_restriction
        if http_version is not None:
            self._values["http_version"] = http_version
        if log_bucket is not None:
            self._values["log_bucket"] = log_bucket
        if log_file_prefix is not None:
            self._values["log_file_prefix"] = log_file_prefix
        if log_includes_cookies is not None:
            self._values["log_includes_cookies"] = log_includes_cookies
        if minimum_protocol_version is not None:
            self._values["minimum_protocol_version"] = minimum_protocol_version
        if price_class is not None:
            self._values["price_class"] = price_class
        if web_acl_id is not None:
            self._values["web_acl_id"] = web_acl_id

    @builtins.property
    def default_behavior(self) -> BehaviorOptions:
        '''The default behavior for the distribution.'''
        result = self._values.get("default_behavior")
        assert result is not None, "Required property 'default_behavior' is missing"
        return typing.cast(BehaviorOptions, result)

    @builtins.property
    def additional_behaviors(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, BehaviorOptions]]:
        '''Additional behaviors for the distribution, mapped by the pathPattern that specifies which requests to apply the behavior to.

        :default: - no additional behaviors are added.
        '''
        result = self._values.get("additional_behaviors")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, BehaviorOptions]], result)

    @builtins.property
    def certificate(
        self,
    ) -> typing.Optional[aws_cdk.aws_certificatemanager.ICertificate]:
        '''A certificate to associate with the distribution.

        The certificate must be located in N. Virginia (us-east-1).

        :default: - the CloudFront wildcard certificate (*.cloudfront.net) will be used.
        '''
        result = self._values.get("certificate")
        return typing.cast(typing.Optional[aws_cdk.aws_certificatemanager.ICertificate], result)

    @builtins.property
    def comment(self) -> typing.Optional[builtins.str]:
        '''Any comments you want to include about the distribution.

        :default: - no comment
        '''
        result = self._values.get("comment")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def default_root_object(self) -> typing.Optional[builtins.str]:
        '''The object that you want CloudFront to request from your origin (for example, index.html) when a viewer requests the root URL for your distribution. If no default object is set, the request goes to the origin's root (e.g., example.com/).

        :default: - no default root object
        '''
        result = self._values.get("default_root_object")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def domain_names(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Alternative domain names for this distribution.

        If you want to use your own domain name, such as www.example.com, instead of the cloudfront.net domain name,
        you can add an alternate domain name to your distribution. If you attach a certificate to the distribution,
        you must add (at least one of) the domain names of the certificate to this list.

        :default: - The distribution will only support the default generated name (e.g., d111111abcdef8.cloudfront.net)
        '''
        result = self._values.get("domain_names")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def enabled(self) -> typing.Optional[builtins.bool]:
        '''Enable or disable the distribution.

        :default: true
        '''
        result = self._values.get("enabled")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def enable_ipv6(self) -> typing.Optional[builtins.bool]:
        '''Whether CloudFront will respond to IPv6 DNS requests with an IPv6 address.

        If you specify false, CloudFront responds to IPv6 DNS requests with the DNS response code NOERROR and with no IP addresses.
        This allows viewers to submit a second request, for an IPv4 address for your distribution.

        :default: true
        '''
        result = self._values.get("enable_ipv6")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def enable_logging(self) -> typing.Optional[builtins.bool]:
        '''Enable access logging for the distribution.

        :default: - false, unless ``logBucket`` is specified.
        '''
        result = self._values.get("enable_logging")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def error_responses(self) -> typing.Optional[typing.List["ErrorResponse"]]:
        '''How CloudFront should handle requests that are not successful (e.g., PageNotFound).

        :default: - No custom error responses.
        '''
        result = self._values.get("error_responses")
        return typing.cast(typing.Optional[typing.List["ErrorResponse"]], result)

    @builtins.property
    def geo_restriction(self) -> typing.Optional["GeoRestriction"]:
        '''Controls the countries in which your content is distributed.

        :default: - No geographic restrictions
        '''
        result = self._values.get("geo_restriction")
        return typing.cast(typing.Optional["GeoRestriction"], result)

    @builtins.property
    def http_version(self) -> typing.Optional["HttpVersion"]:
        '''Specify the maximum HTTP version that you want viewers to use to communicate with CloudFront.

        For viewers and CloudFront to use HTTP/2, viewers must support TLS 1.2 or later, and must support server name identification (SNI).

        :default: HttpVersion.HTTP2
        '''
        result = self._values.get("http_version")
        return typing.cast(typing.Optional["HttpVersion"], result)

    @builtins.property
    def log_bucket(self) -> typing.Optional[aws_cdk.aws_s3.IBucket]:
        '''The Amazon S3 bucket to store the access logs in.

        :default: - A bucket is created if ``enableLogging`` is true
        '''
        result = self._values.get("log_bucket")
        return typing.cast(typing.Optional[aws_cdk.aws_s3.IBucket], result)

    @builtins.property
    def log_file_prefix(self) -> typing.Optional[builtins.str]:
        '''An optional string that you want CloudFront to prefix to the access log filenames for this distribution.

        :default: - no prefix
        '''
        result = self._values.get("log_file_prefix")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def log_includes_cookies(self) -> typing.Optional[builtins.bool]:
        '''Specifies whether you want CloudFront to include cookies in access logs.

        :default: false
        '''
        result = self._values.get("log_includes_cookies")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def minimum_protocol_version(self) -> typing.Optional["SecurityPolicyProtocol"]:
        '''The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections.

        CloudFront serves your objects only to browsers or devices that support at
        least the SSL version that you specify.

        :default: - SecurityPolicyProtocol.TLS_V1_2_2021 if the '

        :aws-cdk: /aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021' feature flag is set; otherwise, SecurityPolicyProtocol.TLS_V1_2_2019.
        '''
        result = self._values.get("minimum_protocol_version")
        return typing.cast(typing.Optional["SecurityPolicyProtocol"], result)

    @builtins.property
    def price_class(self) -> typing.Optional["PriceClass"]:
        '''The price class that corresponds with the maximum price that you want to pay for CloudFront service.

        If you specify PriceClass_All, CloudFront responds to requests for your objects from all CloudFront edge locations.
        If you specify a price class other than PriceClass_All, CloudFront serves your objects from the CloudFront edge location
        that has the lowest latency among the edge locations in your price class.

        :default: PriceClass.PRICE_CLASS_ALL
        '''
        result = self._values.get("price_class")
        return typing.cast(typing.Optional["PriceClass"], result)

    @builtins.property
    def web_acl_id(self) -> typing.Optional[builtins.str]:
        '''Unique identifier that specifies the AWS WAF web ACL to associate with this CloudFront distribution.

        To specify a web ACL created using the latest version of AWS WAF, use the ACL ARN, for example
        ``arn:aws:wafv2:us-east-1:123456789012:global/webacl/ExampleWebACL/473e64fd-f30b-4765-81a0-62ad96dd167a``.
        To specify a web ACL created using AWS WAF Classic, use the ACL ID, for example ``473e64fd-f30b-4765-81a0-62ad96dd167a``.

        :default: - No AWS Web Application Firewall web access control list (web ACL).

        :see: https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CreateDistribution.html#API_CreateDistribution_RequestParameters.
        '''
        result = self._values.get("web_acl_id")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "DistributionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.EdgeLambda",
    jsii_struct_bases=[],
    name_mapping={
        "event_type": "eventType",
        "function_version": "functionVersion",
        "include_body": "includeBody",
    },
)
class EdgeLambda:
    def __init__(
        self,
        *,
        event_type: "LambdaEdgeEventType",
        function_version: aws_cdk.aws_lambda.IVersion,
        include_body: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''Represents a Lambda function version and event type when using Lambda@Edge.

        The type of the {@link AddBehaviorOptions.edgeLambdas} property.

        :param event_type: The type of event in response to which should the function be invoked.
        :param function_version: The version of the Lambda function that will be invoked. **Note**: it's not possible to use the '$LATEST' function version for Lambda@Edge!
        :param include_body: Allows a Lambda function to have read access to the body content. Only valid for "request" event types (``ORIGIN_REQUEST`` or ``VIEWER_REQUEST``). See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-include-body-access.html Default: false
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "event_type": event_type,
            "function_version": function_version,
        }
        if include_body is not None:
            self._values["include_body"] = include_body

    @builtins.property
    def event_type(self) -> "LambdaEdgeEventType":
        '''The type of event in response to which should the function be invoked.'''
        result = self._values.get("event_type")
        assert result is not None, "Required property 'event_type' is missing"
        return typing.cast("LambdaEdgeEventType", result)

    @builtins.property
    def function_version(self) -> aws_cdk.aws_lambda.IVersion:
        '''The version of the Lambda function that will be invoked.

        **Note**: it's not possible to use the '$LATEST' function version for Lambda@Edge!
        '''
        result = self._values.get("function_version")
        assert result is not None, "Required property 'function_version' is missing"
        return typing.cast(aws_cdk.aws_lambda.IVersion, result)

    @builtins.property
    def include_body(self) -> typing.Optional[builtins.bool]:
        '''Allows a Lambda function to have read access to the body content.

        Only valid for "request" event types (``ORIGIN_REQUEST`` or ``VIEWER_REQUEST``).
        See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-include-body-access.html

        :default: false
        '''
        result = self._values.get("include_body")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "EdgeLambda(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.ErrorResponse",
    jsii_struct_bases=[],
    name_mapping={
        "http_status": "httpStatus",
        "response_http_status": "responseHttpStatus",
        "response_page_path": "responsePagePath",
        "ttl": "ttl",
    },
)
class ErrorResponse:
    def __init__(
        self,
        *,
        http_status: jsii.Number,
        response_http_status: typing.Optional[jsii.Number] = None,
        response_page_path: typing.Optional[builtins.str] = None,
        ttl: typing.Optional[aws_cdk.core.Duration] = None,
    ) -> None:
        '''Options for configuring custom error responses.

        :param http_status: The HTTP status code for which you want to specify a custom error page and/or a caching duration.
        :param response_http_status: The HTTP status code that you want CloudFront to return to the viewer along with the custom error page. If you specify a value for ``responseHttpStatus``, you must also specify a value for ``responsePagePath``. Default: - the error code will be returned as the response code.
        :param response_page_path: The path to the custom error page that you want CloudFront to return to a viewer when your origin returns the ``httpStatus``, for example, /4xx-errors/403-forbidden.html. Default: - the default CloudFront response is shown.
        :param ttl: The minimum amount of time, in seconds, that you want CloudFront to cache the HTTP status code specified in ErrorCode. Default: - the default caching TTL behavior applies
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "http_status": http_status,
        }
        if response_http_status is not None:
            self._values["response_http_status"] = response_http_status
        if response_page_path is not None:
            self._values["response_page_path"] = response_page_path
        if ttl is not None:
            self._values["ttl"] = ttl

    @builtins.property
    def http_status(self) -> jsii.Number:
        '''The HTTP status code for which you want to specify a custom error page and/or a caching duration.'''
        result = self._values.get("http_status")
        assert result is not None, "Required property 'http_status' is missing"
        return typing.cast(jsii.Number, result)

    @builtins.property
    def response_http_status(self) -> typing.Optional[jsii.Number]:
        '''The HTTP status code that you want CloudFront to return to the viewer along with the custom error page.

        If you specify a value for ``responseHttpStatus``, you must also specify a value for ``responsePagePath``.

        :default: - the error code will be returned as the response code.
        '''
        result = self._values.get("response_http_status")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def response_page_path(self) -> typing.Optional[builtins.str]:
        '''The path to the custom error page that you want CloudFront to return to a viewer when your origin returns the ``httpStatus``, for example, /4xx-errors/403-forbidden.html.

        :default: - the default CloudFront response is shown.
        '''
        result = self._values.get("response_page_path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def ttl(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The minimum amount of time, in seconds, that you want CloudFront to cache the HTTP status code specified in ErrorCode.

        :default: - the default caching TTL behavior applies
        '''
        result = self._values.get("ttl")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ErrorResponse(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.FailoverStatusCode")
class FailoverStatusCode(enum.Enum):
    '''HTTP status code to failover to second origin.'''

    FORBIDDEN = "FORBIDDEN"
    '''Forbidden (403).'''
    NOT_FOUND = "NOT_FOUND"
    '''Not found (404).'''
    INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR"
    '''Internal Server Error (500).'''
    BAD_GATEWAY = "BAD_GATEWAY"
    '''Bad Gateway (502).'''
    SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE"
    '''Service Unavailable (503).'''
    GATEWAY_TIMEOUT = "GATEWAY_TIMEOUT"
    '''Gateway Timeout (504).'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.FileCodeOptions",
    jsii_struct_bases=[],
    name_mapping={"file_path": "filePath"},
)
class FileCodeOptions:
    def __init__(self, *, file_path: builtins.str) -> None:
        '''Options when reading the function's code from an external file.

        :param file_path: The path of the file to read the code from.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "file_path": file_path,
        }

    @builtins.property
    def file_path(self) -> builtins.str:
        '''The path of the file to read the code from.'''
        result = self._values.get("file_path")
        assert result is not None, "Required property 'file_path' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FileCodeOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.FunctionAssociation",
    jsii_struct_bases=[],
    name_mapping={"event_type": "eventType", "function": "function"},
)
class FunctionAssociation:
    def __init__(
        self,
        *,
        event_type: "FunctionEventType",
        function: "IFunction",
    ) -> None:
        '''Represents a CloudFront function and event type when using CF Functions.

        The type of the {@link AddBehaviorOptions.functionAssociations} property.

        :param event_type: The type of event which should invoke the function.
        :param function: The CloudFront function that will be invoked.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "event_type": event_type,
            "function": function,
        }

    @builtins.property
    def event_type(self) -> "FunctionEventType":
        '''The type of event which should invoke the function.'''
        result = self._values.get("event_type")
        assert result is not None, "Required property 'event_type' is missing"
        return typing.cast("FunctionEventType", result)

    @builtins.property
    def function(self) -> "IFunction":
        '''The CloudFront function that will be invoked.'''
        result = self._values.get("function")
        assert result is not None, "Required property 'function' is missing"
        return typing.cast("IFunction", result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FunctionAssociation(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.FunctionAttributes",
    jsii_struct_bases=[],
    name_mapping={"function_arn": "functionArn", "function_name": "functionName"},
)
class FunctionAttributes:
    def __init__(
        self,
        *,
        function_arn: builtins.str,
        function_name: builtins.str,
    ) -> None:
        '''Attributes of an existing CloudFront Function to import it.

        :param function_arn: The ARN of the function.
        :param function_name: The name of the function.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "function_arn": function_arn,
            "function_name": function_name,
        }

    @builtins.property
    def function_arn(self) -> builtins.str:
        '''The ARN of the function.'''
        result = self._values.get("function_arn")
        assert result is not None, "Required property 'function_arn' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def function_name(self) -> builtins.str:
        '''The name of the function.'''
        result = self._values.get("function_name")
        assert result is not None, "Required property 'function_name' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FunctionAttributes(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class FunctionCode(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-cloudfront.FunctionCode",
):
    '''Represents the function's source code.'''

    def __init__(self) -> None:
        jsii.create(self.__class__, self, [])

    @jsii.member(jsii_name="fromFile") # type: ignore[misc]
    @builtins.classmethod
    def from_file(cls, *, file_path: builtins.str) -> "FunctionCode":
        '''Code from external file for function.

        :param file_path: The path of the file to read the code from.

        :return: code object with contents from file.
        '''
        options = FileCodeOptions(file_path=file_path)

        return typing.cast("FunctionCode", jsii.sinvoke(cls, "fromFile", [options]))

    @jsii.member(jsii_name="fromInline") # type: ignore[misc]
    @builtins.classmethod
    def from_inline(cls, code: builtins.str) -> "FunctionCode":
        '''Inline code for function.

        :param code: The actual function code.

        :return: code object with inline code.
        '''
        return typing.cast("FunctionCode", jsii.sinvoke(cls, "fromInline", [code]))

    @jsii.member(jsii_name="render") # type: ignore[misc]
    @abc.abstractmethod
    def render(self) -> builtins.str:
        '''renders the function code.'''
        ...


class _FunctionCodeProxy(FunctionCode):
    @jsii.member(jsii_name="render")
    def render(self) -> builtins.str:
        '''renders the function code.'''
        return typing.cast(builtins.str, jsii.invoke(self, "render", []))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, FunctionCode).__jsii_proxy_class__ = lambda : _FunctionCodeProxy


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.FunctionEventType")
class FunctionEventType(enum.Enum):
    '''The type of events that a CloudFront function can be invoked in response to.'''

    VIEWER_REQUEST = "VIEWER_REQUEST"
    '''The viewer-request specifies the incoming request.'''
    VIEWER_RESPONSE = "VIEWER_RESPONSE"
    '''The viewer-response specifies the outgoing response.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.FunctionProps",
    jsii_struct_bases=[],
    name_mapping={
        "code": "code",
        "comment": "comment",
        "function_name": "functionName",
    },
)
class FunctionProps:
    def __init__(
        self,
        *,
        code: FunctionCode,
        comment: typing.Optional[builtins.str] = None,
        function_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for creating a CloudFront Function.

        :param code: The source code of the function.
        :param comment: A comment to describe the function. Default: - same as ``functionName``
        :param function_name: A name to identify the function. Default: - generated from the ``id``
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "code": code,
        }
        if comment is not None:
            self._values["comment"] = comment
        if function_name is not None:
            self._values["function_name"] = function_name

    @builtins.property
    def code(self) -> FunctionCode:
        '''The source code of the function.'''
        result = self._values.get("code")
        assert result is not None, "Required property 'code' is missing"
        return typing.cast(FunctionCode, result)

    @builtins.property
    def comment(self) -> typing.Optional[builtins.str]:
        '''A comment to describe the function.

        :default: - same as ``functionName``
        '''
        result = self._values.get("comment")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def function_name(self) -> typing.Optional[builtins.str]:
        '''A name to identify the function.

        :default: - generated from the ``id``
        '''
        result = self._values.get("function_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "FunctionProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class GeoRestriction(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.GeoRestriction",
):
    '''Controls the countries in which content is distributed.'''

    @jsii.member(jsii_name="allowlist") # type: ignore[misc]
    @builtins.classmethod
    def allowlist(cls, *locations: builtins.str) -> "GeoRestriction":
        '''Allow specific countries which you want CloudFront to distribute your content.

        :param locations: Two-letter, uppercase country code for a country that you want to allow. Include one element for each country. See ISO 3166-1-alpha-2 code on the *International Organization for Standardization* website
        '''
        return typing.cast("GeoRestriction", jsii.sinvoke(cls, "allowlist", [*locations]))

    @jsii.member(jsii_name="blacklist") # type: ignore[misc]
    @builtins.classmethod
    def blacklist(cls, *locations: builtins.str) -> "GeoRestriction":
        '''(deprecated) DEPRECATED.

        :param locations: -

        :deprecated: use ``denylist``

        :stability: deprecated
        '''
        return typing.cast("GeoRestriction", jsii.sinvoke(cls, "blacklist", [*locations]))

    @jsii.member(jsii_name="denylist") # type: ignore[misc]
    @builtins.classmethod
    def denylist(cls, *locations: builtins.str) -> "GeoRestriction":
        '''Deny specific countries which you don't want CloudFront to distribute your content.

        :param locations: Two-letter, uppercase country code for a country that you want to deny. Include one element for each country. See ISO 3166-1-alpha-2 code on the *International Organization for Standardization* website
        '''
        return typing.cast("GeoRestriction", jsii.sinvoke(cls, "denylist", [*locations]))

    @jsii.member(jsii_name="whitelist") # type: ignore[misc]
    @builtins.classmethod
    def whitelist(cls, *locations: builtins.str) -> "GeoRestriction":
        '''(deprecated) DEPRECATED.

        :param locations: -

        :deprecated: use ``allowlist``

        :stability: deprecated
        '''
        return typing.cast("GeoRestriction", jsii.sinvoke(cls, "whitelist", [*locations]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="locations")
    def locations(self) -> typing.List[builtins.str]:
        '''Two-letter, uppercase country code for a country that you want to allow/deny.

        Include one element for each country.
        See ISO 3166-1-alpha-2 code on the *International Organization for Standardization* website
        '''
        return typing.cast(typing.List[builtins.str], jsii.get(self, "locations"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="restrictionType")
    def restriction_type(self) -> builtins.str:
        '''Specifies the restriction type to impose.'''
        return typing.cast(builtins.str, jsii.get(self, "restrictionType"))


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.HttpVersion")
class HttpVersion(enum.Enum):
    '''Maximum HTTP version to support.'''

    HTTP1_1 = "HTTP1_1"
    '''HTTP 1.1.'''
    HTTP2 = "HTTP2"
    '''HTTP 2.'''


@jsii.interface(jsii_type="@aws-cdk/aws-cloudfront.ICachePolicy")
class ICachePolicy(typing_extensions.Protocol):
    '''Represents a Cache Policy.'''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cachePolicyId")
    def cache_policy_id(self) -> builtins.str:
        '''The ID of the cache policy.

        :attribute: true
        '''
        ...


class _ICachePolicyProxy:
    '''Represents a Cache Policy.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-cloudfront.ICachePolicy"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cachePolicyId")
    def cache_policy_id(self) -> builtins.str:
        '''The ID of the cache policy.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "cachePolicyId"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, ICachePolicy).__jsii_proxy_class__ = lambda : _ICachePolicyProxy


@jsii.interface(jsii_type="@aws-cdk/aws-cloudfront.IDistribution")
class IDistribution(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Interface for CloudFront distributions.'''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="distributionDomainName")
    def distribution_domain_name(self) -> builtins.str:
        '''The domain name of the Distribution, such as d111111abcdef8.cloudfront.net.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="distributionId")
    def distribution_id(self) -> builtins.str:
        '''The distribution ID for this distribution.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="domainName")
    def domain_name(self) -> builtins.str:
        '''(deprecated) The domain name of the Distribution, such as d111111abcdef8.cloudfront.net.

        :deprecated: - Use ``distributionDomainName`` instead.

        :stability: deprecated
        :attribute: true
        '''
        ...


class _IDistributionProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''Interface for CloudFront distributions.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-cloudfront.IDistribution"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="distributionDomainName")
    def distribution_domain_name(self) -> builtins.str:
        '''The domain name of the Distribution, such as d111111abcdef8.cloudfront.net.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "distributionDomainName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="distributionId")
    def distribution_id(self) -> builtins.str:
        '''The distribution ID for this distribution.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "distributionId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="domainName")
    def domain_name(self) -> builtins.str:
        '''(deprecated) The domain name of the Distribution, such as d111111abcdef8.cloudfront.net.

        :deprecated: - Use ``distributionDomainName`` instead.

        :stability: deprecated
        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "domainName"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IDistribution).__jsii_proxy_class__ = lambda : _IDistributionProxy


@jsii.interface(jsii_type="@aws-cdk/aws-cloudfront.IFunction")
class IFunction(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Represents a CloudFront Function.'''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionArn")
    def function_arn(self) -> builtins.str:
        '''The ARN of the function.

        :attribute: true
        '''
        ...

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionName")
    def function_name(self) -> builtins.str:
        '''The name of the function.

        :attribute: true
        '''
        ...


class _IFunctionProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''Represents a CloudFront Function.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-cloudfront.IFunction"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionArn")
    def function_arn(self) -> builtins.str:
        '''The ARN of the function.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "functionArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionName")
    def function_name(self) -> builtins.str:
        '''The name of the function.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "functionName"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IFunction).__jsii_proxy_class__ = lambda : _IFunctionProxy


@jsii.interface(jsii_type="@aws-cdk/aws-cloudfront.IKeyGroup")
class IKeyGroup(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Represents a Key Group.'''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="keyGroupId")
    def key_group_id(self) -> builtins.str:
        '''The ID of the key group.

        :attribute: true
        '''
        ...


class _IKeyGroupProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''Represents a Key Group.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-cloudfront.IKeyGroup"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="keyGroupId")
    def key_group_id(self) -> builtins.str:
        '''The ID of the key group.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "keyGroupId"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IKeyGroup).__jsii_proxy_class__ = lambda : _IKeyGroupProxy


@jsii.interface(jsii_type="@aws-cdk/aws-cloudfront.IOrigin")
class IOrigin(typing_extensions.Protocol):
    '''Represents the concept of a CloudFront Origin.

    You provide one or more origins when creating a Distribution.
    '''

    @jsii.member(jsii_name="bind")
    def bind(
        self,
        scope: aws_cdk.core.Construct,
        *,
        origin_id: builtins.str,
    ) -> "OriginBindConfig":
        '''The method called when a given Origin is added (for the first time) to a Distribution.

        :param scope: -
        :param origin_id: The identifier of this Origin, as assigned by the Distribution this Origin has been used added to.
        '''
        ...


class _IOriginProxy:
    '''Represents the concept of a CloudFront Origin.

    You provide one or more origins when creating a Distribution.
    '''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-cloudfront.IOrigin"

    @jsii.member(jsii_name="bind")
    def bind(
        self,
        scope: aws_cdk.core.Construct,
        *,
        origin_id: builtins.str,
    ) -> "OriginBindConfig":
        '''The method called when a given Origin is added (for the first time) to a Distribution.

        :param scope: -
        :param origin_id: The identifier of this Origin, as assigned by the Distribution this Origin has been used added to.
        '''
        options = OriginBindOptions(origin_id=origin_id)

        return typing.cast("OriginBindConfig", jsii.invoke(self, "bind", [scope, options]))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IOrigin).__jsii_proxy_class__ = lambda : _IOriginProxy


@jsii.interface(jsii_type="@aws-cdk/aws-cloudfront.IOriginAccessIdentity")
class IOriginAccessIdentity(
    aws_cdk.core.IResource,
    aws_cdk.aws_iam.IGrantable,
    typing_extensions.Protocol,
):
    '''Interface for CloudFront OriginAccessIdentity.'''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="originAccessIdentityName")
    def origin_access_identity_name(self) -> builtins.str:
        '''The Origin Access Identity Name.'''
        ...


class _IOriginAccessIdentityProxy(
    jsii.proxy_for(aws_cdk.core.IResource), # type: ignore[misc]
    jsii.proxy_for(aws_cdk.aws_iam.IGrantable), # type: ignore[misc]
):
    '''Interface for CloudFront OriginAccessIdentity.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-cloudfront.IOriginAccessIdentity"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="originAccessIdentityName")
    def origin_access_identity_name(self) -> builtins.str:
        '''The Origin Access Identity Name.'''
        return typing.cast(builtins.str, jsii.get(self, "originAccessIdentityName"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IOriginAccessIdentity).__jsii_proxy_class__ = lambda : _IOriginAccessIdentityProxy


@jsii.interface(jsii_type="@aws-cdk/aws-cloudfront.IOriginRequestPolicy")
class IOriginRequestPolicy(typing_extensions.Protocol):
    '''Represents a Origin Request Policy.'''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="originRequestPolicyId")
    def origin_request_policy_id(self) -> builtins.str:
        '''The ID of the origin request policy.

        :attribute: true
        '''
        ...


class _IOriginRequestPolicyProxy:
    '''Represents a Origin Request Policy.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-cloudfront.IOriginRequestPolicy"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="originRequestPolicyId")
    def origin_request_policy_id(self) -> builtins.str:
        '''The ID of the origin request policy.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "originRequestPolicyId"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IOriginRequestPolicy).__jsii_proxy_class__ = lambda : _IOriginRequestPolicyProxy


@jsii.interface(jsii_type="@aws-cdk/aws-cloudfront.IPublicKey")
class IPublicKey(aws_cdk.core.IResource, typing_extensions.Protocol):
    '''Represents a Public Key.'''

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="publicKeyId")
    def public_key_id(self) -> builtins.str:
        '''The ID of the key group.

        :attribute: true
        '''
        ...


class _IPublicKeyProxy(
    jsii.proxy_for(aws_cdk.core.IResource) # type: ignore[misc]
):
    '''Represents a Public Key.'''

    __jsii_type__: typing.ClassVar[str] = "@aws-cdk/aws-cloudfront.IPublicKey"

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="publicKeyId")
    def public_key_id(self) -> builtins.str:
        '''The ID of the key group.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "publicKeyId"))

# Adding a "__jsii_proxy_class__(): typing.Type" function to the interface
typing.cast(typing.Any, IPublicKey).__jsii_proxy_class__ = lambda : _IPublicKeyProxy


@jsii.implements(IKeyGroup)
class KeyGroup(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.KeyGroup",
):
    '''A Key Group configuration.

    :resource: AWS::CloudFront::KeyGroup
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        items: typing.Sequence[IPublicKey],
        comment: typing.Optional[builtins.str] = None,
        key_group_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param items: A list of public keys to add to the key group.
        :param comment: A comment to describe the key group. Default: - no comment
        :param key_group_name: A name to identify the key group. Default: - generated from the ``id``
        '''
        props = KeyGroupProps(
            items=items, comment=comment, key_group_name=key_group_name
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromKeyGroupId") # type: ignore[misc]
    @builtins.classmethod
    def from_key_group_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        key_group_id: builtins.str,
    ) -> IKeyGroup:
        '''Imports a Key Group from its id.

        :param scope: -
        :param id: -
        :param key_group_id: -
        '''
        return typing.cast(IKeyGroup, jsii.sinvoke(cls, "fromKeyGroupId", [scope, id, key_group_id]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="keyGroupId")
    def key_group_id(self) -> builtins.str:
        '''The ID of the key group.'''
        return typing.cast(builtins.str, jsii.get(self, "keyGroupId"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.KeyGroupProps",
    jsii_struct_bases=[],
    name_mapping={
        "items": "items",
        "comment": "comment",
        "key_group_name": "keyGroupName",
    },
)
class KeyGroupProps:
    def __init__(
        self,
        *,
        items: typing.Sequence[IPublicKey],
        comment: typing.Optional[builtins.str] = None,
        key_group_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for creating a Public Key.

        :param items: A list of public keys to add to the key group.
        :param comment: A comment to describe the key group. Default: - no comment
        :param key_group_name: A name to identify the key group. Default: - generated from the ``id``
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "items": items,
        }
        if comment is not None:
            self._values["comment"] = comment
        if key_group_name is not None:
            self._values["key_group_name"] = key_group_name

    @builtins.property
    def items(self) -> typing.List[IPublicKey]:
        '''A list of public keys to add to the key group.'''
        result = self._values.get("items")
        assert result is not None, "Required property 'items' is missing"
        return typing.cast(typing.List[IPublicKey], result)

    @builtins.property
    def comment(self) -> typing.Optional[builtins.str]:
        '''A comment to describe the key group.

        :default: - no comment
        '''
        result = self._values.get("comment")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def key_group_name(self) -> typing.Optional[builtins.str]:
        '''A name to identify the key group.

        :default: - generated from the ``id``
        '''
        result = self._values.get("key_group_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "KeyGroupProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.LambdaEdgeEventType")
class LambdaEdgeEventType(enum.Enum):
    '''The type of events that a Lambda@Edge function can be invoked in response to.'''

    ORIGIN_REQUEST = "ORIGIN_REQUEST"
    '''The origin-request specifies the request to the origin location (e.g. S3).'''
    ORIGIN_RESPONSE = "ORIGIN_RESPONSE"
    '''The origin-response specifies the response from the origin location (e.g. S3).'''
    VIEWER_REQUEST = "VIEWER_REQUEST"
    '''The viewer-request specifies the incoming request.'''
    VIEWER_RESPONSE = "VIEWER_RESPONSE"
    '''The viewer-response specifies the outgoing response.'''


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.LambdaFunctionAssociation",
    jsii_struct_bases=[],
    name_mapping={
        "event_type": "eventType",
        "lambda_function": "lambdaFunction",
        "include_body": "includeBody",
    },
)
class LambdaFunctionAssociation:
    def __init__(
        self,
        *,
        event_type: LambdaEdgeEventType,
        lambda_function: aws_cdk.aws_lambda.IVersion,
        include_body: typing.Optional[builtins.bool] = None,
    ) -> None:
        '''
        :param event_type: The lambda event type defines at which event the lambda is called during the request lifecycle.
        :param lambda_function: A version of the lambda to associate.
        :param include_body: Allows a Lambda function to have read access to the body content. Only valid for "request" event types (``ORIGIN_REQUEST`` or ``VIEWER_REQUEST``). See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-include-body-access.html Default: false
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "event_type": event_type,
            "lambda_function": lambda_function,
        }
        if include_body is not None:
            self._values["include_body"] = include_body

    @builtins.property
    def event_type(self) -> LambdaEdgeEventType:
        '''The lambda event type defines at which event the lambda is called during the request lifecycle.'''
        result = self._values.get("event_type")
        assert result is not None, "Required property 'event_type' is missing"
        return typing.cast(LambdaEdgeEventType, result)

    @builtins.property
    def lambda_function(self) -> aws_cdk.aws_lambda.IVersion:
        '''A version of the lambda to associate.'''
        result = self._values.get("lambda_function")
        assert result is not None, "Required property 'lambda_function' is missing"
        return typing.cast(aws_cdk.aws_lambda.IVersion, result)

    @builtins.property
    def include_body(self) -> typing.Optional[builtins.bool]:
        '''Allows a Lambda function to have read access to the body content.

        Only valid for "request" event types (``ORIGIN_REQUEST`` or ``VIEWER_REQUEST``).
        See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-include-body-access.html

        :default: false
        '''
        result = self._values.get("include_body")
        return typing.cast(typing.Optional[builtins.bool], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LambdaFunctionAssociation(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.LoggingConfiguration",
    jsii_struct_bases=[],
    name_mapping={
        "bucket": "bucket",
        "include_cookies": "includeCookies",
        "prefix": "prefix",
    },
)
class LoggingConfiguration:
    def __init__(
        self,
        *,
        bucket: typing.Optional[aws_cdk.aws_s3.IBucket] = None,
        include_cookies: typing.Optional[builtins.bool] = None,
        prefix: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Logging configuration for incoming requests.

        :param bucket: Bucket to log requests to. Default: - A logging bucket is automatically created.
        :param include_cookies: Whether to include the cookies in the logs. Default: false
        :param prefix: Where in the bucket to store logs. Default: - No prefix.
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if bucket is not None:
            self._values["bucket"] = bucket
        if include_cookies is not None:
            self._values["include_cookies"] = include_cookies
        if prefix is not None:
            self._values["prefix"] = prefix

    @builtins.property
    def bucket(self) -> typing.Optional[aws_cdk.aws_s3.IBucket]:
        '''Bucket to log requests to.

        :default: - A logging bucket is automatically created.
        '''
        result = self._values.get("bucket")
        return typing.cast(typing.Optional[aws_cdk.aws_s3.IBucket], result)

    @builtins.property
    def include_cookies(self) -> typing.Optional[builtins.bool]:
        '''Whether to include the cookies in the logs.

        :default: false
        '''
        result = self._values.get("include_cookies")
        return typing.cast(typing.Optional[builtins.bool], result)

    @builtins.property
    def prefix(self) -> typing.Optional[builtins.str]:
        '''Where in the bucket to store logs.

        :default: - No prefix.
        '''
        result = self._values.get("prefix")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "LoggingConfiguration(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IOriginAccessIdentity)
class OriginAccessIdentity(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.OriginAccessIdentity",
):
    '''An origin access identity is a special CloudFront user that you can associate with Amazon S3 origins, so that you can secure all or just some of your Amazon S3 content.

    :resource: AWS::CloudFront::CloudFrontOriginAccessIdentity
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        comment: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param comment: Any comments you want to include about the origin access identity. Default: "Allows CloudFront to reach the bucket"
        '''
        props = OriginAccessIdentityProps(comment=comment)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromOriginAccessIdentityName") # type: ignore[misc]
    @builtins.classmethod
    def from_origin_access_identity_name(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        origin_access_identity_name: builtins.str,
    ) -> IOriginAccessIdentity:
        '''Creates a OriginAccessIdentity by providing the OriginAccessIdentityName.

        :param scope: -
        :param id: -
        :param origin_access_identity_name: -
        '''
        return typing.cast(IOriginAccessIdentity, jsii.sinvoke(cls, "fromOriginAccessIdentityName", [scope, id, origin_access_identity_name]))

    @jsii.member(jsii_name="arn")
    def _arn(self) -> builtins.str:
        '''The ARN to include in S3 bucket policy to allow CloudFront access.'''
        return typing.cast(builtins.str, jsii.invoke(self, "arn", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cloudFrontOriginAccessIdentityS3CanonicalUserId")
    def cloud_front_origin_access_identity_s3_canonical_user_id(self) -> builtins.str:
        '''The Amazon S3 canonical user ID for the origin access identity, used when giving the origin access identity read permission to an object in Amazon S3.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "cloudFrontOriginAccessIdentityS3CanonicalUserId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="grantPrincipal")
    def grant_principal(self) -> aws_cdk.aws_iam.IPrincipal:
        '''Derived principal value for bucket access.'''
        return typing.cast(aws_cdk.aws_iam.IPrincipal, jsii.get(self, "grantPrincipal"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="originAccessIdentityName")
    def origin_access_identity_name(self) -> builtins.str:
        '''The Origin Access Identity Name (physical id).

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "originAccessIdentityName"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.OriginAccessIdentityProps",
    jsii_struct_bases=[],
    name_mapping={"comment": "comment"},
)
class OriginAccessIdentityProps:
    def __init__(self, *, comment: typing.Optional[builtins.str] = None) -> None:
        '''Properties of CloudFront OriginAccessIdentity.

        :param comment: Any comments you want to include about the origin access identity. Default: "Allows CloudFront to reach the bucket"
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if comment is not None:
            self._values["comment"] = comment

    @builtins.property
    def comment(self) -> typing.Optional[builtins.str]:
        '''Any comments you want to include about the origin access identity.

        :default: "Allows CloudFront to reach the bucket"
        '''
        result = self._values.get("comment")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OriginAccessIdentityProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.implements(IOrigin)
class OriginBase(
    metaclass=jsii.JSIIAbstractClass,
    jsii_type="@aws-cdk/aws-cloudfront.OriginBase",
):
    '''Represents a distribution origin, that describes the Amazon S3 bucket, HTTP server (for example, a web server), Amazon MediaStore, or other server from which CloudFront gets your files.'''

    def __init__(
        self,
        domain_name: builtins.str,
        *,
        connection_attempts: typing.Optional[jsii.Number] = None,
        connection_timeout: typing.Optional[aws_cdk.core.Duration] = None,
        custom_headers: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        origin_path: typing.Optional[builtins.str] = None,
        origin_shield_region: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param domain_name: -
        :param connection_attempts: The number of times that CloudFront attempts to connect to the origin; valid values are 1, 2, or 3 attempts. Default: 3
        :param connection_timeout: The number of seconds that CloudFront waits when trying to establish a connection to the origin. Valid values are 1-10 seconds, inclusive. Default: Duration.seconds(10)
        :param custom_headers: A list of HTTP header names and values that CloudFront adds to requests it sends to the origin. Default: {}
        :param origin_path: An optional path that CloudFront appends to the origin domain name when CloudFront requests content from the origin. Must begin, but not end, with '/' (e.g., '/production/images'). Default: '/'
        :param origin_shield_region: When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance. Default: - origin shield not enabled
        '''
        props = OriginProps(
            connection_attempts=connection_attempts,
            connection_timeout=connection_timeout,
            custom_headers=custom_headers,
            origin_path=origin_path,
            origin_shield_region=origin_shield_region,
        )

        jsii.create(self.__class__, self, [domain_name, props])

    @jsii.member(jsii_name="bind")
    def bind(
        self,
        _scope: aws_cdk.core.Construct,
        *,
        origin_id: builtins.str,
    ) -> "OriginBindConfig":
        '''Binds the origin to the associated Distribution.

        Can be used to grant permissions, create dependent resources, etc.

        :param _scope: -
        :param origin_id: The identifier of this Origin, as assigned by the Distribution this Origin has been used added to.
        '''
        options = OriginBindOptions(origin_id=origin_id)

        return typing.cast("OriginBindConfig", jsii.invoke(self, "bind", [_scope, options]))

    @jsii.member(jsii_name="renderCustomOriginConfig")
    def _render_custom_origin_config(
        self,
    ) -> typing.Optional[CfnDistribution.CustomOriginConfigProperty]:
        return typing.cast(typing.Optional[CfnDistribution.CustomOriginConfigProperty], jsii.invoke(self, "renderCustomOriginConfig", []))

    @jsii.member(jsii_name="renderS3OriginConfig")
    def _render_s3_origin_config(
        self,
    ) -> typing.Optional[CfnDistribution.S3OriginConfigProperty]:
        return typing.cast(typing.Optional[CfnDistribution.S3OriginConfigProperty], jsii.invoke(self, "renderS3OriginConfig", []))


class _OriginBaseProxy(OriginBase):
    pass

# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class
typing.cast(typing.Any, OriginBase).__jsii_proxy_class__ = lambda : _OriginBaseProxy


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.OriginBindConfig",
    jsii_struct_bases=[],
    name_mapping={
        "failover_config": "failoverConfig",
        "origin_property": "originProperty",
    },
)
class OriginBindConfig:
    def __init__(
        self,
        *,
        failover_config: typing.Optional["OriginFailoverConfig"] = None,
        origin_property: typing.Optional[CfnDistribution.OriginProperty] = None,
    ) -> None:
        '''The struct returned from {@link IOrigin.bind}.

        :param failover_config: The failover configuration for this Origin. Default: - nothing is returned
        :param origin_property: The CloudFormation OriginProperty configuration for this Origin. Default: - nothing is returned
        '''
        if isinstance(failover_config, dict):
            failover_config = OriginFailoverConfig(**failover_config)
        if isinstance(origin_property, dict):
            origin_property = CfnDistribution.OriginProperty(**origin_property)
        self._values: typing.Dict[str, typing.Any] = {}
        if failover_config is not None:
            self._values["failover_config"] = failover_config
        if origin_property is not None:
            self._values["origin_property"] = origin_property

    @builtins.property
    def failover_config(self) -> typing.Optional["OriginFailoverConfig"]:
        '''The failover configuration for this Origin.

        :default: - nothing is returned
        '''
        result = self._values.get("failover_config")
        return typing.cast(typing.Optional["OriginFailoverConfig"], result)

    @builtins.property
    def origin_property(self) -> typing.Optional[CfnDistribution.OriginProperty]:
        '''The CloudFormation OriginProperty configuration for this Origin.

        :default: - nothing is returned
        '''
        result = self._values.get("origin_property")
        return typing.cast(typing.Optional[CfnDistribution.OriginProperty], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OriginBindConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.OriginBindOptions",
    jsii_struct_bases=[],
    name_mapping={"origin_id": "originId"},
)
class OriginBindOptions:
    def __init__(self, *, origin_id: builtins.str) -> None:
        '''Options passed to Origin.bind().

        :param origin_id: The identifier of this Origin, as assigned by the Distribution this Origin has been used added to.
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "origin_id": origin_id,
        }

    @builtins.property
    def origin_id(self) -> builtins.str:
        '''The identifier of this Origin, as assigned by the Distribution this Origin has been used added to.'''
        result = self._values.get("origin_id")
        assert result is not None, "Required property 'origin_id' is missing"
        return typing.cast(builtins.str, result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OriginBindOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.OriginFailoverConfig",
    jsii_struct_bases=[],
    name_mapping={"failover_origin": "failoverOrigin", "status_codes": "statusCodes"},
)
class OriginFailoverConfig:
    def __init__(
        self,
        *,
        failover_origin: IOrigin,
        status_codes: typing.Optional[typing.Sequence[jsii.Number]] = None,
    ) -> None:
        '''The failover configuration used for Origin Groups, returned in {@link OriginBindConfig.failoverConfig}.

        :param failover_origin: The origin to use as the fallback origin.
        :param status_codes: The HTTP status codes of the response that trigger querying the failover Origin. Default: - 500, 502, 503 and 504
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "failover_origin": failover_origin,
        }
        if status_codes is not None:
            self._values["status_codes"] = status_codes

    @builtins.property
    def failover_origin(self) -> IOrigin:
        '''The origin to use as the fallback origin.'''
        result = self._values.get("failover_origin")
        assert result is not None, "Required property 'failover_origin' is missing"
        return typing.cast(IOrigin, result)

    @builtins.property
    def status_codes(self) -> typing.Optional[typing.List[jsii.Number]]:
        '''The HTTP status codes of the response that trigger querying the failover Origin.

        :default: - 500, 502, 503 and 504
        '''
        result = self._values.get("status_codes")
        return typing.cast(typing.Optional[typing.List[jsii.Number]], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OriginFailoverConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.OriginProps",
    jsii_struct_bases=[],
    name_mapping={
        "connection_attempts": "connectionAttempts",
        "connection_timeout": "connectionTimeout",
        "custom_headers": "customHeaders",
        "origin_path": "originPath",
        "origin_shield_region": "originShieldRegion",
    },
)
class OriginProps:
    def __init__(
        self,
        *,
        connection_attempts: typing.Optional[jsii.Number] = None,
        connection_timeout: typing.Optional[aws_cdk.core.Duration] = None,
        custom_headers: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        origin_path: typing.Optional[builtins.str] = None,
        origin_shield_region: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties to define an Origin.

        :param connection_attempts: The number of times that CloudFront attempts to connect to the origin; valid values are 1, 2, or 3 attempts. Default: 3
        :param connection_timeout: The number of seconds that CloudFront waits when trying to establish a connection to the origin. Valid values are 1-10 seconds, inclusive. Default: Duration.seconds(10)
        :param custom_headers: A list of HTTP header names and values that CloudFront adds to requests it sends to the origin. Default: {}
        :param origin_path: An optional path that CloudFront appends to the origin domain name when CloudFront requests content from the origin. Must begin, but not end, with '/' (e.g., '/production/images'). Default: '/'
        :param origin_shield_region: When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance. Default: - origin shield not enabled
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if connection_attempts is not None:
            self._values["connection_attempts"] = connection_attempts
        if connection_timeout is not None:
            self._values["connection_timeout"] = connection_timeout
        if custom_headers is not None:
            self._values["custom_headers"] = custom_headers
        if origin_path is not None:
            self._values["origin_path"] = origin_path
        if origin_shield_region is not None:
            self._values["origin_shield_region"] = origin_shield_region

    @builtins.property
    def connection_attempts(self) -> typing.Optional[jsii.Number]:
        '''The number of times that CloudFront attempts to connect to the origin;

        valid values are 1, 2, or 3 attempts.

        :default: 3
        '''
        result = self._values.get("connection_attempts")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def connection_timeout(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The number of seconds that CloudFront waits when trying to establish a connection to the origin.

        Valid values are 1-10 seconds, inclusive.

        :default: Duration.seconds(10)
        '''
        result = self._values.get("connection_timeout")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def custom_headers(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''A list of HTTP header names and values that CloudFront adds to requests it sends to the origin.

        :default: {}
        '''
        result = self._values.get("custom_headers")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def origin_path(self) -> typing.Optional[builtins.str]:
        '''An optional path that CloudFront appends to the origin domain name when CloudFront requests content from the origin.

        Must begin, but not end, with '/' (e.g., '/production/images').

        :default: '/'
        '''
        result = self._values.get("origin_path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def origin_shield_region(self) -> typing.Optional[builtins.str]:
        '''When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance.

        :default: - origin shield not enabled

        :see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/origin-shield.html
        '''
        result = self._values.get("origin_shield_region")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OriginProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.OriginProtocolPolicy")
class OriginProtocolPolicy(enum.Enum):
    '''Defines what protocols CloudFront will use to connect to an origin.'''

    HTTP_ONLY = "HTTP_ONLY"
    '''Connect on HTTP only.'''
    MATCH_VIEWER = "MATCH_VIEWER"
    '''Connect with the same protocol as the viewer.'''
    HTTPS_ONLY = "HTTPS_ONLY"
    '''Connect on HTTPS only.'''


class OriginRequestCookieBehavior(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.OriginRequestCookieBehavior",
):
    '''Determines whether any cookies in viewer requests (and if so, which cookies) are included in requests that CloudFront sends to the origin.'''

    @jsii.member(jsii_name="all") # type: ignore[misc]
    @builtins.classmethod
    def all(cls) -> "OriginRequestCookieBehavior":
        '''All cookies in viewer requests are included in requests that CloudFront sends to the origin.'''
        return typing.cast("OriginRequestCookieBehavior", jsii.sinvoke(cls, "all", []))

    @jsii.member(jsii_name="allowList") # type: ignore[misc]
    @builtins.classmethod
    def allow_list(cls, *cookies: builtins.str) -> "OriginRequestCookieBehavior":
        '''Only the provided ``cookies`` are included in requests that CloudFront sends to the origin.

        :param cookies: -
        '''
        return typing.cast("OriginRequestCookieBehavior", jsii.sinvoke(cls, "allowList", [*cookies]))

    @jsii.member(jsii_name="none") # type: ignore[misc]
    @builtins.classmethod
    def none(cls) -> "OriginRequestCookieBehavior":
        '''Cookies in viewer requests are not included in requests that CloudFront sends to the origin.

        Any cookies that are listed in a CachePolicy are still included in origin requests.
        '''
        return typing.cast("OriginRequestCookieBehavior", jsii.sinvoke(cls, "none", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="behavior")
    def behavior(self) -> builtins.str:
        '''The behavior of cookies: allow all, none or an allow list.'''
        return typing.cast(builtins.str, jsii.get(self, "behavior"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cookies")
    def cookies(self) -> typing.Optional[typing.List[builtins.str]]:
        '''The cookies to allow, if the behavior is an allow list.'''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "cookies"))


class OriginRequestHeaderBehavior(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.OriginRequestHeaderBehavior",
):
    '''Determines whether any HTTP headers (and if so, which headers) are included in requests that CloudFront sends to the origin.'''

    @jsii.member(jsii_name="all") # type: ignore[misc]
    @builtins.classmethod
    def all(cls, *cloudfront_headers: builtins.str) -> "OriginRequestHeaderBehavior":
        '''All HTTP headers in viewer requests are included in requests that CloudFront sends to the origin.

        Additionally, any additional CloudFront headers provided are included; the additional headers are added by CloudFront.

        :param cloudfront_headers: -

        :see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-cloudfront-headers.html
        '''
        return typing.cast("OriginRequestHeaderBehavior", jsii.sinvoke(cls, "all", [*cloudfront_headers]))

    @jsii.member(jsii_name="allowList") # type: ignore[misc]
    @builtins.classmethod
    def allow_list(cls, *headers: builtins.str) -> "OriginRequestHeaderBehavior":
        '''Listed headers are included in requests that CloudFront sends to the origin.

        :param headers: -
        '''
        return typing.cast("OriginRequestHeaderBehavior", jsii.sinvoke(cls, "allowList", [*headers]))

    @jsii.member(jsii_name="none") # type: ignore[misc]
    @builtins.classmethod
    def none(cls) -> "OriginRequestHeaderBehavior":
        '''HTTP headers are not included in requests that CloudFront sends to the origin.

        Any headers that are listed in a CachePolicy are still included in origin requests.
        '''
        return typing.cast("OriginRequestHeaderBehavior", jsii.sinvoke(cls, "none", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="behavior")
    def behavior(self) -> builtins.str:
        '''The behavior of headers: allow all, none or an allow list.'''
        return typing.cast(builtins.str, jsii.get(self, "behavior"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="headers")
    def headers(self) -> typing.Optional[typing.List[builtins.str]]:
        '''The headers for the allow list or the included CloudFront headers, if applicable.'''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "headers"))


@jsii.implements(IOriginRequestPolicy)
class OriginRequestPolicy(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.OriginRequestPolicy",
):
    '''A Origin Request Policy configuration.

    :resource: AWS::CloudFront::OriginRequestPolicy
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        comment: typing.Optional[builtins.str] = None,
        cookie_behavior: typing.Optional[OriginRequestCookieBehavior] = None,
        header_behavior: typing.Optional[OriginRequestHeaderBehavior] = None,
        origin_request_policy_name: typing.Optional[builtins.str] = None,
        query_string_behavior: typing.Optional["OriginRequestQueryStringBehavior"] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param comment: A comment to describe the origin request policy. Default: - no comment
        :param cookie_behavior: The cookies from viewer requests to include in origin requests. Default: OriginRequestCookieBehavior.none()
        :param header_behavior: The HTTP headers to include in origin requests. These can include headers from viewer requests and additional headers added by CloudFront. Default: OriginRequestHeaderBehavior.none()
        :param origin_request_policy_name: A unique name to identify the origin request policy. The name must only include '-', '_', or alphanumeric characters. Default: - generated from the ``id``
        :param query_string_behavior: The URL query strings from viewer requests to include in origin requests. Default: OriginRequestQueryStringBehavior.none()
        '''
        props = OriginRequestPolicyProps(
            comment=comment,
            cookie_behavior=cookie_behavior,
            header_behavior=header_behavior,
            origin_request_policy_name=origin_request_policy_name,
            query_string_behavior=query_string_behavior,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromOriginRequestPolicyId") # type: ignore[misc]
    @builtins.classmethod
    def from_origin_request_policy_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        origin_request_policy_id: builtins.str,
    ) -> IOriginRequestPolicy:
        '''Imports a Origin Request Policy from its id.

        :param scope: -
        :param id: -
        :param origin_request_policy_id: -
        '''
        return typing.cast(IOriginRequestPolicy, jsii.sinvoke(cls, "fromOriginRequestPolicyId", [scope, id, origin_request_policy_id]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ALL_VIEWER")
    def ALL_VIEWER(cls) -> IOriginRequestPolicy:
        '''This policy includes all values (query strings, headers, and cookies) in the viewer request.'''
        return typing.cast(IOriginRequestPolicy, jsii.sget(cls, "ALL_VIEWER"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CORS_CUSTOM_ORIGIN")
    def CORS_CUSTOM_ORIGIN(cls) -> IOriginRequestPolicy:
        '''This policy includes the header that enables cross-origin resource sharing (CORS) requests when the origin is a custom origin.'''
        return typing.cast(IOriginRequestPolicy, jsii.sget(cls, "CORS_CUSTOM_ORIGIN"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CORS_S3_ORIGIN")
    def CORS_S3_ORIGIN(cls) -> IOriginRequestPolicy:
        '''This policy includes the headers that enable cross-origin resource sharing (CORS) requests when the origin is an Amazon S3 bucket.'''
        return typing.cast(IOriginRequestPolicy, jsii.sget(cls, "CORS_S3_ORIGIN"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ELEMENTAL_MEDIA_TAILOR")
    def ELEMENTAL_MEDIA_TAILOR(cls) -> IOriginRequestPolicy:
        '''This policy is designed for use with an origin that is an AWS Elemental MediaTailor endpoint.'''
        return typing.cast(IOriginRequestPolicy, jsii.sget(cls, "ELEMENTAL_MEDIA_TAILOR"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="USER_AGENT_REFERER_HEADERS")
    def USER_AGENT_REFERER_HEADERS(cls) -> IOriginRequestPolicy:
        '''This policy includes only the User-Agent and Referer headers.

        It doesn’t include any query strings or cookies.
        '''
        return typing.cast(IOriginRequestPolicy, jsii.sget(cls, "USER_AGENT_REFERER_HEADERS"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="originRequestPolicyId")
    def origin_request_policy_id(self) -> builtins.str:
        '''The ID of the origin request policy.'''
        return typing.cast(builtins.str, jsii.get(self, "originRequestPolicyId"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.OriginRequestPolicyProps",
    jsii_struct_bases=[],
    name_mapping={
        "comment": "comment",
        "cookie_behavior": "cookieBehavior",
        "header_behavior": "headerBehavior",
        "origin_request_policy_name": "originRequestPolicyName",
        "query_string_behavior": "queryStringBehavior",
    },
)
class OriginRequestPolicyProps:
    def __init__(
        self,
        *,
        comment: typing.Optional[builtins.str] = None,
        cookie_behavior: typing.Optional[OriginRequestCookieBehavior] = None,
        header_behavior: typing.Optional[OriginRequestHeaderBehavior] = None,
        origin_request_policy_name: typing.Optional[builtins.str] = None,
        query_string_behavior: typing.Optional["OriginRequestQueryStringBehavior"] = None,
    ) -> None:
        '''Properties for creating a Origin Request Policy.

        :param comment: A comment to describe the origin request policy. Default: - no comment
        :param cookie_behavior: The cookies from viewer requests to include in origin requests. Default: OriginRequestCookieBehavior.none()
        :param header_behavior: The HTTP headers to include in origin requests. These can include headers from viewer requests and additional headers added by CloudFront. Default: OriginRequestHeaderBehavior.none()
        :param origin_request_policy_name: A unique name to identify the origin request policy. The name must only include '-', '_', or alphanumeric characters. Default: - generated from the ``id``
        :param query_string_behavior: The URL query strings from viewer requests to include in origin requests. Default: OriginRequestQueryStringBehavior.none()
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if comment is not None:
            self._values["comment"] = comment
        if cookie_behavior is not None:
            self._values["cookie_behavior"] = cookie_behavior
        if header_behavior is not None:
            self._values["header_behavior"] = header_behavior
        if origin_request_policy_name is not None:
            self._values["origin_request_policy_name"] = origin_request_policy_name
        if query_string_behavior is not None:
            self._values["query_string_behavior"] = query_string_behavior

    @builtins.property
    def comment(self) -> typing.Optional[builtins.str]:
        '''A comment to describe the origin request policy.

        :default: - no comment
        '''
        result = self._values.get("comment")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def cookie_behavior(self) -> typing.Optional[OriginRequestCookieBehavior]:
        '''The cookies from viewer requests to include in origin requests.

        :default: OriginRequestCookieBehavior.none()
        '''
        result = self._values.get("cookie_behavior")
        return typing.cast(typing.Optional[OriginRequestCookieBehavior], result)

    @builtins.property
    def header_behavior(self) -> typing.Optional[OriginRequestHeaderBehavior]:
        '''The HTTP headers to include in origin requests.

        These can include headers from viewer requests and additional headers added by CloudFront.

        :default: OriginRequestHeaderBehavior.none()
        '''
        result = self._values.get("header_behavior")
        return typing.cast(typing.Optional[OriginRequestHeaderBehavior], result)

    @builtins.property
    def origin_request_policy_name(self) -> typing.Optional[builtins.str]:
        '''A unique name to identify the origin request policy.

        The name must only include '-', '_', or alphanumeric characters.

        :default: - generated from the ``id``
        '''
        result = self._values.get("origin_request_policy_name")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def query_string_behavior(
        self,
    ) -> typing.Optional["OriginRequestQueryStringBehavior"]:
        '''The URL query strings from viewer requests to include in origin requests.

        :default: OriginRequestQueryStringBehavior.none()
        '''
        result = self._values.get("query_string_behavior")
        return typing.cast(typing.Optional["OriginRequestQueryStringBehavior"], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "OriginRequestPolicyProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class OriginRequestQueryStringBehavior(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.OriginRequestQueryStringBehavior",
):
    '''Determines whether any URL query strings in viewer requests (and if so, which query strings) are included in requests that CloudFront sends to the origin.'''

    @jsii.member(jsii_name="all") # type: ignore[misc]
    @builtins.classmethod
    def all(cls) -> "OriginRequestQueryStringBehavior":
        '''All query strings in viewer requests are included in requests that CloudFront sends to the origin.'''
        return typing.cast("OriginRequestQueryStringBehavior", jsii.sinvoke(cls, "all", []))

    @jsii.member(jsii_name="allowList") # type: ignore[misc]
    @builtins.classmethod
    def allow_list(
        cls,
        *query_strings: builtins.str,
    ) -> "OriginRequestQueryStringBehavior":
        '''Only the provided ``queryStrings`` are included in requests that CloudFront sends to the origin.

        :param query_strings: -
        '''
        return typing.cast("OriginRequestQueryStringBehavior", jsii.sinvoke(cls, "allowList", [*query_strings]))

    @jsii.member(jsii_name="none") # type: ignore[misc]
    @builtins.classmethod
    def none(cls) -> "OriginRequestQueryStringBehavior":
        '''Query strings in viewer requests are not included in requests that CloudFront sends to the origin.

        Any query strings that are listed in a CachePolicy are still included in origin requests.
        '''
        return typing.cast("OriginRequestQueryStringBehavior", jsii.sinvoke(cls, "none", []))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="behavior")
    def behavior(self) -> builtins.str:
        '''The behavior of query strings -- allow all, none, or only an allow list.'''
        return typing.cast(builtins.str, jsii.get(self, "behavior"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="queryStrings")
    def query_strings(self) -> typing.Optional[typing.List[builtins.str]]:
        '''The query strings to allow, if the behavior is an allow list.'''
        return typing.cast(typing.Optional[typing.List[builtins.str]], jsii.get(self, "queryStrings"))


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.OriginSslPolicy")
class OriginSslPolicy(enum.Enum):
    SSL_V3 = "SSL_V3"
    TLS_V1 = "TLS_V1"
    TLS_V1_1 = "TLS_V1_1"
    TLS_V1_2 = "TLS_V1_2"


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.PriceClass")
class PriceClass(enum.Enum):
    '''The price class determines how many edge locations CloudFront will use for your distribution.

    See https://aws.amazon.com/cloudfront/pricing/ for full list of supported regions.
    '''

    PRICE_CLASS_100 = "PRICE_CLASS_100"
    '''USA, Canada, Europe, & Israel.'''
    PRICE_CLASS_200 = "PRICE_CLASS_200"
    '''PRICE_CLASS_100 + South Africa, Kenya, Middle East, Japan, Singapore, South Korea, Taiwan, Hong Kong, & Philippines.'''
    PRICE_CLASS_ALL = "PRICE_CLASS_ALL"
    '''All locations.'''


@jsii.implements(IPublicKey)
class PublicKey(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.PublicKey",
):
    '''A Public Key Configuration.

    :resource: AWS::CloudFront::PublicKey
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        encoded_key: builtins.str,
        comment: typing.Optional[builtins.str] = None,
        public_key_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param encoded_key: The public key that you can use with signed URLs and signed cookies, or with field-level encryption. The ``encodedKey`` parameter must include ``-----BEGIN PUBLIC KEY-----`` and ``-----END PUBLIC KEY-----`` lines.
        :param comment: A comment to describe the public key. Default: - no comment
        :param public_key_name: A name to identify the public key. Default: - generated from the ``id``
        '''
        props = PublicKeyProps(
            encoded_key=encoded_key, comment=comment, public_key_name=public_key_name
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromPublicKeyId") # type: ignore[misc]
    @builtins.classmethod
    def from_public_key_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        public_key_id: builtins.str,
    ) -> IPublicKey:
        '''Imports a Public Key from its id.

        :param scope: -
        :param id: -
        :param public_key_id: -
        '''
        return typing.cast(IPublicKey, jsii.sinvoke(cls, "fromPublicKeyId", [scope, id, public_key_id]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="publicKeyId")
    def public_key_id(self) -> builtins.str:
        '''The ID of the key group.'''
        return typing.cast(builtins.str, jsii.get(self, "publicKeyId"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.PublicKeyProps",
    jsii_struct_bases=[],
    name_mapping={
        "encoded_key": "encodedKey",
        "comment": "comment",
        "public_key_name": "publicKeyName",
    },
)
class PublicKeyProps:
    def __init__(
        self,
        *,
        encoded_key: builtins.str,
        comment: typing.Optional[builtins.str] = None,
        public_key_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''Properties for creating a Public Key.

        :param encoded_key: The public key that you can use with signed URLs and signed cookies, or with field-level encryption. The ``encodedKey`` parameter must include ``-----BEGIN PUBLIC KEY-----`` and ``-----END PUBLIC KEY-----`` lines.
        :param comment: A comment to describe the public key. Default: - no comment
        :param public_key_name: A name to identify the public key. Default: - generated from the ``id``
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "encoded_key": encoded_key,
        }
        if comment is not None:
            self._values["comment"] = comment
        if public_key_name is not None:
            self._values["public_key_name"] = public_key_name

    @builtins.property
    def encoded_key(self) -> builtins.str:
        '''The public key that you can use with signed URLs and signed cookies, or with field-level encryption.

        The ``encodedKey`` parameter must include ``-----BEGIN PUBLIC KEY-----`` and ``-----END PUBLIC KEY-----`` lines.

        :see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/field-level-encryption.html
        '''
        result = self._values.get("encoded_key")
        assert result is not None, "Required property 'encoded_key' is missing"
        return typing.cast(builtins.str, result)

    @builtins.property
    def comment(self) -> typing.Optional[builtins.str]:
        '''A comment to describe the public key.

        :default: - no comment
        '''
        result = self._values.get("comment")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def public_key_name(self) -> typing.Optional[builtins.str]:
        '''A name to identify the public key.

        :default: - generated from the ``id``
        '''
        result = self._values.get("public_key_name")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "PublicKeyProps(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.S3OriginConfig",
    jsii_struct_bases=[],
    name_mapping={
        "s3_bucket_source": "s3BucketSource",
        "origin_access_identity": "originAccessIdentity",
        "origin_headers": "originHeaders",
        "origin_path": "originPath",
        "origin_shield_region": "originShieldRegion",
    },
)
class S3OriginConfig:
    def __init__(
        self,
        *,
        s3_bucket_source: aws_cdk.aws_s3.IBucket,
        origin_access_identity: typing.Optional[IOriginAccessIdentity] = None,
        origin_headers: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        origin_path: typing.Optional[builtins.str] = None,
        origin_shield_region: typing.Optional[builtins.str] = None,
    ) -> None:
        '''S3 origin configuration for CloudFront.

        :param s3_bucket_source: The source bucket to serve content from.
        :param origin_access_identity: The optional Origin Access Identity of the origin identity cloudfront will use when calling your s3 bucket. Default: No Origin Access Identity which requires the S3 bucket to be public accessible
        :param origin_headers: Any additional headers to pass to the origin. Default: - No additional headers are passed.
        :param origin_path: The relative path to the origin root to use for sources. Default: /
        :param origin_shield_region: When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance. Default: - origin shield not enabled
        '''
        self._values: typing.Dict[str, typing.Any] = {
            "s3_bucket_source": s3_bucket_source,
        }
        if origin_access_identity is not None:
            self._values["origin_access_identity"] = origin_access_identity
        if origin_headers is not None:
            self._values["origin_headers"] = origin_headers
        if origin_path is not None:
            self._values["origin_path"] = origin_path
        if origin_shield_region is not None:
            self._values["origin_shield_region"] = origin_shield_region

    @builtins.property
    def s3_bucket_source(self) -> aws_cdk.aws_s3.IBucket:
        '''The source bucket to serve content from.'''
        result = self._values.get("s3_bucket_source")
        assert result is not None, "Required property 's3_bucket_source' is missing"
        return typing.cast(aws_cdk.aws_s3.IBucket, result)

    @builtins.property
    def origin_access_identity(self) -> typing.Optional[IOriginAccessIdentity]:
        '''The optional Origin Access Identity of the origin identity cloudfront will use when calling your s3 bucket.

        :default: No Origin Access Identity which requires the S3 bucket to be public accessible
        '''
        result = self._values.get("origin_access_identity")
        return typing.cast(typing.Optional[IOriginAccessIdentity], result)

    @builtins.property
    def origin_headers(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''Any additional headers to pass to the origin.

        :default: - No additional headers are passed.
        '''
        result = self._values.get("origin_headers")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def origin_path(self) -> typing.Optional[builtins.str]:
        '''The relative path to the origin root to use for sources.

        :default: /
        '''
        result = self._values.get("origin_path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def origin_shield_region(self) -> typing.Optional[builtins.str]:
        '''When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance.

        :default: - origin shield not enabled
        '''
        result = self._values.get("origin_shield_region")
        return typing.cast(typing.Optional[builtins.str], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "S3OriginConfig(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.SSLMethod")
class SSLMethod(enum.Enum):
    '''The SSL method CloudFront will use for your distribution.

    Server Name Indication (SNI) - is an extension to the TLS computer networking protocol by which a client indicates
    which hostname it is attempting to connect to at the start of the handshaking process. This allows a server to present
    multiple certificates on the same IP address and TCP port number and hence allows multiple secure (HTTPS) websites
    (or any other service over TLS) to be served by the same IP address without requiring all those sites to use the same certificate.

    CloudFront can use SNI to host multiple distributions on the same IP - which a large majority of clients will support.

    If your clients cannot support SNI however - CloudFront can use dedicated IPs for your distribution - but there is a prorated monthly charge for
    using this feature. By default, we use SNI - but you can optionally enable dedicated IPs (VIP).

    See the CloudFront SSL for more details about pricing : https://aws.amazon.com/cloudfront/custom-ssl-domains/
    '''

    SNI = "SNI"
    VIP = "VIP"


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.SecurityPolicyProtocol")
class SecurityPolicyProtocol(enum.Enum):
    '''The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections.

    CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify.
    '''

    SSL_V3 = "SSL_V3"
    TLS_V1 = "TLS_V1"
    TLS_V1_2016 = "TLS_V1_2016"
    TLS_V1_1_2016 = "TLS_V1_1_2016"
    TLS_V1_2_2018 = "TLS_V1_2_2018"
    TLS_V1_2_2019 = "TLS_V1_2_2019"
    TLS_V1_2_2021 = "TLS_V1_2_2021"


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.SourceConfiguration",
    jsii_struct_bases=[],
    name_mapping={
        "behaviors": "behaviors",
        "connection_attempts": "connectionAttempts",
        "connection_timeout": "connectionTimeout",
        "custom_origin_source": "customOriginSource",
        "failover_criteria_status_codes": "failoverCriteriaStatusCodes",
        "failover_custom_origin_source": "failoverCustomOriginSource",
        "failover_s3_origin_source": "failoverS3OriginSource",
        "origin_headers": "originHeaders",
        "origin_path": "originPath",
        "origin_shield_region": "originShieldRegion",
        "s3_origin_source": "s3OriginSource",
    },
)
class SourceConfiguration:
    def __init__(
        self,
        *,
        behaviors: typing.Sequence[Behavior],
        connection_attempts: typing.Optional[jsii.Number] = None,
        connection_timeout: typing.Optional[aws_cdk.core.Duration] = None,
        custom_origin_source: typing.Optional[CustomOriginConfig] = None,
        failover_criteria_status_codes: typing.Optional[typing.Sequence[FailoverStatusCode]] = None,
        failover_custom_origin_source: typing.Optional[CustomOriginConfig] = None,
        failover_s3_origin_source: typing.Optional[S3OriginConfig] = None,
        origin_headers: typing.Optional[typing.Mapping[builtins.str, builtins.str]] = None,
        origin_path: typing.Optional[builtins.str] = None,
        origin_shield_region: typing.Optional[builtins.str] = None,
        s3_origin_source: typing.Optional[S3OriginConfig] = None,
    ) -> None:
        '''A source configuration is a wrapper for CloudFront origins and behaviors.

        An origin is what CloudFront will "be in front of" - that is, CloudFront will pull it's assets from an origin.

        If you're using s3 as a source - pass the ``s3Origin`` property, otherwise, pass the ``customOriginSource`` property.

        One or the other must be passed, and it is invalid to pass both in the same SourceConfiguration.

        :param behaviors: The behaviors associated with this source. At least one (default) behavior must be included.
        :param connection_attempts: The number of times that CloudFront attempts to connect to the origin. You can specify 1, 2, or 3 as the number of attempts. Default: 3
        :param connection_timeout: The number of seconds that CloudFront waits when trying to establish a connection to the origin. You can specify a number of seconds between 1 and 10 (inclusive). Default: cdk.Duration.seconds(10)
        :param custom_origin_source: A custom origin source - for all non-s3 sources.
        :param failover_criteria_status_codes: HTTP status code to failover to second origin. Default: [500, 502, 503, 504]
        :param failover_custom_origin_source: A custom origin source for failover in case the s3OriginSource returns invalid status code. Default: - no failover configuration
        :param failover_s3_origin_source: An s3 origin source for failover in case the s3OriginSource returns invalid status code. Default: - no failover configuration
        :param origin_headers: (deprecated) Any additional headers to pass to the origin. Default: - No additional headers are passed.
        :param origin_path: (deprecated) The relative path to the origin root to use for sources. Default: /
        :param origin_shield_region: When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance. Default: - origin shield not enabled
        :param s3_origin_source: An s3 origin source - if you're using s3 for your assets.
        '''
        if isinstance(custom_origin_source, dict):
            custom_origin_source = CustomOriginConfig(**custom_origin_source)
        if isinstance(failover_custom_origin_source, dict):
            failover_custom_origin_source = CustomOriginConfig(**failover_custom_origin_source)
        if isinstance(failover_s3_origin_source, dict):
            failover_s3_origin_source = S3OriginConfig(**failover_s3_origin_source)
        if isinstance(s3_origin_source, dict):
            s3_origin_source = S3OriginConfig(**s3_origin_source)
        self._values: typing.Dict[str, typing.Any] = {
            "behaviors": behaviors,
        }
        if connection_attempts is not None:
            self._values["connection_attempts"] = connection_attempts
        if connection_timeout is not None:
            self._values["connection_timeout"] = connection_timeout
        if custom_origin_source is not None:
            self._values["custom_origin_source"] = custom_origin_source
        if failover_criteria_status_codes is not None:
            self._values["failover_criteria_status_codes"] = failover_criteria_status_codes
        if failover_custom_origin_source is not None:
            self._values["failover_custom_origin_source"] = failover_custom_origin_source
        if failover_s3_origin_source is not None:
            self._values["failover_s3_origin_source"] = failover_s3_origin_source
        if origin_headers is not None:
            self._values["origin_headers"] = origin_headers
        if origin_path is not None:
            self._values["origin_path"] = origin_path
        if origin_shield_region is not None:
            self._values["origin_shield_region"] = origin_shield_region
        if s3_origin_source is not None:
            self._values["s3_origin_source"] = s3_origin_source

    @builtins.property
    def behaviors(self) -> typing.List[Behavior]:
        '''The behaviors associated with this source.

        At least one (default) behavior must be included.
        '''
        result = self._values.get("behaviors")
        assert result is not None, "Required property 'behaviors' is missing"
        return typing.cast(typing.List[Behavior], result)

    @builtins.property
    def connection_attempts(self) -> typing.Optional[jsii.Number]:
        '''The number of times that CloudFront attempts to connect to the origin.

        You can specify 1, 2, or 3 as the number of attempts.

        :default: 3
        '''
        result = self._values.get("connection_attempts")
        return typing.cast(typing.Optional[jsii.Number], result)

    @builtins.property
    def connection_timeout(self) -> typing.Optional[aws_cdk.core.Duration]:
        '''The number of seconds that CloudFront waits when trying to establish a connection to the origin.

        You can specify a number of seconds between 1 and 10 (inclusive).

        :default: cdk.Duration.seconds(10)
        '''
        result = self._values.get("connection_timeout")
        return typing.cast(typing.Optional[aws_cdk.core.Duration], result)

    @builtins.property
    def custom_origin_source(self) -> typing.Optional[CustomOriginConfig]:
        '''A custom origin source - for all non-s3 sources.'''
        result = self._values.get("custom_origin_source")
        return typing.cast(typing.Optional[CustomOriginConfig], result)

    @builtins.property
    def failover_criteria_status_codes(
        self,
    ) -> typing.Optional[typing.List[FailoverStatusCode]]:
        '''HTTP status code to failover to second origin.

        :default: [500, 502, 503, 504]
        '''
        result = self._values.get("failover_criteria_status_codes")
        return typing.cast(typing.Optional[typing.List[FailoverStatusCode]], result)

    @builtins.property
    def failover_custom_origin_source(self) -> typing.Optional[CustomOriginConfig]:
        '''A custom origin source for failover in case the s3OriginSource returns invalid status code.

        :default: - no failover configuration
        '''
        result = self._values.get("failover_custom_origin_source")
        return typing.cast(typing.Optional[CustomOriginConfig], result)

    @builtins.property
    def failover_s3_origin_source(self) -> typing.Optional[S3OriginConfig]:
        '''An s3 origin source for failover in case the s3OriginSource returns invalid status code.

        :default: - no failover configuration
        '''
        result = self._values.get("failover_s3_origin_source")
        return typing.cast(typing.Optional[S3OriginConfig], result)

    @builtins.property
    def origin_headers(
        self,
    ) -> typing.Optional[typing.Mapping[builtins.str, builtins.str]]:
        '''(deprecated) Any additional headers to pass to the origin.

        :default: - No additional headers are passed.

        :deprecated: Use originHeaders on s3OriginSource or customOriginSource

        :stability: deprecated
        '''
        result = self._values.get("origin_headers")
        return typing.cast(typing.Optional[typing.Mapping[builtins.str, builtins.str]], result)

    @builtins.property
    def origin_path(self) -> typing.Optional[builtins.str]:
        '''(deprecated) The relative path to the origin root to use for sources.

        :default: /

        :deprecated: Use originPath on s3OriginSource or customOriginSource

        :stability: deprecated
        '''
        result = self._values.get("origin_path")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def origin_shield_region(self) -> typing.Optional[builtins.str]:
        '''When you enable Origin Shield in the AWS Region that has the lowest latency to your origin, you can get better network performance.

        :default: - origin shield not enabled

        :see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/origin-shield.html
        '''
        result = self._values.get("origin_shield_region")
        return typing.cast(typing.Optional[builtins.str], result)

    @builtins.property
    def s3_origin_source(self) -> typing.Optional[S3OriginConfig]:
        '''An s3 origin source - if you're using s3 for your assets.'''
        result = self._values.get("s3_origin_source")
        return typing.cast(typing.Optional[S3OriginConfig], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "SourceConfiguration(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


class ViewerCertificate(
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.ViewerCertificate",
):
    '''Viewer certificate configuration class.'''

    @jsii.member(jsii_name="fromAcmCertificate") # type: ignore[misc]
    @builtins.classmethod
    def from_acm_certificate(
        cls,
        certificate: aws_cdk.aws_certificatemanager.ICertificate,
        *,
        aliases: typing.Optional[typing.Sequence[builtins.str]] = None,
        security_policy: typing.Optional[SecurityPolicyProtocol] = None,
        ssl_method: typing.Optional[SSLMethod] = None,
    ) -> "ViewerCertificate":
        '''Generate an AWS Certificate Manager (ACM) viewer certificate configuration.

        :param certificate: AWS Certificate Manager (ACM) certificate. Your certificate must be located in the us-east-1 (US East (N. Virginia)) region to be accessed by CloudFront
        :param aliases: Domain names on the certificate (both main domain name and Subject Alternative names).
        :param security_policy: The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify. Default: - SSLv3 if sslMethod VIP, TLSv1 if sslMethod SNI
        :param ssl_method: How CloudFront should serve HTTPS requests. See the notes on SSLMethod if you wish to use other SSL termination types. Default: SSLMethod.SNI
        '''
        options = ViewerCertificateOptions(
            aliases=aliases, security_policy=security_policy, ssl_method=ssl_method
        )

        return typing.cast("ViewerCertificate", jsii.sinvoke(cls, "fromAcmCertificate", [certificate, options]))

    @jsii.member(jsii_name="fromCloudFrontDefaultCertificate") # type: ignore[misc]
    @builtins.classmethod
    def from_cloud_front_default_certificate(
        cls,
        *aliases: builtins.str,
    ) -> "ViewerCertificate":
        '''Generate a viewer certifcate configuration using the CloudFront default certificate (e.g. d111111abcdef8.cloudfront.net) and a {@link SecurityPolicyProtocol.TLS_V1} security policy.

        :param aliases: Alternative CNAME aliases You also must create a CNAME record with your DNS service to route queries.
        '''
        return typing.cast("ViewerCertificate", jsii.sinvoke(cls, "fromCloudFrontDefaultCertificate", [*aliases]))

    @jsii.member(jsii_name="fromIamCertificate") # type: ignore[misc]
    @builtins.classmethod
    def from_iam_certificate(
        cls,
        iam_certificate_id: builtins.str,
        *,
        aliases: typing.Optional[typing.Sequence[builtins.str]] = None,
        security_policy: typing.Optional[SecurityPolicyProtocol] = None,
        ssl_method: typing.Optional[SSLMethod] = None,
    ) -> "ViewerCertificate":
        '''Generate an IAM viewer certificate configuration.

        :param iam_certificate_id: Identifier of the IAM certificate.
        :param aliases: Domain names on the certificate (both main domain name and Subject Alternative names).
        :param security_policy: The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify. Default: - SSLv3 if sslMethod VIP, TLSv1 if sslMethod SNI
        :param ssl_method: How CloudFront should serve HTTPS requests. See the notes on SSLMethod if you wish to use other SSL termination types. Default: SSLMethod.SNI
        '''
        options = ViewerCertificateOptions(
            aliases=aliases, security_policy=security_policy, ssl_method=ssl_method
        )

        return typing.cast("ViewerCertificate", jsii.sinvoke(cls, "fromIamCertificate", [iam_certificate_id, options]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="aliases")
    def aliases(self) -> typing.List[builtins.str]:
        return typing.cast(typing.List[builtins.str], jsii.get(self, "aliases"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="props")
    def props(self) -> CfnDistribution.ViewerCertificateProperty:
        return typing.cast(CfnDistribution.ViewerCertificateProperty, jsii.get(self, "props"))


@jsii.data_type(
    jsii_type="@aws-cdk/aws-cloudfront.ViewerCertificateOptions",
    jsii_struct_bases=[],
    name_mapping={
        "aliases": "aliases",
        "security_policy": "securityPolicy",
        "ssl_method": "sslMethod",
    },
)
class ViewerCertificateOptions:
    def __init__(
        self,
        *,
        aliases: typing.Optional[typing.Sequence[builtins.str]] = None,
        security_policy: typing.Optional[SecurityPolicyProtocol] = None,
        ssl_method: typing.Optional[SSLMethod] = None,
    ) -> None:
        '''
        :param aliases: Domain names on the certificate (both main domain name and Subject Alternative names).
        :param security_policy: The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify. Default: - SSLv3 if sslMethod VIP, TLSv1 if sslMethod SNI
        :param ssl_method: How CloudFront should serve HTTPS requests. See the notes on SSLMethod if you wish to use other SSL termination types. Default: SSLMethod.SNI
        '''
        self._values: typing.Dict[str, typing.Any] = {}
        if aliases is not None:
            self._values["aliases"] = aliases
        if security_policy is not None:
            self._values["security_policy"] = security_policy
        if ssl_method is not None:
            self._values["ssl_method"] = ssl_method

    @builtins.property
    def aliases(self) -> typing.Optional[typing.List[builtins.str]]:
        '''Domain names on the certificate (both main domain name and Subject Alternative names).'''
        result = self._values.get("aliases")
        return typing.cast(typing.Optional[typing.List[builtins.str]], result)

    @builtins.property
    def security_policy(self) -> typing.Optional[SecurityPolicyProtocol]:
        '''The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections.

        CloudFront serves your objects only to browsers or devices that support at
        least the SSL version that you specify.

        :default: - SSLv3 if sslMethod VIP, TLSv1 if sslMethod SNI
        '''
        result = self._values.get("security_policy")
        return typing.cast(typing.Optional[SecurityPolicyProtocol], result)

    @builtins.property
    def ssl_method(self) -> typing.Optional[SSLMethod]:
        '''How CloudFront should serve HTTPS requests.

        See the notes on SSLMethod if you wish to use other SSL termination types.

        :default: SSLMethod.SNI

        :see: https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_ViewerCertificate.html
        '''
        result = self._values.get("ssl_method")
        return typing.cast(typing.Optional[SSLMethod], result)

    def __eq__(self, rhs: typing.Any) -> builtins.bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs: typing.Any) -> builtins.bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return "ViewerCertificateOptions(%s)" % ", ".join(
            k + "=" + repr(v) for k, v in self._values.items()
        )


@jsii.enum(jsii_type="@aws-cdk/aws-cloudfront.ViewerProtocolPolicy")
class ViewerProtocolPolicy(enum.Enum):
    '''How HTTPs should be handled with your distribution.'''

    HTTPS_ONLY = "HTTPS_ONLY"
    '''HTTPS only.'''
    REDIRECT_TO_HTTPS = "REDIRECT_TO_HTTPS"
    '''Will redirect HTTP requests to HTTPS.'''
    ALLOW_ALL = "ALLOW_ALL"
    '''Both HTTP and HTTPS supported.'''


@jsii.implements(ICachePolicy)
class CachePolicy(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CachePolicy",
):
    '''A Cache Policy configuration.

    :link: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html
    :resource: AWS::CloudFront::CachePolicy
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        cache_policy_name: typing.Optional[builtins.str] = None,
        comment: typing.Optional[builtins.str] = None,
        cookie_behavior: typing.Optional[CacheCookieBehavior] = None,
        default_ttl: typing.Optional[aws_cdk.core.Duration] = None,
        enable_accept_encoding_brotli: typing.Optional[builtins.bool] = None,
        enable_accept_encoding_gzip: typing.Optional[builtins.bool] = None,
        header_behavior: typing.Optional[CacheHeaderBehavior] = None,
        max_ttl: typing.Optional[aws_cdk.core.Duration] = None,
        min_ttl: typing.Optional[aws_cdk.core.Duration] = None,
        query_string_behavior: typing.Optional[CacheQueryStringBehavior] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param cache_policy_name: A unique name to identify the cache policy. The name must only include '-', '_', or alphanumeric characters. Default: - generated from the ``id``
        :param comment: A comment to describe the cache policy. Default: - no comment
        :param 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. Default: CacheCookieBehavior.none()
        :param default_ttl: The default amount of time for objects to stay in the CloudFront cache. Only used when the origin does not send Cache-Control or Expires headers with the object. Default: - The greater of 1 day and ``minTtl``
        :param enable_accept_encoding_brotli: Whether to normalize and include the ``Accept-Encoding`` header in the cache key when the ``Accept-Encoding`` header is 'br'. Default: false
        :param enable_accept_encoding_gzip: Whether to normalize and include the ``Accept-Encoding`` header in the cache key when the ``Accept-Encoding`` header is 'gzip'. Default: false
        :param header_behavior: Determines whether any HTTP headers are included in the cache key and automatically included in requests that CloudFront sends to the origin. Default: CacheHeaderBehavior.none()
        :param max_ttl: The maximum amount of time for objects to stay in the CloudFront cache. CloudFront uses this value only when the origin sends Cache-Control or Expires headers with the object. Default: - The greater of 1 year and ``defaultTtl``
        :param min_ttl: The minimum amount of time for objects to stay in the CloudFront cache. Default: Duration.seconds(0)
        :param query_string_behavior: Determines whether any query strings are included in the cache key and automatically included in requests that CloudFront sends to the origin. Default: CacheQueryStringBehavior.none()
        '''
        props = CachePolicyProps(
            cache_policy_name=cache_policy_name,
            comment=comment,
            cookie_behavior=cookie_behavior,
            default_ttl=default_ttl,
            enable_accept_encoding_brotli=enable_accept_encoding_brotli,
            enable_accept_encoding_gzip=enable_accept_encoding_gzip,
            header_behavior=header_behavior,
            max_ttl=max_ttl,
            min_ttl=min_ttl,
            query_string_behavior=query_string_behavior,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromCachePolicyId") # type: ignore[misc]
    @builtins.classmethod
    def from_cache_policy_id(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        cache_policy_id: builtins.str,
    ) -> ICachePolicy:
        '''Imports a Cache Policy from its id.

        :param scope: -
        :param id: -
        :param cache_policy_id: -
        '''
        return typing.cast(ICachePolicy, jsii.sinvoke(cls, "fromCachePolicyId", [scope, id, cache_policy_id]))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="AMPLIFY")
    def AMPLIFY(cls) -> ICachePolicy:
        '''This policy is designed for use with an origin that is an AWS Amplify web app.'''
        return typing.cast(ICachePolicy, jsii.sget(cls, "AMPLIFY"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CACHING_DISABLED")
    def CACHING_DISABLED(cls) -> ICachePolicy:
        '''Disables caching.

        This policy is useful for dynamic content and for requests that are not cacheable.
        '''
        return typing.cast(ICachePolicy, jsii.sget(cls, "CACHING_DISABLED"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CACHING_OPTIMIZED")
    def CACHING_OPTIMIZED(cls) -> ICachePolicy:
        '''Optimize cache efficiency by minimizing the values that CloudFront includes in the cache key.

        Query strings and cookies are not included in the cache key, and only the normalized 'Accept-Encoding' header is included.
        '''
        return typing.cast(ICachePolicy, jsii.sget(cls, "CACHING_OPTIMIZED"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="CACHING_OPTIMIZED_FOR_UNCOMPRESSED_OBJECTS")
    def CACHING_OPTIMIZED_FOR_UNCOMPRESSED_OBJECTS(cls) -> ICachePolicy:
        '''Optimize cache efficiency by minimizing the values that CloudFront includes in the cache key.

        Query strings and cookies are not included in the cache key, and only the normalized 'Accept-Encoding' header is included.
        Disables cache compression.
        '''
        return typing.cast(ICachePolicy, jsii.sget(cls, "CACHING_OPTIMIZED_FOR_UNCOMPRESSED_OBJECTS"))

    @jsii.python.classproperty # type: ignore[misc]
    @jsii.member(jsii_name="ELEMENTAL_MEDIA_PACKAGE")
    def ELEMENTAL_MEDIA_PACKAGE(cls) -> ICachePolicy:
        '''Designed for use with an origin that is an AWS Elemental MediaPackage endpoint.'''
        return typing.cast(ICachePolicy, jsii.sget(cls, "ELEMENTAL_MEDIA_PACKAGE"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="cachePolicyId")
    def cache_policy_id(self) -> builtins.str:
        '''The ID of the cache policy.'''
        return typing.cast(builtins.str, jsii.get(self, "cachePolicyId"))


@jsii.implements(IDistribution)
class CloudFrontWebDistribution(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.CloudFrontWebDistribution",
):
    '''Amazon CloudFront is a global content delivery network (CDN) service that securely delivers data, videos, applications, and APIs to your viewers with low latency and high transfer speeds.

    CloudFront fronts user provided content and caches it at edge locations across the world.

    Here's how you can use this construct::

       # Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
       from aws_cdk.aws_cloudfront import CloudFrontWebDistribution


       source_bucket = Bucket(self, "Bucket")

       distribution = CloudFrontWebDistribution(self, "MyDistribution",
           origin_configs=[SourceConfiguration(
               s3_origin_source=S3OriginConfig(
                   s3_bucket_source=source_bucket
               ),
               behaviors=[Behavior(is_default_behavior=True)]
           )
           ]
       )

    This will create a CloudFront distribution that uses your S3Bucket as it's origin.

    You can customize the distribution using additional properties from the CloudFrontWebDistributionProps interface.

    :resource: AWS::CloudFront::Distribution
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        origin_configs: typing.Sequence[SourceConfiguration],
        alias_configuration: typing.Optional[AliasConfiguration] = None,
        comment: typing.Optional[builtins.str] = None,
        default_root_object: typing.Optional[builtins.str] = None,
        enabled: typing.Optional[builtins.bool] = None,
        enable_ip_v6: typing.Optional[builtins.bool] = None,
        error_configurations: typing.Optional[typing.Sequence[CfnDistribution.CustomErrorResponseProperty]] = None,
        geo_restriction: typing.Optional[GeoRestriction] = None,
        http_version: typing.Optional[HttpVersion] = None,
        logging_config: typing.Optional[LoggingConfiguration] = None,
        price_class: typing.Optional[PriceClass] = None,
        viewer_certificate: typing.Optional[ViewerCertificate] = None,
        viewer_protocol_policy: typing.Optional[ViewerProtocolPolicy] = None,
        web_acl_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param origin_configs: The origin configurations for this distribution. Behaviors are a part of the origin.
        :param alias_configuration: (deprecated) AliasConfiguration is used to configured CloudFront to respond to requests on custom domain names. Default: - None.
        :param comment: A comment for this distribution in the CloudFront console. Default: - No comment is added to distribution.
        :param default_root_object: The default object to serve. Default: - "index.html" is served.
        :param enabled: Enable or disable the distribution. Default: true
        :param enable_ip_v6: If your distribution should have IPv6 enabled. Default: true
        :param error_configurations: How CloudFront should handle requests that are not successful (eg PageNotFound). By default, CloudFront does not replace HTTP status codes in the 4xx and 5xx range with custom error messages. CloudFront does not cache HTTP status codes. Default: - No custom error configuration.
        :param geo_restriction: Controls the countries in which your content is distributed. Default: No geo restriction
        :param http_version: The max supported HTTP Versions. Default: HttpVersion.HTTP2
        :param logging_config: Optional - if we should enable logging. You can pass an empty object ({}) to have us auto create a bucket for logging. Omission of this property indicates no logging is to be enabled. Default: - no logging is enabled by default.
        :param price_class: The price class for the distribution (this impacts how many locations CloudFront uses for your distribution, and billing). Default: PriceClass.PRICE_CLASS_100 the cheapest option for CloudFront is picked by default.
        :param viewer_certificate: Specifies whether you want viewers to use HTTP or HTTPS to request your objects, whether you're using an alternate domain name with HTTPS, and if so, if you're using AWS Certificate Manager (ACM) or a third-party certificate authority. Default: ViewerCertificate.fromCloudFrontDefaultCertificate()
        :param viewer_protocol_policy: The default viewer policy for incoming clients. Default: RedirectToHTTPs
        :param web_acl_id: Unique identifier that specifies the AWS WAF web ACL to associate with this CloudFront distribution. To specify a web ACL created using the latest version of AWS WAF, use the ACL ARN, for example ``arn:aws:wafv2:us-east-1:123456789012:global/webacl/ExampleWebACL/473e64fd-f30b-4765-81a0-62ad96dd167a``. To specify a web ACL created using AWS WAF Classic, use the ACL ID, for example ``473e64fd-f30b-4765-81a0-62ad96dd167a``. Default: - No AWS Web Application Firewall web access control list (web ACL).
        '''
        props = CloudFrontWebDistributionProps(
            origin_configs=origin_configs,
            alias_configuration=alias_configuration,
            comment=comment,
            default_root_object=default_root_object,
            enabled=enabled,
            enable_ip_v6=enable_ip_v6,
            error_configurations=error_configurations,
            geo_restriction=geo_restriction,
            http_version=http_version,
            logging_config=logging_config,
            price_class=price_class,
            viewer_certificate=viewer_certificate,
            viewer_protocol_policy=viewer_protocol_policy,
            web_acl_id=web_acl_id,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromDistributionAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_distribution_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        distribution_id: builtins.str,
        domain_name: builtins.str,
    ) -> IDistribution:
        '''Creates a construct that represents an external (imported) distribution.

        :param scope: -
        :param id: -
        :param distribution_id: The distribution ID for this distribution.
        :param domain_name: The generated domain name of the Distribution, such as d111111abcdef8.cloudfront.net.
        '''
        attrs = CloudFrontWebDistributionAttributes(
            distribution_id=distribution_id, domain_name=domain_name
        )

        return typing.cast(IDistribution, jsii.sinvoke(cls, "fromDistributionAttributes", [scope, id, attrs]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="distributionDomainName")
    def distribution_domain_name(self) -> builtins.str:
        '''The domain name created by CloudFront for this distribution.

        If you are using aliases for your distribution, this is the domainName your DNS records should point to.
        (In Route53, you could create an ALIAS record to this value, for example.)
        '''
        return typing.cast(builtins.str, jsii.get(self, "distributionDomainName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="distributionId")
    def distribution_id(self) -> builtins.str:
        '''The distribution ID for this distribution.'''
        return typing.cast(builtins.str, jsii.get(self, "distributionId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="domainName")
    def domain_name(self) -> builtins.str:
        '''(deprecated) The domain name created by CloudFront for this distribution.

        If you are using aliases for your distribution, this is the domainName your DNS records should point to.
        (In Route53, you could create an ALIAS record to this value, for example.)

        :deprecated: - Use ``distributionDomainName`` instead.

        :stability: deprecated
        '''
        return typing.cast(builtins.str, jsii.get(self, "domainName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="loggingBucket")
    def logging_bucket(self) -> typing.Optional[aws_cdk.aws_s3.IBucket]:
        '''The logging bucket for this CloudFront distribution.

        If logging is not enabled for this distribution - this property will be undefined.
        '''
        return typing.cast(typing.Optional[aws_cdk.aws_s3.IBucket], jsii.get(self, "loggingBucket"))


@jsii.implements(IDistribution)
class Distribution(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.Distribution",
):
    '''A CloudFront distribution with associated origin(s) and caching behavior(s).'''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        default_behavior: BehaviorOptions,
        additional_behaviors: typing.Optional[typing.Mapping[builtins.str, BehaviorOptions]] = None,
        certificate: typing.Optional[aws_cdk.aws_certificatemanager.ICertificate] = None,
        comment: typing.Optional[builtins.str] = None,
        default_root_object: typing.Optional[builtins.str] = None,
        domain_names: typing.Optional[typing.Sequence[builtins.str]] = None,
        enabled: typing.Optional[builtins.bool] = None,
        enable_ipv6: typing.Optional[builtins.bool] = None,
        enable_logging: typing.Optional[builtins.bool] = None,
        error_responses: typing.Optional[typing.Sequence[ErrorResponse]] = None,
        geo_restriction: typing.Optional[GeoRestriction] = None,
        http_version: typing.Optional[HttpVersion] = None,
        log_bucket: typing.Optional[aws_cdk.aws_s3.IBucket] = None,
        log_file_prefix: typing.Optional[builtins.str] = None,
        log_includes_cookies: typing.Optional[builtins.bool] = None,
        minimum_protocol_version: typing.Optional[SecurityPolicyProtocol] = None,
        price_class: typing.Optional[PriceClass] = None,
        web_acl_id: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param default_behavior: The default behavior for the distribution.
        :param additional_behaviors: Additional behaviors for the distribution, mapped by the pathPattern that specifies which requests to apply the behavior to. Default: - no additional behaviors are added.
        :param certificate: A certificate to associate with the distribution. The certificate must be located in N. Virginia (us-east-1). Default: - the CloudFront wildcard certificate (*.cloudfront.net) will be used.
        :param comment: Any comments you want to include about the distribution. Default: - no comment
        :param default_root_object: The object that you want CloudFront to request from your origin (for example, index.html) when a viewer requests the root URL for your distribution. If no default object is set, the request goes to the origin's root (e.g., example.com/). Default: - no default root object
        :param domain_names: Alternative domain names for this distribution. If you want to use your own domain name, such as www.example.com, instead of the cloudfront.net domain name, you can add an alternate domain name to your distribution. If you attach a certificate to the distribution, you must add (at least one of) the domain names of the certificate to this list. Default: - The distribution will only support the default generated name (e.g., d111111abcdef8.cloudfront.net)
        :param enabled: Enable or disable the distribution. Default: true
        :param enable_ipv6: Whether CloudFront will respond to IPv6 DNS requests with an IPv6 address. If you specify false, CloudFront responds to IPv6 DNS requests with the DNS response code NOERROR and with no IP addresses. This allows viewers to submit a second request, for an IPv4 address for your distribution. Default: true
        :param enable_logging: Enable access logging for the distribution. Default: - false, unless ``logBucket`` is specified.
        :param error_responses: How CloudFront should handle requests that are not successful (e.g., PageNotFound). Default: - No custom error responses.
        :param geo_restriction: Controls the countries in which your content is distributed. Default: - No geographic restrictions
        :param http_version: Specify the maximum HTTP version that you want viewers to use to communicate with CloudFront. For viewers and CloudFront to use HTTP/2, viewers must support TLS 1.2 or later, and must support server name identification (SNI). Default: HttpVersion.HTTP2
        :param log_bucket: The Amazon S3 bucket to store the access logs in. Default: - A bucket is created if ``enableLogging`` is true
        :param log_file_prefix: An optional string that you want CloudFront to prefix to the access log filenames for this distribution. Default: - no prefix
        :param log_includes_cookies: Specifies whether you want CloudFront to include cookies in access logs. Default: false
        :param minimum_protocol_version: The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. CloudFront serves your objects only to browsers or devices that support at least the SSL version that you specify. Default: - SecurityPolicyProtocol.TLS_V1_2_2021 if the '
        :param price_class: The price class that corresponds with the maximum price that you want to pay for CloudFront service. If you specify PriceClass_All, CloudFront responds to requests for your objects from all CloudFront edge locations. If you specify a price class other than PriceClass_All, CloudFront serves your objects from the CloudFront edge location that has the lowest latency among the edge locations in your price class. Default: PriceClass.PRICE_CLASS_ALL
        :param web_acl_id: Unique identifier that specifies the AWS WAF web ACL to associate with this CloudFront distribution. To specify a web ACL created using the latest version of AWS WAF, use the ACL ARN, for example ``arn:aws:wafv2:us-east-1:123456789012:global/webacl/ExampleWebACL/473e64fd-f30b-4765-81a0-62ad96dd167a``. To specify a web ACL created using AWS WAF Classic, use the ACL ID, for example ``473e64fd-f30b-4765-81a0-62ad96dd167a``. Default: - No AWS Web Application Firewall web access control list (web ACL).
        '''
        props = DistributionProps(
            default_behavior=default_behavior,
            additional_behaviors=additional_behaviors,
            certificate=certificate,
            comment=comment,
            default_root_object=default_root_object,
            domain_names=domain_names,
            enabled=enabled,
            enable_ipv6=enable_ipv6,
            enable_logging=enable_logging,
            error_responses=error_responses,
            geo_restriction=geo_restriction,
            http_version=http_version,
            log_bucket=log_bucket,
            log_file_prefix=log_file_prefix,
            log_includes_cookies=log_includes_cookies,
            minimum_protocol_version=minimum_protocol_version,
            price_class=price_class,
            web_acl_id=web_acl_id,
        )

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromDistributionAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_distribution_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        distribution_id: builtins.str,
        domain_name: builtins.str,
    ) -> IDistribution:
        '''Creates a Distribution construct that represents an external (imported) distribution.

        :param scope: -
        :param id: -
        :param distribution_id: The distribution ID for this distribution.
        :param domain_name: The generated domain name of the Distribution, such as d111111abcdef8.cloudfront.net.
        '''
        attrs = DistributionAttributes(
            distribution_id=distribution_id, domain_name=domain_name
        )

        return typing.cast(IDistribution, jsii.sinvoke(cls, "fromDistributionAttributes", [scope, id, attrs]))

    @jsii.member(jsii_name="addBehavior")
    def add_behavior(
        self,
        path_pattern: builtins.str,
        origin: IOrigin,
        *,
        allowed_methods: typing.Optional[AllowedMethods] = None,
        cached_methods: typing.Optional[CachedMethods] = None,
        cache_policy: typing.Optional[ICachePolicy] = None,
        compress: typing.Optional[builtins.bool] = None,
        edge_lambdas: typing.Optional[typing.Sequence[EdgeLambda]] = None,
        function_associations: typing.Optional[typing.Sequence[FunctionAssociation]] = None,
        origin_request_policy: typing.Optional[IOriginRequestPolicy] = None,
        smooth_streaming: typing.Optional[builtins.bool] = None,
        trusted_key_groups: typing.Optional[typing.Sequence[IKeyGroup]] = None,
        viewer_protocol_policy: typing.Optional[ViewerProtocolPolicy] = None,
    ) -> None:
        '''Adds a new behavior to this distribution for the given pathPattern.

        :param path_pattern: the path pattern (e.g., 'images/*') that specifies which requests to apply the behavior to.
        :param origin: the origin to use for this behavior.
        :param allowed_methods: HTTP methods to allow for this behavior. Default: AllowedMethods.ALLOW_GET_HEAD
        :param cached_methods: HTTP methods to cache for this behavior. Default: CachedMethods.CACHE_GET_HEAD
        :param cache_policy: The cache policy for this behavior. The cache policy determines what values are included in the cache key, and the time-to-live (TTL) values for the cache. Default: CachePolicy.CACHING_OPTIMIZED
        :param compress: Whether you want CloudFront to automatically compress certain files for this cache behavior. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/ServingCompressedFiles.html#compressed-content-cloudfront-file-types for file types CloudFront will compress. Default: true
        :param edge_lambdas: The Lambda@Edge functions to invoke before serving the contents. Default: - no Lambda functions will be invoked
        :param function_associations: The CloudFront functions to invoke before serving the contents. Default: - no functions will be invoked
        :param origin_request_policy: The origin request policy for this behavior. The origin request policy determines which values (e.g., headers, cookies) are included in requests that CloudFront sends to the origin. Default: - none
        :param smooth_streaming: Set this to true to indicate you want to distribute media files in the Microsoft Smooth Streaming format using this behavior. Default: false
        :param trusted_key_groups: A list of Key Groups that CloudFront can use to validate signed URLs or signed cookies. Default: - no KeyGroups are associated with cache behavior
        :param viewer_protocol_policy: The protocol that viewers can use to access the files controlled by this behavior. Default: ViewerProtocolPolicy.ALLOW_ALL
        '''
        behavior_options = AddBehaviorOptions(
            allowed_methods=allowed_methods,
            cached_methods=cached_methods,
            cache_policy=cache_policy,
            compress=compress,
            edge_lambdas=edge_lambdas,
            function_associations=function_associations,
            origin_request_policy=origin_request_policy,
            smooth_streaming=smooth_streaming,
            trusted_key_groups=trusted_key_groups,
            viewer_protocol_policy=viewer_protocol_policy,
        )

        return typing.cast(None, jsii.invoke(self, "addBehavior", [path_pattern, origin, behavior_options]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="distributionDomainName")
    def distribution_domain_name(self) -> builtins.str:
        '''The domain name of the Distribution, such as d111111abcdef8.cloudfront.net.'''
        return typing.cast(builtins.str, jsii.get(self, "distributionDomainName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="distributionId")
    def distribution_id(self) -> builtins.str:
        '''The distribution ID for this distribution.'''
        return typing.cast(builtins.str, jsii.get(self, "distributionId"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="domainName")
    def domain_name(self) -> builtins.str:
        '''The domain name of the Distribution, such as d111111abcdef8.cloudfront.net.'''
        return typing.cast(builtins.str, jsii.get(self, "domainName"))


@jsii.implements(IFunction)
class Function(
    aws_cdk.core.Resource,
    metaclass=jsii.JSIIMeta,
    jsii_type="@aws-cdk/aws-cloudfront.Function",
):
    '''A CloudFront Function.

    :resource: AWS::CloudFront::Function
    '''

    def __init__(
        self,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        code: FunctionCode,
        comment: typing.Optional[builtins.str] = None,
        function_name: typing.Optional[builtins.str] = None,
    ) -> None:
        '''
        :param scope: -
        :param id: -
        :param code: The source code of the function.
        :param comment: A comment to describe the function. Default: - same as ``functionName``
        :param function_name: A name to identify the function. Default: - generated from the ``id``
        '''
        props = FunctionProps(code=code, comment=comment, function_name=function_name)

        jsii.create(self.__class__, self, [scope, id, props])

    @jsii.member(jsii_name="fromFunctionAttributes") # type: ignore[misc]
    @builtins.classmethod
    def from_function_attributes(
        cls,
        scope: constructs.Construct,
        id: builtins.str,
        *,
        function_arn: builtins.str,
        function_name: builtins.str,
    ) -> IFunction:
        '''Imports a function by its name and ARN.

        :param scope: -
        :param id: -
        :param function_arn: The ARN of the function.
        :param function_name: The name of the function.
        '''
        attrs = FunctionAttributes(
            function_arn=function_arn, function_name=function_name
        )

        return typing.cast(IFunction, jsii.sinvoke(cls, "fromFunctionAttributes", [scope, id, attrs]))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionArn")
    def function_arn(self) -> builtins.str:
        '''the ARN of the CloudFront function.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "functionArn"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionName")
    def function_name(self) -> builtins.str:
        '''the name of the CloudFront function.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "functionName"))

    @builtins.property # type: ignore[misc]
    @jsii.member(jsii_name="functionStage")
    def function_stage(self) -> builtins.str:
        '''the deployment stage of the CloudFront function.

        :attribute: true
        '''
        return typing.cast(builtins.str, jsii.get(self, "functionStage"))


__all__ = [
    "AddBehaviorOptions",
    "AliasConfiguration",
    "AllowedMethods",
    "Behavior",
    "BehaviorOptions",
    "CacheCookieBehavior",
    "CacheHeaderBehavior",
    "CachePolicy",
    "CachePolicyProps",
    "CacheQueryStringBehavior",
    "CachedMethods",
    "CfnCachePolicy",
    "CfnCachePolicyProps",
    "CfnCloudFrontOriginAccessIdentity",
    "CfnCloudFrontOriginAccessIdentityProps",
    "CfnDistribution",
    "CfnDistributionProps",
    "CfnFunction",
    "CfnFunctionProps",
    "CfnKeyGroup",
    "CfnKeyGroupProps",
    "CfnOriginRequestPolicy",
    "CfnOriginRequestPolicyProps",
    "CfnPublicKey",
    "CfnPublicKeyProps",
    "CfnRealtimeLogConfig",
    "CfnRealtimeLogConfigProps",
    "CfnStreamingDistribution",
    "CfnStreamingDistributionProps",
    "CloudFrontAllowedCachedMethods",
    "CloudFrontAllowedMethods",
    "CloudFrontWebDistribution",
    "CloudFrontWebDistributionAttributes",
    "CloudFrontWebDistributionProps",
    "CustomOriginConfig",
    "Distribution",
    "DistributionAttributes",
    "DistributionProps",
    "EdgeLambda",
    "ErrorResponse",
    "FailoverStatusCode",
    "FileCodeOptions",
    "Function",
    "FunctionAssociation",
    "FunctionAttributes",
    "FunctionCode",
    "FunctionEventType",
    "FunctionProps",
    "GeoRestriction",
    "HttpVersion",
    "ICachePolicy",
    "IDistribution",
    "IFunction",
    "IKeyGroup",
    "IOrigin",
    "IOriginAccessIdentity",
    "IOriginRequestPolicy",
    "IPublicKey",
    "KeyGroup",
    "KeyGroupProps",
    "LambdaEdgeEventType",
    "LambdaFunctionAssociation",
    "LoggingConfiguration",
    "OriginAccessIdentity",
    "OriginAccessIdentityProps",
    "OriginBase",
    "OriginBindConfig",
    "OriginBindOptions",
    "OriginFailoverConfig",
    "OriginProps",
    "OriginProtocolPolicy",
    "OriginRequestCookieBehavior",
    "OriginRequestHeaderBehavior",
    "OriginRequestPolicy",
    "OriginRequestPolicyProps",
    "OriginRequestQueryStringBehavior",
    "OriginSslPolicy",
    "PriceClass",
    "PublicKey",
    "PublicKeyProps",
    "S3OriginConfig",
    "SSLMethod",
    "SecurityPolicyProtocol",
    "SourceConfiguration",
    "ViewerCertificate",
    "ViewerCertificateOptions",
    "ViewerProtocolPolicy",
]

publication.publish()

# Loading modules to ensure their types are registered with the jsii runtime library
import aws_cdk.aws_cloudfront.experimental
