AWSCDK::CloudFront

1 namespaces · 158 types

Amazon CloudFront Construct Library

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 replaces the CloudFrontWebDistribution API which is now deprecated. 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-lib/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. An S3 bucket origin can either be configured as a standard bucket or as a website endpoint (see AWS docs for Using an S3 Bucket).

# Creates a distribution from an S3 bucket with origin access control
my_bucket = AWSCDK::S3::Bucket.new(self, "myBucket")
AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3BucketOrigin.with_origin_access_control(my_bucket),
    },
})

See the README of the aws-cdk-lib/aws-cloudfront-origins module for more information on setting up S3 origins and origin access control (OAC).

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 (internet_facing is true). Both Application and Network load balancers are supported.

# Creates a distribution from an ELBv2 load balancer
vpc = nil # AWSCDK::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 = AWSCDK::ElasticLoadBalancingv2::ApplicationLoadBalancer.new(self, "LB", {
    vpc: vpc,
    internet_facing: true,
})
AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: AWSCDK::CloudFrontOrigins::LoadBalancerV2Origin.new(lb)},
})

From an HTTP endpoint

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

# Creates a distribution from an HTTP endpoint
AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("www.example.com")},
})

CloudFront SaaS Manager resources

Multi-tenant distribution and tenant providing ACM certificates

You can use Cloudfront to build multi-tenant distributions to house applications.

To create a multi-tenant distribution w/parameters, create a Distribution construct, and then update DistributionConfig in the CfnDistribution to use connectionMode: "tenant-only"

Then create a tenant

# Create the simple Origin
my_bucket = AWSCDK::S3::Bucket.new(self, "myBucket")
s3_origin = AWSCDK::CloudFrontOrigins::S3BucketOrigin.with_origin_access_control(my_bucket, {
    origin_access_levels: [AWSCDK::CloudFront::AccessLevel::READ, AWSCDK::CloudFront::AccessLevel::LIST],
})

# Create the Distribution construct
my_multi_tenant_distribution = AWSCDK::CloudFront::Distribution.new(self, "distribution", {
    default_behavior: {
        origin: s3_origin,
    },
    default_root_object: "index.html",
})

# Access the underlying L1 CfnDistribution to configure SaaS Manager properties which are not yet available in the L2 Distribution construct
cfn_distribution = my_multi_tenant_distribution.node.default_child

default_cache_behavior = {
    target_origin_id: my_bucket.bucket_arn,
    viewer_protocol_policy: "allow-all",
    compress: false,
    allowed_methods: ["GET", "HEAD"],
    cache_policy_id: AWSCDK::CloudFront::CachePolicy.CACHING_OPTIMIZED.cache_policy_id,
}
# Create the updated distributionConfig
distribution_config = {
    default_cache_behavior: default_cache_behavior,
    enabled: true,
    # the properties below are optional
    connection_mode: "tenant-only",
    origins: [
        {
            id: my_bucket.bucket_arn,
            domain_name: my_bucket.bucket_domain_name,
            s3_origin_config: {},
            origin_path: "/{{tenantName}}",
        },
    ],
    tenant_config: {
        parameter_definitions: [
            {
                definition: {
                    string_schema: {
                        required: false,
                        # the properties below are optional
                        comment: "tenantName",
                        default_value: "root",
                    },
                },
                name: "tenantName",
            },
        ],
    },
}

# Override the distribution configuration to enable multi-tenancy.
cfn_distribution.distribution_config = distribution_config

# Create a distribution tenant using an existing ACM certificate
cfn_distribution_tenant = AWSCDK::CloudFront::CfnDistributionTenant.new(self, "distribution-tenant", {
    distribution_id: my_multi_tenant_distribution.distribution_id,
    domains: ["my-tenant.my.domain.com"],
    name: "my-tenant",
    enabled: true,
    parameters: [
        {
            name: "tenantName",
            value: "app",
        },
    ],
    customizations: {
        certificate: {
            arn: "REPLACE_WITH_ARN",
        },
    },
})

Multi-tenant distribution and tenant with CloudFront-hosted certificate

A distribution tenant with CloudFront-hosted domain validation is useful if you don't currently have traffic to the domain.

Start by creating a parent multi-tenant distribution, then create the distribution tenant.

require 'aws-cdk-lib'


# Create the simple Origin
my_bucket = AWSCDK::S3::Bucket.new(self, "myBucket")
s3_origin = AWSCDK::CloudFrontOrigins::S3BucketOrigin.with_origin_access_control(my_bucket, {
    origin_access_levels: [AWSCDK::CloudFront::AccessLevel::READ, AWSCDK::CloudFront::AccessLevel::LIST],
})

# Create the Distribution construct
my_multi_tenant_distribution = AWSCDK::CloudFront::Distribution.new(self, "cf-hosted-distribution", {
    default_behavior: {
        origin: s3_origin,
    },
    default_root_object: "index.html",
})

# Access the underlying L1 CfnDistribution to configure SaaS Manager properties which are not yet available in the L2 Distribution construct
cfn_distribution = my_multi_tenant_distribution.node.default_child

default_cache_behavior = {
    target_origin_id: my_bucket.bucket_arn,
    viewer_protocol_policy: "allow-all",
    compress: false,
    allowed_methods: ["GET", "HEAD"],
    cache_policy_id: AWSCDK::CloudFront::CachePolicy.CACHING_OPTIMIZED.cache_policy_id,
}
# Create the updated distributionConfig
distribution_config = {
    default_cache_behavior: default_cache_behavior,
    enabled: true,
    # the properties below are optional
    connection_mode: "tenant-only",
    origins: [
        {
            id: my_bucket.bucket_arn,
            domain_name: my_bucket.bucket_domain_name,
            s3_origin_config: {},
            origin_path: "/{{tenantName}}",
        },
    ],
    tenant_config: {
        parameter_definitions: [
            {
                definition: {
                    string_schema: {
                        required: false,
                        # the properties below are optional
                        comment: "tenantName",
                        default_value: "root",
                    },
                },
                name: "tenantName",
            },
        ],
    },
}

# Override the distribution configuration to enable multi-tenancy.
cfn_distribution.distribution_config = distribution_config

# Create a connection group and a cname record in an existing hosted zone to validate domain ownership
connection_group = AWSCDK::CloudFront::CfnConnectionGroup.new(self, "cf-hosted-connection-group", {
    enabled: true,
    ipv6_enabled: true,
    name: "my-connection-group",
})

# Import the existing hosted zone info, replacing with your hostedZoneId and zoneName
hosted_zone_id = "YOUR_HOSTED_ZONE_ID"
zone_name = "my.domain.com"
hosted_zone = AWSCDK::Route53::HostedZone.from_hosted_zone_attributes(self, "hosted-zone", {
    hosted_zone_id: hosted_zone_id,
    zone_name: zone_name,
})

record = AWSCDK::Route53::CnameRecord.new(self, "cname-record", {
    domain_name: connection_group.attr_routing_endpoint,
    zone: hosted_zone,
    record_name: "cf-hosted-tenant.my.domain.com",
})

