Choose Your Own SAML Adventure: A Self-Directed Journey to AWS Identity Federation Mastery

Automating federation setup across multiple accounts and roles (Microsoft variant)

In most situations, AWS customers move towards a multiple AWS account strategy as their maturity on the AWS platform increases. While there are many different reasons for doing so, blast radius reduction ranks among the most common, especially regarding human operators. In these scenarios, it is not uncommon for a single AWS customer to have hundreds or even thousands of AWS accounts. In this exercise, we implement a solution for automating the required federation components, both within AWS and the back-end Active Directory, across any number of accounts and associated roles. This automation, in concert with the AWS-<Account Number>-<Role Name> naming convention you implemented in the first exercise, allows your cloud identity infrastructure to scale to any number of AWS accounts.

Architecture

The following image provides a visual representation of what you are about to construct during this advanced use case exercise. The core components include:

Exercise architecture

Note: The EC2 instance for trusted automation that can be deployed during this advanced use case has been configured with an EC2 instance profile that is associated with a powerful IAM role. This role necessarily and deliberately allows the resident automation to perform sensitive API calls (e.g. iam:PutRolePolicy, iam:CreateRole). As such, you must carefully control RDP access to this machine. You should not grant access to individuals who do not have equivalent IAM permissions.

Note: You should use this architecture and associated AWS CloudFormation template for demonstration and learning purposes ONLY. The template contains default passwords and has not been hardened in any way beyond the default configuration provided by the Amazon Machine Image (AMI). Furthermore, the IdP infrastructure has been simplified to focus on the learning objectives and is not set up for availability and scalability, and is not appropriate for production use.

Prerequisites

The following list identifies the prerequisites for this exercise. If you have not completed these tasks, please do so now:

Benefits of direct federation

Finally, before we begin, it is worth noting why we've opted for the direct federation approach. The other main alternative that is often considered is the "hub & spoke model" in which a user federates into one account and then utilizes (from an end-user perspective) cross-account trusts to move into the AWS account on which they are interested in operating. While there are merits to the hub & spoke model in some cases, most federation customers should opt for the direct federation model implemented here for the following reasons.

Deploy Exercise Infrastructure

To get started, we will first start by deploying the necessary infrastructure to each of the AWS accounts.

Deploy cross-account role template in the child account

Let's start by deploying the necessary CloudFormation template into your second AWS account. You can review the full template here. In summary, this template creates an AWS IAM role that can be assumed from your first AWS account. This role is then configured with the following policy.

{
            "Action": [
                     "iam:CreateRole",
                     "iam:CreateSAMLProvider",
                     "iam:DeleteRole",
                     "iam:DeleteRolePolicy",
                     "iam:DeleteSAMLProvider",
                     "iam:GetRole",
                     "iam:GetRolePolicy",
                     "iam:GetSAMLProvider",
                     "iam:ListRolePolicies",
                     "iam:ListRoles",
                     "iam:ListSAMLProviders",
                     "iam:PutRolePolicy",
                     "iam:UpdateSAMLProvider"
              ],
              "Effect": "Allow",
              "Resource": "*"
}

This role will be used by the trusted automation to configure the IAM elements necessary for federation in the child account. Start by logging in to the AWS Management Console of your second AWS account, and select CloudFormation.

AWS Management Console

If you aren't already there, switch to the Tokyo (ap-northeast-1) region, and then choose Create Stack.

AWS CloudFormation Console

On the first step, Select Template, choose Specify an Amazon S3 template URL, enter the following, and then choose Next.

https://s3.amazonaws.com/federationworkshopreinvent2016/cloudformation/MultiAccountChildAccount.json

AWS CloudFormation Create Stack

On the second step, Specify Details, enter the parameters according to the following table, and then choose Next.

Configuration Element Value
Stack name FederationWorkshopXARole
MasterAccount The 12 digit AWS account number of your first AWS account. This is the account where you deployed the identity provider in the initial exercise.

Note: If you need help finding your account number, please refer to the documentation.

AWS CloudFormation Create Stack

On the third step, Options, you may proceed with the defaults by choosing Next.

AWS CloudFormation Create Stack

Finally review the information to ensure it is correct, acknowledge the creation of of IAM resources, and then choose Create.

AWS CloudFormation Create Stack

The template requires 1-2 minutes to complete. You can choose Refresh during this time to view the creation status in real time.

AWS CloudFormation Create Stack

