Managing AWS
Accounts like a PRO!

Luciano Mammino (@loige)

2024-09-27

What if...

𝕏 loige

You could spin up new AWS accounts in seconds?

Grab the slides

What if...

Grab the slides

𝕏 loige

You could spin up new AWS accounts in seconds?

 You could automatically configure access to these account?

What if...

Grab the slides

𝕏 loige

You could spin up new AWS accounts in seconds?

 You could automatically configure access to these account?

 You could easily provision resources and apply best practices?

What if...

Grab the slides

𝕏 loige

 You could automatically configure access to these account?

 You could easily provision resources and apply best practices?

You could easily access and manage these accounts from your CLI?

What if...

Grab the slides

𝕏 loige

 You could easily provision resources and apply best practices?

You could easily access and manage these accounts from your CLI?

We could get rid of IAM
users and long-lived access keys?

What if...

Grab the slides

𝕏 loige

 You could easily provision resources and apply best practices?

You could easily access and manage these accounts from your CLI?

You could get rid of IAM
users and long-lived access keys?

Dragons!

What if...

Grab the slides

𝕏 loige

 You could easily provision resources and apply best practices?

You could easily access and manage these accounts from your CLI?

We could get rid of IAM
users and long-lived access keys?

Here be ...

Dragons!

Noobs!

What if...

Grab the slides

𝕏 loige

Here be ...

Dragons!

Noobs!

👋 I'm Luciano (🇮🇹🍕🍝🤌)

👨‍💻 Senior Architect @ fourTheorem

📔 Co-Author of Node.js Design Patterns  👉

Let's connect!

linktr.ee/loige

$ ~ whoami

👋 I'm Luciano (🇮🇹🍕🍝🤌)

👨‍💻 Senior Architect @ fourTheorem

📔 Co-Author of Crafting Lambda Functions in Rust  👉

Let's connect!

linktr.ee/loige

$ ~ whoami

Early-access available at

50% discount! 🤑

Always re-imagining

We are a pioneering technology consultancy focused on AWS and serverless

✉️ Reach out to us at  hello@fourTheorem.com

😇 We are always looking for talent: fth.link/careers

We can help with:

Cloud Migrations

Training & Cloud enablement

Building high-performance serverless applications

Cutting cloud costs

𝕏 loige

𝕏 loige

𝕏 loige

Why do we want multiple accounts?

𝕏 loige

Why do we want multiple accounts?

Isolation

𝕏 loige

Why do we want multiple accounts?

Cost management

𝕏 loige

Why do we want multiple accounts?

Environment segregation

𝕏 loige

Why do we want multiple accounts?

Compliance

𝕏 loige

Why do we want multiple accounts?

Access control

𝕏 loige

Why do we want multiple accounts?

Because AWS says so!

𝕏 loige

Ok, but at which point in my cloud journey should I have multiple accounts?

RIGHT NOW!

𝕏 loige

RIGHT NOW!

Ok, but at which point in my cloud journey should I have multiple accounts?

𝕏 loige

Let's do this!

𝕏 loige

Terminology

𝕏 loige

Terminology

Organization

A collection of accounts managed together

𝕏 loige

Terminology

Root account

a.k.a. Management account
Your first account (owner of the organization)

𝕏 loige

Terminology

Organizational Unit

a.k.a. OU
A logical group of accounts

𝕏 loige

Terminology

Account

... an AWS account, DUH!

𝕏 loige

Accounts in an organization form a tree structure

𝕏 loige

Accounts in an organization form a tree structure

OUs

𝕏 loige

Accounts in an organization form a tree structure

Accounts

Management account

𝕏 loige

Step 1.

Enable IAM Identity Center

𝕏 loige

Step 1.

Enable IAM Identity Center

This is what you want! Your current account will become the "management" account of the organization!

𝕏 loige

Step 2.

Customise your
"access portal" URL

*

* You won't be able to change this later, choose wisely! 😨

𝕏 loige

Step 3.

Create OUs and accounts

𝕏 loige

Step 3.

Create OUs and accounts

Create an OU

Create an Account
(or invite an existing account into the Org)

𝕏 loige

Step 3.

Create OUs and accounts

This needs to be unique!

TIP: Use "subaddressing"

  • loigetemp@gmail.com
  • loigetemp+aws-sandbox@gmail.com
  • loigetemp+aws-production@gmail.com
  • loigetemp+aws-development@gmail.com

𝕏 loige