# Create the cloudfront-hosted tenant, passing in the previously created connection group
cloudfront_hosted_tenant = AWSCDK::CloudFront::CfnDistributionTenant.new(self, "cf-hosted-tenant", {
    distribution_id: my_multi_tenant_distribution.distribution_id,
    name: "cf-hosted-tenant",
    domains: ["cf-hosted-tenant.my.domain.com"],
    connection_group_id: connection_group.attr_id,
    enabled: true,
    managed_certificate_request: {
        validation_token_host: "cloudfront",
    },
})

Multi-tenant distribution and tenant with self-hosted certificate

A tenant with self-hosted domain validation is useful if you already have traffic to the domain and can't tolerate downtime during migration to multi-tenant architecture.

The tenant will be created, and the managed certificate will be awaiting validation of domain ownership. You can then validate domain ownership via http redirect or token file upload. More details here

Traffic won't be migrated until you update your hosted zone to point the tenant domain to the CloudFront RoutingEndpoint.

Start by creating a parent multi-tenant distribution

# Create the simple Origin
my_bucket = AWSCDK::S3::Bucket.new(self, "myBucket")
s3_origin = AWSCDK::CloudFrontOrigins::S3BucketOrigin.with_origin_access_control(my_bucket, {
    origin_access_levels: [AWSCDK::CloudFront::AccessLevel::READ, AWSCDK::CloudFront::AccessLevel::LIST],
})

# Create the Distribution construct
my_multi_tenant_distribution = AWSCDK::CloudFront::Distribution.new(self, "cf-hosted-distribution", {
    default_behavior: {
        origin: s3_origin,
    },
    default_root_object: "index.html",
})

# Access the underlying L1 CfnDistribution to configure SaaS Manager properties which are not yet available in the L2 Distribution construct
cfn_distribution = my_multi_tenant_distribution.node.default_child

default_cache_behavior = {
    target_origin_id: my_bucket.bucket_arn,
    viewer_protocol_policy: "allow-all",
    compress: false,
    allowed_methods: ["GET", "HEAD"],
    cache_policy_id: AWSCDK::CloudFront::CachePolicy.CACHING_OPTIMIZED.cache_policy_id,
}
# Create the updated distributionConfig
distribution_config = {
    default_cache_behavior: default_cache_behavior,
    enabled: true,
    # the properties below are optional
    connection_mode: "tenant-only",
    origins: [
        {
            id: my_bucket.bucket_arn,
            domain_name: my_bucket.bucket_domain_name,
            s3_origin_config: {},
            origin_path: "/{{tenantName}}",
        },
    ],
    tenant_config: {
        parameter_definitions: [
            {
                definition: {
                    string_schema: {
                        required: false,
                        # the properties below are optional
                        comment: "tenantName",
                        default_value: "root",
                    },
                },
                name: "tenantName",
            },
        ],
    },
}

# Override the distribution configuration to enable multi-tenancy.
cfn_distribution.distribution_config = distribution_config

# Create a connection group so we have access to the RoutingEndpoint associated with the tenant we are about to create
connection_group = AWSCDK::CloudFront::CfnConnectionGroup.new(self, "self-hosted-connection-group", {
    enabled: true,
    ipv6_enabled: true,
    name: "self-hosted-connection-group",
})

# Export the RoutingEndpoint, skip this step if you'd prefer to fetch it from the CloudFront console or via Cloudfront.ListConnectionGroups API
AWSCDK::CfnOutput.new(self, "RoutingEndpoint", {
    value: connection_group.attr_routing_endpoint,
    description: "CloudFront Routing Endpoint to be added to my hosted zone CNAME records",
})

# Create a distribution tenant with a self-hosted domain.
self_hosted_tenant = AWSCDK::CloudFront::CfnDistributionTenant.new(self, "self-hosted-tenant", {
    distribution_id: my_multi_tenant_distribution.distribution_id,
    connection_group_id: connection_group.attr_id,
    name: "self-hosted-tenant",
    domains: ["self-hosted-tenant.my.domain.com"],
    enabled: true,
    managed_certificate_request: {
        primary_domain_name: "self-hosted-tenant.my.domain.com",
        validation_token_host: "self-hosted",
    },
})

While CDK is deploying, it will attempt to validate domain ownership by confirming that a validation token is served directly from your domain, or via http redirect.

follow the steps here to complete domain setup before deploying this CDK stack, or while CDK is in the waiting state during tenant creation. Refer to the section "I have existing traffic"

A simple option for validating via http redirect, would be to add a rewrite rule like so to your server (Apache in this example)

RewriteEngine On
RewriteCond %{REQUEST_URI} ^/\.well-known/pki-validation/(.+)$ [NC]
RewriteRule ^(.*)$ https://validation.us-east-1.acm-validations.aws/%{ENV:AWS_ACCOUNT_ID}/.well-known/pki-validation/%1 [R=301,L]

Then, when you are ready to accept traffic, follow the steps here using the RoutingEndpoint from above to configure DNS to point to CloudFront.

VPC origins

You can use CloudFront to deliver content from applications that are hosted in your virtual private cloud (VPC) private subnets. You can use Application Load Balancers (ALBs), Network Load Balancers (NLBs), and EC2 instances in private subnets as VPC origins.

Learn more about Restrict access with VPC origins.

See the README of the aws-cdk-lib/aws-cloudfront-origins module for more information on setting up VPC origins.

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.

# To use your own domain name in a Distribution, you must associate a certificate
require 'aws-cdk-lib'

hosted_zone = nil # AWSCDK::Route53::HostedZone

my_bucket = nil # AWSCDK::S3::Bucket

my_certificate = AWSCDK::CertificateManager::Certificate.new(self, "mySiteCert", {
    domain_name: "www.example.com",
    validation: AWSCDK::CertificateManager::CertificateValidation.from_dns(hosted_zone),
})
AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: AWSCDK::CloudFrontOrigins::S3Origin.new(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 minimum_protocol_version property.

# Create a Distribution with a custom domain name and a minimum protocol version.
my_bucket = nil # AWSCDK::S3::Bucket

AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: AWSCDK::CloudFrontOrigins::S3Origin.new(my_bucket)},
    domain_names: ["www.example.com"],
    minimum_protocol_version: AWSCDK::CloudFront::SecurityPolicyProtocol::TLS_V1_2016,
    ssl_support_method: AWSCDK::CloudFront::SSLMethod::SNI,
})

Moving an alternate domain name to a different distribution

When you try to add an alternate domain name to a distribution but the alternate domain name is already in use on a different distribution, you get a CNAMEAlreadyExists error (One or more of the CNAMEs you provided are already associated with a different resource).

In that case, you might want to move the existing alternate domain name from one distribution (the source distribution) to another (the target distribution). The following steps are an overview of the process. For more information, see Moving an alternate domain name to a different distribution.

  1. Deploy the stack with the target distribution. The certificate property must be specified but the domain_names should be absent.
  2. Move the alternate domain name by running CloudFront associate-alias command. For the example and preconditions, see the AWS documentation above.
  3. Specify the domain_names property with the alternative domain name, then deploy the stack again to resolve the drift at the alternative domain name.

Cross Region Certificates

This feature is currently experimental

You can enable the Stack property cross_region_references in order to access resources in a different stack and region. With this feature flag enabled it is possible to do something like creating a CloudFront distribution in us-east-2 and an ACM certificate in us-east-1.

require 'aws-cdk-lib'

app = nil # AWSCDK::App


