Skip to main content

CloudFront Distribution Has Origin Failover Configured

Overview

This check verifies that your Amazon CloudFront distributions have an origin group configured with at least two origins. Origin groups enable automatic failover: if your primary origin becomes unavailable, CloudFront automatically routes requests to a secondary origin.

Risk

Without origin failover, your primary origin is a single point of failure. If that origin experiences an outage, regional incident, or denial-of-service attack, your entire CloudFront distribution stops serving content. This can lead to:

  • Complete website or application downtime
  • Elevated error rates (5xx errors) for your users
  • Increased latency during partial failures
  • Potential SLA violations and degraded customer experience

Remediation Steps

Prerequisites

You need access to the AWS Console with permissions to modify CloudFront distributions. You also need a secondary origin ready (such as a backup S3 bucket or secondary application server).

Required IAM permissions

Your IAM user or role needs these permissions:

  • cloudfront:GetDistribution
  • cloudfront:GetDistributionConfig
  • cloudfront:UpdateDistribution
  • cloudfront:CreateDistribution (if creating new distributions)

AWS Console Method

  1. Open the CloudFront console
  2. Select your distribution from the list
  3. Go to the Origins tab
  4. Ensure you have at least two origins:
    • If you only have one origin, click Create origin to add a secondary origin
    • Give your secondary origin a descriptive name (e.g., backup-origin)
  5. Create an origin group:
    • Click Create origin group
    • Enter a name for the group (e.g., primary-failover-group)
    • Select your primary origin as the first member
    • Select your secondary origin as the second member
    • Under Failover criteria, select the HTTP status codes that should trigger failover (typically 500, 502, 503, 504)
    • Click Create origin group
  6. Update your cache behavior to use the origin group:
    • Go to the Behaviors tab
    • Select the behavior you want to protect (usually the default behavior)
    • Click Edit
    • Under Origin and origin groups, select your new origin group
    • Click Save changes
  7. Wait for the distribution to deploy (status changes from "In Progress" to "Deployed")
AWS CLI (optional)

The CLI method requires retrieving the current configuration, modifying it, and updating the distribution. Replace <DISTRIBUTION-ID> with your actual distribution ID.

Step 1: Get the current distribution configuration

aws cloudfront get-distribution-config \
--id <DISTRIBUTION-ID> \
--region us-east-1 \
--output json > distribution-config.json

Step 2: Extract the ETag (needed for updates)

ETAG=$(cat distribution-config.json | jq -r '.ETag')
echo "ETag: $ETAG"

Step 3: Modify the configuration

Edit distribution-config.json to add your origin group. The OriginGroups section should be added at the same level as Origins:

{
"OriginGroups": {
"Quantity": 1,
"Items": [
{
"Id": "OriginGroupWithFailover",
"FailoverCriteria": {
"StatusCodes": {
"Quantity": 4,
"Items": [500, 502, 503, 504]
}
},
"Members": {
"Quantity": 2,
"Items": [
{ "OriginId": "PrimaryOrigin" },
{ "OriginId": "SecondaryOrigin" }
]
}
}
]
}
}

Also update your DefaultCacheBehavior (or relevant cache behavior) to use the origin group:

{
"DefaultCacheBehavior": {
"TargetOriginId": "OriginGroupWithFailover",
...
}
}

Step 4: Update the distribution

Extract just the DistributionConfig portion and update:

cat distribution-config.json | jq '.DistributionConfig' > updated-config.json

aws cloudfront update-distribution \
--id <DISTRIBUTION-ID> \
--if-match "$ETAG" \
--distribution-config file://updated-config.json \
--region us-east-1
CloudFormation (optional)

This CloudFormation template creates a CloudFront distribution with origin failover configured:

AWSTemplateFormatVersion: '2010-09-09'
Description: CloudFront distribution with origin failover configured

Parameters:
PrimaryOriginDomain:
Type: String
Description: Domain name of the primary origin (e.g., primary-bucket.s3.us-east-1.amazonaws.com)
SecondaryOriginDomain:
Type: String
Description: Domain name of the secondary origin (e.g., secondary-bucket.s3.us-east-1.amazonaws.com)

Resources:
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Enabled: true
Comment: Distribution with origin failover
DefaultRootObject: index.html

Origins:
- Id: PrimaryOrigin
DomainName: !Ref PrimaryOriginDomain
S3OriginConfig:
OriginAccessIdentity: ''
- Id: SecondaryOrigin
DomainName: !Ref SecondaryOriginDomain
S3OriginConfig:
OriginAccessIdentity: ''

