What are Multi-Region Access Points?

Multi-Region Access Points are an innovative feature offered by cloud service providers like Amazon Web Services (AWS). They allow businesses to create a single access point name that spans multiple AWS regions. In simpler terms, it enables seamless access to data stored in different regions through a single global endpoint. 

In this article, we demonstrate how to enhance content delivery using Amazon S3 Multi-Region Access Points, combined with Amazon CloudFront. This powerful setup allows you to store objects in Amazon S3 and distribute them globally in an Active-Active configuration. The key benefit here is latency-based routing, ensuring the fastest possible content delivery. By leveraging S3’s multi-region storage alongside CloudFront, a leading content delivery network, you can significantly improve latency and overall performance for users worldwide.

Solution Overview

AWS S3 Multi-Region Access Points provide a global endpoint that applications can use to fulfill requests from S3 buckets among many located in multiple AWS Regions. Instead of sending requests over the congested public internet, S3 Multi-Region Access Points provide built-in network resilience with the acceleration of internet-based requests to S3. 

CloudFront, as a content delivery network (CDN), enhances the delivery speed of both static and dynamic web content to your users. This service ensures that your audience experiences faster access to your website’s content. CloudFront delivers your content through a worldwide network of data centers called edge locations, connected to the AWS Regions through the AWS network backbone. 


