Background Link to heading
I have recently started using AWS Organizations to create and manage multiple AWS accounts. This is great for a number of reasons:
- By adhering to a “one AWS account, one project” model, I can easily track my spend. A glance at the monthly bill for the AWS account hosting a project is enough to tell me how much the project costs, in total. No mucking about with tags.
- As long as I do not explicitly set up cross-account access via IAM Roles, then project accounts are completely isolated from one another.
- All accounts can use the billing info associated with the AWS Organizations “owner” account (the account that was used to create the AWS Organizations “tree”). I don’t need separate billing or contact info for each new AWS Organizations account.
For the most part, this is great. I still run some projects (like my personal website) directly out of the master account that owns my AWS Organizations tree, but for the most part I have migrated other projects into their own separate accounts.
Moving domain names around Link to heading
Using AWS Organizations for new projects is easy: simply create a new AWS Organizations member account, log into it (usually via AssumeRole from the master account) and start setting things up.
It’s not so easy if you have existing resources that have to be shuffled around. In particular, if you have domain names you need to move, you’ll swiftly discover that there is no option in the AWS console to move a registered domain name from one AWS account to another.
It’s not difficult, but it can only be done with the AWS CLI.
The actual process Link to heading
Moving an existing domain is a two-step process:
- First, move your domain name from the source AWS account to the destination account.
- Create a hosted zone in the destination account, copy over your DNS records, and point your domain at the new NS servers in the new Hosted Zone.
I found instructions here but felt like they could use a more detailed writeup. So here goes.
Step 1: Starting the transfer (source AWS account) Link to heading
From the source account (where the domain name is currently located), execute the following:
aws route53domains transfer-domain-to-another-aws-account --domain-name <domain name> --account-id <target-account-id>
For instance, if your domain name is mysite.com
and your account ID is 228348348
, then you would run:
aws route53domains transfer-domain-to-another-aws-account --domain-name mysite.com --account-id 228348348
If this works, it will generate some JSON-formatted output, like this:
{
"OperationId": "91e1a9b8-66t1-4de2-bd67-f31738bd4b7c",
"Password": "=Fo.tR3:qV0+J%"
}
Make sure you save this somewhere. You will need that password later.
Step 2: Accepting the transfer (target AWS account) Link to heading
In a text editor, open up a fresh file and copy-paste this in:
{
"Password": "mypassword",
"DomainName": "mysite.com"
}
Replace “mypassword” with the password you saved earlier, and replace “mysite.com” with your domain name.
Save that file somewhere. Give it an easy to remember name like domain.json
. Then, from a terminal (you want to be in the directory where you saved the file), run:
aws route53domains accept-domain-transfer-from-another-aws-account --cli-input-json file://domain.json --profile target_account
That weird little file://
bit in front of your filename is required, so make sure to include that.
The --profile target_account
flag at the end tells the AWS CLI which profile to use to execute the command. Up to this point, we assumed we were executing all commands using the AWS CLI default profile, which we assumed was associated with the source account.
We now want to execute commands inside the target account, which is why we have added the --profile
flag at the end. We are explicitly telling the AWS CLI to use a different identity (in this case, belonging to a different AWS account) to execute the command.
How do you create multiple AWS CLI profiles? Easy: you modify .aws/config
in your home directory. Full instructions are here.
As an example, my .aws/config
looks something like this (anonymized, obviously):
[profile default]
region = us-west-2
[profile target_account]
role_arn = arn:aws:iam::234834834:role/OrganizationAccountAccessRole
source_profile = default
region = us-east-1
You’ll notice that there are two [profile]
blocks. That first one is the default profile. In my case, it points to the master account that “owns” the AWS Organizations account tree.
That second [profile]
block is for the target account I’m moving my domain to. It is an AWS Organizations account, and I’m accessing it using an IAM role called OrganizationAccountAccessRole
, which is a default Administrator role created inside all new AWS Organizations accounts by default.
So in my case, to accept the domain transfer inside the target account, the correct AWS CLI command would be:
aws route53domains accept-domain-transfer-from-another-aws-account --cli-input-json file://domain.json --profile target_account
Of course you don’t have to make things so complex. If you prefer, you could just use an Access Key and Access Key Secret in your target account [profile]
, rather than an IAM Role. Up to you! I did it this way because I’m using AWS Organizations, but you might choose to do things differently if you’re moving your domain between unrelated AWS accounts.
That’s it! You should now be able to go to the Registered Domains
section in the Route53 console under your target account, and see your domain name listed there.
Or, if you want to keep doing things the CLI Way:
aws route53domains list-domains --profile target_account
Which should output something like this:
{
"Domains": [
{
"DomainName": "mysite.com",
"AutoRenew": true,
"TransferLock": false,
"Expiry": 1697595818.0
}
]
}
Troubleshooting Link to heading
Depending on which AWS regional endpoint your AWS CLI is set up to use by default, you might get an error like this one:
Could not connect to the endpoint URL: "https://route53domains.us-west-2.amazonaws.com/"
The easiest way to fix this is to change the region =
line in your .aws/config
file to something like region = us-east-1
. A lot of AWS domain-related services live in the us-east-1
region, so choosing that as your default endpoint can solve this issue.
Step 3: Hosted Zone configuration Link to heading
Your next step will be to create a new Hosted Zone in the target account, move your DNS records over (but do not alter the SOA or NS records under either Hosted Zone!), then update the Nameservers list under your domain name to point to the NS servers listed in your new Hosted Zone.
I don’t go into details here. The existing AWS documentation on migrating Hosted Zones is already very good.
Hope this helps somebody!