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 ValidationResourceRecords
.
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-update 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.
conclusion
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