When you want to configure a custom domain for an AppRunner service with CloudFormation, you will notice that the required resource
AWS::AppRunner::CustomDomain is missing. In this blog I will introduce a temporary solution for this problem, which will allow you to deploy everything using CloudFormation.
configuring the custom domain
To set up a custom domain for an App Runner service using CloudFormation, you follow these steps:
- associate the domain name with the apprunner service
- store the required domain validation records in your DNS hosted zone
- create an alias record to resolve to the actual apprunner service
- add the custom provider to do the magic!
associate the custom domain name
To associate the custom domain name with the apprunner service, add the following resource to your template:
AppRunnerCustomDomain: Type: Custom::AppRunnerCustomDomain Properties: ServiceArn: !Ref App DomainName: !Ref DomainName ServiceToken: !GetAtt AppRunnerCustomDomainProvider.Arn
This will call the AssociateCustomDomain to associate the domain name with the AWS App Runner subdomain URL of your service. It will return the domain validation records as the attribute
store the domain validation records
To prove you own the domain, you have to add the validation resource records to your DNS zone as follows:
CertificateValidationRecords: Type: AWS::Route53::RecordSetGroup Properties: Comment: provided by AWS AppRunner HostedZoneId: !GetAtt DNSDomain.Id RecordSets: !GetAtt AppRunnerCustomDomain.ValidationResourceRecords
The domain validation records returned by the
AppRunnerCustomDomain have default values for weight and time-to-live. The resource set id is the set to the app runner service id.
The validation records allow the AppRunner service to create the required certificates for the domain name.
create an alias record for apprunner service
To resolve the custom domain name to the app runner subdomain, add a route53 alias records as follows:
AppAlias: Type: AWS::Route53::RecordSetGroup Properties: Comment: provided by AWS AppRunner HostedZoneId: !GetAtt DNSDomain.Id RecordSets: - Name: !Ref DomainName Type: A AliasTarget: DNSName: !GetAtt App.ServiceUrl HostedZoneId: !FindInMap [AppRunnerHostedZones, !Ref 'AWS::Region', Id]
To get the id of the hosted zone of the subdomain of
awsapprunner.com in your region, look it up in the AWS console and add it to the map. We only did the lookup for eu-west-1. If there is an API call to retrieve the hosted zones, please let us know!
Mappings: AppRunnerHostedZones: eu-west-1: Id: Z087551914Z2PCAU0QHMW
add the custom provider
Add the custom provider to make the appropriate calls to manage the domain names of apprunner services. Normally we distribute custom providers as ready-to-deploy Lambda zipfiles, but as we expect the
AWS::AppRunner::CustomDomain any time soon, we have chosen to create an inline version of the AppRunnerCustomDomain provider.
AppRunnerCustomDomainProvider: Type: AWS::Lambda::Function Properties: Description: Custom::AppDomainCustomDomain provider Handler: index.handler MemorySize: 128 Timeout: 900 Role: !GetAtt 'LambdaRole.Arn' Runtime: python3.9 Code: ZipFile: | ...
As it is over 200 lines of YAML and Python, we recommend to copy the appropiate lines from the example CloudFormation template you can also download the source code of the AppRunnerCustomDomain separately and use our aws-cfn-uodate utility to update your template.
that is all!
So, there are only three real steps to associate a custom domain with an AWS AppRunner service. The custom provider is a temporary stop gap measure.
With this custom provider you can associate custom domains with AWS AppRunner services using AWS CloudFormation, until AWS::AppRunner::CustomDomain appears. If it helps, we would like to offer AWS our services to ensure that CloudFormation is always on-par with the API before new features are released.
Image by Anne-marie Ridderhof from Pixabay