OriginGroups:
Quantity: 1
Items:
- Id: OriginGroupWithFailover
FailoverCriteria:
StatusCodes:
Quantity: 4
Items:
- 500
- 502
- 503
- 504
Members:
Quantity: 2
Items:
- OriginId: PrimaryOrigin
- OriginId: SecondaryOrigin

DefaultCacheBehavior:
TargetOriginId: OriginGroupWithFailover
ViewerProtocolPolicy: redirect-to-https
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6
Compress: true

Outputs:
DistributionId:
Description: CloudFront Distribution ID
Value: !Ref CloudFrontDistribution
DistributionDomainName:
Description: CloudFront Distribution Domain Name
Value: !GetAtt CloudFrontDistribution.DomainName

Deploy with:

aws cloudformation deploy \
--template-file template.yaml \
--stack-name cloudfront-with-failover \
--parameter-overrides \
PrimaryOriginDomain=primary-bucket.s3.us-east-1.amazonaws.com \
SecondaryOriginDomain=secondary-bucket.s3.us-east-1.amazonaws.com \
--region us-east-1
Terraform (optional)

This Terraform configuration creates a CloudFront distribution with origin failover:

terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

variable "primary_origin_domain" {
description = "Domain name of the primary origin"
type = string
}

variable "secondary_origin_domain" {
description = "Domain name of the secondary origin"
type = string
}

resource "aws_cloudfront_distribution" "with_failover" {
enabled = true
comment = "Distribution with origin failover"
default_root_object = "index.html"

origin {
domain_name = var.primary_origin_domain
origin_id = "PrimaryOrigin"
}

origin {
domain_name = var.secondary_origin_domain
origin_id = "SecondaryOrigin"
}

origin_group {
origin_id = "OriginGroupWithFailover"

failover_criteria {
status_codes = [500, 502, 503, 504]
}

member {
origin_id = "PrimaryOrigin"
}

member {
origin_id = "SecondaryOrigin"
}
}

default_cache_behavior {
allowed_methods = ["GET", "HEAD"]
cached_methods = ["GET", "HEAD"]
target_origin_id = "OriginGroupWithFailover"
viewer_protocol_policy = "redirect-to-https"
compress = true

forwarded_values {
query_string = false
cookies {
forward = "none"
}
}
}

restrictions {
geo_restriction {
restriction_type = "none"
}
}

viewer_certificate {
cloudfront_default_certificate = true
}
}

output "distribution_id" {
description = "CloudFront Distribution ID"
value = aws_cloudfront_distribution.with_failover.id
}

output "distribution_domain_name" {
description = "CloudFront Distribution Domain Name"
value = aws_cloudfront_distribution.with_failover.domain_name
}

Deploy with:

terraform init
terraform apply \
-var="primary_origin_domain=primary-bucket.s3.us-east-1.amazonaws.com" \
-var="secondary_origin_domain=secondary-bucket.s3.us-east-1.amazonaws.com"

Verification

After making changes, verify that origin failover is properly configured:

  1. In the CloudFront console, open your distribution
  2. Go to the Origins tab
  3. Confirm you see an Origin groups section with at least one group
  4. Click on the origin group to verify it has two members and failover criteria defined
  5. Go to the Behaviors tab and confirm your cache behavior targets the origin group (not a single origin)
CLI verification

Run the Prowler check to verify the remediation:

prowler aws --checks cloudfront_distributions_multiple_origin_failover_configured

Or check via AWS CLI:

aws cloudfront get-distribution \
--id <DISTRIBUTION-ID> \
--region us-east-1 \
--query 'Distribution.DistributionConfig.OriginGroups'

The output should show Quantity of 1 or more and contain your origin group configuration with two members.

Additional Resources

Notes

  • Failover criteria: CloudFront triggers failover based on HTTP status codes. The common choices are 500, 502, 503, and 504. You can also include 403 and 404 if appropriate for your use case.
  • Origin sync: Ensure your secondary origin has the same content as your primary. Consider using S3 Cross-Region Replication or similar mechanisms to keep origins synchronized.
  • Cost implications: Running multiple origins (especially in different regions) may increase your costs. Factor this into your resilience planning.
  • Testing failover: Periodically test your failover configuration by simulating primary origin failures. This ensures the secondary origin is properly configured and content is accessible.
  • Latency considerations: If your secondary origin is in a different region, users may experience increased latency during failover. Place secondary origins strategically based on your user distribution.