├── .github └── ISSUE_TEMPLATE │ └── new-saas-pattern-submission.md ├── .gitignore ├── AccountPerTenant ├── authors.json ├── images │ ├── Account-Per-Tenant-Architecture.png │ ├── dario-rivera.jpeg │ └── tod-golding.jpeg └── pattern.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DeploymentModels ├── authors.json ├── images │ └── tod-golding.jpeg └── pattern.md ├── ExternallyHostedIdentity ├── authors.json ├── images │ └── tod-golding.jpeg └── pattern.md ├── FullStackPool ├── authors.json ├── images │ └── tod-golding.jpeg └── pattern.md ├── FullStackSilo ├── authors.json ├── images │ ├── full-stack-silo.png │ └── tod-golding.jpeg └── pattern.md ├── Identity ├── authors.json ├── images │ ├── demo-architecture.png │ └── tod-golding.jpeg └── pattern.md ├── JustInTimeIdentityMigration ├── authors.json ├── images │ └── tod-golding.jpeg └── pattern.md ├── LICENSE ├── PUBLISHING.md ├── README.md ├── SelfHostedIdentity ├── authors.json ├── images │ └── tod-golding.jpeg └── pattern.md ├── SiloedCompute ├── authors.json ├── images │ └── tod-golding.jpeg └── pattern.md ├── VPCPerTenant ├── authors.json ├── images │ └── tod-golding.jpeg └── pattern.md ├── _pattern-template ├── authors.json ├── images │ ├── author-placeholder.png │ └── demo-architecture.png └── pattern.md └── patterns.json /.github/ISSUE_TEMPLATE/new-saas-pattern-submission.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: New saas pattern submission 3 | about: Submit a new saas pattern 4 | title: New pattern submission 5 | labels: '' 6 | assignees: swarwick 7 | 8 | --- 9 | 10 | To submit a pattern to the SaaS Patterns collection, submit an issue with the following information. 11 | 12 | **To learn more about submitting a pattern, read the [publishing guidelines](https://github.com/aws-samples/saasbuilder-patterns/blob/main/PUBLISHING.md) page.** 13 | - Use the pattern template located at [here](https://github.com/aws-samples/saasbuilder-patterns/tree/main/_pattern-template) to set up a pattern. 14 | - You can test the format of your layout [here](https://saasbuilder.com/#/Preview) to validate the markdown 15 | Note the following information for the pattern: 16 | - pattern.md file completed 17 | - authors.json file completed with all authors of this pattern 18 | - Update the patterns.json file in the repositories root directory and include your new pattern in the correct location as a new root pattern or child of another pattern 19 | - Architecture diagrams stored in images sub folder in either (PNG, JPEG, or GIF) format. 20 | - All reference material linked 21 | 22 | You must ensure that the sections of the pattern.md are completed in full. 23 | 24 | ## GitHub PR for template: 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | .idea/ -------------------------------------------------------------------------------- /AccountPerTenant/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | }, 10 | { 11 | "name": "Dario Rivera", 12 | "image": "./images/dario-rivera.jpeg", 13 | "bio": "Senior Solutions at AWS", 14 | "linkedin": "https://www.linkedin.com/in/dario-rivera-nc/" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /AccountPerTenant/images/Account-Per-Tenant-Architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/AccountPerTenant/images/Account-Per-Tenant-Architecture.png -------------------------------------------------------------------------------- /AccountPerTenant/images/dario-rivera.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/AccountPerTenant/images/dario-rivera.jpeg -------------------------------------------------------------------------------- /AccountPerTenant/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/AccountPerTenant/images/tod-golding.jpeg -------------------------------------------------------------------------------- /AccountPerTenant/pattern.md: -------------------------------------------------------------------------------- 1 |

2 | Architecture 3 |

4 | 5 | ### Core Concept 6 | * In this full stack silo pattern, we’re placing all the resources of a given tenant in a separate account. This means that your onboarding process and operational experience will need to provision and configure a new account. 7 | 8 | ### Key Considerations 9 | * While you can automate aspects of each tenant accounts, there are some aspects of account configuration that cannot be achieved through automation. Account limits are amongst this list and represent a key area you’ll want to consider as you look at what limits will need to be adjusted for each new tenant account. 10 | * AWS Control Tower provides tools for orchestrating the provisioning and configuration of accounts. It provides mechanisms that can simplify this deployment and introduce guardrails that may enhance the overall security and isolation footprint of your SaaS offering. 11 | * While siloing resources, tenants are not allowed to run separate versions of the product. The operational experience here inherits the job of providing a single pane of glass that can provide an aggregated view of all tenant environments. Application deployments will send all deployment data to all tenants. 12 | * The control plane of your SaaS environment will need access to all tenant accounts. This means you’ll need to configure and enable cross-account access, opening up paths for your control plane to deploy, operate, and manage tenant environments. 13 | * Any account-per-tenant model needs to consider the overall scaling profile of your SaaS environment. The number of tenants may exceed account limits, for example. Also, managing and operating large numbers of tenants in an account-per-tenant model can be challenging as it would require significant operations overhead. Aggregation of operational data, deployments, and a host of other areas get more complex in environments with a large number of tenant accounts. 14 | 15 | ### References 16 | Managing the Account Lifecycle in account per tenant SaaS Environments on AWS 17 | 18 | SaaS Tenant Isolation Strategies 19 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /DeploymentModels/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /DeploymentModels/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/DeploymentModels/images/tod-golding.jpeg -------------------------------------------------------------------------------- /DeploymentModels/pattern.md: -------------------------------------------------------------------------------- 1 | ### Core Concept 2 | * There are many ways to deploy a SaaS solution. Compliance, isolation, noisy neighbor, tiering and other considerations can have lead you to deploy your SaaS offering in any number of different deployment patterns that best align with the business and operational goals of your SaaS environment. These deployment models are not mutually exclusive. Some SaaS businesses may opt to support multiple deployment models to address the specific and personas of their customer base. 3 | 4 | 5 | ### Why It Matters 6 | * Picking the deployment model of your SaaS application represents one of the most fundamental decisions you’ll need to make for your SaaS offering. You’ll need to weigh a variety of business and technical factors, determining which mix of customer, market, and technical considerations will shape the deployment model ultimately select. This decision will also have a direct impact on the operational efficiency, agility, and overall success of the SaaS offering. 7 | ### When Should I be Thinking About This? 8 | * Figuring out your deployment model is one of the most early and foundational elements of building your overall SaaS business and technical footprint. You upfront process should be looking at tiering, isolation, noisy neighbor, and customer tiering profiles to determine which deployment models are best aligned to the needs of your business. 9 | ### What Are The Typical Deployment Patterns? 10 | * Generally deployment appears in three distinct patterns, including full stack silo, full stack pool, and bridge deployment models. The basic idea here is that we’re picking a deployment model that determines the degree to which tenants will be sharing resources. A full stack silo, for example, has all resources of a tenant running in a separate infrastructure. Full stack pool is the polar opposite of this model, sharing all resources for all tenants. The bridge model allows for middle ground where some resources may be siloed and some may be pooled. All three of these patterns still rely on a common control plane that manages and operates all tenants through a shared experience. 11 | 12 | -------------------------------------------------------------------------------- /ExternallyHostedIdentity/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /ExternallyHostedIdentity/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/ExternallyHostedIdentity/images/tod-golding.jpeg -------------------------------------------------------------------------------- /ExternallyHostedIdentity/pattern.md: -------------------------------------------------------------------------------- 1 | ### Core Concept 2 | * While hosting your own identity offers a great deal of freedom and customization, Externally-hosted identity is a reality for some SaaS providers. Their customers may simply require them to accept authentication from their identity provider. For other SaaS providers, it may be essential that they support authentication from a variety of well known providers. This could be essential to promoting customer acquisition and reducing the overall friction of the experience. The challenge of this model is that the SaaS provider has no control over the representation of the user within these environments. This means that you’ll need to take other measures to connect user identity with tenant identity and generate the tenant context that your system relies on. 3 | 4 | ### Key Considerations 5 | * To connecting tenants to user can often be achieved though a federation mechanism that will connect user data with your tenant identity. With Amazon Cognito, for example, you can federate to external identity provider, storing tenant context in Cognito. When the tenant authenticates against the external identity provider, Cognito will stitch its data together with the user identity to get a token that includes tenant context. 6 | * Your ability to support external providers will also be influenced by the authentication specifications that are supported by these external providers. Many comply with OIDC, for example, and may be able to conform to a standard flow. However, their implementation of that specification can vary. 7 | * The degree to which external providers comply with token specifications can vary. The content of ID and Access token, for example, could vary from one implementation to the next. You’ll need to ensure that each provider can comply the needs of your SaaS environment. 8 | * In some instances, you may be required to integrate with a custom identity provider that does not conform to any industry specifications. In these cases, you’ll have to determine how best to abstract away the custom characteristics of these integrations. 9 | * While support externally-hosted identity providers can be essential to your success, you need to strike a balance between embracing one-off solutions and undermining the overall agility of your SaaS offering. If the onboarding of each tenant requires custom code and these integrations add increment overhead, this could end up impacting your ability to achieve the operational efficiency goals that SaaS demands. 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /FullStackPool/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /FullStackPool/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/FullStackPool/images/tod-golding.jpeg -------------------------------------------------------------------------------- /FullStackPool/pattern.md: -------------------------------------------------------------------------------- 1 | ### Core Concept 2 | * A full stack pool deployment is one where all the resources are shared by tenants. This model focuses heavily on maximizing the operational, agility, and cost efficiency that is associated with having tenants share a scale resources collectively. Deploying and operating these environments has less complexity than siloed environments. Isolation can prove more challenging in pooled environments where there’s a reliance on more creative and more fine-grained isolation constructs. 3 | 4 | 5 | ### Key Considerations 6 | * Each layer/service/component of your pooled SaaS infrastructure introduces new considerations when it comes to isolation and noisy neighbor conditions. Your architecture must consider how it will ensure that tenants are not allowed to saturate your pooled resources. You’ll also need to introduce isolation constructs that can limit access to the tenant’s resources that reside in a pooled infrastructure construct. 7 | * Pooled compute resource must respond rapidly to shifts in workload. New tenants may be added to the system and tenants may have highly variable workloads. These dynamics often require focused scaling strategies that ensure that can accommodate the fluid nature of multi-tenant workloads. 8 | * Every architecture should support fault tolerance. The bar for fault tolerance in fully pooled environments is especially high. Outages of any kind in a pooled environment can impact all the tenants in your system. Circuit breakers, async integration, microservice decomposition—these are amongst a long list of strategies that should be applied to maximize the durability of your SaaS environment. 9 | * Throttling is generally a good strategy across any SaaS environment. However, in a pooled model it becomes especially important to introduce throttling policies to prevent tenants from putting excess load on the system’s services. 10 | 11 | ### References 12 | [AWS re:Invent 2019: SaaS tenant isolation patterns](https://www.youtube.com/watch?v=fuDZq-EspNA) 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /FullStackSilo/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /FullStackSilo/images/full-stack-silo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/FullStackSilo/images/full-stack-silo.png -------------------------------------------------------------------------------- /FullStackSilo/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/FullStackSilo/images/tod-golding.jpeg -------------------------------------------------------------------------------- /FullStackSilo/pattern.md: -------------------------------------------------------------------------------- 1 |

2 | Architecture 3 |

4 | 5 | ### Core Concept 6 | * The idea of full stack silo is that all of the infrastructure for a tenant is deployed in a single, self-contained construct. Silo models are used for a variety of reasons. Some rely on a silo based on compliance considerations. Others may choose silo based on noisy neighbor, legacy migration, or a host of other consideration. This model can have some adverse effects on the cost, operational, and agility efficiency of a SaaS environment. 7 |
8 | 9 | 10 | ### Key Considerations 11 | * Silo is every bit as valid as any SaaS model that may share infrastructure. The key here is determining whether silo aligns with the needs of your customers or the state of your current application. Some teams that are migrating rely on this model as the starting point for lifting and shifting monolithic legacy applications into a SaaS model where the siloed nature of this model make it easier. The distributed/dedicate nature of this model does introduce operational complexity and can impact the cost efficiency of your offering. In some cases, you may choose to offer silo to a select set of “premium” tier tenants as a way to differentiate the experience of your SaaS solution. 12 | * Even though each tenant has separate resources in a full stack silo model, these siloes will still be managed and operated collectively. When new features are released they are released to all of the tenants. Tenants are never allowed to run one-off versions or be deployed independently. This would undermine the value proposition of SaaS and move more toward a managed service model. 13 | * That siloed nature of this model make the calculation of cost-per-tenant analytics much simpler. Here you can use tagging and other out-of-the-box AWS cost attribution constructs to profile the costs of each tenant silo. 14 | * Siloes are inherently less cost efficient that pooled models. Even with auto-scaling and other mechanisms in place, you’re likely to have some static and/or under-consumed resources—especially when a tenant is idle. 15 | * As you silo infrastructure, you must consider how you will route tenant workloads to specific tenant siloes. Each technology stack may support a variety of routing constructs. You’ll need to identify a model for observing tenant context and using that context to route requests to the appropriate tenant silo. 16 | * Siloed environments generally have more complex deployment footprints. Your DevOps model will need to consider how it rolls out new features across the collection of tenant siloes. 17 | * While the resources of a siloed SaaS environment are not shared by tenants, this does not mean that you’re solution is not multi-tenant. If a silo manages, operates, onboards, and deploys all tenants with the same experience, then this is still a multi-tenant SaaS environment. It can still benefit from the same agility and operational efficiency that is part of SaaS. 18 | 19 | ### References 20 | [AWS re:Invent 2019: SaaS tenant isolation patterns](https://www.youtube.com/watch?v=fuDZq-EspNA) 21 | 22 | -------------------------------------------------------------------------------- /Identity/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /Identity/images/demo-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/Identity/images/demo-architecture.png -------------------------------------------------------------------------------- /Identity/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/Identity/images/tod-golding.jpeg -------------------------------------------------------------------------------- /Identity/pattern.md: -------------------------------------------------------------------------------- 1 | ### Core Concept 2 | * Identity is a well-understood. There is a broad range of tools and services that can support your ability to authenticate users in a variety of models. However, in SaaS environments identity takes on additional scope and responsibility. In a multi-tenant SaaS environment, your identity solution must introduce the notion of a tenant and bind that tenant to a user. This creates what is referred to as a “SaaS Identity”, where both the identity of the user and the identity of its corresponding tenant are unified. When you look at tokens returned from a SaaS authentication process, they will now include the context of the tenant. How this identity is acquired and resolved can vary based on the needs of a SaaS environment. You may host your own identity solution, you may rely on external providers, or you may use some mix of these models. In all cases, though, you sill need to arrive at a solution that stitches together a SaaS identity. 3 | 4 | ### Why It Matters 5 | * Identity represents the entry point of your multi-tenant experience. It is the point at which we acquire tenant context and share that with all the downstream moving parts of our SaaS architecture. How you represent identity will be essential to your ability to streamline how and where identity is applied across the rest of your architecture. It connects you to isolation, routing, data partitioning, and a host of other architectural considerations. Identity also plays a pivotal role in the onboarding and tiering experience of your SaaS customers. It influences how you will introduce new tenants. You may also chose different models for representing tenant identity based on the tiering model of your application. 6 | 7 | ### When Should I be Thinking About This? 8 | * Identity is amongst the areas that should be at the front of your design and architecture process. It is at the core of bringing multi-tenancy to your environment and serves as a forcing function across the rest of your architecture. You may not have all the requirements of identity resolved up front. However, it’s still essential that you pick some strategy for connecting users to tenants so you can inject tenant context into the rest of your solution. 9 | 10 | ### What Are The Typical Deployment Patterns? 11 | * While there are multiple ways to implement identity, there are some common themes. The patterns are typically driven more by the needs of your market segments, your customer onboarding experience, and the realities of your domain. The two main categories here would be internally and externally hosted identity. With internally hosted identity, a SaaS provider would own all the moving parts of the identity. With the externally hosted identity model, the identity provider would require some federation model that would allow them to authenticate from external sources while still mapping users to your SaaS environment’s notion of tenants. SSO can also be part of these patterns. Of course, there are also hybrid models as well that support some mix of these options. -------------------------------------------------------------------------------- /JustInTimeIdentityMigration/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /JustInTimeIdentityMigration/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/JustInTimeIdentityMigration/images/tod-golding.jpeg -------------------------------------------------------------------------------- /JustInTimeIdentityMigration/pattern.md: -------------------------------------------------------------------------------- 1 | ### Core Concept 2 | * Even when an SaaS environment relies its own self-hosted identity model, these providers may discover customers that are hesitant to do a one-time migration of all their users to the SaaS system. In this mode, they prefer an approach that migrates users to their internally hosted experience. Here, a tenant will be configured with an external provider. When a user authenticates, the system will first attempt to authenticate against the internal provider. If they are not in the internal provider, the system will attempt to authenticate against the external provider. If they are in the external provider, they will be authenticated and migrated to the internal provider. 3 | 4 | ### Key Considerations 5 | * The general approach here is to start with the idea that an identity exists within the SaaS environment. This means all requests to authenticate will start with the internally hosted identity provider. If this user is not found there, it will then attempt to authenticate against the customer identity provider. 6 | * This migration process can introduce some latency into the initial onboarding process. Your solution should make every attempt to minimize the impact of this process, limiting friction for the onboarding process. 7 | * In this model, the assumption is that this migration of users will occur within a limited window of time. You have to determine when you may stop accepting users from the customer’s environment. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /PUBLISHING.md: -------------------------------------------------------------------------------- 1 | ## How to Publish a Pattern 2 | 3 | To submit a new saas builder pattern, or to make changes to existing code, follow the instructions below. Note: I can take up to 24 hours for a new pattern to appear after a pull request is accepted. 4 | 5 | ## Repo Names 6 | 7 | * **local:** Your local copy of the forked repository. 8 | * **origin:** Your forked, remote copy of the original repository. 9 | * **upstream:** The original, remote saasbuilder-patterns repository. 10 | 11 | ## Initial Setup 12 | 13 | [Fork and Clone](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the saasbuilder-patterns repo. 14 | 15 | 1. Fork the original saasbuilder-patterns repo to create a copy of the repo in your own GitHub account: https://github.com/aws-samples/saasbuilder-patterns 16 | 1. Clone your copy of the repo to download it locally: `git clone https://github.com/{your-github-username}/saasbuilder-patterns.git` 17 | 1. Change into the new local directory: `cd saasbuilder-patterns` 18 | 1. Add the original saasbuilder-patterns repo as another remote repo called "upstream": `git remote add upstream https://github.com/aws-samples/saasbuilder-patterns` 19 | 1. For verification, display the remote repos: `git remote -v` 20 | 21 | The output should look like this: 22 | 23 | ``` 24 | origin https://github.com/{your-github-username}/saasbuilder-patterns.git (fetch) 25 | origin https://github.com/{your-github-username}/saasbuilder-patterns.git (push) 26 | upstream https://github.com/aws-samples/saasbuilder-patterns (fetch) 27 | upstream https://github.com/aws-samples/saasbuilder-patterns (push) 28 | ``` 29 | 30 | ## Create Branch 31 | 32 | Create a new local branch for each saas pattern or modification being made. This allows you to create separate pull requests in the upstream repo. 33 | 34 | 1. Create and checkout a new local branch before making code changes: `git checkout -b {branch-name}` 35 | 36 | Branch name syntax: `{username}-{pattern|fix}-{description}` 37 | 38 | Example branch name: `myusername-silo-security-saasbuilder` 39 | 40 | 1. For verification, display all branches: `git branch -a` 41 | 42 | The output should look like this: 43 | 44 | ``` 45 | * {branch-name} 46 | main 47 | remotes/origin/HEAD → origin/main 48 | remotes/origin/main 49 | ``` 50 | 51 | ## Your Pattern 52 | 53 | Now is the time to create your new saas pattern or modify an existing pattern. 54 | 55 | 1. If you are creating a new saas pattern, copy the folder named "_pattern-template" to start with a template: `cp -r _pattern-template {new-folder-name}` 56 | 2. If you are modifying an existing pattern, make your code changes now. 57 | 3. Update the authors.json file complete with all authors of this pattern 58 | 4. Update the patterns.json file in the repositories root directory and include your new pattern in the correct location as a new root or child of another pattern. Create a new UUID for your new patterns id and make sure it is not used by any other existing pattern. 59 | 5. You can test the format of your layout [here](https://main.d64uo5pr4i9km.amplifyapp.com/#/Preview) to validate the patterns markdown. Use the full URL to your github pattern folder for [example](https://main.d64uo5pr4i9km.amplifyapp.com/#/Preview?pattern=https://github.com/aws-samples/saasbuilder-patterns/tree/main/FullStackSilo). 60 | 6. When your pattern is complete, stage the changes to your local branch: `git add .` 61 | 7. Commit the changes to your local branch: `git commit -m 'Comment here'` 62 | 63 | ## Pull Request 64 | 65 | Push your code to the remote repos and [create a pull request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request). 66 | 67 | 1. Push the local branch to the remote origin repo: `git push origin {branch-name}` 68 | 69 | If this is the first push to the remote origin repo, you will be asked to Connect to GitHub to authorize the connection. Sometimes the pop-up window appears behind other windows. 70 | 71 | 1. Go to the [upstream repo](https://github.com/aws-samples/saasbuilder-patterns) in Github and click "Compare & pull request". 72 | 1. Enter an appropriate title including path the pattern should appear under: 73 | 74 | Example title: `New pattern submission - Under - Deployment Models\Full Stack Silo Deployment\Silo Security` 75 | 76 | 1. Add a short description of the pattern. 77 | 1. Click "Create pull request". 78 | 1. Submit a [new issue](https://github.com/aws-samples/saasbuilder-patterns/issues/new?assignees=swarwick&labels=&template=new-saas-pattern-submission.md&title=New+pattern+submission+-+Under+-+{Pattern\Path}) or use an existing issue to provide the additional details that will be used to build the saas pattern on SaaSBuilder.com. 79 | 1. Add a link to the pull request in the "GitHub PR for template" section. If you type a hashtag (#), it will display a list of the current pull requests to select from. 80 | 2. Click "Submit new issue" (Or update an existing issue). 81 | 3. Example issue: https://github.com/aws-samples/saasbuilder-patterns/issues/1 82 | 83 | ## Sync Repos 84 | 85 | After your pull request has been accepted into the upstream repo: 86 | 87 | 1. Switch to your local main branch: `git checkout main` 88 | 1. Pull changes that occurred in the upstream repo: `git fetch upstream` 89 | 1. Merge the upstream main branch with your local main branch: `git merge upstream/main main` 90 | 1. Push changes from you local repo to the remote origin repo: `git push origin main` 91 | 92 | ## Delete Branches 93 | 94 | Delete any unnecessary local and origin branches. 95 | 96 | 1. Switch to your local main branch: `git checkout main` 97 | 1. For verification, display all branches: `git branch -a` 98 | 1. Delete any unnecessary local branches: `git branch -d {branch-name}` 99 | 1. Delete any unnecessary remote origin branches: `git push origin --delete {branch-name}` 100 | 101 | ## Helpful Tips 102 | 103 | 1. When creating a pattern.md file for your saas pattern, place example code and commands within a `code block`. 104 | 2. Place any architecture diagrams or related images in the `images` folder in either (PNG, JPEG, or GIF) format 105 | 3. Add any reference material related to the saas pattern in the reference section at the bottom 106 | 107 | ## Example Patterns 108 | 109 | 1. Full Stack Silo: [GitHub](https://github.com/aws-samples/saasbuilder-patterns/tree/main/FullStackSilo) 110 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SaaS Builder Patterns 2 | A repository of well-defined SaaS patterns. The intent of this repository is to help the community expand its knowledge base and contribute to a better understanding of SaaS principles and strategies. 3 | 4 | The [patterns.json](patterns.json) file contains a dictionary of the patterns available and how they related to other patterns. 5 | 6 | If you would like to submit a pattern please follow the [publishing guide](PUBLISHING.md) 7 | -------------------------------------------------------------------------------- /SelfHostedIdentity/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /SelfHostedIdentity/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/SelfHostedIdentity/images/tod-golding.jpeg -------------------------------------------------------------------------------- /SelfHostedIdentity/pattern.md: -------------------------------------------------------------------------------- 1 | ### Core Concept 2 | * With self-hosted identity, a SaaS provider will select the identity tooling/service that best aligns with the needs of their environment. They will define all the moving parts of the authentication flow, including defining the custom claims/attributes that will be associated with each user within the scope of the identity model. This approach gives the SaaS provider the greatest control over their identity experience, enabling them to provide the business and customers with a rich collection of authentication and tiering options. 3 | 4 | ### Key Considerations 5 | * Self-hosted identity can be tightly woven into your overall tenant onboarding process where you can better orchestrate the creation, management, and lifecycle of the users in your SaaS environment. 6 | * Many identity providers offer a range of configuration options for their authentication experience. Support for MFA, password expiration policies, password format policies, and host of other options are often provided. In a self-hosted model, you can selectively offer these features to tenants. For example, your basic tier tenants may be provided a fixed combination of more limited options, while your premium tier tenants could be allowed to configure the full set of options. So, I might allow my premium tier tenants to turn on/off any of the features listed above. 7 | * Adding claims/attributes to your identity in your self-hosted model can be used to associate key data with your SaaS identity. Tenant identifier, roles, etc. are all natural attributes that make sense to bind to your identity. However, you should draw a hard line between what is needed for your SaaS identity and what is needed to introduce general purpose role configuration into your environment. If you have application constructs that are continually be added/updated to enable application paths, those attributes and configuration should be managed outside the scope of your identity experience. This is where traditional RBAC and other frameworks can fill this need. 8 | * Some self-hosted identity solutions may offer a range of constructs for representing and grouping users. For example, Amazon Cognito has the notion of User Pools and groups. As part of your architecture, for example, you may want to put all users into a single user pool or you may choose to place them in a separate pools. In each of these cases you have to considering the scalability of the model along with the tiering needs of your environment. You might offer premium tier tenants their own user pool and put all the remaining users in their own pool. There are lots of permutations here. The key here is to identify a grouping strategy that best aligns with the needs of the business and how it may influence the auth flow of your experience. 9 | * A self-hosted identity provider often serves as the overall tenant user management of your system. As you look at this service, you’ll want to think beyond the authentication experience and consider how this will shape and influence the overall user management experience of your tenants. What data and actions will need to be supported to support the configuration and management of all the system’s users. Will identity be managed in one location and all the other capabilities of identity be managed through services in your application? 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /SiloedCompute/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /SiloedCompute/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/SiloedCompute/images/tod-golding.jpeg -------------------------------------------------------------------------------- /SiloedCompute/pattern.md: -------------------------------------------------------------------------------- 1 | ### Core Concept 2 | * In a siloed compute mode, we saying that a compute resource will be deployed in a model where the compute resources are dedicated to a tenant. The motives for siloing computing can span a range of considerations, including noisy neighbor, isolation, tiering models, and application use cases. The mechanisms for partitioning compute can vary substantially. Containers and serverless, would rely on different strategies silo compute. 3 | 4 | ### Key Considerations 5 | * Siloing compute resources does not mean that every resources that’s touched by a compute resource is also siloed. A siloed EKS cluster, for example, could still interact with a database that is running in a pooled model. In this mode, each individual resource (compute, storage, etc.) can be deployed in a silo or pool model. 6 | * How you silo compute can often be heavily influenced by the landscape of microservices that may be in your application. Each microservice of your application may make different choices about which microservices are deployed in a siloed compute model. In these instances, you may actually have a service that has multiple siloed compute deployments (one for each tenant that has been configured as requiring siloed compute resources for that microservice). 7 | * Siloed compute does not require the compute to be deployed within a construct that isolates the compute. A siloed compute deployment, for example, does not require a separate VPC or Account to run the siloed compute resources. Siloed compute only means that the compute will not process requests from multiple tenants. 8 | * Siloing compute resources does not insure that those resources are considered “isolated” from cross-tenant access. Siloed compute sets the stage for isolation, but your system must still apply policies and strategies to enforce isolation. 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /VPCPerTenant/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Tod Golding", 5 | "image": "./images/tod-golding.jpeg", 6 | "bio": "Software architect and wannabe playwright", 7 | "linkedin": "https://www.linkedin.com/in/tod-golding-0ba35b2/", 8 | "twitter": "https://twitter.com/tod_golding" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /VPCPerTenant/images/tod-golding.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/VPCPerTenant/images/tod-golding.jpeg -------------------------------------------------------------------------------- /VPCPerTenant/pattern.md: -------------------------------------------------------------------------------- 1 | ### Core Concept 2 | * In this full stack silo pattern VPCs are used as the fundamental unit of deployment and isolation for each tenant. A VPC is provisioned each time a tenant onboards along with the application infrastructure that will be associated with that tenant. Networking constructs will be used to ensure that tenants are prevented from accessing the the VPCs of other tenants. 3 | 4 | ### Key Considerations 5 | * You’ll want to think about how many tenants your system expects to support. If you’re anticipating 10’s of thousands of tenants, the VPC-per-tenant model may not be a fit for you. You may run into account limits with this model. More importantly, having this many VPCs could undermine the agility and manageability of your environment. The more distributed these tenants, the more challenging it is to coordinate updates, aggregate operational data, and so on. Some may also consider a pods as a way to mitigate some of the challenges here, using separate accounts to host pods of VPCs for each tenant. 6 | * The control plane of your SaaS environment will need access to all tenant VPCs. How you secure this access will depend on the needs of your application and the types of interactions you’ll need to support. Some might use secure networking mechanisms (PrivateLink, for example) or messaging constructs (EventBridge). The key here is to pick a technology that best aligns to the security and integration model of your solution. 7 | 8 | -------------------------------------------------------------------------------- /_pattern-template/authors.json: -------------------------------------------------------------------------------- 1 | { 2 | "authors": [ 3 | { 4 | "name": "Your name", 5 | "image": "link-to-your-photo.jpg (full url or partial path to this patterns images folder ex. ./images/photo.jpg)", 6 | "bio": "Your bio.", 7 | "linkedin": "linked-in-ID", 8 | "twitter": "twitter-handle" 9 | } 10 | ] 11 | } -------------------------------------------------------------------------------- /_pattern-template/images/author-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/_pattern-template/images/author-placeholder.png -------------------------------------------------------------------------------- /_pattern-template/images/demo-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saasbuilder-patterns/54bc81bd320c29948b4a198983fec12a93135a23/_pattern-template/images/demo-architecture.png -------------------------------------------------------------------------------- /_pattern-template/pattern.md: -------------------------------------------------------------------------------- 1 |

2 | Architecture 3 |

4 | 5 | ### Core Concept 6 | * Describe the concept at a high level 7 | 8 | ### Key Considerations 9 | * List various considerations for this pattern 10 | * Limitations 11 | * Advantages 12 | * Typical use cases 13 | 14 | ### Code Example 15 | ```yaml 16 | AWSTemplateFormatVersion: '2010-09-09' 17 | Transform: AWS::Serverless-2016-10-31 18 | Description: > 19 | sam-app 20 | Sample SAM Template for sam-app 21 | 22 | Globals: 23 | Function: 24 | Timeout: 20 25 | MemorySize: 512 26 | Environment: 27 | Variables: 28 | TABLE_NAME: !Ref DemoTable 29 | ENDPOINT_OVERRIDE: "" 30 | 31 | Resources: 32 | GetDemoFunction: 33 | Type: AWS::Serverless::Function 34 | Properties: 35 | CodeUri: target/aws-sam-java-rest-1.0.0.jar 36 | Handler: com.amazonaws.handler.DemoHandler::handleRequest 37 | Runtime: java8 38 | Policies: 39 | - DynamoDBReadPolicy: 40 | TableName: !Ref DemoTable 41 | Events: 42 | GetDemo: 43 | Type: Api 44 | Properties: 45 | Path: /demo/{demo_id} 46 | Method: get 47 | ``` 48 | 49 | **Code sample** 50 | ```javascript 51 | function demo(input) { 52 | console.log(input); 53 | } 54 | ``` 55 | 56 | ### References 57 | Example Reference 1 58 | 59 | Example Reference 2 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /patterns.json: -------------------------------------------------------------------------------- 1 | { 2 | "patterns": [ 3 | { 4 | "id": "48774131-176e-489d-b1bf-23a940ab2c16", 5 | "name": "Deployment Models", 6 | "path": "DeploymentModels", 7 | "children": [ 8 | { 9 | "id": "155ac272-8e89-11ec-b909-0242ac120002", 10 | "name": "Full Stack Silo Deployment", 11 | "path": "FullStackSilo", 12 | "children": [ 13 | { 14 | "id": "097463b2-8e8b-11ec-b909-0242ac120002", 15 | "name": "Account per tenant", 16 | "path": "AccountPerTenant" 17 | }, 18 | { 19 | "id": "0fb71756-8e8b-11ec-b909-0242ac120002", 20 | "name": "VPC per tenant", 21 | "path": "VPCPerTenant" 22 | } 23 | ] 24 | }, 25 | { 26 | "id": "1b2cc466-8e89-11ec-b909-0242ac120002", 27 | "name": "Full Stack Pool Deployment", 28 | "path": "FullStackPool" 29 | }, 30 | { 31 | "id": "59C45492-714F-4481-9F79-DEBC6409A5D9", 32 | "name": "Siloed Compute", 33 | "path": "SiloedCompute" 34 | } 35 | ] 36 | }, 37 | { 38 | "id": "452ecd96-eb17-11ec-8fea-0242ac120002", 39 | "name": "Identity", 40 | "path": "Identity", 41 | "children": [ 42 | { 43 | "id": "02e6e91c-fc42-4940-854e-e1ffa1b14f2a", 44 | "name": "Self-Hosted Identity", 45 | "path": "SelfHostedIdentity" 46 | }, 47 | { 48 | "id": "02e6e91c-fc42-4940-854e-e1fga1b14f2a", 49 | "name": "Externally Hosted Identity", 50 | "path": "ExternallyHostedIdentity" 51 | }, 52 | { 53 | "id": "905242c2-c397-4f84-a0fe-c59269834c1b", 54 | "name": "Just In Time Identity Migration", 55 | "path": "JustInTimeIdentityMigration" 56 | } 57 | ] 58 | } 59 | ] 60 | } 61 | --------------------------------------------------------------------------------