Giter Club home page Giter Club logo

aws-saas-factory-bootcamp's Introduction

Building SaaS Solutions on AWS

SaaSAWS

This Bootcamp is also available in Portuguese (pt-br) language.

Introduction

SaaS presents developers with a unique blend of challenges: multi-tenancy, onboarding, security, data partitioning, tenant isolation, and identity.

One of the best ways to understand architectural principles of SaaS is to dig into working examples of designing, building, and optimizing SaaS. In this bootcamp workshop, we’ll expose you to the core concepts of SaaS architecture by diving into a reference SaaS architecture where you can see the moving parts of a SaaS solution in action.

This workshop provides a series of activities for attendees to interact with a functional solution, and hands-on exercises that introduce code and configuration to realize and extend the capabilities of this SaaS environment. The combination of lecture and exercises through the lens of a working reference solution give greater insight into SaaS on AWS best practices.

Who should participate?

Application developers and architects that are looking to get into the details of implementing a SaaS solution on AWS are encouraged to participate. The content of the bootcamp is geared toward those newer to SaaS. However, even if you have a background in SaaS, this experience could still expose you to specifics of delivering SaaS on AWS.

How do I start?

If you are participating in this bootcamp workshop during an AWS event, follow the instructions of the instructors on site.

If you would like to run through the lab exercises in a self-guided manner, all you need to do is launch the workshop.yml AWS CloudFormation template in your AWS account and then start by clicking the Lab 1 icon below.

Note that this workshop deploys infrastructure into your AWS account that is outside of the free tier, and you should delete the CloudFormation stack when you are finished to minimize costs. The Cognito resources and IAM roles and policies created by the onboarding system will need to be removed manually after the stack delete.

Lab Guides

Lab 1 - Identity and Onboarding

Lab1

Lab 2 - Multi-Tenant Microservices

Lab2

Lab 3 - Data Isolation

Lab3

License

This workshop is licensed under the Apache 2.0 License. See the LICENSE file.

aws-saas-factory-bootcamp's People

Contributors

bparvizi-aws avatar brtrvn avatar pdantasa avatar tiagoreichert avatar ujwalbukka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aws-saas-factory-bootcamp's Issues

Lab 3 Documentation Edits

Part 1 - Step 17 redundant
Part 1 - Step 22 Screenshot update as code lines are incorrect
Step 22 GUID not matching up to real tenant id

Unable to register new tenant

New tenant/user registration fails with saas-bootcamp-user-svc-task-role is not authorized to perform: cognito-idp:TagResource on resource: *

LAB 1: CORS ISSUE between cloudfront and API

Hello guys,

How did you go through the CORS issue on the tenant registration step ? I can't register I keep having CORS issue between my CloudFront and my API .../reg....

How come I'm the only one with this issue?

CF workshop template fails

When running the workshop.yml CF template the Baseline nested stack fails standing up the workshop. The error I receive is below:

Embedded stack arn:aws:cloudformation:us-east-1:479698460486:stack/B2-Baseline-M3JRIU7AZ012/5affd0f0-34bd-11eb-b506-0a68381145d1 was not successfully created: The following resource(s) failed to create: [WebClient, AuthService, UserService, OrderService, ProductService, TenantService, RegistrationService].

After this is hit it rolls back the deployment and the logs are removed.

Cannot provision bootcamp in stand-alone AWS account

To fix the Cloud9 issues with the event engine, we hard coded an IAM role in saas-bootcamp-cloud9.template. This prevents the stacks from properly deploying in a normal AWS account. We need a Lambda function that will check for the existence of that role and set a CloudFormation condition respectively.

Is there a guide to go with this repository?

Hi, I know this repository just got created, but I was wondering if there is a planned session that will be covering items in this repository or if there is something that's already available? Looks very interesting & thanks for publishing this!

EDIT: Sorry, just read about SaaS Factory program at AWS.

Move PDFs to Markdown or other format

It's complicated to reference specific parts of the PDF, and impossible to create pull requests. Suggest moving them to some format that would allow easier contributions.

Optimization Lab 3

lab3part2 step 4-6 is a lot of tiny steps.. might be worth adding some screenshots. I had to do it twice because I missed something

Finding the userpool for a user in usermanagement service

We intend to have the same user in multiple tenant accounts. This means the same username/email will be mapped to multiple Cognito pool ids in user management service. How can we decide which pool to authenticate the user against when we do not want to have the users select the tenant.

Cloud9 custom provisioning scripts hardcode AWS region

The various build.sh and [servicename].sh scripts designed to be run from within the Cloud9 environment have the AWS region hard coded to us-east-1. This breaks if the baseline CloudFormation template was deployed in any other region.

Some scripts strongly depends on the aws account environment.

For brand-new account is ok.
But if the account has even one cloudformation stack, some scripts don't work.

