In bigger organisations it is common to have one central AWS account with IAM User accounts and a whole lot of independent per-project or per-team accounts that are only through cross-account access from this central account.

The benefits is obvious – company has a single place where they manage user accounts, credentials, passwords, permissions, etc. It is a very similar concept to switching from local Linux accounts to a centralised LDAP or AD authentication.

Overview

Because AWS accounts are in general independent (unless they are part of AWS Organizations tree) we need to set up a trust relationship between the “Login” account and the “Project” account.

  • Login account

    Permit IAM Users to Assume a role in Project AWS account. Obviously all actions of IAM Users are controlled by by IAM Policies, therefore we have to explicitly permit the assumption of the remote account Role.

  • Project account

    Permit the assumption of the IAM Role by users from the Login account. Obviously we can’t let anyone from anywhere assume IAM Roles in our accounts, hence the role must permit its assumption from the Login account and from nowhere else.

High level process

We will implement a simplified version of the above diagram with only 2 accounts, that will allow me (IAM User michael.ludvig) to login to aws-nz-login account and assume an Admin role in our Dev account aws-nz-dev, without me having to have an IAM User account in the Dev AWS account.

In the Login account (aws-nz-login) we create an IAM Group named CloudOps, and an unprivileged IAM User michael.ludvig as a member of that group.

In the Dev account (aws-nz-dev) we will create an IAM Role named Admin with AdministratorAccess managed policy attached.

“Remote” Dev account setup

Login to your Dev account with Root credentials or as IAM User with administrative privileges!

Unlike “normal” IAM roles the Admin roles must permit access from the Login account. In the IAM Roles console it’s very easy as there is a dedicated tab just for this.

Create IAM role – Step 1

Create IAM role – Step 2

Create IAM role – Step 3

Admin role setup using AWS-CLI

If you like things automated, like I do, you may prefer to use AWS CLI or CloudFormation. For AWS CLI we have to create the AssumeRolePolicyDocument first as a file on the filesystem, let’s call it assume-role-policy.json:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::987654321098:root"                    # This is Login account ID
      }
    }
  ]
}

Next we call the AWS CLI:

~ $ aws --profile devops-root iam create-role --role-name Admin --assume-role-policy-document file://assume-role-policy.json
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "arn:aws:iam::987654321098:root"    # This is Login account ID
                    }
                }
            ]
        },
        "RoleId": "AROABCDEFGHIJKLMN",
        "CreateDate": "2017-12-05T04:13:50.415Z",
        "RoleName": "Admin",
        "Path": "/",
        "Arn": "arn:aws:iam::123456789012:role/Admin"              # This is Dev account ID
    }
}

Note down the ARN – we will use it later. As a separate call you’ll also want to attach some policies – the Admin role should be well served with the AdministratorAccess managed policy:

~ $ aws --profile devops-root iam attach-role-policy --role-name Admin \
        --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

That’s all for the “Remote” Dev account setup.

Login account setup

Login to your Login account with Root credentials or as IAM User with administrative privileges!

The next step is to give the IAM Users in the Login account the permission to Assume the Admin role in the Dev account. I expect that you already have the CloudOps group created and users added, we won’t cover such basics here.

What we need to do now is attach the right IAM Policy to the CloudOps group that lets the group members call sts:AssumeRole on the Dev account Admin role ARN. The policy is very simple

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::123456789012:role/Admin"             # This is Dev account ID
            ]
        }
    ]
}

You can either attach this to the CloudOps Group Permissions as an Inline Policy through the AWS Console, or save it as a file e.g. Dev-Admin-policy.json and use AWS CLI to attach it:

~ $ aws --profile login-root iam put-group-policy --group-name CloudOps \
        --policy-name Dev-Admin-policy --policy-document file://Dev-Admin-policy.json

In both cases you should end up with the policy listed under Login account CloudOps Group Permissions:

That concludes the setup phase. In the next post we’ll show how to use the Cross-account access both from the console and as well from AWS-CLI.