

# Automate MediaTailor and CDN with CloudFormation
CloudFormation automation

Automating AWS Elemental MediaTailor with a content delivery network (CDN) using AWS CloudFormation streamlines your ad insertion workflow and improves reliability.

This section shows you how to use AWS CloudFormation (AWS infrastructure as code service) to automatically set up AWS Elemental MediaTailor with a content delivery network (CDN). Although you can manually configure this integration as described in previous sections, using CloudFormation saves time and reduces errors by automating the entire process with a single template.

If you're new to CloudFormation, it's a service that lets you create a template file that defines all of the AWS resources that you need. When you deploy this template, CloudFormation automatically creates and configures those resources for you, ensuring that they work together correctly.

For more information about CloudFormation, see the [CloudFormation User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html). For information about MediaTailor resource types in CloudFormation, see [AWS::MediaTailor Resource Type Reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_MediaTailor.html).

**Topics**
+ [Why use AWS CloudFormation](cloudformation-benefits.md)
+ [Prepare for deployment](prepare-cloudformation-deployment.md)
+ [Deploy the template](deploy-cloudformation-template.md)
+ [Use the deployed resources](use-deployed-resources.md)
+ [Test and validate your deployment](test-validate-deployment.md)
+ [Troubleshoot deployment issues](troubleshoot-deployment-issues.md)
+ [Customize the template](customize-cloudformation-template.md)
+ [Template reference](cloudformation-template-reference.md)

# Why use CloudFormation for MediaTailor and CDN integration
Why use AWS CloudFormation

AWS Elemental MediaTailor automation with AWS CloudFormation provides significant advantages for broadcast professionals managing streaming workflows. Manually configuring MediaTailor with a content delivery network (CDN) can be time-consuming and error-prone. Using CloudFormation automation offers the following advantages.
+ **Consistency**: Ensures the same configuration is deployed every time, reducing human error.
+ **Version control**: Store your infrastructure as code in a version control system for tracking changes.
+ **Rapid deployment**: Deploy complex configurations in minutes instead of hours of manual configuration.
+ **Environment replication**: Easily replicate configurations across development, testing, and production environments.
+ **Documentation**: The template itself serves as documentation of your infrastructure.

Here's how the automated workflow compares to manual configuration:


| Manual setup (multiple steps) | Automated setup (single template) | 
| --- | --- | 
| Create MediaTailor playback configuration | Deploy one CloudFormation template with parameters | 
| Create CloudFront distribution | 
| Configure cache behaviors | 
| Set up security configurations | 

The automated workflow for setting up MediaTailor with CloudFront follows these steps:

1. Deploy the CloudFormation template with your content origin and ad server parameters

1. CloudFormation creates and configures all necessary resources:
   + MediaTailor playback configuration for ad insertion
   + CloudFront distribution with appropriate cache behaviors
   + Security configurations for content protection

1. Use the CloudFormation outputs to access your ad-enabled stream URLs

1. Stream your content with dynamically inserted ads

# Prepare for CloudFormation deployment of CDN and MediaTailor integrations
Prepare for deployment

AWS Elemental MediaTailor deployment with AWS CloudFormation requires specific prerequisites and preparation steps. Before you begin working with CloudFormation to integrate MediaTailor and Amazon CloudFront, make sure you have the following.
+ An AWS account with permissions to create MediaTailor, CloudFront, and CloudFormation resources
+ A content origin where your video content is hosted (such as AWS Elemental MediaPackage, Amazon S3, or another origin server)
+ An ad decision server (ADS) that can respond to VAST requests

Before deploying the CloudFormation template, gather these required parameters:

`AdServerUrl`  
URL of the VAST ad server for dynamic ad insertion. A static VAST endpoint is provided for testing.

`ContentOriginDomainName`  
Domain name of your content origin without protocol (e.g., *mediapackage-domain.mediapackagev2.us-west-2.amazonaws.com*, *mybucket.s3.amazonaws.com*, or *custom-origin.example.com*). Do not include http:// or https:// prefixes or any paths.

`ContentOriginType`  
The type of content origin:  
+ *mediapackagev2*: For AWS Elemental MediaPackage origins
+ *s3*: For Amazon S3 bucket origins
+ *custom*: For any other origin type

The template will create several AWS resources that work together to deliver your content with personalized ads. The following describes what each component does:

## Origin access control


Origin Access Control (OAC) is a security feature that ensures your content can only be accessed through CloudFront, not directly from your origin server. This helps protect your content from unauthorized access.

For MediaPackage and Amazon S3 origins, the template creates an Origin Access Control (OAC) resource to secure access to your content. 

## MediaTailor playback configuration


The MediaTailor playback configuration is the core component that handles ad insertion. It receives content from your origin, requests ads from your ad server, and combines them into a personalized stream for each viewer.

The template creates an MediaTailor playback configuration with the following settings:
+ Video content source pointing to your CloudFront distribution
+ Ad decision server URL configured to your specified VAST endpoint
+ Live pre-roll configuration for ad insertion during live streams
+ CDN configuration with appropriate segment URL prefixes

## CloudFront distribution


The CloudFront distribution delivers your content to viewers worldwide with low latency. It handles different types of requests (manifests, content segments, ad segments) and routes them to the appropriate origins.

For broadcast professionals new to CDNs, here are some key terms:

Origin  
A server where your original content is stored (like MediaPackage or Amazon S3)

Cache behavior  
Rules that determine how different types of content are cached and delivered

Cache policy  
Settings that control how long content is cached and what request components affect caching

The template creates a CloudFront distribution with the following components:
+ Three origins:
  + Content origin (MediaPackage, Amazon S3, or custom)
  + MediaTailor manifests origin
  + MediaTailor segments origin
+ Cache behaviors with appropriate patterns:
  + Default behavior for content segments
  + Behavior for MediaTailor ad segments (/tm/\$1)
  + Behavior for MediaTailor interstitial media (/v1/i-media/\$1)
  + Behavior for personalized manifests (/v1/\$1)
  + Behavior for segment redirect requests (/segment/\$1)
+ Optimized cache policies for each behavior:
  + `CachingOptimized` for cacheable content
  + `CachingDisabled` for personalized manifests
+ Origin request policies to ensure proper header forwarding
+ Response header policies for CORS support

# Deploy the CloudFormation template for CDN and MediaTailor integrations
Deploy the template

AWS Elemental MediaTailor deployment using the AWS CloudFormation template is straightforward once you understand what the template will create. This process takes about 15-30 minutes, with most of the time spent waiting for the CloudFront distribution to deploy.

To deploy the CloudFormation template and set up your automated ad insertion workflow:

**To deploy the MediaTailor CloudFormation template**

1. Download the CloudFormation template from the AWS Elemental MediaTailor GitHub repository or copy it from the [AWS CloudFormation template reference for AWS Elemental MediaTailor and Amazon CloudFront integration](cloudformation-template-reference.md).

