使用 C# 和 為孤島模型在 SaaS 架構中的租用戶加入 AWS CDK - AWS 方案指引

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用 C# 和 為孤島模型在 SaaS 架構中的租用戶加入 AWS CDK

由 Tabby Ward (AWS)、Susmitha Reddy Gankidi (AWS) 和 Vijai Anand Ramalingam (AWS) 建立

程式碼儲存庫:Tennat Onboarding Silo

環境:PoC 或試行

技術:現代化; DevOps

工作負載:開放原始碼

AWS 服務:AWS CloudFormation;Amazon DynamoDB ;Amazon DynamoDB Streams;AWSLambda;Amazon API Gateway

Summary

軟體即服務 SaaS ) 應用程式可以使用各種不同的架構模型建置。孤島模型是指提供租戶專用資源的架構。

SaaS 應用程式仰賴無摩擦模型,將新租戶引入其環境。這通常需要許多元件的協調,才能成功佈建和設定建立新租用戶所需的所有元素。在 SaaS 架構中,此程序稱為租戶加入。應針對每個 SaaS 環境,使用基礎設施作為加入程序中的程式碼,以完全自動化加入。

此模式會引導您完成在 Amazon Web Services () 上建立租用戶和佈建租用戶基本基礎設施的範例AWS。此模式使用 C# 和AWS雲端開發套件 (AWS CDK)。

由於此模式會建立帳單警示,因此建議您在美國東部 (維吉尼亞北部) 或 us-east-1 AWS區域部署堆疊。如需詳細資訊,請參閱 AWS 文件

先決條件和限制

先決條件

限制

  • AWS CDK 使用 AWS CloudFormation,因此AWSCDK應用程式受 CloudFormation 服務配額限制。如需詳細資訊,請參閱AWS CloudFormation 配額 。 

  • 租用戶 CloudFormation 堆疊是使用 CloudFormation 服務角色建立的,infra-cloudformation-role該服務角色在動作 (sns* 和 sqs*) 上有萬用字元,但資源鎖定在tenant-cluster字首。對於生產使用案例,請評估此設定,並僅提供此服務角色的必要存取權。InfrastructureProvision Lambda 函數也會使用萬用字元 (cloudformation*) 來佈建 CloudFormation 堆疊,但資源會鎖定至tenant-cluster字首。

  • 此範例程式碼的Docker 建置使用 --platform=linux/amd64 來強制以映像linux/amd64為基礎。這是為了確保最終影像成品適用於 Lambda,依預設, Lambda 會使用 x86-64 架構。如果您需要變更目標 Lambda 架構,請務必同時變更 Dockerfiles 和AWSCDK程式碼。如需詳細資訊,請參閱部落格文章將 AWS Lambda 函數遷移至 Arm 型 AWS Graviton2 處理器

  • 堆疊刪除程序不會清除堆疊產生的 CloudWatch 日誌 (日誌群組和日誌)。您必須透過 AWS Management Console Amazon CloudWatch 主控台手動清除日誌,或透過 手動清除日誌API。