stack1 = AWSCDK::Stack.new(app, "Stack1", {
    env: {
        region: "us-east-1",
    },
    cross_region_references: true,
})
cert = AWSCDK::CertificateManager::Certificate.new(stack1, "Cert", {
    domain_name: "*.example.com",
    validation: AWSCDK::CertificateManager::CertificateValidation.from_dns(AWSCDK::Route53::PublicHostedZone.from_hosted_zone_id(stack1, "Zone", "Z0329774B51CGXTDQV3X")),
})

stack2 = AWSCDK::Stack.new(app, "Stack2", {
    env: {
        region: "us-east-2",
    },
    cross_region_references: true,
})
AWSCDK::CloudFront::Distribution.new(stack2, "Distribution", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("example.com"),
    },
    domain_names: ["dev.example.com"],
    certificate: cert,
})

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.

# Create a Distribution with configured HTTP methods and viewer protocol policy of the cache.
my_bucket = nil # AWSCDK::S3::Bucket

my_web_distribution = AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3Origin.new(my_bucket),
        allowed_methods: AWSCDK::CloudFront::AllowedMethods.ALLOW_ALL,
        viewer_protocol_policy: AWSCDK::CloudFront::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 my_web_distribution to override the default viewer protocol policy for all of the images.

# Add a behavior to a Distribution after initial creation.
my_bucket = nil # AWSCDK::S3::Bucket
my_web_distribution = nil # AWSCDK::CloudFront::Distribution

my_web_distribution.add_behavior("/images/*.jpg", AWSCDK::CloudFrontOrigins::S3Origin.new(my_bucket), {
    viewer_protocol_policy: AWSCDK::CloudFront::ViewerProtocolPolicy::REDIRECT_TO_HTTPS,
})

These behaviors can also be specified at distribution creation time.

# Create a Distribution with additional behaviors at creation time.
my_bucket = nil # AWSCDK::S3::Bucket

bucket_origin = AWSCDK::CloudFrontOrigins::S3Origin.new(my_bucket)
AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {
        origin: bucket_origin,
        allowed_methods: AWSCDK::CloudFront::AllowedMethods.ALLOW_ALL,
        viewer_protocol_policy: AWSCDK::CloudFront::ViewerProtocolPolicy::REDIRECT_TO_HTTPS,
    },
    additional_behaviors: {
        "/images/*.jpg" => {
            origin: bucket_origin,
            viewer_protocol_policy: AWSCDK::CloudFront::ViewerProtocolPolicy::REDIRECT_TO_HTTPS,
        },
    },
})

Attaching WAF Web Acls

You can attach the AWS WAF web ACL to a 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. The web ACL must be in the us-east-1 region.

To specify a web ACL created using AWS WAF Classic, use the ACL ID, for example 473e64fd-f30b-4765-81a0-62ad96dd167a.

bucket_origin = nil # AWSCDK::CloudFrontOrigins::S3Origin
web_acl = nil # AWSCDK::WAFv2::CfnWebACL

distribution = AWSCDK::CloudFront::Distribution.new(self, "Distribution", {
    default_behavior: {origin: bucket_origin},
    web_acl_id: web_acl.attr_arn,
})

You can also attach a web ACL to a distribution after creation.

bucket_origin = nil # AWSCDK::CloudFrontOrigins::S3Origin
web_acl = nil # AWSCDK::WAFv2::CfnWebACL

distribution = AWSCDK::CloudFront::Distribution.new(self, "Distribution", {
    default_behavior: {origin: bucket_origin},
})

distribution.attach_web_acl_id(web_acl.attr_arn)

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.

# Using an existing cache policy for a Distribution
bucket_origin = nil # AWSCDK::CloudFrontOrigins::S3Origin

AWSCDK::CloudFront::Distribution.new(self, "myDistManagedPolicy", {
    default_behavior: {
        origin: bucket_origin,
        cache_policy: AWSCDK::CloudFront::CachePolicy.CACHING_OPTIMIZED,
    },
})
# Creating a custom cache policy for a Distribution -- all parameters optional
bucket_origin = nil # AWSCDK::CloudFrontOrigins::S3Origin

