How to configure a custom domain for an AWS AppRunner Service using AWS CloudFormation

on
Jan 15, 2023
in

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:

  1. associate the domain name with the apprunner service
  2. store the required domain validation records in your DNS hosted zone
  3. create an alias record to resolve to the actual apprunner service
  4. 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

Mark van Holsteijn is a senior software systems architect, and CTO of binx.io. He is passionate about removing waste in the software delivery process and keeping things clear and simple.
Share this article: Tweet this post / Post on LinkedIn