此模式設定為範例。針對生產用途,請評估下列設定,並根據業務需求進行變更:

  • 此範例中的 AWS Simple Storage Service (Amazon S3) 儲存貯體未啟用版本控制以簡化操作。視需要評估和更新設定。

  • 此範例設定 Amazon API Gateway RESTAPI端點,無需身分驗證、授權或限流,以簡化操作。對於生產用途,我們建議您將系統與業務安全基礎設施整合。評估此設定,並視需要新增必要的安全設定。

  • 在此租戶基礎設施範例中,Amazon Simple Notification Service (Amazon SNS)Amazon Simple Queue Service (Amazon SQS) 僅具有最低設定。每個租戶的 AWS Key Management Service (AWS KMS) 會開啟帳戶中的 Amazon CloudWatch 和 Amazon SNS服務,以便根據AWSKMS金鑰政策 使用。設定只是範例預留位置。根據您的業務使用案例,視需要調整設定。

  • 整個設定,包括但不限於API端點和後端租用戶使用 佈建和刪除AWS CloudFormation,僅涵蓋基本的快樂路徑案例。根據您的業務需求,使用必要的重試邏輯、其他錯誤處理邏輯和安全邏輯來評估和更新設定。

  • 範例程式碼會與 up-to-date cdk-nag 一起測試,以在撰寫本文時檢查政策。未來可能會強制執行新政策。這些新政策可能需要您根據建議手動修改堆疊,才能部署堆疊。檢閱現有的程式碼,以確保其與您的業務需求相符。

  • 程式碼依賴 AWSCDK產生隨機字尾,而不是依賴大多數建立資源的靜態指派實體名稱。此設定旨在確保這些資源是唯一的,並且不會與其他堆疊衝突。如需詳細資訊,請參閱 AWS CDK 文件 。根據您的業務需求進行調整。

  • 此範例程式碼套件 。NET Lambda 成品會進入 Docker 型映像,並使用 Lambda 提供的容器映像執行期 執行。容器映像執行期對於標準傳輸和儲存機制 (容器登錄檔) 和更準確的本機測試環境 (透過容器映像) 具有優勢。您可以切換專案以使用 Lambda 提供的 。NET 執行時間,以減少 Docker 映像的建置時間,但接著您需要設定傳輸和儲存機制,並確保本機設定符合 Lambda 設定。調整程式碼以符合使用者的業務需求。

產品版本

  • AWS CDK 2.45.0 版或更新版本

  • Visual Studio 2022

架構

技術堆疊

  • Amazon API Gateway

  • AWS CloudFormation

  • Amazon CloudWatch

  • Amazon DynamoDB

  • AWS Identity and Access Management (IAM)

  • AWS KMS

  • AWS Lambda

  • Amazon S3

  • Amazon SNS

  • Amazon SQS

架構

下圖顯示租戶堆疊建立流程。如需控制平面和租戶技術堆疊的詳細資訊,請參閱其他資訊一節。

在 上建立租用戶並佈建租用戶基本基礎設施的工作流程AWS。

租戶堆疊建立流程

  1. 使用者將具有新租戶承載 (租戶名稱、租戶描述) 的POSTAPI請求JSON傳送至 Amazon API Gateway REST API 託管的 。API Gateway 會處理請求,並將其轉送至後端 Lambda 租用戶加入函數。在此範例中,沒有授權或身分驗證。在生產設定中,這API應與 SaaS 基礎設施安全系統整合。

  2. 租戶加入函數會驗證請求。然後,它會嘗試將租用戶記錄存放到 Amazon DynamoDB 租用戶加入資料表中,其中包含租用戶名稱、產生的租用戶全域唯一識別碼 (UUID) 和租用戶描述。 

  3. DynamoDB 儲存記錄後,DynamoDB 串流會啟動下游 Lambda 租用戶基礎設施函數。

  4. 租用戶基礎設施 Lambda 函數會根據收到的 DynamoDB 串流來運作。如果串流是針對INSERT事件,則函數會使用串流的 NewImage 區段 (最新更新記錄,租戶名稱欄位) 來叫用 CloudFormation ,以使用存放在 S3 儲存貯體中的範本來建立新的租戶基礎設施。 CloudFormation 範本需要租用戶名稱參數。 

  5. AWS CloudFormation 根據 CloudFormation 範本和輸入參數建立租戶基礎設施。

  6. 每個租戶基礎設施設定都有 CloudWatch 警示、帳單警示和警示事件。

  7. 警示事件會變成SNS主題的訊息,由租戶的AWSKMS金鑰加密。

  8. SNS 主題會將收到的警示訊息轉送至SQS佇列,該佇列由租戶AWSKMS的 加密以進行加密金鑰。

其他系統可與 Amazon 整合SQS,以根據佇列中的訊息執行動作。在此範例中,若要保持程式碼通用,傳入的訊息會保留在佇列中,且需要手動刪除。

