Estudo de caso: Por que uso a infraestrutura da Nuvem AWS para meus produtos

Publicados: 2022-03-11

Como plataforma para executar um produto de software complexo e exigente, a AWS oferece flexibilidade ao utilizar recursos quando necessário, na escala necessária. É sob demanda e instantâneo, permitindo controle total sobre o ambiente em execução. Ao propor uma solução de arquitetura em nuvem para um cliente, a infraestrutura provisionada e seu preço dependem muito dos requisitos que precisam ser configurados antecipadamente.

Este artigo apresentará uma dessas arquiteturas de infraestrutura em nuvem da AWS, proposta e implementada para LEVELS, uma rede social com uma função de pagamento facial integrada que encontra e aplica todos os benefícios que os usuários podem obter pelos programas de cartão em que estão, coisas que possuem ou locais eles vivem em.

Requisitos

O cliente tinha dois requisitos principais que a solução proposta deveria atender:

  1. Segurança
  2. Escalabilidade

Segurança e escalabilidade na nuvem AWS

O requisito de segurança era proteger os dados dos usuários contra acesso não autorizado de fora, mas também de dentro. O requisito de escalabilidade era sobre a capacidade da infraestrutura de suportar o crescimento do produto, adaptando-se automaticamente ao aumento do tráfego e picos ocasionais, bem como failover e recuperação automáticos em caso de falhas de servidores, minimizando o tempo de inatividade potencial.

Visão geral dos conceitos de segurança da AWS

Um dos principais benefícios de configurar sua própria infraestrutura na Nuvem AWS é o isolamento total da rede e o controle total sobre sua nuvem. Essa é a principal razão pela qual você escolheria a rota de infraestrutura como serviço (IaaS), em vez de executar ambientes de plataforma como serviço (PaaS) um pouco mais simples, que oferecem padrões de segurança sólidos, mas não possuem o controle completo e refinado que você obtém configurando sua própria nuvem com a AWS.

Embora a LEVELS fosse um produto jovem quando se aproximou da Toptal para os serviços de consultoria da AWS, eles estavam dispostos a se comprometer com a AWS e sabiam que queriam segurança de última geração com sua infraestrutura, pois estão muito preocupados com os dados e a privacidade do usuário. Além disso, eles planejam oferecer suporte ao processamento de cartão de crédito no futuro, então eles sabiam que precisariam garantir a conformidade com o PCI-DSS em algum momento.

Nuvem Privada Virtual (VPC)

A segurança na AWS começa com a criação de sua própria Amazon Virtual Private Cloud (VPC) - uma rede virtual dedicada que hospeda seus recursos da AWS e é logicamente isolada de outras redes virtuais na Nuvem AWS. A VPC obtém seu próprio intervalo de endereços IP, sub-redes totalmente configuráveis, tabelas de roteamento, listas de controle de acesso à rede e grupos de segurança (na verdade, um firewall).

Com LEVELS, começamos isolando nosso ambiente de produção dos ambientes de desenvolvimento, teste e controle de qualidade. A primeira ideia era executar cada um deles como sua própria VPC totalmente isolada, cada um executando todos os serviços conforme exigido pelo aplicativo. Após algumas considerações, descobrimos que poderíamos permitir algum compartilhamento de recursos nos três ambientes de não produção, o que reduziu o custo até certo ponto.

Assim, estabelecemos o ambiente de produção como uma VPC, com ambientes de desenvolvimento, teste e controle de qualidade como outra VPC.

Isolamento de acesso em nível de VPC

A configuração de duas VPC isola o ambiente de produção dos três ambientes restantes em um nível de rede, garantindo que a configuração incorreta acidental do aplicativo não consiga cruzar esse limite. Mesmo que a configuração do ambiente de não produção aponte erroneamente para recursos do ambiente de produção, como banco de dados ou filas de mensagens, não há como obter acesso a eles.

Isolamento de acesso à rede VPC
Isolamento de acesso à rede VPC

Com ambientes de desenvolvimento, teste e controle de qualidade compartilhando a mesma VPC, o acesso entre fronteiras é possível em caso de configuração incorreta, mas, como esses ambientes usam dados de teste, não existe nenhuma preocupação real de segurança com a falta de isolamento.

Modelo de segurança da loja de ativos