Note: To support any number of AWS accounts, you would simply deploy the FederationWorkshopXARole CloudFormation stack in each additional child account.

Deploy cross-account role template in the master account

Next, log out of the child account, and log in to the AWS Management Console of your first AWS account. Once you have done so, repeat the directions above to deploy the FederationWorkshopXARole CloudFormation stack in master account.

AWS CloudFormation Create Stack

Download and modify the CloudFormation template for trusted automation

Our next CloudFormation template creates an EC2 instance for trusted automation and an associated IAM instance profile and role. This role defines the other half of the cross-account trust relationship established above. The template must be customized slightly before deployment. Start by using curl to download the generic template to your local workstation using the following command.

curl -o MultiAccountMasterAccountMS.json http://federationworkshopreinvent2016.s3-website-us-east-1.amazonaws.com/cloudformation/MultiAccountMasterAccountMS.json

Download AWS CloudFormation Template

Then, open this CloudFormation template within your favorite text editor and modify it in the following two ways:

vim MultiAccountMasterAccount.json

Modify AWS CloudFormation Template

Note: To support any number of AWS accounts, you would simply add one additional line to this policy per additional child account.

Deploy trusted automation template in the master account

Now that the trusted automation template has been modified to fit your environment, we deploy it into the master AWS account. Start by logging in to the AWS Management Console, and select CloudFormation.

AWS Management Console

If you aren't already there, switch to the Tokyo (ap-northeast-1) region, and then choose Create Stack.

AWS CloudFormation Console

On the first step, Select Template, choose Upload a template to Amazon S3, browse to the copy of the template that you modified above, and then choose Next.

AWS CloudFormation Create Stack

On the second step, Specify Details, enter the parameters according to the following table and then choose Next.

Configuration Element Value
Stack name FederationWorkshopTrustedAutomation
InstanceType m3.medium
KeyName Select an existing EC2 key pair within the ap-northeast-1 region. If you do not have an existing key pair refer to the documentation here to create a new one.
PublicSubnetId Select the same public subnet where you deployed the identity provider in the initial exercise.
SourceCidrForRDP The CIDR notation for the IP range that RDP should be restricted to. The workshop facilitators will advise how to best configure this for the conference wifi. For static environments, http://checkip.amazonaws.com/ can be used to determine your current IP address.
VPC Select the VPC that contains the public subnet above.

AWS CloudFormation Create Stack

On the third step, Options, you may proceed with the defaults by choosing Next.

AWS CloudFormation Create Stack

Finally, review the information to ensure it is correct, acknowledge the creation of of IAM resources and IAM resources with custom names, and then choose Create.

AWS CloudFormation Create Stack

The template requires 7-8 minutes to complete. You can choose Refresh during this time to view the creation status in real time.

AWS CloudFormation Create Stack

After the stack creation has completed, use the Outputs tab to determine the public IP address of the Trusted Automation instance. Copy down this value because you need it in the following steps.

AWS CloudFormation Create Stack

Configure the trusted automation instance

Now that you have deployed the additional infrastructure, the trusted automation instance needs to be joined to the existing active directory domain and configured in a few additional ways.

Login to your trusted automation instance via RDP

Login using RDP to your trusted automation instance using the public IP address that you noted in the above. Use the local Administrator credential, as shown in the following screenshot.

RDP connection

Note: By default, the password for the local Administrator account is set to Pass@123.

Update DNS configuration

First, we need to configure the trusted automation instance to use the domain controller instance for DNS. Start by determining the private IP address of the domain controller (DC) instance. You can obtain the private IP address from the Output tab from the FederationWorkshopADFS CloudFormation stack you deployed in the first exercise.

DNS

To update the DNS configuration, open a new Windows PowerShell window, and enter the following command.

Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses <PrivateIPaddressofDC>

Note: Be sure to use the actual value of the private IP address of the domain controller in the above command.
Note: If you receive an error stating that the interface "Ethernet" does not exist, use a value of "Ethernet 2" in the above command.

Now test DNS resolution by pinging the domain controller using the following command.

ping example.com

You should receive replies from the private IP address of the domain controller instance, as shown in the following screenshot.

PowerShell

Join the example.com domain

To complete the domain-joining activity, enter the following command into the open Windows PowerShell window.

systempropertiescomputername

In the System Properties dialog, choose Change.

Computer Name

Under Member of, choose Domain, type example.com, and choose OK.

Domain

In the Windows Security dialog, authenticate with a user name Administrator and password Pass@123.