租戶堆疊刪除流程

  1. 使用者將具有新租戶承載 (租戶名稱、租戶描述) DELETEAPI的請求傳送至 Amazon API Gateway RESTAPI託管JSON的 ,其將處理請求並轉送至租戶加入函數。在此範例中,沒有授權或身分驗證。在生產設定中,API這會與 SaaS 基礎設施安全系統整合。

  2. 租戶加入函數會驗證請求,然後嘗試從租戶加入資料表中刪除租戶記錄 (租戶名稱)。 

  3. DynamoDB 成功刪除記錄 (記錄存在於資料表中並刪除) 後,DynamoDB 串流會啟動下游 Lambda 租用戶基礎設施函數。

  4. 租用戶基礎設施 Lambda 函數會根據收到的 DynamoDB 串流記錄來運作。如果串流是針對REMOVE事件,則函數會使用記錄的 OldImage 區段 (記錄資訊和租用戶名稱欄位,在最新變更之前,也就是刪除),根據該記錄資訊來啟動現有堆疊的刪除。

  5. AWS CloudFormation 根據輸入刪除目標租戶堆疊。

工具

AWS 服務

其他工具

  • Visual Studio 是 IDE,其中包含編譯器、程式碼完成工具、圖形設計器和其他支援軟體開發的功能。

Code

此模式的程式碼位於 SaaS Architecture for Silo 模型APG範例儲存庫中的租戶加入中。

史詩

任務描述所需的技能

驗證 Node.js 安裝。

若要確認 Node.js 已安裝在您的本機機器上,請執行下列命令。

node --version
AWS 管理員、 AWS DevOps

安裝 AWS CDK Toolkit。

若要在本機電腦上安裝 AWS CDK Toolkit,請執行下列命令。

npm install -g aws-cdk

如果未安裝 npm,您可以從 Node.js 網站 進行安裝。

AWS 管理員、 AWS DevOps

驗證 AWS CDK Toolkit 版本。

若要驗證AWSCDK工具組版本是否正確安裝在您的機器上,請執行下列命令。 

cdk --version
AWS 管理員、 AWS DevOps
任務描述所需的技能

複製儲存庫。

複製儲存庫 ,然後導覽至 \tenant-onboarding-in-saas-architecture-for-silo-model-apg-example 資料夾。

在 Visual Studio 2022 中,開啟\src\TenantOnboardingInfra.sln解決方案。開啟 TenantOnboardingInfraStack.cs 檔案並檢閱程式碼。

下列資源會建立作為此堆疊的一部分:

  • DynamoDB 表

  • S3 儲存貯體 (將 CloudFormation 範本上傳至 S3 儲存貯體。)

  • Lambda 執行角色

  • Lambda 函數

  • API 閘道 API

  • Lambda 函數的事件來源

AWS 管理員、 AWS DevOps

檢閱 CloudFormation 範本。

\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\template 資料夾中,開啟 infra.yaml並檢閱 CloudFormation 範本。此範本將與從租戶加入 DynamoDB 資料表擷取的租戶名稱進行補充。

範本會佈建租戶特定的基礎設施。在此範例中,它會佈建AWSKMS金鑰、Amazon SNS 、Amazon SQS和 CloudWatch 警示。

應用程式開發人員、 AWS DevOps

檢閱租戶加入函數。

開啟 Function.cs,然後檢閱使用 Visual Studio AWS Lambda 專案 () 建立的租戶加入函數程式碼。NET Core- C#) 範本搭配 。NET 6 (容器映像) 藍圖。

開啟 Dockerfile,然後檢閱程式碼。Dockerfile 是文字檔案,其中包含建置 Lambda 容器映像的指示。

請注意,下列 NuGet 套件會新增為TenantOnboardingFunction專案的相依性:

  • Amazon.Lambda.APIGatewayEvents

  • AWSSDK.DynamoDBv2

  • Newtonsoft.Json

應用程式開發人員、 AWS DevOps

檢閱租用戶 InfraProvisioning 函數。

導覽至 \tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\src\InfraProvisioningFunction

開啟 Function.cs,然後檢閱使用 Visual Studio AWS Lambda 專案 () 建立的租戶基礎設施佈建函數程式碼。NET Core- C#) 範本搭配 。NET 6 (容器映像) 藍圖。

開啟 Dockerfile,然後檢閱程式碼。