1. Open the [CloudFormation console](https://console.aws.amazon.com/cloudformation/home).

1. Choose **Create stack** > **With new resources (standard)**.

1. Under **Specify template**, choose **Upload a template file** and upload the template.

1. Enter a stack name and provide values for the required parameters:
   + **AdServerUrl**: URL of your VAST ad server (e.g., https://*your-ad-server.com*/vast)
   + **ContentOriginDomainName**: Domain name of your content origin without protocol (e.g., *mediapackage-domain.mediapackagev2.us-west-2.amazonaws.com*)
   + **ContentOriginType**: Select the type of content origin:
     + *mediapackagev2*: For AWS Elemental MediaPackage origins
     + *s3*: For Amazon S3 bucket origins
     + *custom*: For any other origin type

1. Review the configuration and choose **Create stack**.

1. Wait for the stack creation to complete, which typically takes 5-10 minutes. You can monitor progress in the **Events** tab.

1. Once complete, navigate to the **Outputs** tab to find the URLs for your HLS and DASH manifests.

**Note**  
If you're using AWS Elemental MediaPackage as your content origin, make sure your MediaPackage endpoints are properly configured and accessible. For more information, see [MediaPackage CDN integration](mediapackage-integration.md).

# Use the CloudFormation deployed resources for CDN and MediaTailor integration
Use the deployed resources

AWS Elemental MediaTailor resources deployed by the AWS CloudFormation stack provide several important outputs that you'll use to access your content with ad insertion. After the CloudFormation stack is created successfully, you'll need to understand how to use the outputs to access your content with ads inserted. This is similar to how you would use MediaTailor URLs in a manual setup, but the CloudFormation deployment provides these URLs automatically.

After successful deployment, the CloudFormation stack provides several important outputs that you'll use to access your content with ad insertion:

`CloudFrontDomainName`  
The domain name of your CloudFront distribution (e.g., *d1234abcdef.CloudFront.net*)

`HlsManifestUrl`  
Base URL for HLS manifests with ad insertion (e.g., https://*d1234abcdef.CloudFront.net*/v1/master/*12345*/*my-playback-config*/)

`DashManifestUrl`  
Base URL for DASH manifests with ad insertion (e.g., https://*d1234abcdef.CloudFront.net*/v1/dash/*12345*/*my-playback-config*/)

`MediaTailorPlaybackConfigName`  
Name of the created MediaTailor playback configuration (such as *my-stack-PlaybackConfig*)

## Construct playback URLs


To create the complete playback URL for your content with ads, you'll need to combine the base URL from the CloudFormation outputs with your specific manifest path. This is a critical step for broadcast professionals to understand, as it connects your existing content with the ad insertion system.

1. Start with the appropriate manifest URL from the outputs:

   ```
   HlsManifestUrl: https://d1234abcdef.CloudFront.net/v1/master/12345/my-playback-config/
   ```

1. Append your specific manifest path:

   ```
   Your manifest path: channel/index.m3u8
   ```

1. The complete playback URL becomes:

   ```
   https://d1234abcdef.CloudFront.net/v1/master/12345/my-playback-config/channel/index.m3u8
   ```

Use this URL in your video player to play content with dynamically inserted ads.

**Tip**  
If you're not sure what your manifest path should be, check your origin server. For MediaPackage origins, this is the path to your endpoint's HLS or DASH manifest. For Amazon S3 origins, this is the path to your manifest file within the bucket.

For more information about MediaTailor URL structure, see [Set up CDN integration with MediaTailor](cdn-configuration.md).

## Configure a video player


After you have your playback URL, you need to configure a video player to use it. For broadcast professionals, this is similar to configuring a player for any HLS or DASH stream, but now the stream will include personalized ads. Here's a simple example using the popular HLS.js player:

```
<!DOCTYPE html>
<html>
<head>
    <title>MediaTailor Playback Example</title>
    <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
    <video id="video" controls style="width: 640px; height: 360px;"></video>
    
    <script>
        const video = document.getElementById('video');
        const mediaUrl = 'https://<replaceable>d1234abcdef.CloudFront.net</replaceable>/v1/master/<replaceable>12345</replaceable>/<replaceable>my-playback-config</replaceable>/<replaceable>channel/index.m3u8</replaceable>';
        
        if (Hls.isSupported()) {
            const hls = new Hls();
            hls.loadSource(mediaUrl);
            hls.attachMedia(video);
        } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
            video.src = mediaUrl;
        }
    </script>
</body>
</html>
```

You can also use professional broadcast players like:
+ JW Player
+ Bitmovin Player
+ THEOplayer
+ Video.js

For more information about player integration with MediaTailor, see [MediaTailor ad server integration requirements](vast.md).

# Test and validate your CloudFormation deployment for CDN and MediaTailor integration
Test and validate your deployment

AWS Elemental MediaTailor deployment validation is a critical step for broadcast professionals before going live. This section guides you through testing your deployment to ensure ads are being inserted properly and content is delivered smoothly.

After deploying the CloudFormation template, follow these steps to verify that your setup is working correctly:

**To test your MediaTailor and CloudFront integration**

1. Verify that all resources were created successfully in the CloudFormation console.

1. Check that the MediaTailor playback configuration is active in the [MediaTailor console](https://console.aws.amazon.com/mediatailor/home).

1. Verify that the CloudFront distribution is deployed and enabled in the [CloudFront console](https://console.aws.amazon.com/CloudFront/home).

1. Test playback using a sample manifest:

   1. Construct the full playback URL as described in [Construct playback URLs](use-deployed-resources.md#construct-playback-urls).

   1. Use a video player that supports HLS or DASH (like VLC, JW Player, or the AWS console player).

   1. Verify that content plays and ads are inserted at the expected break points.

1. Check the MediaTailor logs in CloudWatch for any ad insertion errors.

When testing ad insertion, look for these indicators of success:
+ Smooth transitions between content and ads
+ Ads appear at the expected break points (pre-roll, mid-roll, post-roll)
+ Ad quality matches the content quality
+ No buffering or playback errors during ad transitions

For more detailed testing procedures, see [Understanding AWS Elemental MediaTailor ad insertion behavior](ad-behavior.md). For comprehensive CDN integration testing and validation, see [Testing and validation for CDN and MediaTailor integrations](cdn-integration-testing.md).

# Troubleshoot common CloudFormation deployment issues for CDN and MediaTailor integrations
Troubleshoot deployment issues

AWS Elemental MediaTailor deployment issues can occur even with automation during deployment or playback. As a broadcast professional, understanding how to troubleshoot these issues will help you maintain a reliable streaming service with ad insertion.

If you encounter issues with your CloudFormation deployment or the resulting MediaTailor and CloudFront integration, refer to these common problems and solutions:

## CloudFormation deployment issues


Stack creation fails with "Resource creation failed" error  
**Possible causes:**  
+ Invalid content origin domain name format
+ Insufficient permissions to create resources
**Solution:** Check the specific resource error in the CloudFormation events tab. Verify that the content origin domain name is correctly formatted without protocol prefixes or paths. Ensure your IAM role has sufficient permissions to create all required resources.

CloudFront distribution takes a long time to deploy  
**Cause:** CloudFront distributions typically take 15-30 minutes to fully deploy.  
**Solution:** This is normal behavior. Wait for the distribution to reach the "Deployed" state before testing.

## Playback and ad insertion issues


Content plays but no ads are inserted  
**Possible causes:**  
+ Ad decision server not responding or returning empty VAST
+ Content does not contain ad markers
**Solution:** Verify that your ad server is accessible and returning valid VAST responses. Check that your content has proper ad markers (SCTE-35 markers for live content or ad break tags for VOD).

403 Forbidden errors when accessing content  
**Possible causes:**  
+ Origin access control not configured correctly
+ Origin bucket or endpoint permissions issues
**Solution:** For Amazon S3 origins, verify that the bucket policy allows access from the CloudFront distribution. For MediaPackage origins, check that the origin access control is properly configured and that the endpoint is accessible.

Playback errors or buffering  
**Possible causes:**  
+ Cache behavior path patterns not matching content paths
+ Incorrect origin domain configuration
**Solution:** Verify that your cache behaviors have the correct path patterns to route requests to the appropriate origins. Check CloudFront logs to see which origin is handling the requests and confirm it's the expected one.

For broadcast professionals, these additional troubleshooting tips may help:
+ Use the Amazon CloudWatch Logs Insights to search for specific error patterns in MediaTailor logs
+ Test with a simple VAST ad server first (like the default one provided in the template) before using your production ad server
+ Verify your content's ad markers using the MediaTailor manifest inspector tool in the console
+ Check network traffic in your browser's developer tools to see if requests to the ad server are being made correctly

For additional troubleshooting, check the CloudWatch logs for both MediaTailor and CloudFront to identify specific errors. 

# Customize the CloudFormation template for CDN and MediaTailor integrations
Customize the template

AWS Elemental MediaTailor template customization allows broadcast professionals to adapt the AWS CloudFormation template to fit specific workflow requirements. Although the basic template works for many scenarios, these customizations can help you address more complex needs.

The examples below show YAML code snippets that you can add to the template. If you're not familiar with YAML or CloudFormation syntax, consider working with a developer or AWS solutions architect to make these changes.

You can customize the CloudFormation template to meet your specific workflow requirements.

## Add or modify origins


For broadcast workflows that use multiple content sources (like primary and backup sources, or different content libraries), you can add additional origins to your CloudFront distribution:

```
Origins:
  # Add a new origin for additional content
  - Id: SecondaryContentOrigin
    DomainName: secondary-content.example.com
    CustomOriginConfig:
      OriginProtocolPolicy: 'https-only'
      OriginSSLProtocols: 
        - TLSv1.2
```

Then add a corresponding cache behavior to route specific patterns to this origin:

```
CacheBehaviors:
  - PathPattern: '/secondary-content/*'
    TargetOriginId: SecondaryContentOrigin
    ViewerProtocolPolicy: 'https-only'
    CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6  # Managed-CachingOptimized
```

## Create custom cache policies


For broadcast workflows with specific caching requirements (like quality selection parameters or viewer authentication), you can create custom cache policies instead of using the managed ones. For detailed guidance on TTL values and caching strategies, see [Caching optimization for CDN and MediaTailor integrations](cdn-optimize-caching.md).

```
# Define a custom cache policy
CustomCachePolicy:
  Type: AWS::CloudFront::CachePolicy
  Properties:
    CachePolicyConfig:
      Name: !Sub '${AWS::StackName}-CustomCachePolicy'
      DefaultTTL: 86400  # 24 hours
      MaxTTL: 31536000   # 1 year
      MinTTL: 1          # 1 second
      ParametersInCacheKeyAndForwardedToOrigin:
        CookiesConfig:
          CookieBehavior: none
        HeadersConfig:
          HeaderBehavior: none
        QueryStringsConfig:
          QueryStringBehavior: whitelist
          QueryStrings:
            - quality
            - format

# Reference the custom policy in a cache behavior
CacheBehaviors:
  - PathPattern: '/custom-path/*'
    TargetOriginId: ContentOrigin
    ViewerProtocolPolicy: 'https-only'
    CachePolicyId: !Ref CustomCachePolicy
```

## Enhance MediaTailor configuration


For broadcast workflows that need advanced ad insertion features, you can enhance the MediaTailor configuration with options like ad prefetching (to reduce latency), personalization thresholds, and bumper ads.

```
MediaTailorPlaybackConfig:
  Type: AWS::MediaTailor::PlaybackConfiguration
  Properties:
    # Add ad prefetching for improved performance
    AvailSuppression:
      Mode: BEHIND_LIVE_EDGE
      Value: 00:00:00
    # Add personalization parameters
    PersonalizationThresholdSeconds: 2
    # Add bumper ads
    Bumper:
      StartUrl: https://example.com/bumper-start.mp4
      EndUrl: https://example.com/bumper-end.mp4
    # Other existing properties...
```

For more information about MediaTailor configuration options, see [Using AWS Elemental MediaTailor to insert ads](configurations.md).

## Add security features


For broadcast workflows with specific security requirements (like geo-restrictions or protection against DDoS attacks), you can add AWS WAF integration and geo-restrictions:

```
# Create a AWS WAF Web ACL
WebACL:
  Type: AWS::WAFv2::WebACL
  Properties:
    Name: !Sub '${AWS::StackName}-WebACL'
    Scope: CloudFront
    DefaultAction:
      Allow: {}
    VisibilityConfig:
      SampledRequestsEnabled: true
      CloudWatchMetricsEnabled: true
      MetricName: !Sub '${AWS::StackName}-WebACL'
    Rules:
      - Name: RateLimitRule
        Priority: 0
        Action:
          Block: {}
        VisibilityConfig:
          SampledRequestsEnabled: true
          CloudWatchMetricsEnabled: true
          MetricName: RateLimitRule
        Statement:
          RateBasedStatement:
            Limit: 1000
            AggregateKeyType: IP

# Reference the AWS WAF Web ACL in the CloudFront distribution
CloudFrontDistribution:
  Type: AWS::CloudFront::Distribution
  Properties:
    DistributionConfig:
      WebACLId: !GetAtt WebACL.Arn
      # Add geo-restriction
      Restrictions:
        GeoRestriction:
          RestrictionType: whitelist
          Locations:
            - US
            - CA
            - GB
      # Other existing properties...
```

For more information about CloudFormation templates, see the [AWS CloudFormation User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-guide.html).

For broadcast-specific CloudFormation templates and examples, see the [AWS Media Services Tools GitHub repository](https://github.com/aws-samples/aws-media-services-tools).

# AWS CloudFormation template reference for AWS Elemental MediaTailor and Amazon CloudFront integration
Template reference

AWS Elemental MediaTailor integration with Amazon CloudFront can be automated using the following complete AWS CloudFormation template:

```
AWSTemplateFormatVersion: '2010-09-09'
Description: |
  CloudFormation template that sets up AWS Elemental MediaTailor integration with CloudFront Distribution
  for server-side ad insertion. This template supports various content origins including MediaPackage, Amazon S3,
  and custom origins, making it versatile for different streaming architectures.

Parameters:
  AdServerUrl:
    Type: String
    Default: 'https://d1kbmkziz9rksx.CloudFront.net/VASTEndpoint.xml'
    Description: URL of the VAST ad server for dynamic ad insertion. Static VAST endpoint provided for testing. 

  ContentOriginDomainName:
    Type: String
    Description: |
      Domain name of your content origin without protocol (e.g., mediapackage-domain.mediapackagev2.us-west-2.amazonaws.com,
      mybucket.s3.amazonaws.com, or custom-origin.example.com).
      Do not include http:// or https:// prefixes or any paths.
    AllowedPattern: "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"
    ConstraintDescription: Must be a valid domain name (e.g., example.com) without protocol or path components. IP addresses are not allowed.

  ContentOriginType:
    Type: String
    AllowedValues:
      - mediapackagev2
      - s3
      - custom
    Default: mediapackagev2
    Description: |
      The type of content origin:
      - mediapackagev2: AWS Elemental MediaPackage V2
      - s3: Amazon S3 bucket
      - custom: Any other custom origin

Resources:
  #---------------------------------------------------------------------------
  # Origin Access Control (for securing MediaPackage V2 and Amazon S3 origins)
  #---------------------------------------------------------------------------
  CloudFrontOriginAccessControl:
    Type: AWS::CloudFront::OriginAccessControl
    Condition: IsNotCustomOrigin
    Properties:
      OriginAccessControlConfig:
        Name: !Sub '${AWS::StackName}-OAC'
        OriginAccessControlOriginType: !Ref ContentOriginType
        SigningBehavior: always
        SigningProtocol: sigv4
        Description: Origin Access Control for content origin

  #---------------------------------------------------------------------------
  # MediaTailor Playback Configuration
  #---------------------------------------------------------------------------
  MediaTailorPlaybackConfig:
    Type: AWS::MediaTailor::PlaybackConfiguration
    Properties:
      Name: !Sub '${AWS::StackName}-PlaybackConfig'
      # The video content source should point to your CloudFront distribution
      VideoContentSourceUrl: !Sub 'https://${CloudFrontDistribution.DomainName}/'
      # The Ad Decision Server URL is where MediaTailor will request ads
      AdDecisionServerUrl: !Ref AdServerUrl
      # Configuration for pre-roll ads during live streams
      LivePreRollConfiguration:
        AdDecisionServerUrl: !Ref AdServerUrl
        MaxDurationSeconds: 30
      # CDN configuration for integrating with CloudFront
      CdnConfiguration:
        AdSegmentUrlPrefix: '/'
        ContentSegmentUrlPrefix: '/'
      # Set a reasonable manifest segment timeout
      ManifestProcessingRules:
        AdMarkerPassthrough:
          Enabled: false

  #---------------------------------------------------------------------------
  # CloudFront Distribution
  #---------------------------------------------------------------------------
  CloudFrontDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Enabled: true
        HttpVersion: http2and3
        IPV6Enabled: true
        Comment: !Sub 'Distribution for MediaTailor ad insertion with ${ContentOriginType} origin'
        
        # Default cache behavior points to the content origin
        DefaultCacheBehavior:
          TargetOriginId: ContentOrigin
          ViewerProtocolPolicy: 'https-only'
          # Using managed policies for optimal performance and simplicity
          CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6  # Managed-CachingOptimized
          OriginRequestPolicyId: 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf # Managed-HostHeaderOnly
          ResponseHeadersPolicyId: eaab4381-ed33-4a86-88ca-d9558dc6cd63  # Managed-CORS-with-preflight-and-SecurityHeadersPolicy
          Compress: true
        
        # Define all the origins needed for the workflow
        Origins:
          # Main content origin (MediaPackage, Amazon S3, or Custom)
          - Id: ContentOrigin
            DomainName: !Ref ContentOriginDomainName
            # Apply Origin Access Control for secure origins
            OriginAccessControlId: !If [IsNotCustomOrigin, !GetAtt CloudFrontOriginAccessControl.Id, !Ref "AWS::NoValue"]
            # For custom origins, we need a CustomOriginConfig
            CustomOriginConfig:
              OriginProtocolPolicy: 'https-only'
              OriginSSLProtocols: 
                - TLSv1.2
              OriginKeepaliveTimeout: 5
              OriginReadTimeout: 30
              HTTPPort: 80
              HTTPSPort: 443
              
          # MediaTailor Manifests Origin - handles manifest manipulation for ad insertion
          - Id: MediaTailorManifests
            DomainName: !Sub 'manifests.mediatailor.${AWS::Region}.amazonaws.com'
            CustomOriginConfig:
              OriginProtocolPolicy: 'https-only'
              OriginSSLProtocols: 
                - TLSv1.2
              OriginKeepaliveTimeout: 5
              OriginReadTimeout: 30
            # Origin Shield improves caching efficiency 
            OriginShield:
              Enabled: true
              OriginShieldRegion: !Ref AWS::Region
              
          # MediaTailor Segments Origin - handles personalized ads
          - Id: MediaTailorSegments
            DomainName: !Sub 'segments.mediatailor.${AWS::Region}.amazonaws.com'
            CustomOriginConfig:
              OriginProtocolPolicy: 'https-only'
              OriginSSLProtocols: 
                - TLSv1.2
              OriginKeepaliveTimeout: 5
              OriginReadTimeout: 30
        
        # Cache behaviors to route specific request patterns to the right origin
        CacheBehaviors:
          # Handle MediaTailor segment requests for ad content which are cache-able
          - PathPattern: '/tm/*'
            TargetOriginId: MediaTailorSegments
            ViewerProtocolPolicy: 'https-only'
            CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6  # Managed-CachingOptimized
            OriginRequestPolicyId: 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf  # Managed-HostHeaderOnly
            ResponseHeadersPolicyId: eaab4381-ed33-4a86-88ca-d9558dc6cd63  # Managed-CORS-with-preflight-and-SecurityHeadersPolicy
            Compress: true
            
          # Handle MediaTailor interstitial (SGAI) media requests which are cache-able
          - PathPattern: '/v1/i-media/*'
            TargetOriginId: MediaTailorManifests
            ViewerProtocolPolicy: 'https-only'
            CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6  # Managed-CachingOptimized
            OriginRequestPolicyId: 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf  # Managed-HostHeaderOnly
            ResponseHeadersPolicyId: eaab4381-ed33-4a86-88ca-d9558dc6cd63  # Managed-CORS-with-preflight-and-SecurityHeadersPolicy
            Compress: true
            
          # Handle MediaTailor Personalized manifests which are not cache-able
          - PathPattern: '/v1/*'
            TargetOriginId: MediaTailorManifests
            ViewerProtocolPolicy: 'https-only'
            CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad # Managed-CachingDisabled
            OriginRequestPolicyId: 59781a5b-3903-41f3-afcb-af62929ccde1 # Managed-AllViewer
            ResponseHeadersPolicyId: eaab4381-ed33-4a86-88ca-d9558dc6cd63  # Managed-CORS-with-preflight-and-SecurityHeadersPolicy
            Compress: true
            
          # Handle MediaTailor segment *redirect* requests which are not cache-able (used for server side reporting)
          - PathPattern: '/segment/*'
            TargetOriginId: MediaTailorManifests
            ViewerProtocolPolicy: 'https-only'
            CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad # Managed-CachingDisabled
            OriginRequestPolicyId: 59781a5b-3903-41f3-afcb-af62929ccde1 # Managed-AllViewer
            ResponseHeadersPolicyId: eaab4381-ed33-4a86-88ca-d9558dc6cd63  # Managed-CORS-with-preflight-and-SecurityHeadersPolicy
            Compress: true

Conditions:
  IsNotCustomOrigin: !Not [!Equals [!Ref ContentOriginType, 'custom']]

Outputs:
  CloudFrontDomainName:
    Description: Domain name of the CloudFront distribution
    Value: !GetAtt CloudFrontDistribution.DomainName
    
  HlsManifestUrl:
    Description: URL for HLS manifest with ads inserted (append your manifest path)
    Value: !Sub 'https://${CloudFrontDistribution.DomainName}${MediaTailorPlaybackConfig.HlsConfiguration.ManifestEndpointPrefix}'
    
  DashManifestUrl:
    Description: URL for DASH manifest with ads inserted (append your manifest path)
    Value: !Sub 'https://${CloudFrontDistribution.DomainName}${MediaTailorPlaybackConfig.DashConfiguration.ManifestEndpointPrefix}'
    
  MediaTailorPlaybackConfigName:
    Description: Name of the MediaTailor playback configuration
    Value: !Ref MediaTailorPlaybackConfig
```