Automated AWS account initialization with Terraform and OneLogin SAML SSO

IMPORTANT: This tutorial was written with Terraform 0.9.x, so it may not work exactly with newer versions or need to be adapted. E.g. the new provider plugins need to be initialized before doing anything starting with Terraform 0.10.0 and up

The first time you’re using AWS seems easy. One account to manage, maybe only a few users and some roles to create. But after a while, especially in growing companies or agencies, you may decide to switch over to a multi account structure and don’t have all projects in a single AWS account.

The default for such AWS multi account setups is to have one master account which is responsible for consolidated billing and IAM user/roles management only. To switch to other AWS accounts you can use the assumeRole functionality of AWS. Managing the cross-account policies manually can become cumbersome, but we can automate this with Terraform.
If you don’t know Terraform, that’s a really nice tool for provisioning service and infrastructure resources on many cloud and service providers.

This is part 1 of a multi-part tutorial series how to automate the management of an AWS multi account setup with Terraform. Basic knowledge of AWS IAM and Terraform is a requirement.

In this tutorials series I’m using OneLogin as SSO provider, but you can use any SSO provider you want. Or still manage your IAM users by hand. If you do this, then you can omit the SAML/OneLogin stuff and use only assumeRole trust relationships.


First create your new AWS account as usual.

Activate IAM User Access to Billing Information

Then make sure to activate the IAM User Access to Billing Information.

As you should never operate with the root account this step is important. Otherwise you can’t create a role to gain access to the billing and invoices.

Next you need to create a TerraformInit IAM policy with least privileged access which you use to initialize your account:

AWS TerraformInit policy for organizational root account with OneLogin

Then create the IAM user called terraform-init and attach to it the TerraformInit policy from above. This are the only manual steps you need to do and where you are using permanent access keys of this user. This user needs Programmatic access only.


In the next step create the following Terraform files to initialize the account alias, add OneLogin as SAML IdP and configure three basic roles. One Administrator role, one Developer role (as AWS power user) and one Billing role.

To configure the access/secret key to the account you have two possibilities. Either configure them directly in the provider config (unsafe, do it only if you are one man show), or you use a separate credential file with different profiles (don’t commit the credentials!). The config below is already prepared to serve multiple accounts in one step to initialize and maintain.

I also put the account id into the provider to make sure, you never work with the wrong credentials and thus in the wrong accounts.

Terraform initialization of AWS organizational root account, prepared for multiple accounts

Now execute terraform plan to take a look what will be done. If it looks good to you run terraform apply to configure your root account.

When the run has finished you see the acme_saml_provider_arn output which you need to complete the AWS setup within OneLogin. If you’ve finished this part to, you should be able to login to AWS from your OneLogin dashboard.

Depending on your role mappings you may be asked to choose a role or are directly logged in to the AWS console

As said on the beginning, this is only the master account of an AWS multi account setup, which is responsible for IAM and consolidated billing only. For projects you need to create separate accounts.

This is part 1 of a multi-part series how you manage the AWS account basics with Terraform with minimal manual steps only. The daily work can be done with the temporary credentials from the assumed role via SAML or if you don’t use SAML with the credentials of the created IAM users.