DEV Community

hayao-k for AWS Community Builders

Posted on • Originally published at hayao-k.dev

Migrating CloudFront OAI to OAC using CloudFormation

Goals of this post

Describes the CloudFormation template modifications required to migrate CloudFront's Origin access identity (OAI) to Origin Access Control (OAC).

OAC is a new access control method for setting S3 buckets as origins in CloudFront.

Previously we had used Origin Access Identity (OAI) to restrict access to origin S3 buckets to CloudFront only.

OAI is currently treated as Legacy. Migration from OAI to OAC is recommended to support security best practices and new regions.

Sample Template

See my GitHub repository!

CFn-sample-cloudfront-oac

CloudFormation template for building a static site delivery environment with CloudFront and S3. OAC is used for origin access control.

static-site-deploy-default.yaml

Template for using the default CloudFront domain name.

static-site-deploy-cname.yaml

Template for delivery on a custom domain using a TLS certificate issued by AWS Certificate Manager (ACM). You will need to specify the CNAME and ACM identifier when deploying.




Examples of modifications

Migrating existing CloudFormation templates from OAI to OAC requires, as a minimum, the following modifications.

  • Creating an OAC
  • Modifying the bucket policy
  • Modifying Distribution Origin

Creating an OAC

Create an AWS::CloudFront::OriginAccessControl. Description of the OriginAccessControlConfig is an optional field.

Resources:
  CloudFrontOriginAccessControl:
    Type: AWS::CloudFront::OriginAccessControl
    Properties: 
      OriginAccessControlConfig:
        Description: Default Origin Access Control
        Name: !Ref AWS::StackName
        OriginAccessControlOriginType: s3
        SigningBehavior: always
        SigningProtocol: sigv4
Enter fullscreen mode Exit fullscreen mode

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudfront-originaccesscontrol.html

Delete AWS::CloudFront::CloudFrontOriginAccessIdentity as it will no longer be required after migration.

Modifying the bucket policy

In the following example, the policy for OAI has been removed, but it is a recommended migration procedure to include both OAI and OAC policies. This will prevent CloudFront from losing access to S3 buckets during migration to OAC. Please take action as necessary.

Before

 # S3 bucket policy to allow access from CloudFront OAI
  AssetsBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref AssetsBucket
      PolicyDocument:
        Statement:
        - Action: s3:GetObject
          Effect: Allow
          Resource: !Sub ${AssetsBucket.Arn}/*
          Principal:
            AWS: !Sub arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${CloudFrontOriginAccessIdentity}
Enter fullscreen mode Exit fullscreen mode

After

# S3 bucket policy to allow access from CloudFront OAC
  AssetsBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref AssetsBucket
      PolicyDocument:
        Statement:
        - Action: s3:GetObject
          Effect: Allow
          Resource: !Sub ${AssetsBucket.Arn}/*
          Principal:
            Service: cloudfront.amazonaws.com
          Condition:
            StringEquals:
              AWS:SourceArn: !Sub arn:aws:cloudfront::${AWS::AccountId}:distribution/${AssetsDistribution}
Enter fullscreen mode Exit fullscreen mode

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html

Modifying Distribution Origin

OAI sets S3OriginConfig for Distribution Origin, but OAC requires OriginAccessControlId to be specified.

Before

  AssetsDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
        - Id: S3Origin
          DomainName: !GetAtt AssetsBucket.DomainName
          S3OriginConfig:
            OriginAccessIdentity: !Sub origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}
Enter fullscreen mode Exit fullscreen mode

Afeter

  AssetsDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
        - Id: S3Origin
          DomainName: !GetAtt AssetsBucket.DomainName
          S3OriginConfig:
            OriginAccessIdentity: ''
          OriginAccessControlId: !GetAtt CloudFrontOriginAccessControl.Id
Enter fullscreen mode Exit fullscreen mode

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-origin.html

Note: As of September 2022, an empty OriginAccessIdentity must be specified in S3OriginConfig.

Deleting S3OriginConfig will result in the following error when updating the stack.

Resource handler returned message: "Invalid request provided: Exactly one of CustomOriginConfig and S3OriginConfig must be specified"
Enter fullscreen mode Exit fullscreen mode

Image description

Examples of actual migration

Now let's update the existing CloudFormation stack using the modified template. Update the stack to ensure that the change set is as expected.

Image description

As described before, removing the bucket policy for OAI and migrating to OAC will result in Access Denied during distribution updates.

Image description

After updating the distribution, the S3 bucket access settings can be seen to have been updated to OAC.

Image description

The S3 bucket policy is also updated as expected.

Image description

Access from the browser seems to be okay.

Image description

I hope this will be of help to someone else.

Top comments (2)

Collapse
 
alexter42 profile image
Alejandra Monroy

That OriginAccessIdentity empty string did the trick, thanks!

Collapse
 
myrondev profile image
Myron Zaiets

In my case it doesn't work:(