Step 3.

Create OUs and accounts

Suggestions for a good organization structure:

loige.link/aws-organizations

𝕏 loige

Step 4.

Setup the Identity source

𝕏 loige

Step 4.

Setup the Identity source

Users created and managed in IAM Identity Center (different from IAM users!)

Azure AD (and frienz)

M$FT stuff

Any IdP supporting SAML and SCIM

𝕏 loige

Step 4.5

Create & manage your users

(In Identity Center or in your IdP)

𝕏 loige

Step 5

Create groups

𝕏 loige

Configuring access to accounts

?!

Users

Groups

Permission Sets

Assignments

Step 6

𝕏 loige

Terminology - part II

𝕏 loige

Terminology - part II

Permission Set

A collection of policies (managed or custom) that can be assigned to users/groups and accounts

𝕏 loige

Terminology - part II

Assignment

The resource that ties together Users/Groups with Permission Sets and Accounts

𝕏 loige

𝕏 loige

PermissionSet

User / Group

Account

+

+

Assignment

Caius Julius

BillingAccess

Production

DevGroup

ViewOnlyAccess

Production

DevGroup

PowerUserAccess

Dev

𝕏 loige

Step 6

Access to accounts

𝕏 loige

Step 6

Access to accounts

TIP: Redirect specific roles to a given URL

E.g. BillingAccess -> Billing Dashboard

𝕏 loige

Step 6

Access to accounts

Select accounts

𝕏 loige

Step 6

Access to accounts

𝕏 loige

Step 6

Access to accounts

1 Group (AdminGroup)

16 Assignments!

8 Accounts

2 Permission sets

𝕏 loige

🎉

𝕏 loige

Excuse me... You did all the things manually

and call yourself a PRO?!

𝕏 loige

OrgFormation!

Introducing

𝕏 loige

OrgFormation

Open Source Infrastructure as Code (IaC) tool for AWS Organizations

𝕏 loige

OrgFormation

It can manage your accounts and OUs through a YAML file

𝕏 loige

OrgFormation

Extends CloudFormation templates
to deploy stacks across multiple accounts

𝕏 loige

OrgFormation

Allows you to perform a sequence of actions (e.g. deploy a template) by using task files

𝕏 loige

npm install -g aws-organization-formation
org-formation init organization.yml

𝕏 loige

# organization.yml

AWSTemplateFormatVersion: '2010-09-09-OC'
Description: default template generated for organization with master account 730335603479

Organization:
  ManagementAccount:
    Type: OC::ORG::MasterAccount
    Properties:
      AccountName: loigetemp
      AccountId: '730335603479'
      RootEmail: '[REDACTED]'

  OrganizationRoot:
    Type: OC::ORG::OrganizationRoot
    Properties:
      DefaultOrganizationAccessRoleName: OrganizationAccountAccessRole

  MarketplaceOU:
    Type: OC::ORG::OrganizationalUnit
    Properties:
      OrganizationalUnitName: Marketplace
      Accounts: !Ref MarketplaceAccount

  SandboxOU:
    Type: OC::ORG::OrganizationalUnit
    Properties:
      OrganizationalUnitName: Sandbox
      Accounts:
        - !Ref ExperimentsAccount
        - !Ref WorkshopsAccount

  SharedOU:
    Type: OC::ORG::OrganizationalUnit
    Properties:
      OrganizationalUnitName: Shared
      Accounts: !Ref SecurityAccount

  WorkloadsOU:
    Type: OC::ORG::OrganizationalUnit
    Properties:
      OrganizationalUnitName: Workloads
      Accounts:
        - !Ref ProductionAccount
        - !Ref QaAccount
        - !Ref DevelopmentAccount

  DevelopmentAccount:
    Type: OC::ORG::Account
    Properties:
      AccountName: Development
      AccountId: '992382505208'
      RootEmail: '[REDACTED]'

  ExperimentsAccount:
    Type: OC::ORG::Account
    Properties:
      AccountName: Experiments
      AccountId: '992382488722'
      RootEmail: '[REDACTED]'
      
# ... truncated for brevity

𝕏 loige

NewAccount:
  Type: OC::ORG::Account
  Properties:
    AccountName: NewAccount
    RootEmail: 'augustus@imperium.ro'

𝕏 loige

We can easily add a new account to our organization by adding something like:

And then running:

org-formation update organization.yml
 WorkloadsOU:
    Type: OC::ORG::OrganizationalUnit
    Properties:
      OrganizationalUnitName: Workloads
      Accounts:
        - !Ref ProductionAccount
        - !Ref QaAccount
        - !Ref DevelopmentAccount
        - !Ref NewAccount # <---

𝕏 loige

We can also add the new account to an OU:

And then running:

org-formation update organization.yml
Resources:
  PrintLambdaEvent:
	  Type: AWS::Lambda::Function
	  Properties:
      Handler: index.lambda_handler
      Runtime: python3.12
		  Code:
        ZipFile: |
          def lambda_handler(event, context):
              print(event)

𝕏 loige

Let's try to deploy a simple Lambda function to all our Dev accounts

# templates/test-lambda.yml

AWSTemplateFormatVersion: '2010-09-09-OC'

Organization: !Include ../organization.yml

OrganizationBindings:
  DevAccounts:
    OrganizationalUnit: !Ref DevelopmentOU
    Region: "eu-west-1"

Resources:
  PrintEventLambda:
	  Type: AWS::Lambda::Function
	  Properties:
      Handler: index.lambda_handler
      Runtime: python3.12
		  Code:
        ZipFile: |
          def lambda_handler(event, context):
              print(event)
    OrganizationBinding: !Ref DevAccounts

𝕏 loige

# organization-tasks.yml

OrganizationUpdate:
  Type: update-organization
  Template: ./organization.yml

TestLambdaResources:
  Type: update-stacks
  Template: ./templates/test-lambda.yml
  StackName: testLambda
  StackDescription: A simple test Lambda function that prints the received event

𝕏 loige

Now we can run:

org-formation perform-tasks organization-tasks.yml

𝕏 loige

Configuring access to accounts

?!

with OrgFormation

𝕏 loige

Configuring access to accounts

with OrgFormation

There's no way to import your existing
Groups, Permission Sets & Assigments! *

* Except for this very experimental™️ script
loige.link/org-formation-sso-import

𝕏 loige

We have 3 options

  1. Start from scratch: delete all SSO config and recreate it in OrgFormation 😓
     

  2. Manage forward: leave old stuff as is and manage new stuff with OrgFormation 🙄
     

  3. Manual Import: create a new OrgFormation template, deploy it to get a CloudFormation stack, import existing resources into the stack, and update your OrgFormation template correctly. 👨‍⚕️🥄🧠

# templates/sso-assignments.yml

AWSTemplateFormatVersion: '2010-09-09-OC'
Description: SSO Assignments for Users and Groups

Organization: !Include ../organization.yml

OrganizationBindings:
  ManagementAccountBinding:
    # Only the management account
    IncludeMasterAccount: true

Parameters:
  IdentityStoreId:
    Type: String
    Default: "REPLACE THIS WITH YOUR IDENTITY STORE ID"
  ManagingInstanceArn:
    Type: String
    Default: "REPLACE THIS WITH THE ARN OF YOUR IDENTITY CENTER"

Resources:
  # Groups
  AdminGroup:
    OrganizationBinding: !Ref ManagementAccountBinding
    Type: AWS::IdentityStore::Group
    Properties:
      Description: Administrator Access
      DisplayName: Admin
      IdentityStoreId: !Ref IdentityStoreId
      
  # PermissionSets
  AdministratorAccessPermissionSet:
    OrganizationBinding: !Ref ManagementAccountBinding
    Type: AWS::SSO::PermissionSet
    Properties:
      Name: AdministratorAccess
      Description: "Administrator access"
      InstanceArn: !Ref ManagingInstanceArn
      ManagedPolicies:
        - arn:aws:iam::aws:policy/AdministratorAccess
      SessionDuration: PT4H
      
  ReadOnlyAccessPermissionSet:
    OrganizationBinding: !Ref ManagementAccountBinding
    Type: AWS::SSO::PermissionSet
    Properties:
      Name: ReadOnly
      Description: ReadOnlyAccess
      InstanceArn: !Ref ManagingInstanceArn
      ManagedPolicies:
        - arn:aws:iam::aws:policy/ReadOnlyAccess
      SessionDuration: PT4H
      
	# Assignments
	AdminGroupToAdministratorAccessPermissionSetToManagementAccount:
    OrganizationBinding: !Ref ManagementAccountBinding
    Type: AWS::SSO::Assignment
    Properties:
      InstanceArn: !Ref ManagingInstanceArn
      PermissionSetArn: !GetAtt AdministratorAccessPermissionSet.PermissionSetArn
      PrincipalId: !GetAtt AdminGroup.GroupId
      PrincipalType: GROUP
      TargetId: !GetAtt ManagementAccount.AccountId
      TargetType: AWS_ACCOUNT
	
	AdminGroupToReadOnlyAccessPermissionSetToManagementAccount:
    OrganizationBinding: !Ref ManagementAccountBinding
    Type: AWS::SSO::Assignment
    Properties:
      InstanceArn: !Ref ManagingInstanceArn
      PermissionSetArn: !GetAtt ReadOnlyAccessPermissionSet.PermissionSetArn
      PrincipalId: !GetAtt AdminGroup.GroupId
      PrincipalType: GROUP
      TargetId: !GetAtt ManagementAccount.AccountId
      TargetType: AWS_ACCOUNT
      
  # ... truncated for brevity