請注意,下列 NuGet 套件會新增為InfraProvisioningFunction專案的相依性:

  • Amazon.Lambda.DynamoDBEvents

  • AWSSDK.DynamoDBv2

  • AWSSDK.Cloudformation

應用程式開發人員、 AWS DevOps
任務描述所需的技能

建置解決方案。

若要建置解決方案,請執行下列步驟:

  1. 在 Visual Studio 2022 中,開啟 \tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\src\TenantOnboardingInfra.sln 解決方案。 

  2. 開啟解決方案的內容 (按滑鼠右鍵) 選單,然後選擇建置解決方案

注意:建置解決方案之前,請務必將Amazon.CDK.Lib NuGet套件更新至\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\src\TenantOnboardingInfra專案的最新版本。

應用程式開發人員

啟動AWSCDK環境。

開啟 Windows 命令提示,然後導覽至可使用 cdk.json 檔案AWSCDK的應用程式根資料夾 (\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example)。執行下列命令進行引導。

cdk bootstrap

如果您已為憑證建立AWS設定檔,請將 命令與設定檔搭配使用。

cdk bootstrap --profile <profile name>
AWS 管理員、 AWS DevOps

列出AWSCDK堆疊。

若要列出要建立作為此專案一部分的所有堆疊,請執行下列命令。

cdk ls cdk ls --profile <profile name>

如果您已為憑證建立AWS設定檔,請將 命令與設定檔搭配使用。

cdk ls --profile <profile name>
AWS 管理員、 AWS DevOps

檢閱要建立AWS的資源。

若要檢閱將建立為此專案一部分的所有AWS資源,請執行下列命令。

cdk diff

如果您已為憑證建立AWS設定檔,請將 命令與設定檔搭配使用。

cdk diff --profile <profile name>
AWS 管理員、 AWS DevOps

使用 部署所有AWS資源AWSCDK。

若要部署所有AWS資源,請執行下列命令。

cdk deploy --all --require-approval never

如果您已為憑證建立AWS設定檔,請將 命令與設定檔搭配使用。

cdk deploy --all --require-approval never --profile <profile name>

部署完成後,APIURL請從命令提示中的輸出區段複製 ,如下列範例所示。

Outputs: TenantOnboardingInfraStack.TenantOnboardingAPIEndpoint42E526D7 = https://j2qmp8ds21i1i.execute-api.us-west-2.amazonaws.com/prod/
AWS 管理員、 AWS DevOps
任務描述所需的技能

建立新的租戶。

若要建立新的租用戶,請傳送下列 curl 請求。

curl -X POST <TenantOnboardingAPIEndpoint* from CDK Output>tenant -d '{"Name":"Tenant123", "Description":"Stack for Tenant123"}'

將預留位置<TenantOnboardingAPIEndpoint* from CDK Output>變更為 AWS 的實際值CDK,如下列範例所示。

curl -X POST https://j2qmp8ds21i1i.execute-api.us-west-2.amazonaws.com/prod/tenant -d '{"Name":"Tenant123", "Description":"test12"}'

下列範例顯示輸出。

{"message": "A new tenant added - 5/4/2022 7:11:30 AM"}
應用程式開發人員、AWS管理員 AWS DevOps

驗證 DynamoDB 中新建立的租戶詳細資訊。

若要驗證 DynamoDB 中新建立的租戶詳細資訊,請執行下列步驟。

  1. 開啟AWS管理主控台,然後導覽至 Amazon DynamoDB 服務。

  2. 在左側導覽中,選擇探索項目 ,然後選擇TenantOnboarding資料表。

    注意:租戶名稱將以 開頭tenantcluster-。如需詳細資訊,請參閱其他資訊一節。

  3. 確認已使用租戶詳細資訊建立新項目。

應用程式開發人員、AWS管理員、 AWS DevOps

驗證新租用戶的堆疊建立。