Os ativos são armazenados no armazenamento de objetos do Amazon Simple Storage Service (S3) . A infraestrutura de armazenamento do S3 é completamente independente das VPCs e seu modelo de segurança é diferente. O armazenamento é organizado em buckets S3 separados para cada ambiente e/ou classes de ativos, protegendo cada bucket com os direitos de acesso apropriados.

Com LEVELS, várias classes de ativos foram identificadas: uploads de usuários, conteúdo produzido em LEVELS (vídeos promocionais e conteúdo similar), ativos de aplicativos da web e UI (código JS, ícones, fontes), configuração de aplicativos e infraestrutura e pacotes de implantações do lado do servidor.

Cada um deles recebe um bucket S3 separado.

Gerenciamento de segredos do aplicativo

Com a AWS, há um AWS Systems Manager Parameter Store criptografado ou o AWS Secrets Manager , que são serviços de valor-chave gerenciados projetados para manter os segredos seguros (você pode saber mais em Linux Academy e 1Strategy).

A AWS gerencia as chaves de criptografia subjacentes e lida com a criptografia/descriptografia. Os próprios segredos podem ter políticas de permissões de leitura e gravação aplicadas com base nos prefixos de chave, tanto para a infraestrutura quanto para os usuários (servidores e desenvolvedores, respectivamente).

Acesso SSH do servidor

O acesso SSH a servidores em um ambiente totalmente automatizado e imutável não deve ser necessário. Os logs podem ser extraídos e enviados para serviços de log dedicados, o monitoramento também é transferido para um serviço de monitoramento dedicado. Ainda assim, pode haver a necessidade de acesso SSH ocasional para inspeção e depuração de configuração.

Para limitar a superfície de ataque dos servidores, a porta SSH não fica exposta à rede pública. Os servidores são acessados ​​por meio de um bastion host, uma máquina dedicada que permite acesso SSH externo, adicionalmente protegido pela lista de permissões apenas do intervalo de endereços IP permitidos no firewall. O acesso é controlado pela implantação das chaves SSH públicas dos usuários nas caixas apropriadas (os logins por senha são desabilitados). Essa configuração oferece um portão bastante resiliente para invasores maliciosos passarem.

Acesso ao banco de dados

Os mesmos princípios descritos acima se aplicam aos servidores de banco de dados. Também pode haver uma necessidade ocasional de conectar e manipular os dados diretamente no banco de dados, embora isso definitivamente não seja uma prática recomendada, e esse acesso precisa ser protegido da mesma forma que o acesso SSH dos servidores é protegido.

Uma abordagem semelhante pode ser usada, utilizando a mesma infraestrutura de host bastion com encapsulamento SSH. É necessário um túnel SSH duplo, um para o bastion host e, através desse, outro para o servidor que tem acesso ao banco de dados (o bastion host não tem acesso ao servidor de banco de dados). Através desse segundo túnel, uma conexão da máquina cliente do usuário ao servidor de banco de dados está agora disponível.

Visão geral dos conceitos de escalabilidade da AWS

Quando falamos puramente de servidores, a escalabilidade é facilmente alcançada com plataformas mais simples que a AWS. A principal desvantagem é que certos requisitos podem precisar ser cobertos pelos serviços externos da plataforma, o que significa que os dados trafegam pela rede pública e quebram os limites de segurança. Aderindo à AWS, todos os dados são mantidos privados, enquanto a escalabilidade precisa ser projetada para alcançar uma infraestrutura escalável, resiliente e tolerante a falhas.

Com a AWS, a melhor abordagem para escalabilidade é aproveitar os serviços gerenciados da AWS com monitoramento e automação testados em batalha em milhares de clientes que usam a plataforma. Adicione backups de dados e mecanismos de recuperação à mistura e você terá muitas preocupações fora da mesa apenas confiando na própria plataforma.

Ter tudo isso descarregado permite uma equipe de operações menor, compensando um pouco o custo mais alto dos serviços gerenciados da plataforma. A equipe LEVELS ficou feliz em escolher esse caminho sempre que possível.

Amazon Elastic Compute Cloud (EC2)

Confiar em um ambiente comprovado executando instâncias do EC2 ainda é uma abordagem bastante razoável, em comparação com a sobrecarga e a complexidade adicionais da execução de contêineres ou com os conceitos arquitetônicos ainda muito novos e em rápida mudança da computação sem servidor.

