Restructuring AWS - Proper way to configure AWS Accounts, Organisations and Profiles when using Serverless

Indeed, you need to create the ACM certificate in the AWS Account you’ll use it. You cannot create it on another account, it won’t be usable. Must be within the same account. (you can create a ACM certificate with the same domain names in separated accounts though, there is no conflict about that)

I am not quite sure if you fixed all your issues, but I had eventually documented the whole thing internally. Here it is, hope it helps.


Configure an application, with each stage running in a different AWS Account

The AWS configuration to run an app with each stage living in a different AWS Account is a bit tedious, to say the least.

ACM Certificate limitation

For instance, it is not possible for an AWS Account to access another AWS Account’s ACM Certificates.
This means that each certificate must be created in the proper AWS Account.
Therefore, there is a certificate for each stage.

Also, when configuring additional custom domain (like my-budget-advisor.com, which acts as the end-user production website for hep.the-funding-place.org),
the certificate must contain all domain names, like my-budget-advisor.com and hep.the-funding-place.org otherwise there will be a SSL handshake failure.

This implies to know the final end-user domain name when creating the production certificate,
or to have to create another certificate later, and replace the certificate used by the Custom Domain once issued.

Steps overview

The domain should have been bought from the Root AWS Account.
Since we don’t want to deploy anything on the-funding-place.org itself but only on sub-domains then we don’t have to change anything on the apex domain.

Instead, we’ll create a Hosted Zone for each domain you need to create, in the appropriate AWS Account (staging, production, etc.)

Then, we’ll create a “NS” Record Set for each of those domains, so that the requests going to a domain are handled by this domain.
This allows each stage to handle its own DNS properly (unlike it was done with unly.org and staging.unly.org)
and therefore allows developers to deal with DNS of the stage they have access to, instead of configuring all DNS through the AWS Root Account.
(which is neither developer-friendly, nor practical, nor a good design but rather a noobie mistake [that one’s on me!])

Steps to follow - Example with demo.the-funding-place.org

Now that we know a bit more about the limitations we have to deal with, let’s look at the step to setup the whole thing:

  1. Connect to the AWS Console with your usual AWS Account, which has cross-accounts privileges (ability to go to other AWS Accounts)

  2. Switch to the production account of your application, for instance [production] TFP in our case (cross account)

    1. Go to the Route 53 service → Hosted Zones
    2. Create a new Domain Name demo.the-funding-place.org
    3. Change its NS TTL value to 60 instead of 17200, so that if you ever happen to need to change NS in the future it would take 1mn instead of 2 days to propagate
    4. Copy it’s NS value (4 rows of domain names starting by ns-)
  3. Switch to the AWS Root Account (you need to leave the cross-account mode by clicking on “Back to YOUR_EMAIL”) [Only an admin can do that because need write access to the AWS Account “Root”]

    1. Go to the Route 53 service → Hosted Zones
    2. Select your hosted zone, for instance the-funding-place.org in our case
    3. Create a new Record Set, which will link the sub-domain to the DNS configuration defined in the [production] TFP AWS Account
      • Type: “NS”
      • Name: corresponding to the sub-domain you’re configuring, demo in our case (full name becomes demo.the-funding-place.org)
      • Value: The NS value you previously copied
  4. Nice! Now, the DNS settings defined in the [production] TFP AWS Account are applied to demo.the-funding-place.org and we can now create the ACM certificate

  5. Switch to the production account of your application, for instance [production] TFP in our case (cross account)

    1. Go to Certificate Manager service
    2. Select the N. Virginia region (us-east-1) (all certificates must always be created in this region to benefit from edge endpoints)
    3. Request a Certificate
      • Set the most global name as first name (important for the serverless-domain-manager plugin to resolve your certificate correctly), for instance demo.the-funding-place.org
      • Set all other names you may need, usually *.demo.the-funding-place.org is enough and covers potential future use-cases
      • Set all end-user production domain names (such as my-budget-advisor.com) if you know them (you can still create a new certificate later, update the domain name and remove the now-unused certificate, but that sounds like a pain, isn’t? :slight_smile:
    4. Validate and wait for the button Create record in Route 53 (if you added external domain names such as my-budget-advisor.com, then you’ll may need to manually add those records in the appropriate Hosted Zone, if there is no button to do it automatically)
  6. Nice! Your production setup is ready, let’s try to see if we can generate the custom domain by running sls create_domain, you must configure the NODE_ENV and stage properly or it won’t work:
    GROUP_NAME=demo NODE_ENV=production sls create_domain -s demo
    You should get a message like

    demo.the-funding-place.org’ was created/updated. New domains may take up to 40 minutes to be initialized.

    and have to wait a good 30mn for the process to be done.
    You can check its status in API Gateway → Custom Domains (make sure to select your region, like “Ireland”!)

  7. Now that the custom domain is being created, let’s setup the staging environment

  8. Switch to the staging account of your application, for instance [staging] TFP in our case (cross account)

    1. Go to the Route 53 service → Hosted Zones
    2. Create a new Domain Name staging.demo.the-funding-place.org
    3. Change its NS TTL value to 60 instead of 17200, so that if you ever happen to need to change NS in the future it would take 1mn instead of 2 days to propagate
    4. Copy it’s NS value (4 rows of domain names starting by ns-)
  9. Switch to the production account of your application, for instance [production] TFP in our case (cross account)

    1. Go to the Route 53 service → Hosted Zones
    2. Select your hosted zone, for instance demo.the-funding-place.org in our case
    3. Create a new Record Set, which will link the sub-domain to the DNS configuration defined in the [staging] TFP AWS Account
      • Type: “NS”
      • Name: corresponding to the sub-domain you’re configuring, staging in our case (full name becomes stagingdemo.the-funding-place.org)
      • Value: The NS value you previously copied
  10. Nice! Now, the DNS settings defined in the [staging] TFP AWS Account are applied to staging.demo.the-funding-place.org and we can now create the ACM certificate

  11. Switch to the staging account of your application, for instance [staging] TFP in our case (cross account)

    1. Go to Certificate Manager service
    2. Select the N. Virginia region (us-east-1) (all certificates must always be created in this region to benefit from edge endpoints)
    3. Request a Certificate
      • Set the most global name as first name (important for the serverless-domain-manager plugin to resolve your certificate correctly), for instance staging.demo.the-funding-place.org
      • Set all other names you may need, usually *.staging.demo.the-funding-place.org is enough and covers potential future use-cases
    4. Validate and wait for the button Create record in Route 53
  12. Nice! Your staging setup is ready, let’s try to see if we can generate the custom domain by running sls create_domain, you must configure the NODE_ENV and stage properly or it won’t work:
    GROUP_NAME=staging.demo NODE_ENV=staging sls create_domain -s demoStaging
    You should get a message like

    staging.demo.the-funding-place.org’ was created/updated. New domains may take up to 40 minutes to be initialized.

    and have to wait a good 30mn for the process to be done.
    You can check its status in API Gateway → Custom Domains (make sure to select your region, like “Ireland”!)

Finger in the nose, right? Yeah, that’s what documentation is for.
I bet you wish you had to figure all this out by yourselves :wink:

I did. :sweat_smile:

4 Likes