根據 CloudFormation 範本,確認新堆疊已成功建立並佈建為新建立租用戶的基礎設施。

  1. 開啟 CloudFormation 主控台。

  2. 在左側導覽中,選擇堆疊 ,並確認已成功建立具有租用戶名稱的堆疊。

  3. 選擇新建立的租戶堆疊,然後選擇資源索引標籤。請注意警示資源和 Amazon SQS 資源。

  4. 開啟已設定AWS憑證的新終端機,並指向正確的區域。若要發出測試警示,請輸入下列程式碼,<alarm resource name>以步驟 3 中記下的警示資源名稱取代 。

    aws cloudwatch set-alarm-state --alarm-name <alarm resource name> --state-value ALARM --state-reason 'Test setup'

    下列範例顯示具有警示資源名稱的程式碼。

    aws cloudwatch set-alarm-state --alarm-name tenantcluster-tenant123-alarm --state-value ALARM --state-reason 'Test setup'
  5. 開啟主控台並導覽至 Amazon SQS主控台。選擇步驟 3 中識別的 Amazon SQS 資源名稱。請遵循AWS文件指示,從步驟 4 中發出的警示接收和刪除測試訊息。

應用程式開發人員、AWS管理員、 AWS DevOps

刪除租戶堆疊。

若要刪除租戶堆疊,請傳送下列 curl 請求。

curl -X DELETE <TenantOnboardingAPIEndpoint* from CDK Output>tenant/<Tenant Name from previous step>

將預留位置<TenantOnboardingAPIEndpoint* from CDK Output>變更為 的實際值AWSCDK,並將 <Tenant Name from previous step>變更為上一個租用戶建立步驟的實際值,如下列範例所示。

curl -X DELETE https://j2qmp8ds21i1i.execute-api.us-west-2.amazonaws.com/prod/tenant/Tenant123

下列範例顯示輸出。

{"message": "Tenant destroyed - 5/4/2022 7:14:48 AM"}
應用程式開發人員、AWS DevOps、AWS管理員

驗證現有租用戶的堆疊刪除。

若要驗證現有租戶堆疊是否已刪除,請執行下列步驟:

  1. 開啟主控台並導覽至 CloudFormation 主控台。

  2. 在左側導覽中,確認具有租用戶名稱的現有堆疊已不在主控台中 (如果 CloudFormation 主控台設定為僅顯示作用中堆疊),或正在刪除中。如果堆疊不再位於 CloudFormation 主控台中,請使用下拉式清單,將主控台的設定從作用中變更為已刪除,以查看已刪除的堆疊,並確認堆疊已成功刪除。

應用程式開發人員、AWS管理員、 AWS DevOps
任務描述所需的技能

銷毀環境。

在清除堆疊之前,請確定下列事項:

  • DynamoDB 中的所有記錄都會透過先前的租用戶刪除操作,或透過 DynamoDB 主控台或 移除API。每個刪除租戶記錄都會啟動AWS CloudFormation 其對等檔案的清除。 

  • 所有以租用戶為基礎的AWS CloudFormation 堆疊都會在AWS CloudFormation 主控台上清除 (以防 DynamoDB 觸發清除邏輯失敗)。

測試完成後, AWS CDK 可以執行下列命令來銷毀所有堆疊和相關資源。

cdk destroy --all;

如果您為憑證建立AWS設定檔,請使用該設定檔。

確認堆疊刪除提示以刪除堆疊。

AWS 管理員、 AWS DevOps

清除 Amazon CloudWatch Logs。

堆疊刪除程序不會清除堆疊產生的 CloudWatch 日誌 (日誌群組和日誌)。使用 CloudWatch 主控台或 手動清除 CloudWatch 資源API。

應用程式開發人員、AWS DevOps、AWS管理員

相關資源

其他資訊

控制平面技術堆疊

