Networking & Content Delivery

Programmatically deploying CloudFront distributions in AWS China Regions

To operate websites, mobile apps, or services accessible to public users in China, companies should complete internet content provider (ICP) recordal and host systems on local servers or approved cloud servers located in mainland China. Amazon Web Services (AWS) offers AWS China Regions, two Regions situated in China that allow customers to host websites and applications that serve the Chinese market and align with compliance regulations.

While the AWS China Regions provide the same foundational services as Amazon CloudFront and Amazon Simple Storage Service (Amazon S3), there are some key differences compared to global AWS Regions that may cause automated deployments to fail. In this post, we introduce how to programmatically deploy a CloudFront distribution in the AWS China (Beijing) Region using AWS Cloud Development Kit (AWS CDK) while accounting for the nuances of this Region. Following these steps can help website operators optimize their automation code and avoid common errors unique to CloudFront China.

Requirements for delivering content from within China

You can’t use the default CloudFront domain, *.cloudfront.cn, to serve content. You must add an alternate domain name, also known as a CNAME or alias, to your CloudFront distributions in AWS China Regions and then use that domain name in the URLs for your content.

In addition, before creating a CloudFront distribution in AWS China Regions, you must first obtain an ICP recordal for your root domain, such as example.com.cn, from the Chinese authority. The ICP recordal must be applied for by an entity located in mainland China. Moreover, the root domain must be registered through a qualified Chinese domain name registrar and must resolve to an IP address that is hosted within mainland China. Consult the AWS China ICP recordal support documentation for more details on obtaining the required ICP recordal for your domain before proceeding.

The feature differences between AWS China Regions and global AWS Regions are documented in Getting Started with Amazon Web Services in China. We recommend readers avoid configuration failures by not enabling features in CloudFront China that are unavailable, such as AWS WAF web ACL protection, Lambda@Edge and CloudFront Functions associations, or Origin Shield.

Prerequisites

To implement this solution, you must complete these prerequisites.

Upload your SSL certificates to IAM rather than ACM

CloudFront China currently does not support AWS Certificate Manager (ACM) for managing SSL/TLS certificates. Instead, you need to obtain an SSL/TLS certificate from a third-party certificate authority (CA) and upload it to the AWS Identity and Access Management (IAM) certificate store in your account for AWS China Regions. See Managing server certificates in IAM in the AWS Identity and Access Management User Guide for more details.

When your CloudFront distribution is configured, specify the ID of the IAM certificate you uploaded. Be aware that you will need to manually renew the SSL/TLS certificate before it expires. Here is a solution, China CloudFront SSL Plugin, that can help you generate, update, and download free SSL/TLS certificates from a third-party CA. It also supports integration with IAM and CloudFront and automatically renews associated SSL/TLS certificates. With this solution, you don’t need to monitor certificate expiration dates or plan the renewal process in advance, avoiding any lapses in HTTPS availability.

Solution overview

In this section, we aim to explain the unique considerations for programmatically deploying CloudFront distributions in AWS China Regions using AWS CDK and outline common errors through a sample solution.

What the solution will do:

  • Create an Amazon Simple Storage Service (Amazon S3) bucket in AWS China (Beijing) Region.
  • Create an origin access identity (OAI) and grant the S3 bucket access to CloudFront with the OAI.
  • Create a CloudFront distribution with a default cache behavior pointing to the Amazon S3 origin and an IAM server certificate association (we assume that you already have the server certificate ID).

The following diagram shows the architecture of this sample solution.

Architecture of the sample solution

Figure 1: Architecture of the sample solution.

You can find the complete sample code based on AWS CDK in the GitHub repository. We provide AWS CDK code in Python and TypeScript, with the code for each language placed in separate Python/ and TypeScript/ directories.

The following sections walk you through the unique considerations for programmatic deployment of CloudFront in AWS China Regions.

Grant S3 bucket access to CloudFront using OAI rather than origin access control (OAC)

