Lab A5 – Integrate Azure AD with AWS Control Tower
Overview
In this lab we will walk through how to integrate Azure AD with Control
Tower. We will be leveraging a public blog post and an Azure AD
Lambda function for most of the work, with a modification to take
advantage of StackSets and the account structure already provided by
AWS Control Tower.
TIP: It is a best practice to keep AWS SSO configured to be used in a
break glass scenario when using a third-party Identity provider.
Prerequisites
This lab requires an account with Administrator privileges and
Control Tower.
We will be utilizing an Azure free account to create our Azure AD
and test users for this lab. Follow the steps from Microsoft to create
a free account and free access to Azure AD Premium trial https://
azure.microsoft.com/en-us/trial/get-started-active-directory/.
As of the writing of this lab, the control tower deployed the
AWSControlTowerAdmin in master account and
AWSControlTowerExecution in all the accounts. You can also deploy it
using the template provided as part of the AWS CloudFormation
StackSets prerequisites.
1.
2.
Use the master account number for the AdministratorAccountId
parameter.
Step 1: Configure Microsoft Azure ActiveDirectory
TIP: If the Azure portal becomes unresponsive, or does not display
some parts of the console, try with a different browser.
1.1) Copy your Azure AD domain (AKA Tenant ID)
Note: if a custom domain was not created with the account, or if you deleted it, you
can create a new one y following these steps: https://docs.microsoft.com/en-us/
azure/active-directory-domain-services/create-instance
E3C9
E313
1.2) Create a new User
Got to Active Directory/Users/All Users/New User
E3C9
E313
1.3) Login to the Azure portal with the new user and change its
password
Since the user you created has an OTP (One Time Password) you need to login,
change the password, and copy the new password to Notepad for later.
E3C9
E313
1.4) Add a New Enterprise Application
Login with the Account Owner again and go to Active Directory/Enterprise
applications/Application
E3C9
E313
Filter on AWS and select Amazon Web Services
Customize the Name and Add the Application
1.5) Open the Amazon Web Services Application, and click Edit
Note: Depending on the portal behavior this step may not be necessary because
you may already be in the application summary
E3C9
E313
1.6) Enable SAMLE3C9
E313
1.7) Update the Identifier (Entity ID) field with the default value
WARNING: Do NOT rely on the default value (it doesn't work and the error message
will be unhelpful. Copy the default https://signin.aws.amazon.com/
saml and remember to save
You can use the default https://signin.aws.amazon.com/saml value.
Just be aware the identifier must be unique within your Azure account.
E3C9
E313
1.8) Configure the User Attributes
You need to tell Azure AD what SAML attributes and values are expected and
accepted on the AWS side. AWS requires two mandatory attributes in any incoming
SAML assertion.
A) Go and edit User Attributes & Claims
B) Add the RoleSessionName | https://aws.amazon.com/SAML/
Attributes | user.userprincipalname claim
E3C9
E313
C) Add the Role | https://aws.amazon.com/SAML/Attributes |
user.assignedroles claim
D) [OPTIONAL] Add the SessionDuration | https://
aws.amazon.com/SAML/Attributes | 43200 claim
Summary of User Attributes
Your claim list should now be similar to this one
Name (case-
sensitive)
Value Namespace
(case-
sensitive)
Required
or
optional?
RoleSessionName user.userprincipalname
(this will show logged in
user ID in AWS portal, if
you want user name,
replace it with
user.displayName )
https://
aws.amazon.com/
SAML/
Attributes
Required
Role user.assignedroles https://
aws.amazon.com/
SAML/
Attributes
Required
SessionDuration An integer between 900
seconds (15 minutes)
and 43200 seconds (12
hours).
https://
aws.amazon.com/
SAML/
Attributes
Required
Note: This lab assumes users are directly created within your Azure AD
tenant. If you’re using an external user such as a Hotmail, Live, or
Gmail account for proof-of-concept purposes, RoleSessionName should
be set to user.mail instead.
1.9) Copy the Federation Metadata XML URI
Copy the URI to the Application Metadata XML file and save it in Notepad
E3C9
E313
1.10 Copy the Manifest Object ID. Open Azure Portal / Azure Active
Directory / App Registrations / your application name (for example,
“Amazon Web Services (AWS)”) / Manifest / Download
TIP: If you don’t see your application in the list on the App Registrations page, select
All apps from the drop-down list on top of that page and search for it.
Information: All Azure AD applications are described as a JavaScript Object
Notification (JSON) document called manifest. For AWS, this manifest defines all
AWS to Azure AD role mappings. Later, we’ll be using automation to generate
updates to this file. Steps:
E3C9
E313
A) Go into the Amazon Web Services (AWS) application
B) Copy the Object ID. then select the application Manifest
1.11) Set the user you created as the Application Owner
Go to the Settings pane of your registered application
E3C9
E313
Set the owner of the application
1.12) Copy the Login URL E3C9
E313
Go back to Single Sign-on: Azure Active Directory / Enterprise applications / Amazon
Web Services (AWS) / Single sign-on. Scroll down to section 4 and copy the Login
URL.
At this point, we’re done with the initial configuration of Azure AD.
You should have the following:
At this point, we’re done with the initial configuration of Azure AD. All
remaining steps will be performed in your AWS accounts.
Step 2: Configure AWS IAM Identity Providersand Roles
This customization has the roles and a SAML Identity Provider Role
lambda function in a CloudFormation template that we will use
StackSets to deploy to all of the accounts in our Organization.
Information Sample Content
Azure Tenant
IDmyazaccount.onmicrosoft.com
Azure User
Azure User
password
Password you have set after login in with that user
The
Federation
Metadata
URL
https://login.microsoftonline.com/b4f8e8b2-
ABCD-XYZ-9399-097dd6669707/
federationmetadata/2007-06/
federationmetadata.xml?
appid=ed1b3a1f-470c-4717-aadd-36bf7a9487ac
Login URL https://login.microsoftonline.com/b4f8e8b2-
ABCD-XYZ-9399-097dd6669707/saml2
Application
Object IDed1b3a1f-460c-4717-aadd-36bf7a9487ac
2.01) Create a AWSControlTowerExecution role in the Master
account
Verify if you have a AWSControlTowerExecution role in the master account. If you
don't you will have to create one
Go into the Identity and Access Management Console (IAM), and create a Role
named AWSControlTowerExecution
For the Trust Entity, select Another AWS account and use your Master Account
Number
For permission policies, attach the AdinistratorAccess policy
Name the role AWSControlTowerExecution and complete creation
Search the role, go back in Edit mode, and click on the Trust relationship tab
Edit the trust relationship and paste the one below but REPLACE THE ACCOUNT
NUMBER WITH YOUR MASTER ACCOUNT NUMBER
E3C9
E313
1.
2.
3.
4.
5.
6.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::012345678912:role/service-role/AWSControlTowerStackSetRole" }, "Action": "sts:AssumeRole", "Condition": {} } ]}
2.1) Download and Unzip the CloudFormation aws-landing-zone-
default-azure-roles.template for this lab
It is available from: aws-landing-zone-default-azure-roles.template
E3C9
E313
2.2) Launch the aws-landing-zone-default-azure-roles.template as
a CloudFormation StackSet to create roles
E3C9
E313
Navigate to the StackSet console under CloudFormation in the master account
and click “Create StackSet”.
Select “Upload a template to Amazon S3” and select the aws-landing-zone-
default-azure-roles.template
Give the StackSet a good name like AzureADIntegration. If you are using
a shared account, then use aliasAzureADIntegration and enter the
AzureADMetadataUrl you copied from your Azure AD application
configuration above.
1.
2.
3.
Specify Accounts or OUs and 1 region, click Next-Next and Create. Deploy only
into Accounts or OUs you want Azure AD to authorize.
4.
Remember to select the checkbox: 'I acknowledge that AWS CloudFormation
might create IAM resources with custom names.'
Use Control Tower roles: AWSControlTowerStackSetRole and
AWSControlTowerExecution.
If you have deployed any of the other labs, make sure that you enter unique role
names for the three role name parameters and shorten them, e.g.
aliasAzureADAdmin, aliasAzureADPower, aliasAzureADRead etc.
5.
6.
7.
Step 3: Synchronizing AWS Roles to AzureAD
In this step, we configure the Azure AD Role Sync Lambda code to
synchronize our AWS roles with Azure AD.
Run these steps on the Master account.
3.1 Create IAM Roles and the Lambda function to Sync them to
Azure
Download, Unzip, and run the CloudFormation template from azure-ec2.template
in the Master account
Give the stack a unique name like alias-azure-ec2, and create the stack with
default values.
Note: If you are using a SHARED account: First edit the template, search for 'CT-
Lab07' and add your user prefix (aliasCT-Lab07) to make it easier to locate your
instance
Wait for the stack to be fully deployed
Connect to the instance from the AWS Console with an AWS System Manager
(SSM) session
Go to the AWS System Manager service
Click on Session Manager
Click Start Session, and select the CT-Lab07 instance
NOTE: Alternatively, you can do this directly from a terminal session on your
laptop. This required the AWS CLI and the Session Manager Plugin to be
installed. For details see the References section at the end of the lab.
To connect to the instance with the CLI:
Connect with SSO to the Master account but instead of accessing the
console, copy credentials from the CLI access link
Paste these credentials in your terminal and use aws ssm start-session --
region *REGION* --target *INSTANCEDID*
On the SSM Session Terminal execute the following line by line (not as a block)
and REPLACE expected values (like **YOUR-REGION**) with your own values.
E3C9
E313
1.
2.
3.
a.
b.
c.
i.
ii.
4.
screenbashexport AWS_DEFAULT_REGION=**YOUR-REGION**cd ~## The following will confirm your environment in correctly setuppip --version
curl -O http://www.awsmanagementweek.com/controlTower/ctlab07/Aad-iam-sync-
lambda.zipunzip -q Aad-iam-sync-lambda.zipcd Aad-iam-sync-lambdachmod -R +x .####################################################### ---- STEP 1: Create an S3 Bucket ----- #######################################################
# Follow steps and COPY the output bucket name./create-bucket.sh### ---- generated output -----### this will generate output from the S3 bucket creation and configuration### do a 'cat create-bucket.sh' if you are curious of details### REMEMBER to take note of your deployment bucket name. It is part of the script output###### ---- end of simulated output -----
######################################################################### ---- STEP 2: Configure your deployment environment ----- #########################################################################
######## define the ".env" file ############# TIP: see the template with 'cat env.template'### EXAMPLE BELOW(replace with your own values)
cat <<EOF >.envSTACK_NAME=azure-ad-sync-lambda (this name must be UNIQUE)S3_BUCKET_NAME=***deploy-bucket-name*** (from STEP 1)AWS_ASSUME_ROLE_NAME=***azure-ad-sync-role*** (add your PREFIX if necessary)AZURE_OBJECT_ID=3e635845-xxxx-xxxx-xxxx-408c998862e5AZURE_TENANT_ID=eggXXXXXXX.onmicrosoft.comAZURE_USERNAME=adsync@eggXXXXXXX.onmicrosoft.comAZURE_USERNAME=azure-usernameAZURE_PASSWORD=azure-passwordSAMLIDENTITYPROVIDERNAME=AzureAD (add your PREFIX if necessary)ACCOUNTLIST=noneEOF
################################################################################# ---- STEP 2: Deploy a Lambda to Sync IAM Roles to Azure AD ----- ################################################################################### test the environmentmake test## clean up artifacts from a previous executionmake clean## deploy the template with CloudFormationmake deploy-app
## Once deployment completes with success go to the next step## if experiencing an issue go in the CloudFormation consiole to look at the error## or seek assistance from the lab instructor
##################################################################################################### ---- STEP 3: Execute the Lambda function to force an immediate synchronization ----- #####################################################################################################
## you need to locate the function to execute it.## It can be done from the console but we will do it with the CLI
Step 4: Entitling Azure AD users to assumeAWS Roles
Now we are back to following the blog post, the section titled Entitling
Azure AD users to assume AWS Roles.
aws lambda list-functions --query "Functions[*].FunctionName" --output text azure-ad-sync-lambda-AzureADSyncFunc-1QTLOW22NS44F
## If in a shared account you will more than 1. Copy the function that uses your prefix## Then execute the functionaws lambda invoke --function-name azure-ad-sync-lambda-AzureADSyncFunc-1QTLOW22NS44F /tmp/output.txt
3.2) Navigate to the AWS Lambda function in the console and
verify that it executes successfully
The function will be named with this prefix: aad-sync-function-
AzureADSyncFunc-...
Information: the function is invoked on a schedule every 15 minutes by Amazon
CloudWatch Event so you will have to wait until the next invocation.
TROUBLESHOOTING TIPS:
Look at details of the Lambda execution in CloudWatch Logs. This is available
from the Monitoring pane in Lambda
If 0 roles are found, you either did not y roles or you are using a shared account
and forgot to add your prefix to roles or the AWSService.js file. Roles are
discovered because they use the same saml-provider: AzureAD or aliasAzureAD
If you have Sync errors with the Azure account you may have entered incorrect
values when executing configure.sh. You can look up these values in the System
Manager Parameter Store. You can re-execute configure.sh but you will also have
to rebuild and redeploy the package because the lambda function is CACHING
values.
E3C9
E313
•
•
•
4.1) Open Azure Portal > Azure Active Directory > Enterprise
applications > All applications > (your application name)
E3C9
E313
4.2) Select Users and groups > Add user, and assign a role to the
user
E3C9
E313
4.3) Navigate to Azure Active Directory > Enterprise Applications >
Amazon Web Services (AWS) > Properties and copy the User
access URL
E3C9
E313
Step 5: Login to the Azure MyApps portal
Now we can use the new user and new User access URL to login to the
myapps portal and select a role to login to the AWS console.
Ideally using a different browser instance, login to the myapps
portal using the URL you copied previously.
Select the AWS account and AWS role that you want to use to sign
in. Or if you only have one account you will be automatically
logged into the console for that account.
Exploring the Solution
You deployed 3 templates. One created IAM roles in AWS accounts to
handle user authorizations, another deployed an EC2 instance used to
•
•
build a deploy the third template with the Lambda function used to
synchronize IAM roles to Azure AD.
Go into the IAM console in one of these accounts, locate one of the
deployed role, and look at the trust policy. Each role trusts the
same SAML provider named AzureAD or yourAliasAzureAD.
The second template deployed an AWS Lambda function that
synchronize some IAM roles with Azure AD. See you can locate the
Amazon CloudWatch scheduled event that invokes this function.
On the AWS side everything could be deployed with a single
template. Some manual steps were kept to allow you to explore
other aspects. Look at:
The EC2 instance you deployed.
Try executing: ec2-metadata --all. For details on
instance metadata, see References at the end of the lab
It does not have any PEM key but you still were able to use it
through AWS Systems Manager. This EC2 instance does not
allow any public traffic and could have been deployed in a
private subnet and you still could create a session to it.
The instance is using an IAM Role for EC2. See if you can locate
this role in the EC2 Console.
Instead of starting a session through the Session Manager
Console, you can start session from a terminal and the Session
Manager Plugin for the AWS CLI
If you configure the service for it, the Session Manager can also
Audit and Log Session Activity.
Finally, have you noticed the CloudFormation template used to
deploy the instance did not specify an AMI? Instead it used a
template parameter to get the latest AMI for the requested
architecture. See Query for the latest Amazon Linux AMI IDs
using AWS Systems Manager Parameter Store for details
1.
2.
3.
4.
a.
b.
c.
d.
e.
f.
Deleting AWS resources deployed in this lab
In the Master account:
Delete the CloudFormation stack you deployed from the azure-
ec2.template
Delete the Stackset 'aliasAzureADIntegration' deployed from the
aws-landing-zone-default-azure-roles.template
First delete the deployed Stacks of the StackSet
Then delete the StackSet itself
Delete the 'aad-sync-function' stack.
In the System Manager Parameter store you can delete:
/azuread-sync/username
/azuread-sync/tennant
/azuread-sync/password
/azuread-sync/objectid
Delete the alias-640271645869-us-east-2-demosync bucket
You can also delete Amazon CloudWatch Log Groups that were
created for AWS Lambda functions and System Manager Sessions
In the Azure Console, delete the AWS application
REFERENCES
Instance metadata: https://docs.aws.amazon.com/AWSEC2/latest/
UserGuide/ec2-instance-metadata.html
EC2 Instance Metadata Query Tool: https://aws.amazon.com/code/
ec2-instance-metadata-query-tool/
Installing the AWS CLI: https://docs.aws.amazon.com/cli/latest/
userguide/cli-chap-install.html
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
1.
2.
3.
Installing the Session Manager plug-in: https://
docs.aws.amazon.com/systems-manager/latest/userguide/session-
manager-working-with-install-plugin.html
AWS Systems Manager Session Manager: https://
docs.aws.amazon.com/systems-manager/latest/userguide/session-
manager.html
How to automate SAML federation to multiple AWS accounts from
Microsoft Azure Active Directory
SAML Developer Tools
Enabling SAML for Your AWS Resources
Query for the latest Amazon Linux AMI IDs using AWS Systems
Manager Parameter Store
Azure AD does not provide an easy way to use the command line
but there are solutions like aws-azure-login on Github.
How to Use Linux Screen
Copyright 2019, Amazon Web Services, All Rights Reserved.
4.
5.
6.
7.
8.
9.
10.
11.