Jets Assets CloudFront

Jets can create a CloudFront distribution and use it to serve your assets that Jets uploads to s3. Using a CloudFront CDN is recommended.

Though serving assets from S3 is leaps and bounds better than serving them from Lambda, using a CloudFront CDN is even better. CDNs are designed for this very purpose. Your users will have a better experience since the CDN edge locations are closer to them.

To enable:

config/jets/deploy.rb

Jets.deploy.configure do
  config.assets.cloudfront.enable = true
  config.assets.cloudfront.cert.arn = acm_cert_arn(domain: "example.com", region: "us-east-1")
  config.assets.cloudfront.route53.enable = true
  # config.assets.cloudfront.aliases = %w[
  #   assets0.example.com
  #   assets1.example.com
  #   assets2.example.com
  #   assets3.example.com
  # ]
end

Note, when config.assets.cloudfront.aliases is overrides conventional aliases. The conventional aliases would look like this.

config/jets/deploy.rb

Jets.deploy.configure do
  config.assets.cloudfront.aliases = %w[
    demo-dev-assets0.example.com
    demo-dev-assets1.example.com
    demo-dev-assets2.example.com
    demo-dev-assets3.example.com
  ]
end

It is assumed that you do not want the conventional aliases when you explicitly set aliases.

Multiple Hosts

By default, Jets will create multiple hosts from demo-dev-assets0.example.com to demo-dev-assets3.example.com to serve assets. This is catered to the Rails Asset hosts handling. See: ActionView AssetUrlHelper

You can use the %d wildcard in the asset_host to distribute the requests over four hosts.

Expiring CloudFront Caches

On initial creation of the Assets, CloudFront Distribution assets may appear “missing”. This can happen if Route53 does not manage the DNS and Jets cannot automate the DNS record creation. If requests hit CloudFront before you’re done manually setting up the DNS entries on your side, then the CloudFront requests may cache “missing” assets. In this case, you need to expire the caches. Here’s a cheat sheet command.

DIST=E1NL288EXAMPLE
aws cloudfront create-invalidation --distribution-id $DIST --paths '/*'
  • CloudFront Assets Distribution: Jets can create a CloudFront distribution and automatically configure it for assets that get precompiled to the public/assets folder by rails assets:precompile.
  • CloudFront Lambda Distribution: Jets can create a CloudFront distribution and automatically configure it in front of the deployed controller Lambda Function.
  • CloudFront Uploads Distribution: Jets can create a CloudFront distribution and automatically configure it for files like your ActiveStorage uploads.

Reference

The table below covers each setting. Each option is configured with config.OPTION. The config. portion is not shown for conciseness. IE: logger.level vs config.logger.level.

Name Default Description
assets.cloudfront.cert.arn nil ACM Cert ARN. Required when using assets.cloudfront.enable = true. Must be in us-east-1 since it’s for CloudFront. This helper method is useful: acm_cert_arn(domain: "example.com", region: "us-east-1")
assets.cloudfront.cert.minimum_protocol_version TLSv1.2_2021 The TLSv1.2_2021 has been the Cloudfront console default as of 12/24/23.
assets.cloudfront.cert.ssl_support_method sni-only The distribution accepts HTTPS connections from only viewers that support server name indication (SNI). This is recommended. Most browsers and clients support SNI.
assets.cloudfront.default_cache_behavior.allow_methods %w[HEAD GET] Allow methods for the distribution.
assets.cloudfront.default_cache_behavior.properties {} Default cache behavior properties to merge. Allows overriding the propertes in a general way.
assets.cloudfront.default_cache_behavior.viewer_protocol_policy redirect-to-https How CloudFront should handle http requests. The default is to redirect http to https. IE: A https upgrade.
assets.cloudfront.route53.comment “Jets managed CloudFront distribution DNS record” Route53 Record comment.
assets.cloudfront.route53.enable false Enables creation of the Route53 DNS Records that match the CloudFront aliases.
assets.cloudfront.route53.hosted_zone_id nil Route53 Hosted Zone ID. This takes higher precedence over hosted_zone_name.
assets.cloudfront.route53.hosted_zone_name nil Route53 Hosted Zone ID. Allows you to specify the config in a human-readable way. Note route53.domain also works as a convenience.
assets.cloudfront.route53.properties {} Route53 DNS record properties to merge. Allows overriding the propertes in a general way.
assets.cloudfront.route53.ttl 60 Route53 DNS TTL. This is only used when assets.cloudfront.route53.use_alias = false and a CNAME is created instead.
assets.cloudfront.route53.use_alias true Use an A Record with the “Alias” Route53 feature. This allows APEX domains to work with CloudFront distributions.
assets.cloudfront.enable false Enables CloudFront Distribution in front of the Lambda URL. See: Lambda URL CloudFront Distribution
assets.cloudfront.http_version http2 HTTP version that you want viewers to use to communicate with CloudFront.
assets.cloudfront.ipv6_enabled true Enables IPV6 also for CloudFront.
assets.cloudfront.origin.custom_origin_config { HTTPSPort: 443, OriginProtocolPolicy: “https-only” } Custom origin config.
assets.cloudfront.origin.properties {} Origin properties to merge. Allows overriding the propertes in a general way.
assets.cloudfront.origin.viewer_protocol_policy redirect-to-https How CloudFront should handle http requests. The default is to redirect http to https. IE: A https upgrade.
assets.cloudfront.price_class PriceClass_100 Price class you want to pay for CloudFront. There’s PriceClass_100, PriceClass_200, PriceClass_All. Note, since the lower price classes use less regions, they deploy faster.
assets.cloudfront.properties {} Properties to merge and override CloudFront Distribution
assets.cloudfront.spread_hosts true Whether or not to create multiple aliases with pattern assets%d.example.com to spread the requests. Related: Rails Assets
assets.enable true Enables Lambda Function URL for the Controller Lambda Function.

See Full Config Reference