13. December 2018 2018 0

Travis Bickle Clapping

AWS Organizations are an amazing way to do a few existentially important things:

  • Consolidate Payment for multiple AWS Accounts.
  • Group AWS Accounts
  • Provide policies for a Group of AWS Accounts.
  • Control access to AWS Services, by Group or Individual Account
  • Centralize CloudTrail Logging ( released at re:Invent 2018 )

Sooner or later, every business grows to need policies. You may have some policies that should trickle down to your whole organization. You may wish to declare and enforce concepts like S3 buckets should never be deleted, IAM Users should not be able to generate access keys, or perhaps CloudTrail logging should never be stopped. Whether or not these concepts resonate with you, they are the types of ideas that Organizations can declare and enforce.

Some policies may end up being domain specific. PCI-DSS doesn’t apply to non-financial business domains. Rights related to data retention may only apply in certain groups of countries, but not others. AWS Organizations can be leveraged to manifest these ideas.

AWS Organizations brings you technical controls for declaring, enforcing, and ( when paired with AWS Config ) reporting on compliance directives.

Step Zero: Get your plan together.

Austin Powers allow myself to introduce myself, overlaid with text replacing myself with organization

For many organizations having their … AWS Organization … setup as a tree structure is a great option.

The Organizational Concept

At the root of the tree, you have a single account ( the same AWS account from which we will begin working ). This single account runs no code. This account is exclusively for payment and policy management.

In this article, we’re going to:

  • Create a new account that will be the root of our organization
  • Create a Service Control Policy(SCP) that declares cloudhsm should not be used
  • Create a SCP that declares cloudtrail:StopLogging cannot be called
  • Attach those SCPs into our new Organization.
  • Create an OU inside the Organization
  • Bring another account into that OU

The Policy Layout

As you move out from the root and to the first layer of subordinate accounts ( children of the root account ), one policy may apply. Say this policy is “You can run anything except HSM.”

One of those child accounts may have its children who process credit card payments and are subject to PCI-DSS. These grandchildren accounts may be restricted to using an explicit whitelist of services. They may be required to use 2FA when logging in. Maybe they can’t use S3, because srsbzns can’t happen via S3?

But what about existing accounts

You can invite accounts into your organization via one of two ways:

  1. You invite by AWS Account ID
  2. You invite by email, which uses the AWS Console’s root user login’s email address.

I’m going to assume you’ve already got at least one AWS Account, if not, create one and invite it via email. If you do already have an account, find its account id.

The Organizational Layout

The image below illustrates the organizational structure that we’re going to be creating as a part of this writeup. Service Control Policies ( called SCPs hereafter ) will be used to enforce our policies. If you follow the link to the SCPs page, you’ll notice a few important caveats to how SCPs work. In short

  1. SCPs only Deny access
  2. SCPs don’t apply to Service Linked Accounts
  3. SCPs only apply to Principles inside your organization,
  4. if you disable the SCP policy type in a root, you can expect to spend the next several days re-enabling it with much tender loving care.

a directed graph of the organization layout

Step One: Prep your soon-to-be-root account

AWS requires you to verify your email address before you can begin summoning creating subordinate accounts. Choose an account that will be your new root account, and verify the email address on it by logging into the AWS Console, and visiting https://console.aws.amazon.com/organizations/home

Build a fresh account to be the new root account

If you have an existing AWS Account that is not itself the root of an organization, you may want to create a new account for this purpose. This writeup’s screencaps will continue with a fresh account that will be our designated root.

The organizations console default page

AWS Organizations Console for a fresh account, default page

The organization’s console accounts tab, showing the You must verify your email to use AWS Accounts dialogue. AWS Organizations Console for a fresh account, Accounts tab

The organization’s console accounts tab, after verifying the email address. AWS Organizations Console for a fresh account, Accounts tab

Create an admin user

We will need to use the aws CLI just a bit, because there isn’t super amazing CloudFormation support to generate organizational children.