Windows Security

You should see the message, "Welcome to the example.com domain."

Domain

Close the System Properties dialog, and then choose Restart now to complete the domain-join process.

Note: From this step onwards, log in to the trusted automation instance as Example\Administrator with a password of Pass@123.

Add server role

In order for our trusted automation to have access to the necessary windows features and utilities it needs, you must add the Active Directory Domain Services role to the trusted automation instance. After the instance has completed rebooting, repeat the process above to RDP to the trusted automation instance.

Next, open a new PowerShell window and type the following command sequence to add the necessary role, as shown in the following screenshot.

Import-Module ServerManager
Add-WindowsFeature AD-Domain-Services

Server Manager

Configure host file entry for AD FS

Since example.com is only an illustrative domain, you will configure a local host file entry instead of configuring a DNS record for your identity provider. Use Notepad or your favorite editor to add a host file entry for idp1.example.com to the public IP address of the AD FS instance, as shown in the following screenshot.

notepad %windir%\system32\drivers\etc\hosts

Edit /etc/hosts

Trusted automation overview and configuration

Now that you have deployed and configured the trusted automation instance, you can make use of the set of automation scripts that we've provided. Before you begin, the following is a brief overview of the automation package.

Note: These scripts are intended to provide a starting point upon which production grade automation could be built. In their current form, they have been simplified to focus on the learning objectives and do not implement full exception processing. Not appropriate for production use.

Adjust automation configuration files

To get started, you will adjust the configuration files to be specific to your environment. Repeat the process above to RDP to the trusted automation instance. Then, from the desktop, choose the Start menu and type WordPad, as shown in the following screenshot.

WordPad

The first file, accounts.txt is a file that defines all of the AWS accounts on which you want to operate. The format for this file is:

<ACCOUNTNUMBER>,<ROLEPREFIX> (one line per AWS account)

Use WordPad to edit the accounts.txt file. Choose File, then Open, and navigate to the C:\FederationWorkshop\policies directory. Choose accounts.txt and then choose Open.

WordPad

Add one line for each of your AWS accounts. Use FederationWorkshop for the <ROLEPREFIX> as shown in the following screenshot. Save the file when you have finished the changes.

Edit accounts.txt

The second file, roles.txt is a file that defines a standard set of IAM roles that are to be deployed into each of the AWS accounts defined in the accounts.txt file. The format for this file is:

<ROLENAME>.json

The automation further expects that a valid IAM policy document is resident in the same directory that matches each entry in roles.txt. Use WordPad to open roles.txt. You will see that this file was populated for you using two roles, ReadOnly and PowerUser. Expand this to include two additional roles, SecurityAudit and SuperUser as shown in the following screenshot.

SecurityAudit.json
SuperUser.json

Edit roles.txt

Note: For your safety during this learning exercise, all of the provided IAM policy documents have been modeled after the ReadOnlyAccess AWS managed policy. In practice, you would attach a more meaningful and appropriate policy.

Automatically define and populate Active Directory groups

Now that you've adjusted the configuration files, you will run the createadgroups scripts to create the additional Active Directory groups necessary to support our expanded set of AWS accounts & roles according to the AWS-<Account Number>-<Role Name> naming convention. Open a new PowerShell window and use the following command sequence to create the groups.

cd C:\FederationWorkshop\automation
.\createadgroups.ps1

Load AD groups

Note: You will receive an expected error message, the specified group already exists, for the two groups you created in the first exercise.

Now that the additional back end groups have been created, we need to provision alice and bob into these groups in a way that reflects the level of AWS access we want them to have. As we did in the initial exercise, we'll do this "cooking show" style. Return to your PowerShell window and use the following command sequence to add these new group memberships, as shown in the following screenshot.

Import-Module ActiveDirectory
Add-ADGroupMember -Identity "AWS-<ACCOUNT2>-ReadOnly" -Member alice
Add-ADGroupMember -Identity "AWS-<ACCOUNT2>-ReadOnly" -Member bob
Add-ADGroupMember -Identity "AWS-<ACCOUNT2>-SuperUser" -Member bob

Note: Substitute your actual child account number in place of <ACCOUNT2> in each of the commands above.

Edit roles.txt

Automate AWS IAM entity creation and management

Next, we'll focus on the creation and management of the necessary IAM entities using our trusted automation instance. In practice, you may want to alternatively implement these mechanisms as AWS Lambda functions for cost optimization purposes and to reduce operational burden. We've chosen Amazon EC2 here for simplicity in order to focus on the learning objectives.