OAC is not available in AWS China Regions. Therefore, you need to grant the S3 bucket access using OAI. The following TypeScript code snippet in the AWS CDK stack demonstrates this. Be aware of the format of the OAI ID.

    const oai = new cf.OriginAccessIdentity(this, 'MyOriginAccessIdentity');
    oai.applyRemovalPolicy(RemovalPolicy.DESTROY);
    s3Bucket.grantRead(oai);
    const oaiId = `origin-access-identity/cloudfront/${oai.originAccessIdentityId}`;

Manage distribution configurations using CfnDistribution instead of the Distribution package

Most users encounter the error “The parameter CachePolicyId can’t be set for this region” when trying to deploy a CloudFront distribution in AWS China Regions using AWS CDK. The reason is that the Distribution package always tries to create a DefaultCacheBehavior with the BehaviorOptions class, which uses the CachePolicyId parameter. However, cache policies and origin request policies are not available in AWS China Regions, where CloudFront only supports legacy cache settings depending on the ForwardedValues parameter. As a result, deploying a CloudFront distribution in China using AWS CDK fails due to the incompatibility.

To resolve this, you need to use CfnDistribution instead of Distribution. If you write the stack code in Python, you should create the DefaultCacheBehavior using the DefaultCacheBehaviorProperty class rather than BehaviorOptions. The following is a TypeScript code snippet that is simpler than Python.

    const cfDistribution = new cf.CfnDistribution(this, 'MyCloudfrontDistribution', {
      distributionConfig: {
        defaultCacheBehavior: {
          targetOriginId: s3Bucket.bucketName,
          viewerProtocolPolicy: 'redirect-to-https',
          compress: true,
          forwardedValues: {
            queryString: false,
          },
        },

Disable IPv6 for the CloudFront distribution

The default value of the ipv6Enabled parameter is true. However, IPv6 is not supported by CloudFront China. So, you need to specify ipv6Enabled to false.

        ipv6Enabled: false,

Use the Regional domain name of the S3 bucket instead of its domain name

When you use an S3 bucket as a CloudFront origin, note that its domain name bucket-name.s3.amazonaws.com doesn’t work for AWS China Regions. Instead, you need to use the following configuration:

  • If the S3 bucket is located inside the AWS China Regions, use one of the following formats.
    • If your S3 bucket is not a website endpoint (in this case), use the following format: bucket-name.s3.region.amazonaws.com.cn, which is its Regional domain name.
    • If your S3 bucket is a website endpoint, use the following format: bucket-name.s3-website.region.amazonaws.com.cn.
  • If the S3 bucket is located outside of the AWS China Regions, use the following format when you add the bucket as a CloudFront origin: bucket-name.s3-website.region.amazonaws.com.cn.
  • Note that the domain name in all scenarios must end with .cn.
        origins: [
          {
            id: s3Bucket.bucketName,
            domainName: s3Bucket.bucketRegionalDomainName,
            s3OriginConfig: {
              originAccessIdentity: oaiId,
            },
          },
        ],

Specify iamCertificateId; don’t specify cloudFrontDefaultCertificate.

According to AWS CDK documents, if the distribution uses aliases (alternate domain names or CNAMEs), set cloudFrontDefaultCertificate to false and specify values for the following fields: – acmCertificateArn or iamCertificateId (specify a value for one, not both). As mentioned earlier in this post, CloudFront China does not currently support ACM for managing SSL/TLS certificates. You also cannot use the default CloudFront domain, *.cloudfront.cn, to serve content. However, if we set cloudFrontDefaultCertificate to false and specify a value for iamCertificateId, we will hit the following error when bootstrapping the AWS CDK stack:

Resource handler returned message: "Invalid request provided: Exactly one of [AcmCertificateArn, CloudFrontDefaultCertificate, IamCertificateId] needs to be specified" (RequestToken: e2b74c49-7123-51f9-20c7-e0579dxxxxxx, HandlerErrorCode: InvalidRequest)

The correct way is to only specify a value for the iamCertificateId parameter, not including the cloudFrontDefaultCertificate parameter in your code. When executing cdk bootstrap, AWS CDK will deal with other things for you.

        viewerCertificate: {
          iamCertificateId: iamCertId,
          minimumProtocolVersion: 'TLSv1.2_2021',
          sslSupportMethod: 'sni-only',
        },

Solution walkthrough: Programmatically deploying CloudFront distributions in AWS China Regions

Deploying the solution in TypeScript

  1. Modify the value of iamCertId and cname in TypeScript/lib/cloudfront_in_china_stack.ts
// Replace the value with your IAM server certificate ID.
const iamCertId:string = 'YOUR_CERTIFICATE_ID';
// Replace the value with your alternate domain names for the cloudfront distribution
const cname = ['www1.example.com.cn', 'www2.example.com.cn'];
  1. Enter the TypeScript/ directory, install the dependencies, and deploy the AWS CDK stack. It should be deployed into the China (Beijing) Region and will take up to 5 minutes.
cd TypeScript
npm install
cdk synth
cdk bootstrap aws://<YOUR_AWSCN_ACCOUNT_ID>/cn-north-1
cdk deploy
  1. Once the deployment succeeds, the outputs contain the following information:
Outputs:
CloudfrontInChinaStack.BucketDomainName = cloudfrontinchinastack-s3originbucket27b30804-1bfryqjxxxxxx.s3.amazonaws.com
CloudfrontInChinaStack.BucketName = cloudfrontinchinastack-s3originbucket27b30804-1bfryqjxxxxxx
CloudfrontInChinaStack.BucketRegionalDomainName = cloudfrontinchinastack-s3originbucket27b30804-1bfryqjxxxxxx.s3.cn-north-1.amazonaws.com.cn
CloudfrontInChinaStack.DistributionId = E2VZ6SATXXXXXX

Testing the solution

Use the following AWS Command Line Interface (AWS CLI) command to get the information about the CloudFront distribution created by the solution.

aws cloudfront get-distribution --id <DISTRIBUTION_ID> --region cn-north-1

You should get the entire CloudFront distribution information, including the ICP recordal status for your CNAME(s). Note that clients cannot access the CloudFront China distribution unless the ICP recordal status is “APPROVED.” The following is an example of the ICP recordal status in get-distribution outputs:

        "AliasICPRecordals": [
            {
                "CNAME": "www2.example.com.cn",
                "ICPRecordalStatus": "APPROVED"
            },
            {
                "CNAME": "www1.example.com.cn",
                "ICPRecordalStatus": "APPROVED"
            }
        ]

Cleanup

To delete the deployed resources, run the cdk destroy command from the stack directory.

Conclusion

To summarize, websites and apps in China must comply with local regulations. AWS China Regions provide services like CloudFront and Amazon S3 but with some differences from global AWS Regions. As shown in the sample solution, deploying CloudFront distributions in AWS China Regions needs special handling around ICP recordal, SSL/TLS certificates, S3 bucket domains, and configuration specifics that stem from those differences. By following the steps in this post for using AWS CDK in China, companies can automate web architecture smoothly and avoid issues when launching locally. To get started with AWS in China and extend your business, refer to AWS China Gateway for comprehensive guidance and resources.

Cheng Chen Headshot

Cheng Chen

Cheng Chen is a sr. GCR edge specialist SA in the Greater China WWSO team at Amazon Web Services, specializing in Amazon CloudFront, AWS WAF, AWS Shield, AWS Global Accelerator, and Amazon Route 53.

Elon Niu Headshot.jpg

Elon Niu

Elon Niu is a solutions builder in the GCR solutions engineering team at Amazon Web Services, focusing on developing reusable, verified, and easy-to-deploy solutions, to help customers accelerate the workloads deployment on AWS.