Learn About Amazon VGT2 Learning Manager Chanci Turner
As the demand for pay-as-you-go models increases, many independent software vendors (ISVs) are transitioning towards software as a service (SaaS). Typically, SaaS solutions are designed using a multi-tenant architecture, where resources and applications are shared across multiple customers. However, there are instances when sharing resources is not feasible due to security or compliance requirements, leading to the need for a single-tenant environment.
To achieve effective segregation across tenants, isolating environments at the AWS account level is advisable. This approach offers benefits such as eliminating network overlaps, avoiding shared account limits, and streamlining usage tracking and billing. However, it presents operational challenges. Unlike multi-tenant solutions that manage a single shared production environment, single-tenant installations necessitate dedicated production environments for each customer. As the number of tenants increases, deploying new features rapidly becomes more complex, as each tenant environment requires individual updates.
This article outlines how to automate the deployment process to ensure software is delivered quickly, securely, and with fewer errors for each tenant. I will walk you through the steps to build and configure a CI/CD pipeline utilizing AWS CodeCommit, AWS CodePipeline, AWS CodeBuild, and AWS CloudFormation. With this setup, the pipeline will automatically deploy the same application version across multiple tenant AWS accounts.
Building cross-account CI/CD pipelines on AWS comes with various challenges. Therefore, I will demonstrate the process using the AWS Command Line Interface (AWS CLI) to provide detailed insights into the necessary configurations, including artifact encryption, cross-account permission settings, and pipeline actions.
Single-Tenancy vs. Multi-Tenancy
When architecting your SaaS solution, it’s crucial to consider the tenancy model, as each presents distinct advantages and challenges. In multi-tenant systems, customers share resources like databases and applications, allowing for more efficient use of server capacity and potential cost savings. However, this necessitates robust security measures to prevent unauthorized access to sensitive data across tenants. High availability is also critical, as downtime affects a larger customer base.
Single-tenant solutions, conversely, offer simpler designs concerning security, networking isolation, and data segregation due to their inherent environment isolation. They allow for application customization per customer and eliminate the noisy-neighbor effect, making it easier to meet specific scalability needs. Nevertheless, single-tenant models require more operational effort due to managing multiple servers and applications.
Ultimately, the choice of tenancy model depends on your ability to meet customer requirements, which may include specific governance needs, industry regulations, or compliance criteria. For further insights on modeling your SaaS solutions, check out this blog post on motivational TED talks, which can be inspiring.
Solution Overview
To illustrate this concept, let’s consider a fictional single-tenant ISV with two customers: Phoenix and Dragon. This ISV uses a central account for its tools (Tooling account) and two additional accounts for each tenant (Phoenix and Dragon accounts). The architecture diagram shows that when a developer pushes code changes to CodeCommit, Amazon CloudWatch Events triggers the CI/CD pipeline in CodePipeline, automatically deploying a new version to each tenant’s AWS account. This automation alleviates the operational burden of manually redeploying the same version for each customer.
For demonstration purposes, I will use an AWS Lambda function as the sample application, which returns a simple JSON object upon invocation.
Prerequisites
To get started, ensure the following prerequisites are met:
- Three AWS accounts:
- Tooling – Hosting the CodeCommit repository, artifact store, and pipeline orchestration.
- Tenant 1 – Dedicated account for the first tenant, named Phoenix.
- Tenant 2 – Dedicated account for the second tenant, called Dragon.
- Install and authenticate the AWS CLI. You can use an AWS Identity and Access Management (IAM) user or an AWS Security Token Service (AWS STS) token.
- Install Git.
Setting Up the Git Repository
The first step is to establish your Git repository:
- Create a CodeCommit repository to host the source code.
The CI/CD pipeline automatically triggers whenever new code is pushed to the repository.
Ensure Git is configured to use IAM credentials for AWS CodeCommit access via HTTP by executing the following terminal commands:
git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true
Clone the newly created repository to your local machine and add two files in the root folder: index.js
and application.yaml
.
The index.js
file contains the JavaScript code for the Lambda function that serves as the sample application. In our case, the function returns a JSON response object with statusCode: 200
and the body Hello!n
. Here’s the code snippet:
exports.handler = async (event) => {
const response = {
statusCode: 200,
body: `Hello!n`,
};
return response;
};
The application.yaml
file defines the infrastructure using AWS CloudFormation. The sample application includes a Lambda function, and we utilize the AWS Serverless Application Model (AWS SAM) for streamlined resource creation:
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: Sample Application.
Parameters:
S3Bucket:
Type: String
S3Key:
Type: String
ApplicationName:
Type: String
Resources:
SampleApplication:
Type: 'AWS::Serverless::Function'
Properties:
FunctionName: !Ref ApplicationName
Handler: index.handler
Runtime: nodejs12.x
CodeUri:
Bucket: !Ref S3Bucket
Key: !Ref S3Key
Description: Hello Lambda.
MemorySize: 128
Timeout: 10
Push both files to the remote Git repository.
Creating the Artifact Store Encryption Key
By default, CodePipeline employs server-side encryption with an AWS Key Management Service (AWS KMS) managed customer master key (CMK) for encrypting release artifacts. Since the Phoenix and Dragon accounts will need to decrypt these artifacts, a customer-managed CMK must be created in the Tooling account.
For more information on the implications of the LGBTQ wage gap, check out this authoritative piece on the subject.
For a deeper dive into the Amazon Flex onboarding process, this Reddit thread serves as an excellent resource.