Luciano Mammino PRO
Cloud developer, entrepreneur, fighter, butterfly maker! #nodejs #javascript - Author of https://www.nodejsdesignpatterns.com , Founder of https://fullstackbulletin.com
Luciano Mammino (@loige)
2024-09-27
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
👋 I'm Luciano (🇮🇹🍕🍝🤌)
👨💻 Senior Architect @ fourTheorem
📔 Co-Author of Node.js Design Patterns 👉
Let's connect!
👋 I'm Luciano (🇮🇹🍕🍝🤌)
👨💻 Senior Architect @ fourTheorem
📔 Co-Author of Crafting Lambda Functions in Rust 👉
Let's connect!
Early-access available at
50% discount! 🤑
✉️ 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
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
RIGHT NOW!
𝕏 loige
RIGHT NOW!
𝕏 loige
𝕏 loige
𝕏 loige
A collection of accounts managed together
𝕏 loige
a.k.a. Management account
Your first account (owner of the organization)
𝕏 loige
a.k.a. OU
A logical group of accounts
𝕏 loige
... an AWS account, DUH!
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
Enable IAM Identity Center
𝕏 loige
Enable IAM Identity Center
This is what you want! Your current account will become the "management" account of the organization!
𝕏 loige
Customise your
"access portal" URL
* You won't be able to change this later, choose wisely! 😨
𝕏 loige
Create OUs and accounts
𝕏 loige
Create OUs and accounts
Create an OU
Create an Account
(or invite an existing account into the Org)
𝕏 loige
Create OUs and accounts
This needs to be unique!
TIP: Use "subaddressing"
𝕏 loige
Create OUs and accounts
𝕏 loige
Setup the Identity source
𝕏 loige
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
Create & manage your users
(In Identity Center or in your IdP)
𝕏 loige
Create groups
𝕏 loige
?!
Users
Groups
Permission Sets
Assignments
𝕏 loige
𝕏 loige
A collection of policies (managed or custom) that can be assigned to users/groups and accounts
𝕏 loige
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
Access to accounts
𝕏 loige
Access to accounts
TIP: Redirect specific roles to a given URL
E.g. BillingAccess -> Billing Dashboard
𝕏 loige
Access to accounts
Select accounts
𝕏 loige
Access to accounts
𝕏 loige
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!
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 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
?!
𝕏 loige
* Except for this very experimental™️ script
loige.link/org-formation-sso-import
𝕏 loige
Start from scratch: delete all SSO config and recreate it in OrgFormation 😓
Manage forward: leave old stuff as is and manage new stuff with OrgFormation 🙄
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
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
𝕏 loige
NOPE!
𝕏 loige
𝕏 loige
𝕏 loige
granted.dev CLI
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!
By Luciano Mammino
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.
Cloud developer, entrepreneur, fighter, butterfly maker! #nodejs #javascript - Author of https://www.nodejsdesignpatterns.com , Founder of https://fullstackbulletin.com