O provisionamento de instâncias do EC2 precisa ser totalmente automatizado. A automação é obtida por meio de AMIs personalizadas para diferentes classes de servidores e grupos de Auto Scaling cuidando da execução de frotas de servidores dinâmicos, mantendo o número apropriado de instâncias de servidores em execução na frota de acordo com o tráfego atual.

Além disso, o recurso de dimensionamento automático permite definir o limite inferior e superior no número de instâncias do EC2 a serem executadas. O limite inferior auxilia na tolerância a falhas, potencialmente eliminando o tempo de inatividade em caso de falhas de instâncias. O limite superior mantém os custos sob controle, permitindo algum risco de paralisação em caso de condições extremas inesperadas. O escalonamento automático dimensiona dinamicamente o número de instâncias dentro desses limites.

Serviço de banco de dados relacional da Amazon (RDS)

A equipe já executou o Amazon RDS for MySQL , mas o backup apropriado, a tolerância a falhas e a estratégia de segurança ainda não foram desenvolvidos. Na primeira iteração, a instância de banco de dados foi atualizada para um cluster de duas instâncias em cada VPC, configurado como mestre e réplica de leitura, com suporte para failover automático.

Na iteração seguinte, com a disponibilização do mecanismo MySQL versão 5.7, a infraestrutura recebeu um upgrade para o serviço Amazon Aurora MySQL . Embora totalmente gerenciado, o Aurora não é uma solução dimensionada automaticamente. Oferece dimensionamento automático de armazenamento, evitando a questão do planejamento de capacidade. Mas um arquiteto de soluções ainda precisa escolher o tamanho da instância de computação.

O tempo de inatividade devido ao dimensionamento não pode ser evitado, mas pode ser reduzido ao mínimo com a ajuda do recurso de recuperação automática. Graças aos melhores recursos de replicação, o Aurora oferece uma funcionalidade de failover perfeita. O dimensionamento é executado criando uma réplica de leitura com o poder de computação desejado e, em seguida, executando o failover para essa instância. Todas as outras réplicas de leitura também são retiradas do cluster, redimensionadas e trazidas de volta ao cluster. Requer algum malabarismo manual, mas é mais do que factível.

A nova oferta do Aurora Serverless também permite algum nível de dimensionamento automático dos recursos de computação, um recurso que definitivamente vale a pena analisar no futuro.

Serviços gerenciados da AWS

Além desses dois componentes, o restante do sistema se beneficia dos mecanismos de dimensionamento automático dos serviços totalmente gerenciados da AWS. São elas: Elastic Load Balancing (ELB), Amazon Simple Queue Service (SQS), armazenamento de objetos do Amazon S3, funções do AWS Lambda e Amazon Simple Notification Service (SNS), em que nenhum esforço de dimensionamento específico é necessário por parte do arquiteto.

Infraestrutura mutável vs. imutável

Reconhecemos duas abordagens para lidar com a infraestrutura de servidores - uma infraestrutura mutável onde os servidores são instalados e continuamente atualizados e modificados no local; e uma infraestrutura imutável onde os servidores nunca são modificados depois de provisionados, e quaisquer modificações de configuração ou atualizações de servidor são tratadas pelo provisionamento de novos servidores a partir de uma imagem comum ou um script de instalação, substituindo os antigos.

Com LEVELS, a escolha é executar uma infraestrutura imutável sem atualizações no local, alterações de configuração ou ações de gerenciamento. A única exceção são as implantações de aplicativos, que acontecem no local.

Mais informações sobre infraestrutura mutável versus imutável podem ser encontradas no blog da HashiCorp.

Visão geral da arquitetura

Tecnicamente, LEVELS é um aplicativo móvel e um aplicativo da web com o backend da API REST e alguns serviços em segundo plano - um aplicativo bastante típico hoje em dia. Para isso, foi proposta e configurada a seguinte infraestrutura:

LEVELS Visão geral da infraestrutura em nuvem
LEVELS Visão geral da infraestrutura em nuvem

Isolamento de rede virtual - Amazon VPC

O diagrama visualiza uma estrutura de um ambiente em sua VPC. Outros ambientes seguem a mesma estrutura (tendo o Application Load Balancer (ALB) e o cluster do Amazon Aurora compartilhados entre os ambientes de não produção em sua VPC, mas a configuração de rede é exatamente a mesma).

A VPC é configurada em quatro zonas de disponibilidade em uma região da AWS para tolerância a falhas. Sub-redes e grupos de segurança com listas de controle de acesso à rede permitem satisfazer os requisitos de segurança e controle de acesso.

