1. Answers
  2. Serving private content through CloudFront with Origin Access Control

How do I serve private content through CloudFront with Origin Access Control?

In this guide, we will demonstrate how to serve private content through AWS CloudFront using Origin Access Control (OAC). Origin Access Control allows CloudFront to securely access a private S3 bucket, ensuring that the content is not publicly accessible directly from S3.

Steps:

  1. Create an S3 bucket to store your private content.
  2. Create a CloudFront distribution with an Origin Access Control configuration to securely access the S3 bucket.
  3. Restrict S3 bucket access to only allow CloudFront.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

// Step 1: Create an S3 bucket to store private content
const bucket = new aws.s3.Bucket("privateContentBucket", {
    acl: "private", // Ensure the bucket is private
});

// Step 2: Create Origin Access Control for CloudFront
const originAccessControl = new aws.cloudfront.OriginAccessControl("originAccessControl", {
    name: "myOriginAccessControl",
    signingBehavior: "always", // Always sign requests
    signingProtocol: "sigv4", // Use SigV4 protocol
    originAccessControlOriginType: "s3",
});

// Step 3: Create a CloudFront distribution
const distribution = new aws.cloudfront.Distribution("myDistribution", {
    enabled: true,
    origins: [{
        originId: bucket.arn,
        domainName: bucket.bucketRegionalDomainName,
        s3OriginConfig: {
            originAccessIdentity: originAccessControl.id,
        },
    }],
    defaultCacheBehavior: {
        targetOriginId: bucket.arn,
        viewerProtocolPolicy: "redirect-to-https",
        allowedMethods: ["GET", "HEAD"],
        cachedMethods: ["GET", "HEAD"],
        forwardedValues: {
            queryString: false,
            cookies: {
                forward: "none",
            },
        },
    },
    priceClass: "PriceClass_100",
    restrictions: {
        geoRestriction: {
            restrictionType: "none",
        },
    },
    viewerCertificate: {
        cloudfrontDefaultCertificate: true,
    },
});

// Step 4: Update bucket policy to allow access only from CloudFront
const bucketPolicy = new aws.s3.BucketPolicy("bucketPolicy", {
    bucket: bucket.bucket,
    policy: bucket.bucket.apply(bucketName => JSON.stringify({
        Version: "2012-10-17",
        Statement: [{
            Effect: "Allow",
            Principal: {
                Service: "cloudfront.amazonaws.com",
            },
            Action: "s3:GetObject",
            Resource: `arn:aws:s3:::${bucketName}/*`,
            Condition: {
                StringEquals: {
                    "AWS:SourceArn": distribution.arn,
                },
            },
        }],
    })),
});

// Export the CloudFront distribution domain name
export const cdnUrl = distribution.domainName;

Key Points:

  • S3 Bucket: Stores the private content and is configured to be private.
  • Origin Access Control: Ensures that CloudFront can securely access the private S3 bucket.
  • CloudFront Distribution: Distributes the content and uses the Origin Access Control to access the S3 bucket.
  • Bucket Policy: Restricts direct access to the S3 bucket, allowing only CloudFront to access it.

Summary:

We created an S3 bucket to store private content, configured an Origin Access Control for CloudFront, set up a CloudFront distribution to serve the content, and restricted the S3 bucket policy to allow access only from CloudFront. This setup ensures that the content is securely served through CloudFront while keeping the S3 bucket private.

Deploy this code

Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.

Sign up

New to Pulumi?

Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.

Sign up