中寫入的CDKNET程式碼用於佈建控制平面基礎設施,其中包含下列資源:

  1. API 閘道

    作為控制平面堆疊的RESTAPI進入點。

  2. 租戶入職 Lambda 函數

    此 Lambda 函數是由 API Gateway 使用 m 方法啟動。

    POST 方法API請求會導致 (tenant nametenant description) 插入 DynamoDB Tenant Onboarding資料表。

    在此程式碼範例中,租戶名稱也會用作租戶堆疊名稱的一部分,以及該堆疊內資源的名稱。這是為了讓這些資源更容易識別。此租用戶名稱在整個設定中必須是唯一的,以避免衝突或錯誤。詳細的輸入驗證設定會在IAM角色文件和限制區段中說明。

    只有在 資料表中任何其他記錄未使用租戶名稱時,DynamoDB 資料表的持久性程序才會成功。

    在這種情況下,租戶名稱是此資料表的分割區金鑰,因為只有分割區金鑰可以用作PutItem條件表達式。

    如果先前從未記錄過租戶名稱,記錄將成功儲存至資料表。

    不過,如果 資料表中的現有記錄已使用租用戶名稱,操作將會失敗並啟動 DynamoDB ConditionalCheckFailedException例外狀況。例外狀況將用於傳回失敗訊息 (HTTP BadRequest),指出租戶名稱已存在。

    DELETE 方法API請求會從 Tenant Onboarding 資料表中移除特定租用戶名稱的記錄。

    此範例中的 DynamoDB 記錄刪除會成功,即使記錄不存在。

    如果目標記錄存在且已刪除,則會建立 DynamoDB 串流記錄。否則,不會建立下游記錄。

  3. 啟用 Amazon DynamoDB Streams 的租戶加入 DynamoDB

    這會記錄租戶中繼資料資訊,而任何記錄儲存或刪除都會將串流傳送至 Tenant Infrastructure Lambda 函數下游。 

  4. 租戶基礎設施 Lambda 函數

    此 Lambda 函數是由上一個步驟的 DynamoDB 串流記錄啟動。如果記錄是針對INSERT事件,則會叫用存放在 S3 儲存貯體中的 CloudFormation 範本來AWS CloudFormation 建立新的租用戶基礎設施。如果記錄是針對 REMOVE,則會根據串流記錄Tenant Name的欄位啟動現有堆疊的刪除。

  5. S3 bucket (S3 儲存貯體)

    這是用於儲存 CloudFormation 範本。

  6. IAM 每個 Lambda 函數的角色,以及 的服務角色 CloudFormation

    每個 Lambda 函數都有其唯一IAM角色,具有實現其任務的最低權限許可。例如,Tenant On-boardingLambda 函數具有 DynamoDB 的讀取/寫入存取權,Lambda Tenant Infrastructure 函數只能讀取 DynamoDB 串流。

    為租戶堆疊佈建建立自訂 CloudFormation 服務角色。此服務角色包含 CloudFormation 堆疊佈建的其他許可 (例如 AWSKMS金鑰)。這會將角色在 Lambda 和 之間分開 CloudFormation ,以避免單一角色 (基礎設施 Lambda 角色) 的所有許可。

    允許強大動作 (例如建立和刪除 CloudFormation 堆疊) 的許可會鎖定,且僅允許在以 開頭的資源上進行tenantcluster-。例外狀況為 AWS KMS,因為其資源命名慣例。從 擷取的租用戶名稱API將與其他驗證檢查tenantcluster-一起前置 (僅包含破折號的英數字元,且限制為少於 30 個字元,以適應大多數AWS資源命名)。這可確保租戶名稱不會意外導致核心基礎設施堆疊或資源中斷。

租戶技術堆疊

CloudFormation 範本存放在 S3 儲存貯體中。範本會佈建租戶特定的AWSKMS金鑰、 CloudWatch 警示、SNS主題、SQS佇列和SQS政策

Amazon SNS和 Amazon 會將 AWSKMS金鑰用於SQS訊息的資料加密。AwsSolutions-SNS2 和 AwsSolutions-SQS2 的安全實務建議您SQS使用加密設定 Amazon SNS和 Amazon。不過,使用AWS受管金鑰SNS時 CloudWatch ,alarms 不適用於 Amazon,因此在這種情況下,您必須使用客戶受管金鑰。如需詳細資訊,請參閱 AWS 知識中心

此SQS政策用於 Amazon SQS佇列,以允許建立SNS的主題將訊息傳遞至佇列。如果沒有 SQS政策,存取將被拒絕。如需詳細資訊,請參閱 Amazon SNS 文件