Abrangendo a infraestrutura em várias regiões da AWS para tolerância a falhas adicional teria sido muito complexo e desnecessário em um estágio inicial dos negócios e de seu produto, mas é uma opção no futuro.

Informática

LEVELS executa uma API REST tradicional com alguns trabalhadores em segundo plano para a lógica do aplicativo acontecendo em segundo plano. Ambos são executados como frotas dinâmicas de instâncias EC2 simples, totalmente automatizadas por meio de Auto Scaling Groups. O serviço gerenciado do Amazon SQS é usado para distribuição de tarefas em segundo plano (jobs), evitando a necessidade de executar, manter e dimensionar seu próprio servidor MQ.

LEVELS Distribuição de trabalhos em segundo plano
LEVELS Distribuição de trabalhos em segundo plano

Há também algumas tarefas de utilitário que não têm lógica de negócios compartilhada com o restante do aplicativo, como processamento de imagem. Esses tipos de tarefas são executados extremamente bem no AWS Lambda , pois os Lambdas são indefinidamente escaláveis ​​horizontalmente e oferecem processamento paralelo incomparável em comparação com servidores de trabalho.

Balanceamento de carga, escalonamento automático e tolerância a falhas

O balanceamento de carga pode ser obtido manualmente por meio do Nginx ou HAProxy, mas escolher o Amazon Elastic Load Balancing (ELB) adiciona o benefício de ter a infraestrutura de balanceamento de carga intrinsecamente escalável automaticamente, altamente disponível e tolerante a falhas.

O tipo Application Load Balancer (ALB) do ELB é usado, fazendo uso do roteamento de camada HTTP disponível no load balancer. Novas instâncias adicionadas à frota são registradas automaticamente no ALB por meio dos mecanismos da plataforma AWS. O ALB também monitora a disponibilidade das instâncias o tempo todo. Ele tem o poder de cancelar o registro e encerrar as instâncias não íntegras, acionando o Auto Scaling para substituí-las por novas. Por meio dessa interação entre os dois, a recuperação automática da frota EC2 é alcançada.

Armazenamento de dados do aplicativo

O armazenamento de dados do aplicativo é um cluster do Amazon Aurora MySQL , que consiste em uma instância mestre e várias instâncias de réplica de leitura. No caso de falha da instância mestre, uma das réplicas de leitura é promovida automaticamente para uma nova instância mestre. Configurado como tal, satisfaz o requisito de tolerância a falhas solicitado.

Modelo automático de failover de instância do Amazon Aurora
Modelo automático de failover de instância do Amazon Aurora

Réplicas de leitura, como o próprio nome indica, também podem ser usadas para distribuir a carga do cluster de banco de dados para operações de leitura de dados.

O armazenamento de banco de dados é dimensionado automaticamente em incrementos de 10 GB com o Aurora, e os backups também são totalmente gerenciados pela AWS, oferecendo uma restauração pontual por padrão. Tudo isso reduz a carga de administração do banco de dados para praticamente nenhuma, exceto para aumentar o poder de computação do banco de dados quando necessário - um serviço que vale a pena pagar para ser executado sem preocupações.

Armazenando e servindo ativos

LEVELS aceita o conteúdo carregado dos usuários que precisa ser armazenado. O armazenamento de objetos do Amazon S3 é, de maneira bastante previsível, o serviço que cuidará dessa tarefa. Também existem ativos de aplicativos (elementos de interface do usuário - imagens, ícones, fontes) que precisam ser disponibilizados para o aplicativo cliente, para que sejam armazenados no S3 também. Oferecendo backups automatizados dos dados carregados por meio de sua replicação de armazenamento interno, o S3 oferece durabilidade de dados por padrão.

As imagens que os usuários carregam são de vários tamanhos e pesos, muitas vezes desnecessariamente grandes para veiculação direta e com excesso de peso, sobrecarregando as conexões móveis. Produzir diversas variações em diferentes tamanhos permitirá a veiculação de conteúdo mais otimizado para cada caso de uso. O AWS Lambda é aproveitado para essa tarefa, bem como para fazer uma cópia das imagens originais carregadas em um bucket de backup separado, por precaução.

Por fim, um aplicativo da Web executado em navegador também é um conjunto de ativos estáticos - a infraestrutura de compilação de Integração Contínua compila o código JavaScript e armazena cada compilação no S3 também.