The architecture consists of a lot of nested stack and detect root stack name as BASELINE_STACK by referencing to the oldest stack based on CreationTime.

export BASELINE_STACK=$(aws cloudformation describe-stacks | jq -r '[.Stacks[] | select(.ParentId == null) | {CreationTime, StackName}] | sort_by(.CreationTime) | .[0].StackName')

I suggest using other logic not depending on specific account environment.

Query: Tenant selection

Hi,

Note: This is not an issue. Just want to confirm one additional aspect. Please do let me know if I need to raise such requests in any other forum.

I have started using this bootcamp implementation, by making few changes to authentication as per our needs.

Changes:
Instead of /auth endpoint validating UN/PWD and return tokens; my endpoint just validates UN, identifies which Tenant user belongs to, and returns Pool details (Userpool Id, AppClientId. IdPool Id). Client receives these details and uses Amplify to configure the Auth, and starts UN/PWD flow.

Reason for this change is, we can have either of (not both at the same time) the following situations:

  1. User email exists in two Tenants, so this implementation would help me to display a UI to choose which Tenant user wants to login to, and accordingly initiate authentication based on the Tenant selected.
  2. If Federation Authentication is configured to a Tenant, then this implementation would help me to not to enforce PWD, and redirect to respective IdP from client.

Query:

  1. Auth endpoint is unauthenticated and revealing the details (Userpool Id, AppClientId. IdPool Id). Is it OK to reveal such details?
  2. Is there any other way that I can achieve similar requirements (1 & 2 above)?

Thanks in advance for any help.
Sai Koya

Resource import not supported

While loading workshop.yml into Cloudformation, there is the next error:

The following resource types are not supported for resource import: AWS::SSM::Parameter,Custom::CustomResource,Custom::CustomResource,Custom::CustomResource,Custom::CustomResource,Custom::CustomResource

Running with all privileged account.

Thanks

Event engine bugs

  1. Timeout to short for federation - Should be duration of bootcamp
  2. Having to signout when in another account, when isengard works
  3. Caching issues and not loading when changes made

typo

Part 2 / Step 5: product id -> productId

Lab 1 - Step 6 no export names PUBLICSUBNET1 found

I'm looking for advice on how to get past the below in Lab 1 Part 2 - Deploy the user Management Microservice.

17:21:55 UTC-0500 | CREATE_FAILED | AWS::CloudFormation::Stack | DevEnvironment | Embedded stack arn:aws:cloudformation:us-east-2:915842112807:stack/UserManagerService-DevEnvironment-1T0U35TGL2RVK/1a359160-99c7-11e8-9afa-060ae44bf6ec was not successfully created: No export named module-saas-bootcamp-base-PUBLICSUBNET1 found
-- | -- | -- | -- | --

I did start Part 2 a day after finishing Part 1 if that help anything. The Cloud Formation Manager still have green status of the services running.

Thanks

Code for Lab 1?

I am looking for the codebase for lab1 that will onboard and authenticate tenants and their users. This involves provisioning userpool/identity pool/ custom claims. All of that is pretty important information that is missing here. Where can I find it?

typo

Part 2 / Step 1:

Lab2/Part2 /app/source/product-manager/ -> Lab2/Part2 /app/source/product-manager/src/

Web UI client fails to deploy

Lab1/Part6/templates/client/web-client-build.template

Code build fails while installing Ruby gem compass due to upgraded Ruby runtime requirements not being available in the default CodeBuild Linux apt-get repo.

Building native extensions. This could take a while... ERROR: Error installing compass: rb-inotify requires Ruby version >= 2.2.

Auth manager failed update

START RequestId: ae5af682-8ebd-11e8-9b24-a3456f67235f Version: $LATEST
2018-07-23T21:16:40.073Z ae5af682-8ebd-11e8-9b24-a3456f67235f REQUEST RECEIVED:
{
"RequestType": "Create",
"ServiceToken": "arn:aws:lambda:us-east-1:058192547359:function:ApplicationUI-Update-10Z0AEVMJ253-CFNConfiguration-44FKZT5QXZ37",
"ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A058192547359%3Astack/ApplicationUI-Update-10Z0AEVMJ253O-AuthUpdate-1W2LS9CX7B6GA-UpdateService-L9UX6OMVOGDQ/a1e6c9e0-8ebd-11e8-b61a-500c20ff1436%7CCFNInvoke%7C14fa9832-c5ee-4d3a-ac21-e3d233f13cdf?AWSAccessKeyId=AKIAIYSQHCFBJXX7KRIA&Expires=1532387795&Signature=onPFWHD6004VrFbcerc17j4ZL%2FE%3D",
"StackId": "arn:aws:cloudformation:us-east-1:058192547359:stack/ApplicationUI-Update-10Z0AEVMJ253O-AuthUpdate-1W2LS9CX7B6GA-UpdateService-L9UX6OMVOGDQ/a1e6c9e0-8ebd-11e8-b61a-500c20ff1436",
"RequestId": "14fa9832-c5ee-4d3a-ac21-e3d233f13cdf",
"LogicalResourceId": "CFNInvoke",
"ResourceType": "Custom::ConfigFile",
"ResourceProperties": {
"ServiceToken": "arn:aws:lambda:us-east-1:058192547359:function:ApplicationUI-Update-10Z0AEVMJ253-CFNConfiguration-44FKZT5QXZ37",
"TaskDefinition": "arn:aws:ecs:us-east-1:058192547359:task-definition/auth-manager:3",
"Service": "auth-manager",
"Cluster": "module-saas-bootcamp-base-Base-1R9PVNF22IB45-BaselineStack-9T1B4TG4IXCU",
"StackName": "ApplicationUI-Update-10Z0AEVMJ253O-AuthUpdate-1W2LS9CX7B6GA-UpdateService-L9UX6OMVOGDQ"
}
}