This user can be created via CloudFormation, however, and that’s doable via the console.

  1. As your root user, navigate to Services -> CloudFormation
  2. Create Stack
  3. In the Choose a Template section click the radio button onto Specify an Amazon S3 URL
  4. In that URL place https://s3-us-west-2.amazonaws.com/awsadvent-2018-organizations/StepOneCFNs/phase_0_user_and_accesskey.yml
  5. Next
  6. Stack Name AdventAdmin
  7. Next
  8. Nothing needed here on the Options screen
  9. Next
  10. Check the box acknowledging that AWS CloudFormation might create IAM resources with custom names.
  11. Create
  12. Wait for the stack to reach a Create Completed state. CloudFormation Console showing the stack in a complete state

Step Two: Create Some SCPs

The Organizations API has great support via the CLI and the SDKs, but it’s not really present in CloudFormation. We’re going to use the aws cli to interact with the AWS Organizations APIs. If you don’t already have it, here is the guide to installing the aws cli.

Get your credentials together

We created an IAM User in Step One that has full Administrator privilege. For this guide, I’m going to assume that’s the user that you’ll be using.

To get the credentials to use the cli as this user

  1. Services -> CloudFormation
  2. Stacks
  3. AdventAdmin
  4. Outputs The outputs are in a strange place on the CloudFormation Stack CloudFormation Console showing the stack's outputsYou can cut and paste those two values into your CLI to build something like

Make your first SCP

We’re going to first make a Service Control Policy for our entire organzation that states “No one anywhere can run CloudHSM. CloudHSM was chosen for this example because it tends to not be used, and it’s relatively expensive. There’s nothing wrong with CloudHSM! If your business needs CloudHSM, use it! These SCPs should be considered for demonstration purposes only.

  1. Check to be sure that your organization is functional:
  2. Check your existing SCPs. Amazon created one for you when you built your organization. It says “All Accounts in this organization can use all services.” Check it with this command:
  3. Now we’ll create our new SCP, which will state Deny all use of cloudhsm. Notice how the SCP language is almost an IAM policy?
  4. List the policies again, to notice that there are two
  5. Let’s make another SCP, which will state CloudTrail cannot be disabled.
  6. Let’s make another SCP, which will state AWS Config Rules Cannot Be Disabled.

Enable SCPs for your organization and attach them

At this point, we have an Organization and some SCPs, but they aren’t attached.

Our organization does not yet have any structure, and it is not in a state where the SCPs that we created can be attached anywhere.

SCPs have to be explicitly enabled for your Organization. Let us go ahead and do that.

  1. First, we’re going to go ahead run a command that will be disabled via SCP later.
  2. Now, we need to gather the organizational Root id to enable SCPs

    We will now enable SCPs in our Organization’s Root. Take the Id in the output above


  3. List the roots of the organization again, and (hopefully) notice that SCPs are enabled

  4. List out the SCP Policies. You’ll need these Ids in the coming commands

  5. Attach the Deny cloudhsm:* SCP to the root. Doing this will trickle through the whole organization.

  6. Attach the Keep CloudTrail Enabled SCP to the root. Doing this will trickle through the whole organization.

  7. Attach the Keep Config enabled SCP to the root. Doing this will trickle through the whole organization.

    Show which policies are attached to our root object.

  8. Ok, Now let’s see what we’ve disabled*

    BUT, BUT, we just disabled that!! WHAT?!

    SCPs don’t impact the root of your organization. The Aristocrats! Gilbert Gotfried delivering the punchline "The Aristcats!"

    Presumably, this means that if you have an admin/root user in the root of your organization, you can recover. Maybe. With the help of support. ( don’t try this for funsies, folks! )

Step Three: Build out an Organization CloudTrail

Now that we’ve laid the groundwork let’s build out this amazing organization that we’re so excited to try out!

Make an S3 bucket to drop the CloudTrail logs into

We’re now ready to create an S3 bucket into which we’ll stash our CloudTrail Logs for our entire organization, automatically, as the org grows or shrinks.