Depois que todos esses ativos são armazenados com segurança no S3, eles podem ser atendidos diretamente, pois o S3 fornece uma interface HTTP pública ou por meio da CDN do Amazon CloudFront . O CloudFront faz com que os ativos sejam distribuídos geograficamente, reduzindo a latência para os usuários finais, e também habilita o suporte HTTPS para atender ativos estáticos.

LEVELS S3 buckets e visão geral da organização do CloudFront CDN
LEVELS S3 buckets e visão geral da organização do CloudFront CDN

Provisionamento e Gerenciamento de Infraestrutura

O provisionamento da infraestrutura da AWS é uma combinação de rede, os recursos e serviços gerenciados pela AWS e os recursos de computação do EC2. Os serviços gerenciados da AWS são, bem, gerenciados. Não há muito o que fazer com eles, exceto provisionar e aplicar a segurança apropriada, enquanto com os recursos de computação do EC2, precisamos cuidar da configuração e da automação por conta própria.

Ferramentas

O Console AWS baseado na web torna o gerenciamento da infraestrutura AWS “semelhante a lego-bricks” algo menos trivial e, como qualquer trabalho manual, bastante propenso a erros. É por isso que usar uma ferramenta dedicada para automatizar esse trabalho é altamente desejável.

Uma dessas ferramentas é o AWS CloudFormation , desenvolvido e mantido pela AWS. Outro é o Terraform da HashiCorp - uma escolha um pouco mais flexível por oferecer provedores de múltiplas plataformas, mas interessante aqui principalmente devido à filosofia de abordagem de infraestrutura imutável da Terraform. Alinhado com a forma como a infraestrutura LEVELS está sendo executada, o Terraform, juntamente com o Packer para fornecer as imagens AMI básicas, acabou sendo uma ótima opção.

Documentação de Infraestrutura

Um benefício adicional de uma ferramenta de automação é que ela não requer documentação de infraestrutura detalhada, que fica desatualizada mais cedo ou mais tarde. O paradigma “Infrastructure as Code” (IaC) da ferramenta de provisionamento funciona como documentação, com o benefício de estar sempre atualizado com a infraestrutura real. Ter uma visão geral de alto nível, menos provável de ser alterada e relativamente fácil de manter com as eventuais alterações, documentada ao lado é suficiente.

Pensamentos finais

A infraestrutura da Nuvem AWS proposta é uma solução escalável capaz de acomodar o crescimento futuro de produtos principalmente automaticamente. Após quase dois anos, consegue manter os custos de operação baixos, contando com a automação em nuvem sem ter uma equipe de operações de sistemas dedicada 24 horas por dia, 7 dias por semana.

No que diz respeito à segurança, a Nuvem AWS mantém todos os dados e todos os recursos dentro de uma rede privada dentro da mesma nuvem. Nenhum dado confidencial é necessário para trafegar pela rede pública. O acesso externo é concedido com permissões granulares finas aos sistemas de suporte confiáveis ​​(CI/CD, monitoramento externo ou alerta), limitando o escopo de acesso apenas aos recursos necessários para sua função em todo o sistema.

Arquitetado e configurado corretamente, esse sistema é flexível, resiliente, seguro e pronto para atender a todos os requisitos futuros em relação ao dimensionamento para o crescimento do produto ou à implementação de segurança avançada, como conformidade com PCI-DSS.

Não é necessariamente mais barato do que as ofertas de produtos como Heroku ou plataformas semelhantes, que funcionam bem desde que você se encaixe nos padrões de uso comuns cobertos por suas ofertas. Ao escolher a AWS, você ganha mais controle sobre sua infraestrutura, um nível adicional de flexibilidade com a variedade de serviços AWS oferecidos e configuração personalizada com a capacidade de ajuste fino de toda a infraestrutura.

Toptal é um parceiro de consultoria avançado da AWS.

Como Advanced Consulting Partner na Amazon Partner Network (APN), a Toptal fornece soluções em nuvem para empresas e trabalha com elas em todas as etapas de sua jornada.



Leitura adicional no Blog da Toptal Engineering:

  • Faça sua lição de casa: 7 dicas para o exame AWS Certified Solutions Architect
  • Terraform vs. CloudFormation: o guia definitivo
  • Registro SSH e gerenciamento de sessões usando o AWS SSM
  • Trabalhando com suporte a TypeScript e Jest: um tutorial do AWS SAM