“In CloudFront, setting an S3 bucket as the origin enhances performance between the end user and CloudFront. However, if the S3 bucket is geographically distant from the user, the performance may still be affected. This is where S3 Multi-Region Access Points can help. By combining the two services, you can further optimise the performance of your application to deliver assets from your Amazon S3 buckets with the best possible performance.

     

      1. The client makes a CloudFront request that is expected to match the path pattern of the object to the S3 Multi-Region Access Point origin. 
        Eg : xxxxxxxx.cloudfront.net/folderName/objectName.

      1. CloudFront matches the path pattern to the S3 Multi-Region Access Point at the origin and invokes the associated origin request Lambda@Edge function. 

      1. The Lambda function modifies the request object, which is passed in the event object, and signs the request using Signature Version 4A (SigV4A). 

      1. The modified request is returned to CloudFront. 

      1. CloudFront, using the SigV4A authorization headers from the modified request object, requests to the S3 Multi-Region Access Point origin. 

      1. S3 Multi-Region Access Point routes the request to the S3 bucket based on the lowest network latency.

    Some points to consider for Lambda@Edge:

    Permission: 

    Make sure you attach proper permission to Lambda IAM Role (Global).

    CloudWatch Permission:

    {
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Effect": "Allow",
      "Resource": "arn:aws:logs:*:*:*"
    }

    You can see that in the resource section for logs, we didn’t mention region but we have mentioned because when we use Lambda@Edge in CloudFront it deploys a replica of the Lambda in all supported regions. So if we specify the region here then we won’t be able to see the log group created for Lambda for other regions. 

    When you hit the  CloudFront domain then based on the lowest network latency Lambda@Edge triggers the Lambda replica present in that region. Because Lambda@Edge runs your code in AWS Edge locations around the world, close to your users.

    Lambda function must be in us-east-1 region

    Below the lambda log group will be created in all the regions when invoked. You can see the region is us-east-1 because our lambda is in us-east-1 region.

    LogGroup name format : /aws/lambda/us-east-1.LambdaName

    S3 Permission : 

    Give access to all the buckets along with MRAP Access Point.

    {
      "Action": [
          "s3:GetObject"
      ],
      "Effect": "Allow",
      "Resource": [
          "arn:aws:s3:::bucket-1/*",
          "arn:aws:s3:::bucket-2/*",
          "arn:aws:s3:::bucket-3/*",
          "arn:aws:s3:::bucket-4/*",
          "arn:aws:s3:::bucket-5/*",
          "arn:aws:s3::644940547476:accesspoint/xxxxxxx.mrap/*"
      ]
    }

    So the final policy for lambda IAM role policy will look like below.

    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Action": [
                  "s3:GetObject"
              ],
              "Effect": "Allow",
              "Resource": [
                  "arn:aws:s3:::<bucket-1>/*",
                  "arn:aws:s3:::<bucket-2>/*",
                  "arn:aws:s3:::<bucket-3>/*",
                  "arn:aws:s3:::<bucket-4>/*",
                  "arn:aws:s3:::<bucket-5>/*",
                  "arn:aws:s3::644940547476:accesspoint/xxxxxxx.mrap/*"
              ]
          },
          {
              "Effect": "Allow",
              "Action": [
                  "logs:CreateLogGroup",
                  "logs:CreateLogStream",
                  "logs:PutLogEvents"
              ],
              "Resource": [
                  "arn:aws:logs:*:*:*"
              ]
          }
      ]
    }

    Deployment and Implementation Details

    Resources to be created :

    S3 buckets (1 per region. In my case 5 buckets in 5 regions)
    Multi-Region Access Point
    Lambda
    IAM role for lambda
    CloudFront Distribution

    • Make sure you keep the buckets private by disabling public access.
    • Then create the MRAP and make sure to disable public access.

    • The MRAP policy should look like below:

    {
      "Statement": [
          {
              "Action": [
                  "s3:GetObject",
                  "s3:ListBucket"
              ],
              "Effect": "Allow",
              "Principal": {
                  "AWS": "<AccountId>"
              },
              "Resource": [
                  "<MRAP ARN>/object/*",
                  "<MRAP ARN>"
              ],
              "Sid": "AllowMultiRegionAccessPointRead"
          }
      ],
      "Version": "2012-10-17"
    }

    Add/Update all the 5 buckets policy below. Here we are giving access to only MRAP.

    {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Effect": "Allow",
              "Principal": {
                  "AWS": "*"
              },
              "Action": "s3:GetObject",
              "Resource": [
                  "<Bucket ARN>",
                  "<Bucket ARN>/*"
              ],
              "Condition": {
                  "StringEquals": {
                      "s3:DataAccessPointArn": "<MRAP ARN>"
                  }
              }
          }
      ]
    }

    Lambda :

    For lambda IAM role policy, kindly refer to S3 Permission above.

    Below is the sample code in Nodejs for Sigv4.

    After creating the Lambda, make sure to publish the lambda. It will create a new version of lambda.

    To deploy the new version of the lambda to CloudFront as Lambda@Edge follow below steps.

    After creating the Lambda make sure to publish the lambda. It will create a new version of lambda.

    CloudFront :

    ⦁ Navigate to the CloudFront distribution page, and observe that the Origin domain is .accesspoint.s3-global.amazonaws.com

    ⦁ Navigate to the CloudFront distribution behaviors. The Lambda function is associated with the origin request. This optimizes Lambda@Edge use since the signing process will only be performed if the request can’t be served from the CloudFront cache and an origin request is necessary.

    Testing the Deployment

    Before you start testing the deployed solution, you first need to upload a file to each of the Amazon S3 buckets that are associated with the S3 Multi-Region Access Points.

    Note: For testing purposes, upload the file to each S3 bucket separately. For a production configuration, you can use replication rules inside the S3 Multi-Region Access Points to synchronize data among buckets. To learn more, refer to the documentation on configuring bucket replication for use with Multi-Region Access Points.

    We have put a common.txt file in all 5 buckets and the content was region details, as per bucket region.

    Get the CloudFront Distribution domain name then add the file absolute path. In my case, the file was in the root of the bucket. 

    You can see from the above image, we are getting the file that is present in ap-south-1 region as we are in India so MRAP routed the traffic to the lowest latency region. That is ap-south-1.

    To test this setup for other regions, we can use CloudShell, it comes preinstalled with CURL, and you can open it in each AWS Region where you have S3 buckets. Using CloudShell will help to simulate a client being geographically closest to each of the AWS Regions.

    Then execute the command echo “curl ${CLOUD_FRONT_DNS}”

    E.g.  xxxxxx.cloudfront.net/common.txt

    Conclusion

    In this blog, we showed how to CloudFront with S3 Multi-Region Access Point to achieve a multi-region, active setup to further optimize the performance of your application, and deliver the assets from your S3 buckets with the best possible performance. Here, we used CloudFront to route the traffic from the client to the edge and MRAP, to further route the request to the origin. By using this process we optimized the performance of our application to deliver the best possible performance to the end users.

    At CloudZenia we provide solutions to all such issues, you can reach out to book consultations or even follow our blogs to sharpen your skills and learn more.

    Nov 23, 2023