Execute trusted automation

You are now ready to execute the trusted automation that creates and manages the IAM entities necessary for federation. Specifically, you invoke automation that facilitates the creation of the IAM identity provider and the IAM roles for identity provider access. In the initial exercise, you created these entities manually using the AWS Management Console. In this advanced use case, you'll use automation to scale this creation effortlessly across all of your AWS accounts.

The first script, federationproviderdeploy, retrieves the SAML metadata from AD FS and then configures an IAM identity provider for each account in the accounts.txt file. It does so by sequentially performing an Assume Role call into each of the accounts using the cross-account trust roles we deployed at the beginning of this exercise. The script must be customized slightly before execution. From the desktop, choose the Start menu and type WordPad, as shown in the following screenshot.

WordPad

Within WordPad, navigate to C:\FederationWorkshop\automation\ and open the federationproviderdeploy script. Find the variable named metadataurl, and reverse the comment hashes so that the AD FS variant of the metadataurl variable is active, as shown in the following screenshot.

WordPad

After your changes are complete, open a new PowerShell window and execute it, as shown in the following screenshot.

cd C:\FederationWorkshop\automation
C:\Python27\python.exe .\federationproviderdeploy.py

Deploy federation provider

Note: The script has detected that idp1 already existed in our first account and did not mangle this configuration.

The second script, federationrolesdeploy, is used to configure a set of IAM roles for federation. These roles reference the identity provider configured above. It does so by inspecting both the accounts.txt file and the roles.txt file and producing all of the resulting permutations. The resulting IAM roles are named using the concatenation of ROLEPREFIX (accounts.txt) and ROLENAME (roles.txt) (e.g. FederationWorkshop-ReadOnly). Recall that the ROLENAME portion matches exactly 1:1 to the AWS-<Account Number>-<Role Name> naming convention we implemented for the Active Directory groups.

After the roles are created, the final step of the script takes the json policy document in the same directory and applies it as an inline policy on the role. This script also utilizes the Assume Role pattern described above. Take a second to review the contents of the script and then execute it, as shown in the following screenshot.

C:\Python27\python.exe .\federationrolesdeploy.py

Deploy federation roles

Note: The script has detected that the original two roles existed in our first account and did not mangle these configurations.

Inspect the result

Before we test the outcome of this automation, let's first inspect things. Log in to the AWS Management Console for your second AWS account, and select Identity & Access Management.

AWS Management Console

Choose Identity Providers from the left hand navigation menu. We can see that our identity provider has been created using the idp1 name our configuration expects.

AWS Management Console

Now, choose Roles from the left hand navigation menu, and type FederationWorkshop into the search bar. Note that all of the IAM roles have been configured.

AWS Management Console

You can explore these roles to see how the automation has properly established the trust policy necessary for federation and bound an inline policy that matches the policy document on the trusted automation instance.

Testing

Finally, it is now time to test our revised configuration. Open a new browser window, and enter the IdP initiated login URL for AD FS.

https://idp1.example.com/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices

When presented with the authentication form, login with bob's credentials.

AD FS login page

Note: You may need to utilize a private browser window to force AD FS to re-authenticate you.

Note that the role selection page automatically reflect's bob's new roles. It is also important to notice that no adjustments to the IdP configuration were required, this was entirely handled by the regular expression transformation we configured in the initial exercise.

AWS Role Chooser Page

Select the FederationWorkshop-ReadOnly role under your 2nd AWS account, and choose Sign In.

AWS Role Chooser Page

You are now logged into your 2nd AWS account as bob. For our last test, let's assume the bob wishes to switch back to your first AWS account. Within the same browser window, again enter the IdP initiated login URL for AD FS.

https://idp1.example.com/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp=urn:amazon:webservices

AD FS does not ask you to authenticate because you are already signed in. Instead, you are immediately returned to the role selection page. From here, you can select any one of bob's other roles to assume. This process can be repeated any number of times so that Bob can easily switch between his various roles throughout the course of his duties.

AWS Role Chooser Page

If time permits

If time permits, you can extend the learning of this advanced use case by performing these additional steps on your own.

Exercise complete

Congratulations! You have completed the advanced use case of automating federation setup across multiple accounts and roles.

With this use case complete, you are now ready to continue your journey through more of the advanced use cases. To continue, return to the index of advanced use cases.