my_cache_policy = AWSCDK::CloudFront::CachePolicy.new(self, "myCachePolicy", {
    cache_policy_name: "MyPolicy",
    comment: "A default policy",
    default_ttl: AWSCDK::Duration.days(2),
    min_ttl: AWSCDK::Duration.minutes(1),
    max_ttl: AWSCDK::Duration.days(10),
    cookie_behavior: AWSCDK::CloudFront::CacheCookieBehavior.all,
    header_behavior: AWSCDK::CloudFront::CacheHeaderBehavior.allow_list("X-CustomHeader"),
    query_string_behavior: AWSCDK::CloudFront::CacheQueryStringBehavior.deny_list("username"),
    enable_accept_encoding_gzip: true,
    enable_accept_encoding_brotli: true,
})
AWSCDK::CloudFront::Distribution.new(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.

# Using an existing origin request policy for a Distribution
bucket_origin = nil # AWSCDK::CloudFrontOrigins::S3Origin

AWSCDK::CloudFront::Distribution.new(self, "myDistManagedPolicy", {
    default_behavior: {
        origin: bucket_origin,
        origin_request_policy: AWSCDK::CloudFront::OriginRequestPolicy.CORS_S3_ORIGIN,
    },
})
# Creating a custom origin request policy for a Distribution -- all parameters optional
bucket_origin = nil # AWSCDK::CloudFrontOrigins::S3Origin

my_origin_request_policy = AWSCDK::CloudFront::OriginRequestPolicy.new(self, "OriginRequestPolicy", {
    origin_request_policy_name: "MyPolicy",
    comment: "A default policy",
    cookie_behavior: AWSCDK::CloudFront::OriginRequestCookieBehavior.none,
    header_behavior: AWSCDK::CloudFront::OriginRequestHeaderBehavior.all("CloudFront-Is-Android-Viewer"),
    query_string_behavior: AWSCDK::CloudFront::OriginRequestQueryStringBehavior.allow_list("username"),
})

AWSCDK::CloudFront::Distribution.new(self, "myDistCustomPolicy", {
    default_behavior: {
        origin: bucket_origin,
        origin_request_policy: my_origin_request_policy,
    },
})

Customizing Response Headers with Response Headers Policies

You can configure CloudFront to add one or more HTTP headers to the responses that it sends to viewers (web browsers or other clients), without making any changes to the origin or writing any code. To specify the headers that CloudFront adds to HTTP responses, you use a response headers policy. CloudFront adds the headers regardless of whether it serves the object from the cache or has to retrieve the object from the origin. If the origin response includes one or more of the headers that’s in a response headers policy, the policy can specify whether CloudFront uses the header it received from the origin or overwrites it with the one in the policy. See https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/adding-response-headers.html

[!NOTE] If xssProtection report_uri is specified, then mode_block cannot be set to true.

# Using an existing managed response headers policy
bucket_origin = nil # AWSCDK::CloudFrontOrigins::S3Origin

AWSCDK::CloudFront::Distribution.new(self, "myDistManagedPolicy", {
    default_behavior: {
        origin: bucket_origin,
        response_headers_policy: AWSCDK::CloudFront::ResponseHeadersPolicy.CORS_ALLOW_ALL_ORIGINS,
    },
})

# Creating a custom response headers policy -- all parameters optional
my_response_headers_policy = AWSCDK::CloudFront::ResponseHeadersPolicy.new(self, "ResponseHeadersPolicy", {
    response_headers_policy_name: "MyPolicy",
    comment: "A default policy",
    cors_behavior: {
        access_control_allow_credentials: false,
        access_control_allow_headers: ["X-Custom-Header-1", "X-Custom-Header-2"],
        access_control_allow_methods: ["GET", "POST"],
        access_control_allow_origins: ["*"],
        access_control_expose_headers: ["X-Custom-Header-1", "X-Custom-Header-2"],
        access_control_max_age: AWSCDK::Duration.seconds(600),
        origin_override: true,
    },
    custom_headers_behavior: {
        custom_headers: [
            {header: "X-Amz-Date", value: "some-value", override: true},
            {header: "X-Amz-Security-Token", value: "some-value", override: false},
        ],
    },
    security_headers_behavior: {
        content_security_policy: {content_security_policy: "default-src https:;", override: true},
        content_type_options: {override: true},
        frame_options: {frame_option: AWSCDK::CloudFront::HeadersFrameOption::DENY, override: true},
        referrer_policy: {referrer_policy: AWSCDK::CloudFront::HeadersReferrerPolicy::NO_REFERRER, override: true},
        strict_transport_security: {access_control_max_age: AWSCDK::Duration.seconds(600), include_subdomains: true, override: true},
        xss_protection: {protection: true, mode_block: false, report_uri: "https://example.com/csp-report", override: true},
    },
    remove_headers: ["Server"],
    server_timing_sampling_rate: 50,
})
AWSCDK::CloudFront::Distribution.new(self, "myDistCustomPolicy", {
    default_behavior: {
        origin: bucket_origin,
        response_headers_policy: my_response_headers_policy,
    },
})

Validating signed URLs or signed cookies with Trusted Key Groups

CloudFront Distribution 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.

# Validating signed URLs or signed cookies with Trusted Key Groups

# public key in PEM format
public_key = nil

pub_key = AWSCDK::CloudFront::PublicKey.new(self, "MyPubKey", {
    encoded_key: public_key,
})

key_group = AWSCDK::CloudFront::KeyGroup.new(self, "MyKeyGroup", {
    items: [
        pub_key,
    ],
})

AWSCDK::CloudFront::Distribution.new(self, "Dist", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("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:

my_bucket = nil # AWSCDK::S3::Bucket
# A Lambda@Edge function added to default behavior of a Distribution
# and triggered on every request
my_func = AWSCDK::CloudFront::Experimental::EdgeFunction.new(self, "MyFunction", {
    runtime: AWSCDK::Lambda::Runtime.NODEJS_LATEST,
    handler: "index.handler",
    code: AWSCDK::Lambda::Code.from_asset(path.join(__dirname, "lambda-handler")),
})
AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3Origin.new(my_bucket),
        edge_lambdas: [
            {
                function_version: my_func.current_version,
                event_type: AWSCDK::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.

# Using a lambda Function instead of an EdgeFunction for stacks in `us-east-`.
my_func = AWSCDK::Lambda::Function.new(self, "MyFunction", {
    runtime: AWSCDK::Lambda::Runtime.NODEJS_LATEST,
    handler: "index.handler",
    code: AWSCDK::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.

# Setting stackIds for EdgeFunctions that can be referenced from different applications
# on the same account.
my_func1 = AWSCDK::CloudFront::Experimental::EdgeFunction.new(self, "MyFunction1", {
    runtime: AWSCDK::Lambda::Runtime.NODEJS_LATEST,
    handler: "index.handler",
    code: AWSCDK::Lambda::Code.from_asset(path.join(__dirname, "lambda-handler1")),
    stack_id: "edge-lambda-stack-id-1",
})

my_func2 = AWSCDK::CloudFront::Experimental::EdgeFunction.new(self, "MyFunction2", {
    runtime: AWSCDK::Lambda::Runtime.NODEJS_LATEST,
    handler: "index.handler",
    code: AWSCDK::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.

# Associating a Lambda@Edge function with additional behaviors.

my_func = nil # AWSCDK::CloudFront::Experimental::EdgeFunction
# assigning at Distribution creation
my_bucket = nil # AWSCDK::S3::Bucket

my_origin = AWSCDK::CloudFrontOrigins::S3Origin.new(my_bucket)
my_distribution = AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: my_origin},
    additional_behaviors: {
        "images/*" => {
            origin: my_origin,
            edge_lambdas: [
                {
                    function_version: my_func.current_version,
                    event_type: AWSCDK::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: AWSCDK::CloudFront::LambdaEdgeEventType::VIEWER_RESPONSE,
        },
    ],
})

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

# Adding an existing Lambda@Edge function created in a different stack
# to a CloudFront distribution.
s3_bucket = nil # AWSCDK::S3::Bucket

function_version = AWSCDK::Lambda::Version.from_version_arn(self, "Version", "arn:aws:lambda:us-east-1:123456789012:function:functionName:1")

AWSCDK::CloudFront::Distribution.new(self, "distro", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3BucketOrigin.with_origin_access_control(s3_bucket),
        edge_lambdas: [
            {
                function_version: function_version,
                event_type: AWSCDK::CloudFront::LambdaEdgeEventType::VIEWER_REQUEST,
            },
        ],
    },
})

CloudFront Function

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

s3_bucket = nil # AWSCDK::S3::Bucket
# Add a cloudfront Function to a Distribution
cf_function = AWSCDK::CloudFront::Function.new(self, "Function", {
    code: AWSCDK::CloudFront::FunctionCode.from_inline("function handler(event) { return event.request }"),
    runtime: AWSCDK::CloudFront::FunctionRuntime.JS_2_0,
})
AWSCDK::CloudFront::Distribution.new(self, "distro", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3Origin.new(s3_bucket),
        function_associations: [
            {
                function: cf_function,
                event_type: AWSCDK::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.

If you set auto_publish to false, the function will not be automatically published to the LIVE stage when it’s created.

AWSCDK::CloudFront::Function.new(self, "Function", {
    code: AWSCDK::CloudFront::FunctionCode.from_inline("function handler(event) { return event.request }"),
    runtime: AWSCDK::CloudFront::FunctionRuntime.JS_2_0,
    auto_publish: false,
})

Runtime Version

CloudFront Functions support two runtime versions: cloudfront-js-1.0 and cloudfront-js-2.0. By default, new projects use cloudfront-js-2.0, which is the recommended runtime version with enhanced functionality.

You can explicitly specify the runtime version:

# Use v2.0 explicitly (same as default for new projects)
AWSCDK::CloudFront::Function.new(self, "Function", {
    code: AWSCDK::CloudFront::FunctionCode.from_inline("function handler(event) { return event.request }"),
    runtime: AWSCDK::CloudFront::FunctionRuntime.JS_2_0,
})

# Use v1.0 for legacy compatibility
AWSCDK::CloudFront::Function.new(self, "Function", {
    code: AWSCDK::CloudFront::FunctionCode.from_inline("function handler(event) { return event.request }"),
    runtime: AWSCDK::CloudFront::FunctionRuntime.JS_1_0,
})

Note: Functions associated with a Key Value Store always use cloudfront-js-2.0, as Key Value Store support requires the v2.0 runtime.

When the @aws-cdk/aws-cloudfront:defaultFunctionRuntimeV2_0 feature flag is disabled, the runtime defaults to cloudfront-js-1.0 for backward compatibility.

Key Value Store

A CloudFront Key Value Store can be created and optionally have data imported from a JSON file by default.

To create an empty Key Value Store:

store = AWSCDK::CloudFront::KeyValueStore.new(self, "KeyValueStore")

To also include an initial set of values, the source property can be specified, either from a local file or an inline string. For the structure of this file, see Creating a file of key value pairs.

store_asset = AWSCDK::CloudFront::KeyValueStore.new(self, "KeyValueStoreAsset", {
    key_value_store_name: "KeyValueStoreAsset",
    source: AWSCDK::CloudFront::ImportSource.from_asset("path-to-data.json"),
})

store_inline = AWSCDK::CloudFront::KeyValueStore.new(self, "KeyValueStoreInline", {
    key_value_store_name: "KeyValueStoreInline",
    source: AWSCDK::CloudFront::ImportSource.from_inline(JSON[:stringify]({
        data: [
            {
                key: "key1",
                value: "value1",
            },
            {
                key: "key2",
                value: "value2",
            },
        ],
    })),
})

The Key Value Store can then be associated to a function using the cloudfront-js-2.0 runtime or newer:

store = AWSCDK::CloudFront::KeyValueStore.new(self, "KeyValueStore")
AWSCDK::CloudFront::Function.new(self, "Function", {
    code: AWSCDK::CloudFront::FunctionCode.from_inline("function handler(event) { return event.request }"),
    # Note that JS_2_0 must be used for Key Value Store support
    runtime: AWSCDK::CloudFront::FunctionRuntime.JS_2_0,
    key_value_store: store,
})

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.

# Configure logging for Distributions

# Simplest form - creates a new bucket and logs to it.
AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("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.
AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("www.example.com")},
    enable_logging: true,
     # Optional, this is implied if logBucket is specified
    log_bucket: AWSCDK::S3::Bucket.new(self, "LogBucket", {
        object_ownership: AWSCDK::S3::ObjectOwnership::OBJECT_WRITER,
    }),
    log_file_prefix: "distribution-access-logs/",
    log_includes_cookies: true,
})

CloudFront Distribution Metrics

You can view operational metrics about your CloudFront distributions.

Default CloudFront Distribution Metrics

The following metrics are available by default for all CloudFront distributions:

dist = AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("www.example.com")},
})

# Retrieving default distribution metrics
requests_metric = dist.metric_requests
bytes_uploaded_metric = dist.metric_bytes_uploaded
bytes_downloaded_metric = dist.metric_bytes_downloaded
total_error_rate_metric = dist.metric_total_error_rate
http4xx_error_rate_metric = dist.metric4xx_error_rate
http5xx_error_rate_metric = dist.metric5xx_error_rate

Additional CloudFront Distribution Metrics

You can enable additional CloudFront distribution metrics, which include the following metrics:

dist = AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("www.example.com")},
    publish_additional_metrics: true,
})

# Retrieving additional distribution metrics
latency_metric = dist.metric_origin_latency
cache_hit_rate_metric = dist.metric_cache_hit_rate
http401_error_rate_metric = dist.metric401_error_rate
http403_error_rate_metric = dist.metric403_error_rate
http404_error_rate_metric = dist.metric404_error_rate
http502_error_rate_metric = dist.metric502_error_rate
http503_error_rate_metric = dist.metric503_error_rate
http504_error_rate_metric = dist.metric504_error_rate

HTTP Versions

You can configure CloudFront to use a particular version of the HTTP protocol. By default, newly created distributions use HTTP/2 but can be configured to use both HTTP/2 and HTTP/3 or just HTTP/3. For all supported HTTP versions, see the HttpVerson enum.

# Configure a distribution to use HTTP/2 and HTTP/3
AWSCDK::CloudFront::Distribution.new(self, "myDist", {
    default_behavior: {origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("www.example.com")},
    http_version: AWSCDK::CloudFront::HttpVersion::HTTP2_AND_3,
})

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.

# Using a reference to an imported Distribution
distribution = AWSCDK::CloudFront::Distribution.from_distribution_attributes(self, "ImportedDist", {
    domain_name: "d111111abcdef8.cloudfront.net",
    distribution_id: "012345ABCDEF",
})

Permissions

Use the grant() method to allow actions on the distribution. grant_create_invalidation() is a shorthand to allow CreateInvalidation.

distribution = nil # AWSCDK::CloudFront::Distribution
lambda_fn = nil # AWSCDK::Lambda::Function

distribution.grant(lambda_fn, "cloudfront:ListInvalidations", "cloudfront:GetInvalidation")
distribution.grant_create_invalidation(lambda_fn)

Realtime Log Config

CloudFront supports realtime log delivery from your distribution to a Kinesis stream.

See Real-time logs in the CloudFront User Guide.

Example:

# Adding realtime logs config to a Cloudfront Distribution on default behavior.
require 'aws-cdk-lib'

stream = nil # AWSCDK::Kinesis::Stream


real_time_config = AWSCDK::CloudFront::RealtimeLogConfig.new(self, "realtimeLog", {
    end_points: [
        AWSCDK::CloudFront::Endpoint.from_kinesis_stream(stream),
    ],
    fields: [
        "timestamp",
        "c-ip",
        "time-to-first-byte",
        "sc-status",
    ],
    realtime_log_config_name: "my-delivery-stream",
    sampling_rate: 100,
})

AWSCDK::CloudFront::Distribution.new(self, "myCdn", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("www.example.com"),
        realtime_log_config: real_time_config,
    },
})