Pretty cool, right? Before we can create the S3 bucket that we’re gonna drop our cloudtrails into, we need to get the organization’s OrgId

  1. Use the CLI to grab your OrgId

Now move over to add the CloudFormation Stack that is going to build out the S3 bucket with the right bucket policy for our org to log cloudtrail data into it.

  1. As your root user, navigate to Services -> CloudFormation
  2. Create Stack
  3. In the Choose a Template section put the radio button onto Specify an Amazon S3 URL
  4. In that URL place https://s3-us-west-2.amazonaws.com/awsadvent-2018-organizations/StepThreeCFNs/phase_3_s3_bucket.yml
  5. Next
  6. Stack Name CloudTrailS3Bucket
  7. OrgId your-org-id-from-the-cli-command-above
  8. Next
  9. Nothing needed here on the Options screen
  10. Next
  11. Check the box acknowledging that AWS CloudFormation might create IAM resources with custom names.
  12. Create
  13. Wait for the stack to reach a Create Completed state "Image of the s3 bucket's stack reaching a complete state"

Create an Organizational CloudTrail

Normally, I’d have dropped the CloudTrail creation into CloudFormation, because I’m not a monster… BUT… If you aren’t already aware, you can consider this my heads up to you that new features frequently get CLI/API support well before they manifest in CloudFormation.

CloudFormation does not yet support organizational CloudTrails. TO THE CLI!

  1. Gather the S3 bucket name that we created earlier.
  2. Now we have to enable all organizational features

    Even though this is an error, it’s the one that we want. Features are enabled πŸ‘πŸ‘

  3. Now we have to enable service access for cloudtrail. SCPs don’t impact service access.

  4. Finally, we create the actual trail

Ok, you’ve done a lot so far. And you’re going to be happy that you laid out all this prep work once you have to start answering questions like “Who in X account built out as many EC2s as their account would allow?”

Or, “Did Frank from Accounting actually delete the RDS Database in their AWS Account?”

Step Four: Finally Build Out Some Organization

Let’s get to the purpose that you’re here.. Building out some Organizations!

a directed graph of the organization layout with SCPs

Make An Organizational Unit ( OU ) for developers

You work in a progressive organization that wants individual developers to have their own AWS Accounts, huzzah!

We’re going to build an OU to stuff our developer accounts in, and then we’ll invite some developers into our org

  1. Gather the existing organization’s root. Since we don’t yet have any OUs, all things are rooted from the root.
  2. Now let’s create a subordinate OU
  3. Invite an email address
  4. Or invite an account id
  5. Now go sign in as that account that you just invited. Accept the invitation. This is what the AWS Organizations console should look like. We have one OU named Developer Accounts. Orgs Console organization view
  6. At this point, our newly invited account needs to be moved to our developers OU. When the account joins our organization, it’s parented by the root of the org.

Deep Breath, We’ve done it! πŸŽ‰πŸŽŠ

  1. Check your permissions. I have some credentials stashed away in ~/.aws/credentials for this account (488887740717). When I try and run aws cloudhsmv2 describe-clusters, I will now expect to get a AccessDeniedExeption.
  2. Here’s a final look at the Organizations console with our account placed in the OU. At this point, we can craft additional SCPs or what have you at the OU level, and those SCPs would only apply to the Accounts in the OU. Orgs Console organization view

About the Author

Ed Anderson is the SRE Manager at RealSelf, organizer of ServerlessDays Seattle, and occasional public speaker. Find him on twitter at @edyesed.

About the Editor

Jennifer Davis is a Senior Cloud Advocate at Microsoft. Jennifer is the coauthor of Effective DevOps.Β Previously, she was a principal site reliability engineer at RealSelf, developed cookbooks to simplify building and managing infrastructure at Chef, and built reliable service platforms at Yahoo. She is a core organizer of devopsdays and organizes the Silicon Valley event. She is the founder of CoffeeOps. She has spoken and written about DevOps, Operations, Monitoring, and Automation.