2018-07-23T21:16:40.111Z ae5af682-8ebd-11e8-9b24-a3456f67235f STACK CREATE
2018-07-23T21:16:45.633Z ae5af682-8ebd-11e8-9b24-a3456f67235f { ServiceNotFoundException: null
at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/json.js:48:27)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)
at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)
at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)
at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10
at Request. (/var/task/node_modules/aws-sdk/lib/request.js:38:9)
at Request. (/var/task/node_modules/aws-sdk/lib/request.js:685:12)
at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)
message: null,
code: 'ServiceNotFoundException',
time: 2018-07-23T21:16:45.631Z,
requestId: 'b3fdfccc-8ebd-11e8-80d2-3f1362e8405d',
statusCode: 400,
retryable: false,
retryDelay: 68.71166916807712 } 'ServiceNotFoundException: null\n at Request.extractError (/var/task/node_modules/aws-sdk/lib/protocol/json.js:48:27)\n at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:105:20)\n at Request.emit (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:77:10)\n at Request.emit (/var/task/node_modules/aws-sdk/lib/request.js:683:14)\n at Request.transition (/var/task/node_modules/aws-sdk/lib/request.js:22:10)\n at AcceptorStateMachine.runTo (/var/task/node_modules/aws-sdk/lib/state_machine.js:14:12)\n at /var/task/node_modules/aws-sdk/lib/state_machine.js:26:10\n at Request. (/var/task/node_modules/aws-sdk/lib/request.js:38:9)\n at Request. (/var/task/node_modules/aws-sdk/lib/request.js:685:12)\n at Request.callListeners (/var/task/node_modules/aws-sdk/lib/sequential_executor.js:115:18)'
2018-07-23T21:16:45.730Z ae5af682-8ebd-11e8-9b24-a3456f67235f Response body:
{
"Status": "FAILED",
"Reason": "See the details in CloudWatch Log Stream: 2018/07/23/[$LATEST]1fb9ff364c874bff8225b2196bbf26be",
"PhysicalResourceId": "2018/07/23/[$LATEST]1fb9ff364c874bff8225b2196bbf26be",
"StackId": "arn:aws:cloudformation:us-east-1:058192547359:stack/ApplicationUI-Update-10Z0AEVMJ253O-AuthUpdate-1W2LS9CX7B6GA-UpdateService-L9UX6OMVOGDQ/a1e6c9e0-8ebd-11e8-b61a-500c20ff1436",
"RequestId": "14fa9832-c5ee-4d3a-ac21-e3d233f13cdf",
"LogicalResourceId": "CFNInvoke"
}

2018-07-23T21:16:45.946Z ae5af682-8ebd-11e8-9b24-a3456f67235f Status code: 200
2018-07-23T21:16:45.946Z ae5af682-8ebd-11e8-9b24-a3456f67235f Status message: OK
END RequestId: ae5af682-8ebd-11e8-9b24-a3456f67235f
REPORT RequestId: ae5af682-8ebd-11e8-9b24-a3456f67235f Duration: 5921.41 ms Billed Duration: 6000 ms Memory Size: 128 MB Max Memory Used: 33 MB
START RequestId: dacc37ef-8ebd-11e8-8858-15744465283b Version: $LATEST

question: regarding creating policies

Hi,
Page 24 of PDF files "SaaS Identity and Isolation with Amazon Cognito" says "6. Tenant registration provisions policies for each tenant role." Also Figure13 in the same page shows like that.

But I couldn't find the code related code in app/source/tenant-registration/src/server.js
does the code locate in the User Management Service, not Tenant Registration Service?
I would like to know where it is in.

Lab 1 Step 6 image placement

The image for the "Do You want to add custom attributes?" is at the top of the page. However, there is a sentence that states "Your screen should appear as follows:" with nothing below it. It appears the image at the top of the page should be below that last sentence.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.