gRPC

CloudFront supports gRPC, an open-source remote procedure call (RPC) framework built on HTTP/2. gRPC offers bi-directional streaming and binary protocol that buffers payloads, making it suitable for applications that require low latency communications.

To enable your distribution to handle gRPC requests, you must include HTTP/2 as one of the supported HTTP versions and allow HTTP methods, including POST.

See Using gRPC with CloudFront distributions in the CloudFront User Guide.

Example:

AWSCDK::CloudFront::Distribution.new(self, "myCdn", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("www.example.com"),
        allowed_methods: AWSCDK::CloudFront::AllowedMethods.ALLOW_ALL,
         # `AllowedMethods.ALLOW_ALL` is required if `enableGrpc` is true
        enable_grpc: true,
    },
})

Migrating from the original CloudFrontWebDistribution to the newer Distribution construct

It's possible to migrate a distribution from the original to the modern API. The changes necessary are the following:

The Distribution

Replace new CloudFrontWebDistribution with new Distribution. Some configuration properties have been changed:

Old API New API
origin_configs default_behavior; use additional_behaviors if necessary
viewer_certificate certificate; use domain_names for aliases
error_configurations error_responses
logging_config enable_logging; configure with log_bucket log_file_prefix and log_includes_cookies
viewer_protocol_policy removed; set on each behavior instead. default changed from REDIRECT_TO_HTTPS to ALLOW_ALL

After switching constructs, you need to maintain the same logical ID for the underlying CfnDistribution if you wish to avoid the deletion and recreation of your distribution. To do this, use escape hatches to override the logical ID created by the new Distribution construct with the logical ID created by the old construct.

Example:

source_bucket = nil # AWSCDK::S3::Bucket


