Azure : AWS Single-Account Access from manual to automated using 3 easy steps.

Introduction
As DevOps, Software Developers, Cloud Administrators or any other form of IT related roles, we all deal with usernames and passwords and also multiple accounts across multiple platforms.
At Digitalis.io and AxonOps we have a multitude of different AWS accounts that we need to access on a day-to-day basis.
If you have had the privilege of setting up Azure to AWS Single Sign-On(SSO) you will know that it is a very manual process as documented here.
It takes 29 different steps just for setup excluding account setups to perform in Azure and AWS combined. It can become quite time consuming and prone to error when you have to repeat it for more than 1 AWS account.
Yes, AWS IAM Identity Centre does simplify it, but :
What if your AWS accounts are not all part of the same Organization.
What if you want to keep the user management in Azure and not have to manage another set of users in AWS.
Then AWS Single-Account Access is the preferred option.

Challenges
While putting together the https://github.com/digitalis-io/tf-azure-aws-single-account-access there were a couple challenges that needed to be overcome.
Download the Metadata XML file and upload to AWS
The process in the Microsoft HowTo guide is to click on a link in the Enterprise application and then save the file to disk.

After doing some digging I found the correct URL as the right click Copy Link option does not work. The URL for downloading the Metadata.xml file has some parameters that need to be passed. The is the ID of the application that you are creating, and other than the parameters the URL has no other values needed.
data "http" "azure_metadata_xml" {
depends_on = [time_sleep.wait_60_seconds]
url = "https://login.microsoftonline.com/${azuread_service_principal.azuread_service_principal.application_tenant_id}/federationmetadata/2007-06/federationmetadata.xml?appid=${azuread_service_principal.azuread_service_principal.application_id}"
}
Waiting til the Application has been Provisioned
Having to wait till the app has been created so the correct Metadata.xml file is genererated is required for the correct formatted XML file to be generated and ready to download.
A 60 second delay was built into the Terraform to allow the creation process to finalise.
resource "time_sleep" "wait_60_seconds" {
depends_on = [
azuread_service_principal.azuread_service_principal,
azuread_application_identifier_uri.azuread_aws_sso_application_uri,
azuread_service_principal_token_signing_certificate.azuread_signing_certificate,
azuread_service_principal_claims_mapping_policy_assignment.azuread_claims_mapping_policy_assignment,
azuread_claims_mapping_policy.azuread_sso_policy,
data.azuread_application.azuread_aws_sso_application
]
create_duration = "60s"
}
The current setup saves the file to a generic hashicorp vault location.
This can be changed to save to a local file instead if you choose.
resource "vault_generic_secret" "metadata_sso_xml" {
depends_on = [data.http.azure_metadata_xml]
path = "secret/aws/sso/${var.env}/${var.account}"
data_json = <<EOT
{
"metadata_xml": "${base64encode(data.http.azure_metadata_xml.response_body)}"
}
EOT
lifecycle {
ignore_changes = [data_json]
}
}
Replicating the Gallery Apps automated background steps
Figuring out how to reproduce the Azure UI steps using Terraform was all about digging and research, since the step by step guide uses a Gallery app which has a lot of the complexity hidden and as such is not a forthcoming as to what specific components form part of the setup was probably the biggest time consuming part of putting this repo together.
Create resource and test, based on outcome destroy and repeat or success.
It was a lot of the former.
Attributes and Claims Setup
If you create this resource with terraform, when logging into the Azure Enterprise application and viewing the config we will see the following error.

The above doesnt cause any issues however it does hide the fact that the values have been set and what they are. So you will only ever be able to see/retrieve them vi Graph or Powershell commands.
Running
The code in this repo will automate the creation of the AWS Single Account Access setup for you.
There are 3 steps that are needed for the automation process:
Step 1 : Set the correct AWS, AZURE and Terraform variables.
The terraform variables can also be set in the variables.tf or a tfvars file can be passed at run time.
AWS :
- export AWS_ACCESS_KEY_ID="<CORRECT AWS ACCESS KEY FOR AWS ACCOUNT>"
- export AWS_SECRET_ACCESS_KEY="<CORRECT AWS SECRET ACCESS KEY>"
AZURE :
- export ARM_TENANT_ID=<AZURE ACCOUNT/TENANT FOR SSO SETUP>
Terraform :
- export TF_VAR_region=eu-west-2 #This is the AWS REGION you are deploying too
- export TF_VAR_account=CAN_BE_ANY_DESCRIPTIVE_NAME_FOR_YOUR_AWS_ACCOUNT
- export TF_VAR_env=dev #e.g Dev, Test,Prod, PreProd or any Environment moniker
Step 2 : Update the locals.tf file with :
- List of the Group Display names in AzureAD/EntraID that you want to assign to ReadOnly or Admin
- Notification email address for certificate expirations.
read_only_groups = [
"GROUP 1",
"GROUP 2",
]
admin_groups = [
"ADMIN GROUP 1",
"ADMIN GROUP WITH LONG DISPLAY NAME 2",
]
notification_email = "info@digitalis.io"
Step 3 : Plan then Apply using Terraform
terraform plan
terraform apply
Conclusion
If the above code has been run you can log into myapplications.microsoft.com and you should see the SSO App in the Dashboard.

If you need any help, please do get in touch.