A potential scenario is to have a single Terraform template repository where you need to manage AWS resources across a number of different AWS Accounts. However, because each AWS Account is the edge of its authentication and authorisation profile, there is a need to be able cross this boundary within your Terraform to be able to manage resources cross-account. A method of doing this is by the use of “aliases” within your Terraform, however you need to have your workstation’s AWS Configuration configured appropriately and specify the aliases on each resource to ensure Terraform is managing the expected resource where it is located.
It is possible to have a “provider of last resort”, i.e. a provider which you have no aliases defined for, by doing this if you don’t include an alias/provider in the resource definition, it is assumed by Terraform to use this “last resort”, if you chose to do this is mostly down to your own preferences, however if you do manage accounts across AWS Account boundaries, being explicit in each resource can reduce the likelihood of unexpected results!
Define AWS Configuration (Profiles) on your AWS/Terraform Workstation
Although your locations and requirements will vary here is a simple example where I have an SSO (Single Sign On) based configuration along with two AWS Accounts (which I’ll use to create resources). My AWS configuration file was located in:
~\.aws\config
So we define the SSO session followed by the two profiles for our two AWS Accounts (~\.aws\config).
[sso-session mysso]
sso_start_url = https://3dfbv5d671.awsapps.com/start#
sso_region = eu-west-2
sso_role_name = AWSAdministratorAccess
sso_registration_scopes = sso:account:access
[profile hub-account]
sso_session = mysso
sso_account_id = 12345678910
sso_role_name = AWSAdministratorAccess
region = eu-west-2
[profile spoke-account]
sso_session = mysso
sso_account_id = 10987654321
sso_role_name = AWSAdministratorAccess
region = eu-west-2
Once those are added, you would authenticate as you normally would be using specifying a profile if you so require, although this is not mandatory because we’ll be specifying the actual profile (i.e. AWS Accounts) we want to use explicitly.
export AWS_PROFILE=hub-account
aws sso login --profile=$AWS_PROFILE
Define Providers (with Aliases) in your Terraform
We next need to define the “providers” within our Terraform. Within these definitions we include the “alias” for which we want to refer to the AWS Account when creating AWS resources within our Terraform. (providers.tf)
...
# Hub
provider "aws" {
alias = "hub"
region = "eu-west-2"
profile = "hub-account"
}
# Spoke
provider "aws" {
alias = "spoke"
region = "eu-west-2"
profile = "spoke-account"
}
...
As you can see, we are using a simple example as Hub and Spoke, our first definition is for a “Hub” Account where some network resources (e.g. TGW) will be deployed, then we’ll have a “Spoke” account where we’ll run some workloads, that will need to be “connected” to network resources (i.e. the TGW) within the “Hub” Account, although the mechanics of doing this are outside the scope of this document; this focusses on how you can refer to resources when using the Aliases.
Notice that the names specified in the “profile” line refer to the same name as is used within your AWS config file.
Define AWS Resources with Aliases to the Required Account
OK, so now we are ready to define the AWS Resources within the “Hub” and “Spoke” accounts. Let’s just use something really simple, a VPC (Virtual Private Cloud) definition. We’ll create one in each AWS Account and use the “Alias” (Provider) to tell Terraform which of the two profiles (i.e. providers) to use to create the VPC.
resource "aws_vpc" "hub_vpc" {
provider = aws.hub
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "hub_vpc"
}
}
resource "aws_vpc" "spoke_vpc" {
provider = aws.spoke
cidr_block = "10.1.0.0/16"
instance_tenancy = "default"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "spoke_vpc"
}
}
And that’s it, now when you run the Terraform Apply, it will use the two different Aliases (providers) to create the resources in the appropriate AWS account. Of course, you need to have logged in via SSO first!