my_distribution = AWSCDK::CloudFront::Distribution.new(self, "MyCfWebDistribution", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3Origin.new(source_bucket),
    },
})
cfn_distribution = my_distribution.node.default_child
cfn_distribution.override_logical_id("MyDistributionCFDistribution3H55TI9Q")

Behaviors

The modern API makes use of the CloudFront Origins module to easily configure your origin. Replace your origin configuration with the relevant CloudFront Origins class. For example, here's a behavior with an S3 origin:

source_bucket = nil # AWSCDK::S3::Bucket
oai = nil # AWSCDK::CloudFront::OriginAccessIdentity


AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "MyCfWebDistribution", {
    origin_configs: [
        {
            s3_origin_source: {
                s3_bucket_source: source_bucket,
                origin_access_identity: oai,
            },
            behaviors: [{is_default_behavior: true}],
        },
    ],
})

Becomes:

source_bucket = nil # AWSCDK::S3::Bucket


distribution = AWSCDK::CloudFront::Distribution.new(self, "MyCfWebDistribution", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3Origin.new(source_bucket),
    },
})

In the original API all behaviors are defined in the origin_configs property. The new API is optimized for a single origin and behavior, so the default behavior and additional behaviors will be defined separately.

source_bucket = nil # AWSCDK::S3::Bucket
oai = nil # AWSCDK::CloudFront::OriginAccessIdentity


AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "MyCfWebDistribution", {
    origin_configs: [
        {
            s3_origin_source: {
                s3_bucket_source: source_bucket,
                origin_access_identity: oai,
            },
            behaviors: [{is_default_behavior: true}],
        },
        {
            custom_origin_source: {
                domain_name: "MYALIAS",
            },
            behaviors: [{path_pattern: "/somewhere"}],
        },
    ],
})

Becomes:

source_bucket = nil # AWSCDK::S3::Bucket


distribution = AWSCDK::CloudFront::Distribution.new(self, "MyCfWebDistribution", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3Origin.new(source_bucket),
    },
    additional_behaviors: {
        "/somewhere" => {
            origin: AWSCDK::CloudFrontOrigins::HttpOrigin.new("MYALIAS"),
        },
    },
})

Certificates

If you are using an ACM certificate, you can pass the certificate directly to the certificate prop. Any aliases used before in the ViewerCertificate class should be passed in to the domain_names prop in the modern API.

require 'aws-cdk-lib'
certificate = nil # AWSCDK::CertificateManager::Certificate
source_bucket = nil # AWSCDK::S3::Bucket


viewer_certificate = AWSCDK::CloudFront::ViewerCertificate.from_acm_certificate(certificate, {
    aliases: ["MYALIAS"],
})

AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "MyCfWebDistribution", {
    origin_configs: [
        {
            s3_origin_source: {
                s3_bucket_source: source_bucket,
            },
            behaviors: [{is_default_behavior: true}],
        },
    ],
    viewer_certificate: viewer_certificate,
})

Becomes:

require 'aws-cdk-lib'
certificate = nil # AWSCDK::CertificateManager::Certificate
source_bucket = nil # AWSCDK::S3::Bucket


distribution = AWSCDK::CloudFront::Distribution.new(self, "MyCfWebDistribution", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3Origin.new(source_bucket),
    },
    domain_names: ["MYALIAS"],
    certificate: certificate,
})

IAM certificates aren't directly supported by the new API, but can be easily configured through escape hatches

source_bucket = nil # AWSCDK::S3::Bucket

viewer_certificate = AWSCDK::CloudFront::ViewerCertificate.from_iam_certificate("MYIAMROLEIDENTIFIER", {
    aliases: ["MYALIAS"],
})

AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "MyCfWebDistribution", {
    origin_configs: [
        {
            s3_origin_source: {
                s3_bucket_source: source_bucket,
            },
            behaviors: [{is_default_behavior: true}],
        },
    ],
    viewer_certificate: viewer_certificate,
})

Becomes:

source_bucket = nil # AWSCDK::S3::Bucket

distribution = AWSCDK::CloudFront::Distribution.new(self, "MyCfWebDistribution", {
    default_behavior: {
        origin: AWSCDK::CloudFrontOrigins::S3Origin.new(source_bucket),
    },
    domain_names: ["MYALIAS"],
})

cfn_distribution = distribution.node.default_child

cfn_distribution.add_property_override("ViewerCertificate.IamCertificateId", "MYIAMROLEIDENTIFIER")
cfn_distribution.add_property_override("ViewerCertificate.SslSupportMethod", "sni-only")

Other changes

A number of default settings have changed on the new API when creating a new distribution, behavior, and origin. After making the major changes needed for the migration, run cdk diff to see what settings have changed. If no changes are desired during migration, you will at the least be able to use escape hatches to override what the CDK synthesizes, if you can't change the properties directly.

CloudFrontWebDistribution API

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

Example usage:

# Using a CloudFrontWebDistribution construct.

source_bucket = nil # AWSCDK::S3::Bucket