𝕏 loige

You'll have to manage LOTS

of Assignment resources!

 

𝕏 loige

Unless you use the aws-sso-util macro 
by Ben Kehoe

# templates/sso-assignments.yml

AWSTemplateFormatVersion: '2010-09-09-OC'
Description: SSO Assignments for Users and Groups
Transform: AWS-SSO-Util-2020-11-08 # Enables the macro!

# ...

OrganizationBindings:
  AllAccountsBinding:
    Account: '*'
    IncludeMasterAccount: true

  ManagementAccountBinding:
    IncludeMasterAccount: true
    
# ...

Resources:

  # ...
  
  AdminGroupAssignments:
    OrganizationBinding: !Ref ManagementAccountBinding
    Type: SSOUtil::SSO::AssignmentGroup # Special type introduced by the macro
    Properties:
      Name: AdminGroupAssignments
      InstanceArn: !Ref ManagingInstanceArn
      Principal:
        - Type: GROUP
          Id:
            - !Ref AdminGroup
      PermissionSet:
        - !GetAtt AdministratorAccessPermissionSet.PermissionSetArn
        - !GetAtt ReadOnlyAccessPermissionSet.PermissionSetArn
      Target:
        - Type: AWS_ACCOUNT
          Id:
            - Fn::EnumTargetAccounts AllAccountsBinding ${account} 

𝕏 loige

Unless you use the aws-sso-util macro 
by Ben Kehoe

𝕏 loige

What else can we do with OrgFormation?

Some ideas:

  1. Manage SCPs
  2. Budget alarms per account
  3. Automate domains and TLS certificates for dev accounts
  4. Centralise CloudTrail logs
  5. Forbid creation of IAM Users and Access Key
  6. Forbid use of large (and expensive!) EC2 instances
  7. Enable account/region-level resources (e.g. API Gateway logging)
  8. and a lot more!

𝕏 loige

How do we get temporary access keys for an account?

𝕏 loige

𝕏 loige

𝕏 loige

𝕏 loige

𝕏 loige

NOPE!

𝕏 loige

𝕏 loige

𝕏 loige

granted sso login --sso-region eu-west-1 --sso-start-url https://loigetemp.awsapps.com/start

𝕏 loige

Initial configuration of the granted CLI

Login:

granted sso populate --sso-region eu-west-1 https://loigetemp.awsapps.com/start

𝕏 loige

granted sso populate --prefix loigetemp_ --sso-region eu-west-1 https://loigetemp.awsapps.com/start

Initial configuration of the granted CLI

Populate your profiles (list of accounts and permission sets available to you):

If you work with multiple organizations, you can use a prefix to avoid collisions:

𝕏 loige

Looking for a more detailed walkthrough?

Cover photo by Carlos Ibáñez on Unsplash

𝕏 loige

GRAZIE!

Managing AWS accounts like a PRO

By Luciano Mammino

Managing AWS accounts like a PRO

Using multiple AWS accounts is a best practice that can help you isolate and manage business applications and data. If you have looked at the AWS Well-Architected Framework you might have seen that having multiple accounts for an organisation can help achieve operational excellence, security, reliability, and even cost optimisation. Starting with a good multi-account foundation is something that will enforce many best practices from day 0, like, for example, not having long-lived credentials on developers’ machines. And the benefits just get greater as the company grows and the level of cloud adoption increases. It’s a practice that scales well from 1 developer to thousands of developers! In this talk, I will show you how to leverage services such as AWS IAM Identity Center, AWS Organizations, and tools such as Granted and OrgFormation to manage multiple accounts confidently and consistently.

  • 389