Terraform with AWS Assume Role

Abhishek Amralkar
HackerNoon.com

--

Using different AWS account for the different Environments is now a days best practice so that we can have complete isolation for all the Environments.

In above diagram [copied from segment.io blog] Ops AWS account is the entry point for rest of the AWS accounts. What this means is we don't need to have users on Dev, Staging and Prod AWS account instead we can use AWS STS and Assume Role to bootstrap/access AWS services.

Advantage?

By using separate AWS accounts for different environments

  1. Resource separation and isolation.
  2. Centralized access location.

and many more…..

Prerequisites?

4 AWS accounts and make sure to enable MFA for the root accounts.

Note: We can setup this with 2 AWS accounts too but in this post we are considering 4 AWS accounts.

Lets give name to 4 AWS accounts which we will refer in the post.

  1. Ops [Jump AWS account or I call it as Bastion AWS account]
  2. Dev AWS account
  3. Stage AWS account
  4. Prod AWS account

The ops account serves as the jump point and centralized login. Everyone in the organization can have a IAM account for it.

The other environments have a set of IAM roles to switch between them. It means there’s only ever one login point for our admin accounts, and a single place to restrict access.

As an example, Anay might have access to all three environments, but Abhi can only access dev . But they both login through the ops account.

Instead of having complex IAM settings to restrict access, we can easily lock down users by environment and group them by role. Using each account from the interface is as simple as switching the currently active role.

As soon as we get AWS accounts below are the steps which we need to perform in all

  1. Create IAM users in Ops AWS account. Like anay, abhi etc etc
  2. Create role in all 3 (Dev, Stage and Prod) AWS accounts with some policy attached to it or make it a part of group with certain AWS access resources.
  3. While creating role make sure to add trust relation between the Ops and Dev, Ops and stage, Ops and Prod AWS accounts.

4. Create a user in Ops staging account and it must have rights to assume role from the Dev, Stage and Production account. below is the sample policy you can attach to the user to assume roles.

{
“Version”: “2012–10–17”,
“Statement”: [
{
“Effect”: “Allow”,
“Action”: “sts:AssumeRole”,
“Resource”: “arn:aws:iam::123545678:role/rolename”
}
]
}

Once you have user created configure aws-cli on the host server where you want to run terraform ( you can configure it on your local machine too).

I am assuming here you will have terraform latest version binary on your system and using terraform assume role

provider "aws" {
assume_role {
role_arn = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
session_name = "SESSION_NAME"
external_id = "EXTERNAL_ID"
}
}

Now just add below 2 lines in state file for the module which you want to bootstrap.

    role_arn     = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"
profile = "my_profile_name"

You are all set now to run Terraform securely !

--

--