distribution = AWSCDK::CloudFront::CloudFrontWebDistribution.new(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 domain_name (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 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:

s3_bucket_source = AWSCDK::S3::Bucket.new(self, "Bucket")

distribution = AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "AnAmazingWebsiteProbably", {
    origin_configs: [
        {
            s3_origin_source: {s3_bucket_source: s3_bucket_source},
            behaviors: [{is_default_behavior: true}],
        },
    ],
    viewer_certificate: AWSCDK::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 or Importing Certificates into AWS Certificate Manager in the AWS Certificate Manager User Guide.

Example:

s3_bucket_source = AWSCDK::S3::Bucket.new(self, "Bucket")

certificate = AWSCDK::CertificateManager::Certificate.new(self, "Certificate", {
    domain_name: "example.com",
    subject_alternative_names: ["*.example.com"],
})

distribution = AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "AnAmazingWebsiteProbably", {
    origin_configs: [
        {
            s3_origin_source: {s3_bucket_source: s3_bucket_source},
            behaviors: [{is_default_behavior: true}],
        },
    ],
    viewer_certificate: AWSCDK::CloudFront::ViewerCertificate.from_acm_certificate(certificate, {
        aliases: ["example.com", "www.example.com"],
        security_policy: AWSCDK::CloudFront::SecurityPolicyProtocol::TLS_V1,
         # default
        ssl_method: AWSCDK::CloudFront::SSLMethod::SNI,
    }),
})

IAM certificate

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

See Importing an SSL/TLS Certificate in the CloudFront User Guide.

Example:

s3_bucket_source = AWSCDK::S3::Bucket.new(self, "Bucket")

distribution = AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "AnAmazingWebsiteProbably", {
    origin_configs: [
        {
            s3_origin_source: {s3_bucket_source: s3_bucket_source},
            behaviors: [{is_default_behavior: true}],
        },
    ],
    viewer_certificate: AWSCDK::CloudFront::ViewerCertificate.from_iam_certificate("certificateId", {
        aliases: ["example.com"],
        security_policy: AWSCDK::CloudFront::SecurityPolicyProtocol::SSL_V3,
         # default
        ssl_method: AWSCDK::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:

# Using trusted key groups for Cloudfront Web Distributions.
source_bucket = nil # AWSCDK::S3::Bucket
public_key = nil

pub_key = AWSCDK::CloudFront::PublicKey.new(self, "MyPubKey", {
    encoded_key: public_key,
})

key_group = AWSCDK::CloudFront::KeyGroup.new(self, "MyKeyGroup", {
    items: [
        pub_key,
    ],
})

AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "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 in the CloudFront User Guide.

Example:

# Adding restrictions to a Cloudfront Web Distribution.
source_bucket = nil # AWSCDK::S3::Bucket

AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "MyDistribution", {
    origin_configs: [
        {
            s3_origin_source: {
                s3_bucket_source: source_bucket,
            },
            behaviors: [{is_default_behavior: true}],
        },
    ],
    geo_restriction: AWSCDK::CloudFront::GeoRestriction.allowlist("US", "GB"),
})

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

See Origin Connection Timeout

Example usage:

# Configuring connection behaviors between Cloudfront and your origin
distribution = AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "MyDistribution", {
    origin_configs: [
        {
            connection_attempts: 3,
            connection_timeout: AWSCDK::Duration.seconds(10),
            behaviors: [
                {
                    is_default_behavior: true,
                },
            ],
        },
    ],
})

Origin Fallback

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

# Configuring origin fallback options for the CloudFrontWebDistribution
AWSCDK::CloudFront::CloudFrontWebDistribution.new(self, "ADistribution", {
    origin_configs: [
        {
            s3_origin_source: {
                s3_bucket_source: AWSCDK::S3::Bucket.from_bucket_name(self, "aBucket", "amzn-s3-demo-bucket"),
                origin_path: "/",
                origin_headers: {
                    "myHeader" => "42",
                },
                origin_shield_region: "us-west-2",
            },
            failover_s3_origin_source: {
                s3_bucket_source: AWSCDK::S3::Bucket.from_bucket_name(self, "aBucketFallback", "amzn-s3-demo-bucket1"),
                origin_path: "/somewhere",
                origin_headers: {
                    "myHeader2" => "21",
                },
                origin_shield_region: "us-east-1",
            },
            failover_criteria_status_codes: [AWSCDK::CloudFront::FailoverStatusCode::INTERNAL_SERVER_ERROR],
            behaviors: [
                {
                    is_default_behavior: true,
                },
            ],
        },
    ],
})

KeyGroup & PublicKey API

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.

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.

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 encoded_key parameter when creating a PublicKey.

Example:

# Create a key group to use with CloudFront signed URLs and signed cookies.
AWSCDK::CloudFront::KeyGroup.new(self, "MyKeyGroup", {
    items: [
        AWSCDK::CloudFront::PublicKey.new(self, "MyPublicKey", {
            encoded_key: "...",
        }),
    ],
})

When using a CloudFront PublicKey, only the comment field can be updated after creation. Fields such as encoded_key and public_key_name are immutable, as outlined in the API Reference. Attempting to modify these fields will result in an error:

Resource handler returned message: "Invalid request provided: AWS::CloudFront::PublicKey"

To update the encoded_key, you must change the ID of the public key resource in your template. This causes CloudFormation to create a new cloudfront.PublicKey resource and delete the old one during the next deployment.

Example:

# Step 1: Original deployment
original_key = AWSCDK::CloudFront::PublicKey.new(self, "MyPublicKeyV1", {
    encoded_key: "...",
})

Regenerate a new key and change the construct id in the code:

# Step 2: In a subsequent deployment, create a new key with a different ID
updated_key = AWSCDK::CloudFront::PublicKey.new(self, "MyPublicKeyV2", {
    encoded_key: "...",
})

See:

API Reference

Namespaces 1

Experimental

Classes 56

AllowedMethodsThe HTTP methods that the Behavior will accept requests on. AssetImportSourceAn import source from a local file. CacheCookieBehaviorDetermines whether any cookies in viewer requests are included in the cache key and automa CachedMethodsThe HTTP methods that the Behavior will cache requests on. CacheHeaderBehaviorDetermines whether any HTTP headers are included in the cache key and automatically includ CachePolicyA Cache Policy configuration. CacheQueryStringBehaviorDetermines whether any URL query strings in viewer requests are included in the cache key CfnAnycastIPListAn Anycast static IP list. CfnCachePolicyA cache policy. CfnCloudFrontOriginAccessIdentityThe request to create a new origin access identity (OAI). CfnConnectionFunctionA connection function. CfnConnectionGroupThe connection group for your distribution tenants. CfnContinuousDeploymentPolicyCreates a continuous deployment policy that routes a subset of production traffic from a p CfnDistributionA distribution tells CloudFront where you want content to be delivered from, and the detai CfnDistributionTenantThe distribution tenant. CfnFunctionCreates a CloudFront function. CfnKeyGroupA key group. CfnKeyValueStoreThe key value store. CfnMonitoringSubscriptionA monitoring subscription. CfnOriginAccessControlCreates a new origin access control in CloudFront. CfnOriginRequestPolicyAn origin request policy. CfnPublicKeyA public key that you can use with [signed URLs and signed cookies](https://docs.aws.amazo CfnRealtimeLogConfigA real-time log configuration. CfnResponseHeadersPolicyA response headers policy. CfnStreamingDistributionThis resource is deprecated. CfnTrustStoreA trust store. CfnVPCOriginAn Amazon CloudFront VPC origin. CloudFrontWebDistributionAmazon CloudFront is a global content delivery network (CDN) service that securely deliver DistributionA CloudFront distribution with associated origin(s) and caching behavior(s). DistributionGrantsCollection of grant methods for a IDistributionRef. EndpointRepresents the endpoints available for targetting within a realtime log config resource. FunctionA CloudFront Function. FunctionCodeRepresents the function's source code. FunctionRuntimeThe function's runtime environment version. FunctionURLOriginAccessControlAn Origin Access Control for Lambda Function URLs. GeoRestrictionControls the countries in which content is distributed. ImportSourceThe data to be imported to the key value store. InlineImportSourceAn import source from an inline string. KeyGroupA Key Group configuration. KeyValueStoreA CloudFront Key Value Store. MediaPackageV2OriginAccessControlAn Origin Access Control for AWS Elemental MediaPackage V2 origins. OriginAccessIdentityAn origin access identity is a special CloudFront user that you can associate with Amazon OriginBaseRepresents a distribution origin, that describes the Amazon S3 bucket, HTTP server (for ex OriginRequestCookieBehaviorDetermines whether any cookies in viewer requests (and if so, which cookies) are included OriginRequestHeaderBehaviorDetermines whether any HTTP headers (and if so, which headers) are included in requests th OriginRequestPolicyA Origin Request Policy configuration. OriginRequestQueryStringBehaviorDetermines whether any URL query strings in viewer requests (and if so, which query string PublicKeyA Public Key Configuration. RealtimeLogConfigA Realtime Log Config configuration. ResponseHeadersPolicyA Response Headers Policy configuration. S3ImportSourceAn import source from an S3 object. S3OriginAccessControlAn Origin Access Control for Amazon S3 origins. SigningOptions for how CloudFront signs requests. ViewerCertificateViewer certificate configuration class. VPCOriginA CloudFront VPC Origin configuration. VPCOriginEndpointRepresents the VPC origin endpoint.

Interfaces 82

AddBehaviorOptionsOptions for adding a new behavior to a Distribution. BehaviorA CloudFront behavior wrapper. BehaviorOptionsOptions for creating a new behavior. CachePolicyPropsProperties for creating a Cache Policy. CfnAnycastIPListPropsProperties for defining a `CfnAnycastIpList`. CfnCachePolicyPropsProperties for defining a `CfnCachePolicy`. CfnCloudFrontOriginAccessIdentityPropsProperties for defining a `CfnCloudFrontOriginAccessIdentity`. CfnConnectionFunctionPropsProperties for defining a `CfnConnectionFunction`. CfnConnectionGroupPropsProperties for defining a `CfnConnectionGroup`. CfnContinuousDeploymentPolicyPropsProperties for defining a `CfnContinuousDeploymentPolicy`. CfnDistributionPropsProperties for defining a `CfnDistribution`. CfnDistributionTenantPropsProperties for defining a `CfnDistributionTenant`. CfnFunctionPropsProperties for defining a `CfnFunction`. CfnKeyGroupPropsProperties for defining a `CfnKeyGroup`. CfnKeyValueStorePropsProperties for defining a `CfnKeyValueStore`. CfnMonitoringSubscriptionPropsProperties for defining a `CfnMonitoringSubscription`. CfnOriginAccessControlPropsProperties for defining a `CfnOriginAccessControl`. CfnOriginRequestPolicyPropsProperties for defining a `CfnOriginRequestPolicy`. CfnPublicKeyPropsProperties for defining a `CfnPublicKey`. CfnRealtimeLogConfigPropsProperties for defining a `CfnRealtimeLogConfig`. CfnResponseHeadersPolicyPropsProperties for defining a `CfnResponseHeadersPolicy`. CfnStreamingDistributionPropsProperties for defining a `CfnStreamingDistribution`. CfnTrustStorePropsProperties for defining a `CfnTrustStore`. CfnVPCOriginPropsProperties for defining a `CfnVpcOrigin`. CloudFrontWebDistributionAttributesAttributes used to import a Distribution. CloudFrontWebDistributionProps CustomOriginConfigA custom origin configuration. DistributionAttributesAttributes used to import a Distribution. DistributionPropsProperties for a Distribution. EdgeLambdaRepresents a Lambda function version and event type when using Lambda@Edge. ErrorResponseOptions for configuring custom error responses. FileCodeOptionsOptions when reading the function's code from an external file. FunctionAssociationRepresents a CloudFront function and event type when using CF Functions. FunctionAttributesAttributes of an existing CloudFront Function to import it. FunctionPropsProperties for creating a CloudFront Function. FunctionURLOriginAccessControlPropsProperties for creating a Lambda Function URL Origin Access Control resource. ICachePolicyRepresents a Cache Policy. IDistributionInterface for CloudFront distributions. IFunctionRepresents a CloudFront Function. IKeyGroupRepresents a Key Group. IKeyValueStoreA CloudFront Key Value Store. IOriginRepresents the concept of a CloudFront Origin. IOriginAccessControlRepresents a CloudFront Origin Access Control. IOriginAccessIdentityInterface for CloudFront OriginAccessIdentity. IOriginRequestPolicyRepresents a Origin Request Policy. IPublicKeyRepresents a Public Key. IRealtimeLogConfigRepresents Realtime Log Configuration. IResponseHeadersPolicyRepresents a response headers policy. IVPCOriginRepresents a VPC origin. KeyGroupPropsProperties for creating a Public Key. KeyValueStorePropsThe properties to create a Key Value Store. LambdaFunctionAssociation LoggingConfigurationLogging configuration for incoming requests. MediaPackageV2OriginAccessControlPropsProperties for creating a MediaPackage V2 Origin Access Control resource. OriginAccessControlBasePropsCommon properties for creating a Origin Access Control resource. OriginAccessIdentityPropsProperties of CloudFront OriginAccessIdentity. OriginBindConfigThe struct returned from `IOrigin.bind`. OriginBindOptionsOptions passed to Origin.bind(). OriginFailoverConfigThe failover configuration used for Origin Groups, returned in `OriginBindConfig.failoverC OriginOptionsOptions to define an Origin. OriginPropsProperties to define an Origin. OriginRequestPolicyPropsProperties for creating a Origin Request Policy. PublicKeyPropsProperties for creating a Public Key. RealtimeLogConfigPropsProperties for defining a RealtimeLogConfig resource. ResponseCustomHeaderAn HTTP response header name and its value. ResponseCustomHeadersBehaviorConfiguration for a set of HTTP response headers that are sent for requests that match a c ResponseHeadersContentSecurityPolicyThe policy directives and their values that CloudFront includes as values for the Content- ResponseHeadersContentTypeOptionsDetermines whether CloudFront includes the X-Content-Type-Options HTTP response header wit ResponseHeadersCorsBehaviorConfiguration for a set of HTTP response headers that are used for cross-origin resource s ResponseHeadersFrameOptionsDetermines whether CloudFront includes the X-Frame-Options HTTP response header and the he ResponseHeadersPolicyPropsProperties for creating a Response Headers Policy. ResponseHeadersReferrerPolicyDetermines whether CloudFront includes the Referrer-Policy HTTP response header and the he ResponseHeadersStrictTransportSecurityDetermines whether CloudFront includes the Strict-Transport-Security HTTP response header ResponseHeadersXSSProtectionDetermines whether CloudFront includes the X-XSS-Protection HTTP response header and the h ResponseSecurityHeadersBehaviorConfiguration for a set of security-related HTTP response headers. S3OriginAccessControlPropsProperties for creating a S3 Origin Access Control resource. S3OriginConfigS3 origin configuration for CloudFront. SourceConfigurationA source configuration is a wrapper for CloudFront origins and behaviors. ViewerCertificateOptions VPCOriginAttributesThe properties to import from the VPC origin. VPCOriginOptionsVPC origin endpoint configuration. VPCOriginPropsVPC origin endpoint configuration.

Enums 20

AccessLevelThe level of permissions granted to the CloudFront Distribution when configuring OAC. CloudFrontAllowedCachedMethodsEnums for the methods CloudFront can cache. CloudFrontAllowedMethodsAn enum for the supported methods to a CloudFront distribution. FailoverStatusCodeHTTP status code to failover to second origin. FunctionEventTypeThe type of events that a CloudFront function can be invoked in response to. HeadersFrameOptionEnum representing possible values of the X-Frame-Options HTTP response header. HeadersReferrerPolicyEnum representing possible values of the Referrer-Policy HTTP response header. HttpVersionMaximum HTTP version to support. LambdaEdgeEventTypeThe type of events that a Lambda@Edge function can be invoked in response to. OriginAccessControlOriginTypeOrigin types supported by Origin Access Control. OriginIPAddressTypeThe IP address type for the origin. OriginProtocolPolicyDefines what protocols CloudFront will use to connect to an origin. OriginSelectionCriteriaThe selection criteria for the origin group. OriginSSLPolicy PriceClassThe price class determines how many edge locations CloudFront will use for your distributi SecurityPolicyProtocolThe minimum version of the SSL protocol that you want CloudFront to use for HTTPS connecti SigningBehaviorOptions for which requests CloudFront signs. SigningProtocolThe signing protocol of the Origin Access Control. SSLMethodThe SSL method CloudFront will use for your distribution. ViewerProtocolPolicyHow HTTPs should be handled with your distribution.