O blog da AWS
Criando uma solução SaaS multi-tenant usando serviços serverless da AWS
A mudança para um modelo de entrega de software como serviço (SaaS) é acompanhada pelo desejo de maximizar os custos e a eficiência operacional.
Isso pode ser especialmente desafiador em um ambiente com vários tenants, onde a atividade dos tenants pode ser difícil de prever. Encontrar uma combinação de estratégias de escalabilidade que alinhe a atividade do tenant com o consumo real de recursos pode ser difícil. A estratégia que funciona hoje pode não funcionar amanhã.
Esses atributos tornam o SaaS uma opção atraente para um modelo serverless. Ao remover a noção de servidores de sua arquitetura SaaS, as organizações podem confiar em serviços gerenciados para escalar e fornecer o número preciso de recursos que sua aplicação consome.
Isso simplifica a arquitetura e a pegada operacional da sua solução, eliminando a necessidade de perseguir e gerenciar continuamente as políticas de escalabilidade. Isso também reduz a sobrecarga e a complexidade operacional, transferindo mais responsabilidade operacional para os serviços gerenciados.
Neste post, analisaremos uma solução de referência que fornece uma visão completa de um ambiente SaaS funcional e multi-tenant serverless. O objetivo é explorar as considerações de arquitetura e design necessárias para criar essa solução de referência.
Isso inclui analisar como você pode aproveitar o uso de serviços serverless da Amazon Web Services (AWS), como Amazon API Gateway, Amazon Cognito, AWS Lambda, Amazon DynamoDB, AWS CodePipeline e Amazon CloudWatch, para aproveitar o modelo serverless.
A solução de referência ilustra muitos dos componentes necessários para criar uma solução SaaS multi-tenant, como integração, isolamento de tenants, particionamento de dados, pipeline de implantação de tenants e observabilidade. Você pode usar esse repositório do GitHub para implantar e explorar a solução de referência na sua conta da AWS.
Compatível com vários modelos de implantação
Antes de mergulhar nas especificidades dessa solução de referência SaaS serverless, será benéfico descrever os diferentes modelos de implantação suportados por essa experiência. Incluímos dois modelos de implantação na solução — silo e pool — para destacar como esses modelos podem influenciar a integração, o isolamento, o “noisy-neighbor”, o desempenho e o perfil hierárquico de um ambiente SaaS serverless.
Para o modelo de silo, você verá que cada tenant tem seu próprio conjunto de recursos de infraestrutura. Por outro lado, no modelo de pool, todos os tenants compartilham uma infraestrutura comum de armazenamento e computação. Você pode ler sobre esses modelos de isolamento no whitepaper SaaS Tenant Isolation Strategies.
Essa solução SaaS serverless usa tiers para determinar qual modelo um tenant usa. Os tenants dos níveis Básico, Padrão e Premium compartilharão um conjunto comum de recursos. Os tenants de nível Platinum terão seus próprios recursos dedicados.
Implantando o ambiente básico
O arquivo README fornece instruções para implantar o ambiente básico SaaS serverless.
O processo de instalação provisiona todos os recursos que fazem parte do ambiente básico. Isso representa a infraestrutura e os recursos de que você precisará para começar a integrar os tenants do silo e do pool. Um diagrama dessa infraestrutura básica é mostrado abaixo.
Figura 1 — Visão geral de implantação.
Você notará que temos uma representação completa de todos as aplicações, serviços e infraestrutura necessários para executar nossa solução SaaS multi-tenant serverless. As seções a seguir fornecem um detalhamento dos principais elementos desse ambiente.
Aplicações Web
Você verá que criamos três aplicações diferentes que interagem com os serviços de back-end do ambiente. Usamos o Angular para criar essas aplicações.
O “console de administração do provedor de SaaS” representa uma aplicação usada pelos administradores de um provedor de SaaS. O “Formulário de onboarding/inscrição” serve como uma página de registro pública para que novos tenants se cadastrem. O “Exemplo de aplicação de comércio SaaS” representa uma típica aplicação de comércio eletrônico.
Essa aplicação também inclui algumas funcionalidades mínimas para simular uma aplicação SaaS, permitindo criar/atualizar produtos e pedidos.
Serviços compartilhados
Nosso ambiente também inclui um conjunto de serviços compartilhados que são responsáveis pelos aspectos de integração, tenant e gerenciamento de usuários da solução.
O nome “compartilhado” transmite a noção de que esses serviços são fundamentais para seu ambiente SaaS, fornecendo a funcionalidade transversal que é separada dos serviços de aplicação e compartilhada entre todos os tenants. Isso significa que as operações e os dados usados para integrar, gerenciar, autenticar e configurar tenants são gerenciados por esses serviços compartilhados.
Serviços de aplicações
Os serviços de aplicações são uma representação dos microsserviços que fornecem a funcionalidade comercial da sua solução. Conforme observado acima, a implantação e a função desses serviços de aplicações mudarão com base no tier do tenant.
Para nosso ambiente básico, implantamos os serviços de aplicações que serão consumidos pelos tenants em um tier que usa o modelo agrupado. Posteriormente, ao integrar tenants de tier Platinum, você verá que implantamos serviços de aplicações separados para cada tenant nesse tier.
Armazenamento de dados multi-tenant
Os serviços de aplicaçõess multi-tenants da nossa solução estão usando o Amazon DynamoDB para armazenar nossos dados multi-tenants. Para nossos tenants agrupados, estamos armazenando dados em uma construção agrupada em que os dados dos tenants são misturados em uma tabela compartilhada do DynamoDB. Essa abordagem requer a introdução de uma chave de particionamento de tenants que associe itens do DynamoDB a tenants individuais.
Você pode ler este blog para obter mais detalhes sobre essa abordagem.
Noção de microsserviços serverless
Para entender melhor a arquitetura, você precisa entender a noção de como compomos microsserviços em um ambiente serverless. É verdade que cada função pode ser um microsserviço, mas é mais comum ter uma coleção de funções que representam um microsserviço lógico.
Nesse caso, na borda desses microsserviços está o Amazon API Gateway, apoiado por uma ou mais funções Lambda. Imagine, por exemplo, um serviço de pedidos que tenha funções separadas para criar, ler, atualizar e excluir pedidos. Todas essas funções operam nos mesmos dados e devem ser agrupadas como um microsserviço lógico.
O diagrama abaixo fornece uma representação de alto nível desse conceito. Você também pode consultar este whitepaper para entender esse conceito com mais detalhes.
Figura 2 — Microsserviços serverless.
Registro e integração de tenants
Agora que temos uma ideia da arquitetura básica, vamos ver como os tenants são introduzidos nesse ambiente. Os tenants podem se registrar usando a aplicação web de inscrição. O fluxo de registro do tenant varia um pouco com base no tier que o tenant seleciona durante o processo de inscrição.
O diagrama a seguir mostra o fluxo de registro de tenants e como o serviço de registro de tenants aproveita outros serviços para orquestrar o registro de tenants.
Figura 3 — Fluxo de cadastro de tenants.
As etapas do processo de inscrição são as seguintes:
- O tenant fornece seus detalhes e tier de inscrição. O serviço de registro examina o tier e, se o tenant selecionou um tier Platinum, ele é sinalizado para ser integrado em um modelo isolado (recursos dedicados). Se qualquer outro tier for selecionado, o tenant será sinalizado para ser integrado em um modelo agrupado (recursos compartilhados).
- O serviço de registro invoca o serviço de gerenciamento de usuários para criar um novo usuário administrador do tenant; usamos o Amazon Cognito como nosso provedor de identidade. Para tenants de tier Platinum, você notará que um user pool separado é provisionado para cada tenant. Outros tiers compartilham um user pool comum, mas são atribuídos a grupos diferentes do Cognito dentro desse único user pool. O ID do tenant e a função do usuário são armazenados como uma declaração personalizada no Cognito.
- O serviço de registro invoca o serviço de gerenciamento de tenants para armazenar os detalhes do tenant. Como parte desse processo, associamos uma chave de API ao tenant, com base no tier de tenant selecionado durante a integração.
- Por fim, o serviço de provisionamento de tenants invoca o pipeline de tenants para provisionar qualquer infraestrutura específica para o tier Platinum/silo.
O serviço de registro de tenants usa as políticas de recursos do API Gateway para se autenticar no serviço de gerenciamento de usuários, gerenciamento de tenants e provisionamento.
Pipeline de implantação de tenants
Para essa solução, usamos o AWS CodePipeline para gerenciar a implantação de nossos serviços de aplicaçõess (serviço de produtos e pedidos, no nosso caso).
Esse pipeline é responsável por criar e atualizar a infraestrutura do tenant usando uma abordagem de CI/CD. Quando você publica/mescla seu código na branch principal, o pipeline (conforme mostrado na Figura 4) será acionado automaticamente, criará o fonte, executará todos os testes unitários necessários e implantará os serviços para todos os seus tenants de forma automatizada.
Figura 4 — Tenant CodePipeline.
Como parte dessa experiência de implantação, você notará que introduzimos uma tabela TenantStackMapping. Essa tabela está no centro da experiência do pipeline, fornecendo um mapeamento de tenant/tier que controla como os tenants são implantados.
Nossos tenants pool (tenants de tier Básico, Standard e Premium) estão repletos de entradas nesta tabela para cada stack agrupada como parte da implantação da infraestrutura básica. Então, à medida que os tenants de silo (nível Platinum) são integrados, o sistema cria uma entrada dentro dessa tabela para cada tenant. O CodePipeline faz referência a essa tabela para criar e atualizar stacks, conforme necessário.
Visão final da arquitetura
Depois de provisionar um ou mais tenants de tier Platinum no sistema, sua arquitetura adicionará uma nova infraestrutura para dar suporte a esses tenants (ilustrado na Figura 5). Agora você terá uma infraestrutura em silos para tenants de tier Platinum, junto com a infraestrutura em pool que é implantada como parte do script de provisionamento inicial.
Nesse modelo, cada tenant de tier Platinum tem seu próprio user pool do Cognito, um gateway de API separado, instalações separadas de funções Lambda e seu próprio conjunto de tabelas do DynamoDB.
Figura 5 — Área de cobertura final da implantação.
Autorização de API e isolamento de tenants
A solução de referência SaaS serverless utiliza vários mecanismos para gerenciar a segurança e controlar a atividade do tenant. Na Figura 6, você verá que a solução depende de uma combinação de um autorizador Lambda, Amazon Cognito, políticas dinâmicas de gerenciamento de identidade e acesso (IAM) e serviço STS para implementar esses controles.
Figura 6 — Fluxo de autorização.
O início desse fluxo começa com a autenticação de nossos tenants com o Amazon Cognito, que emite um token JWT (etapas 1 e 2). Esse JWT é então passado em cada solicitação processada pelo API Gateway (Etapa 3). Depois de acessar o API Gateway, um autorizador Lambda é usado para validar e autorizar a solicitação (Etapa 4).
Dentro do autorizador, nosso código ativará ou desativará rotas com base na função do usuário, impedindo o acesso a qualquer rota que não seja válida para esse usuário (Etapa 5). Ele também usará o contexto de tenant do JWT para adquirir credenciais com escopo para o tenant e enviá-las para funções Lambda, onde serão usadas para aplicar acesso com escopo de tenant aos recursos acessados pela função (Etapa 6).
Gerando políticas de isolamento de tenants
Como parte do processo de autorização, o autorizador Lambda gera as credenciais de curta duração com base nas políticas do IAM que são específicas desse tenant. Essas políticas são geradas dinamicamente pelo autorizador Lambda com base no ID de tenant recebido.
Abaixo está um trecho de código JSON que fornece um exemplo de uma política de isolamento de tenants para uma tabela do DynamoDB:
Neste trecho, a variável “tenant_id” é um espaço reservado que é substituído pelo ID do tenant entrante. Como resultado, você obterá uma política relevante somente para esse tenant.
O autorizador Lambda usa essa política do IAM para gerar credenciais de curta duração refinadas usando o método AssumeRole do serviço STS. O resultado disso é uma chave de acesso secreta que tem acesso aos dados apenas desse tenant. O autorizador Lambda fornece essas credenciais de curta duração para as funções downstream do Lambda como parte do contexto do Lambda.
Para aumentar a eficiência desse processo, o autorizador do Lambda armazena em cache as credenciais por um período configurável, com base no token JWT.
Aplicando isolamento de tenants
Os diferentes modelos de hierarquização e implantação de nossa aplicação (silo e pool) também influenciam a história de isolamento da solução SaaS serverless. Nossos tiers agrupados de tenants dependem das credenciais geradas pelo autorizador Lambda para fornecer o controle de acesso refinado que nossos serviços de aplicações em pool exigem.
A estratégia para tenants de silo é um pouco diferente, pois estamos provisionando tabelas separadas do DynamoDB para cada tenant. Nesse caso, não há necessidade de aplicar as credenciais com escopo ao acessar a tabela do DynamoDB de um tenant. Em vez disso, a função de execução do tenant, aplicada durante o provisionamento de nossas funções Lambda em silos, restringe o acesso à tabela específica provisionada para esse tenant.
Os diagramas a seguir mostram essa variação. Na Figura 7, nosso modelo de isolamento se baseia nas credenciais com escopo fornecidas pelo autorizador para limitar o acesso aos itens do DynamoDB em uma tabela pool do DynamoDB.
Figura 7 — Isolamento do tenant — modelo pool.
A Figura 8, por outro lado, usa a função de execução associada à função Lambda para controlar o acesso às tabelas do Amazon DynamoDB.
Figura 8 — Isolamento do tenant — modelo de silo.
Limitação de tenants
É comum que os provedores de SaaS ofereçam experiências diferentes para cada tipo (tier) de tenants que estão usando o sistema. A limitação geralmente faz parte de uma estratégia de classificação mais ampla, na qual tenants de tier básico, por exemplo, têm políticas de limitação que limitam sua capacidade de impactar a experiência dos tenants de tier superior.
O exemplo de solução SaaS serverless aplica essas estratégias baseadas em camadas por meio do API Gateway, que permite criar planos de uso que podem ser associados a uma chave de API para vincular um tier a um determinado plano. No nosso caso, temos um plano de uso para cada tier de tenant (Basic, Standard, Premium e Platinum). Associamos chaves de API separadas a cada um desses planos de uso para configurar nossos limites de throttling baseados em tiers.
Dependendo do seu cenário, você também pode considerar ter um plano de uso por tenant. Geralmente, esse é o caso quando você tem um número limitado de tenants.
Observabilidade do tenant usando Lambda Layers
Como regra geral, as soluções SaaS tentam tornar o desenvolvimento de microsserviços o mais simples possível, introduzindo bibliotecas ou módulos que ocultarão muitos dos detalhes associados à multi-tenancy. Logs, métricas, acesso a dados — todos eles podem exigir o contexto do tenant, por exemplo, e não queremos exigir que os desenvolvedores criem um código único em cada um de seus serviços para gerenciar/acessar/aplicar esse contexto do tenant.
Em um ambiente serverless, temos um mecanismo natural que nos permitirá introduzir um código comum que pode ser reutilizado para atender a essas necessidades comuns de vários tenants. A arquitetura SaaS serverless usa Lambda Layers para centralizar o registro e a coleta de métricas.
Na solução de referência, introduzimos layers para atender a algumas das necessidades comuns de nossos microsserviços. Um layer, por exemplo, é usado para extrair um ID de tenant de um token JWT. Também usamos código em um layer para registrar os registros e métricas com reconhecimento de tenants que são publicados no CloudWatch.
A solução de referência também aproveita o AWS X-Ray para rastreamento e aproveita as anotações do X-Ray para diferenciar os rastreamentos por tenant. Por fim, você também pode usar o CloudWatch Logs Insight para consultar os registros e resumir essas métricas.
Custo por tenant
A capacidade de registrar o ID do tenant permite que você entenda melhor o consumo de seus tenants, especialmente aqueles que operam em um modelo de pool. Como exemplo, este blog uma abordagem para determinar o custo por tenant, com base na ID do tenant dentro dos registros do CloudWatch. Ele usa o AWS Application Cost Profiler (ACP) para obter uma análise granular dos custos dos recursos compartilhados da AWS entre os tenants.
O custo por tenant para tenants do tipo silo (Platinum) é relativamente simples, pois você pode usar tags de alocação de custos para obter uma análise dos custos. Isso é possível, pois os recursos dos tenants do tipo silo não são compartilhados.
Conclusão
Neste post, discutimos como você pode criar uma solução SaaS escalável e segura usando os serviços serverless da AWS. Fornecemos orientações sobre como você pode mapear vários recursos dentro dos serviços serverless da AWS de acordo com as melhores práticas de SaaS.
Essa solução lhe dará uma vantagem inicial e servirá como um ponto de referência em sua jornada de SaaS. O repositório do GitHub também vem com uma documentação detalhada que fornece mais informações sobre o funcionamento interno dessa solução de referência. Você achará isso útil ao se aprofundar na arquitetura e na implementação.
Sobre o AWS SaaS Factory
O AWS SaaS Factory ajuda organizações em qualquer estágio da jornada de SaaS. Seja para criar novos produtos, migrar aplicações existentes ou otimizar soluções de SaaS na AWS. Visite o AWS SaaS Factory Insights Hub para descobrir mais conteúdo técnico e comercial e melhores práticas.
Os criadores de soluções SaaS são incentivados a entrar em contato com seu representante de conta para obter informações sobre modelos de engajamento e trabalhar com a equipe do AWS SaaS Factory.
Inscreva-se para se manter informado sobre as últimas notícias, recursos e eventos de SaaS na AWS.
Este artigo foi traduzido do Blog da AWS em Inglês.
Sobre os autores
Anubhav Sharma é arquiteto sênior de soluções de parceiros
Ujwal Bukka é arquiteto de soluções de parceiros — AWS SaaS Factory