O blog da AWS

Criando um portal de autosserviços para o provisionamento na AWS

Como times de tecnologia podem criar uma “Vending Machine” como solução de autosserviços e permitir que os times corporativos provisionem infraestrutura de maneira autônoma e seguindo boas-práticas

Por Cristiano Scandura, Solutions Architect, Education, Brazil Public Sector

Empresas de diversos portes enfrentam problemas em gerenciar recursos e serviços de TI mesmo em nuvem. É comum ter filas de chamados para o provisionamento de servidores e serviços para serem processados pelos times de operação, impedindo que times de negócio possam ser mais ágeis e inovadores. Em outras situações, podem existir ambientes em nuvem com provisionamento de aplicações que não seguem boas-práticas de governança e operação em nome da agilidade.

Para dar maior agilidade ao processo, ao invés de ser um “balcão de serviços” o time de operações de TI pode disponibilizar aos times de negócios pacotes pré-formatados de aplicações e infraestrutura, por exemplo, imagine um portal de autosserviços onde os times podem escolher um produto “Aplicação Web com banco de dados” e ter disponibilizado automaticamente os servidores já com TAGs para rastrear custos e automatizar processos, infraestrutura  básica de segurança e redes, esteiras de CI/CD, chaves de acesso, repositório e tudo mais que for necessário para operar e governar este ambiente, seguindo boas práticas. Abaixo temos a representação das telas deste portal de autosserviços.

Figura 1: Fluxo de exemplo de um portal de autosserviços.

Governança e Boas Práticas

Antes de seguirmos é importante apresentar alguns conceitos importantes sobre governança e boas praticas, que são:

  • Múltiplas contas: A AWS trabalha com o conceito de agrupamento de recursos através de diferentes contas, isto não gera custos adicionais, mas sim maior visibilidade dos custos. É possível ter contas distintas por ambientes e aplicações ligadas a uma conta principal, que concentra todo o faturamento e a administração através do AWS Organizations.
  • Isolamento: Trabalhando com múltiplas contas ainda fica mais simples a configuração de papeis de acesso no AWS Identity and Access Manager (IAM), onde equipes tem acesso apenas os seus recursos e serviços, com níveis diferentes por ambiente. Por exemplo, uma conta de produção teria um acesso muito mais restrito que uma de desenvolvimento. Além disto, o acesso pode ocorrer no nível do catálogo de serviços.
  • Padronização: A forma como governar e operar os ambientes será muito mais simples com a padronização, onde catálogos de serviços podem ser criados, padronizando quais os serviços podem ser utilizados e garantido que os recursos serão monitorados e processos automatizados serão executados em casos de eventos. Por exemplo, você pode padronizar a criação de um servidor virtual no Amazon Elastic Compute Cloud (EC2) com tipos e AMI (imagem de maquinas da Amazon) pré-aprovadas.
  • Custos: É importante ter visibilidade dos custos e para essa governança, a geração de relatórios de custos por TAGs, contas e times, podem ser comprometidas sem a devida administração na implantação dos recursos.
  • Produtos e não serviços: Por fim, é preciso ter um cuidado para não criar um portal para implementar serviços específicos, como uma função AWS Lambda, afinal a AWS já disponibiliza isto no seu console e seria um portal sobre outro, gerando muito trabalho, em vez disto, pense em Produtos, soluções completas, por exemplo, a implantação de uma estrutura já com contas, acessos, catálogos e conexões, com um único clique.

Arquitetura da Solução

Para implementar está solução de autosserviços de uma maneira simples e segura, com baixo custo e baixa manutenção, usaremos uma arquitetura Serverless. O front-end é escrito em React e armazenado no Amazon Simple Storage Services – S3, publicado através do Amazon Cloudfront e com autenticação usando Amazon Cognito. O back-end tem acesso através do Amazon API Gateway e interagindo com funções no AWS Lambda e processos gerenciados pelo AWS Step Functions. Utilizaremos uma estrutura em JSON com os dados dos produtos e os parâmetros para o provisionamento dos produtos armazenados no banco de dados não-relacional Amazon DynamoDB e a implantação da infraestrutura usa Stackset do AWS CloudFormation a partir de uma conta principal para demais contas da organização.

Figura 2: Arquitetura do portal de autosserviços.

Implantação

O Front-end estará hospedado em um bucket privado no S3 e publicado através do Amazon Cloudfront, a aplicação utilizará funções de Lambda@Edge para inspecionar se as requisições estão autenticadas utilizando JSON Web Tokens (JWT), do contrario, os usuários serão redirecionado para a tela de autenticação fornecida pelo Cognito (OAuth2). Todo o processo de cadastro de usuários é auto gerenciado e pode ser personalizado através de um User Pool no Cognito.

Para prosseguir, é importante fazer o download dos arquivos do repositório do portal de Auto Serviços com o comando abaixo:

git clone https://github.com/aws-samples/aws-severless-vending-machine

Importante: Como essa solução faz deploy em outras contas usando StackSets, é obrigatório seguir os passos descritos em “Pré-requisitos para operações de conjunto de pilhas”. No mínimo é necessário implantar a Stack (pilha) AWSCloudFormationStackSetAdministrationRole na conta principal e a AWSCloudFormationStackSetExecutionRole nas contas filhas, conforme descrito em Conceder permissões auto gerenciadas.

Existe um script de CloudFormation na pasta scripts com o nome deployServerlessVendingMachine.yaml para fazer o deploy de toda esta solução pelo console da AWS. Para instalar, siga estes passos:

  1. Faça login no console do AWS CloudFormation
  2. Selecione Criar Stack.
  3. Em Choose a template (Escolher um modelo), selecione Upload a template to Amazon S3 (Fazer upload de um modelo no Amazon S3) e, depois, Choose File (Escolher arquivo).
  4. Procure o arquivo yaml
  5. Escolha Open (Abrir) e Next (Próximo).
  6. Em Specify Details (Especificar detalhes), insira um Stack name (Nome da pilha).
  7. Em Parameters (Parâmetros), insira:
    1. endereço de E-mail válido de uma pessoa ou time para aprovar as requisições;
    2. endereço de E-mail válido de uma pessoa vai administrar o pool de usuários no Cognito;
    3. endereço de E-mail válido de uma pessoa ou time ou ferramenta para receber notificações;
    4. o Organization Id que terá permissão de consulta no bucket S3 com os templates de CloudFormation.
  8. selecione Next (Próximo).
  9. Na página Options (Opções), role para baixo e selecione Next (Próximo).
  10. No Review (Revisar), escolha Reconheço que a AWS CloudFormationpode criar recursos do IAM e, depois, escolha Criar.

O AWS CloudFormation começará a criar a Stack e exibirá o status CREATE_IN_PROGRESS. Quando o processo estiver concluído, o AWS CloudFormation exibirá o status CREATE_COMPLETE.

Abra a aba Outputs (Saídas) e anote o endpoint da API do Portal que foi criado pelo script de CloudFormation, o nome do Bucket S3, o ID da distribuição do CloudFront e a URL do portal.

Figura 3: Saída (Output) de variáveis da implantação do portal.

Agora, vamos editar o arquivo App.js, localizado na pasta site/vendingmachineapp/src, alterando a linha 44 e adicionando o endpoint do output ApiGatewayInvokeURL:

API: {
       endpoints: [
           {
               name: "VendingMachine-API",
               //CHANGE HERE THE VENDING MACHINE API
               endpoint: "https://RESTAPIID.execute-api.sa-east-1.amazonaws.com/default",
               custom_header: async () => {
                  return { Authorization: `Bearer ${(await Auth.currentSession()).getIdToken().getJwtToken()}` }
               }
           }
       ]
   },

Você pode aproveitar para personalizar o Front-end. Ao finalizar as alterações, salve todos os arquivos e rode o comando abaixo para construir sua aplicação:

cd site/vendingmachineapp/
npm install
npm run build

Na sequência, remova todos os arquivos do bucket S3 do Output S3VendingMachineSiteBucket e faça o upload dos arquivos da pasta site/vendingmachine/build, para isto, ajuste o nome do bucket S3 e execute os seguintes comandos:

cd build
aws s3 rm s3://...-cloudfrontauthorizationedge-.... —recursive
aws s3 cp . s3://...cloudfrontauthorizationedge-.... —recursive

Lembre-se de invalidar os objetos na distribuição do CloudFront toda vez que atualizar os arquivos do Front-end, para isto, execute o comando abaixo alterando o ID da distribuição do CloudFront (output CloudFrontDistributionId):

aws cloudfront create-invalidation \
    --distribution-id EDFDVBD6EXAMPLE \
    --invalidation-batch file://etc/inv-batch.json

Acesse ao site do portal pelo link que está no output VendingMachineUrl e será solicitado o login, que é o e-mail informado no campo EmailCognito e a senha temporária, que foi enviada por e-mail, no momento da criação da infraestrutura.

Figura 4: Tela inicial do portal de autosserviços.

Cadastrar Produtos

Para os administradores cadastrarem novos produtos, inicialmente é necessário criar um template de CloudFormation que será utilizado na padronização e implementação serviços nas contas da organização. O arquivo samples/templates/product-workspaces.yaml é script de exemplo que implementa um desktop virtual no Amazon Workspaces, observe que isto ocorre através de um produto do AWS Service Catalog, para criar uma camada de isolamento.

Resources:
  Workspaces:
    
Type: "AWS::ServiceCatalog::CloudFormationProvisionedProduct"
    Properties:
     ProductName: "Workspace"
     ProvisioningArtifactName: "Workspace Template"

No script de CloudFormation samples/templates/ServiceCatalogBaseline.yaml, criamos alguns produtos no Service Catalog, entre eles, o Workspaces. Para implementar o catalogo de serviços nas contas da organização, execute os comandos abaixo ajustando o nome do bucket S3, regiões e o ID da organização:

aws s3 cp samples/templates/ServiceCatalogBaseline.yaml \
 s3://...-s3templates-....

aws cloudformation create-stack-set --capabilities=CAPABILITY_NAMED_IAM \
  --stack-set-name ServiceCatalogBaseline \
  --template-url https://...-s3templates-.s3.amazonaws.com/ServiceCatalogBaseline.yaml \
  --region "us-east-1" --permission-model SERVICE_MANAGED \
  --auto-deployment Enabled=true,RetainStacksOnAccountRemoval=false
  
 aws cloudformation create-stack-instances --stack-set-name ServiceCatalogBaseline \
 --region REGION_TO_RUN --deployment-targets OrganizationalUnitIds=["ou-orgid"] \
  --regions ["us-east-1", "us-east-2"] \
 --operation-preferences FailureToleranceCount=7

Uma vez que temos os templates de CloudFormation, vamos salva-los no bucket S3 criado durante a implantação da infraestrutura, o output S3VendingMachineTemplatesBucket. Este bucket foi configurado com um bucket policy para ser acessível pelas contas da organização e serão referenciados no momento de implantação das StackInstances. Salve o arquivo de template com o seguinte comando:

aws s3 cp samples/templates/product-workspaces.yaml \
 s3://...-s3templates-....

Na sequência iremos formatar um JSON com as instruções para disponibilizar os produtos no portal de Autosserviços, com nome, descrição, imagens, parâmetros, o link para o template e tags. A aplicação constrói os formulários dos produtos dinamicamente a partir do bloco Options e Tags, então é possível ter produtos com variáveis diferentes. Exemplos desta estrutura de JSON e a explicação de como construi-los estão no arquivo samples/JSON/README.md. Altere o templateUrl apontando para os arquivos que acabamos de salvar no S3:

{
  "image": "workspace.png",
  "imagecard": "workspace-card.png",
  "name": "Workspace",
  "description": "O Amazon WorkSpaces é um serviço de virtualização de desktop persistente e totalmente gerenciado",
  "stack": {
    "stacksetName": "Workspace",
    "parameters": [
      {
        "ParameterValue": "user1",
        "ParameterKey": "User"
      }
    ],
    "templateUrl": "https://XXXXX.s3-sa-east-1.amazonaws.com/products/product-workspace.yaml"   },
  "options": [...],
  "tags": [ ... ]
}

Clique no botão “Adicionar Produto” na tela principal do portal, insira o conteúdo do JSON criado no passo anterior e clique no botão “Incluir”:

Figura 5: Tela para inserir produto.

Figura 6: Resultado de um produto inserido.

Ao clicar no produto, é apresentado a tela de solicitação com os parâmetros necessários para provisionar a infraestrutura, lembre-se que é possível abstrair do usuário final parâmetros técnicos, por exemplo, ao invés de pedir detalhes de disponibilidade dos ambientes (como RTO e RPO), pode ser informado apenas a criticidade entre ALTA e BAIXA.

Quando o usuário solicitar o deploy de uma nova infraestrutura a partir de um produto, a aplicação vai gerar outro JSON com todos os detalhes necessários para o provisionamento.

Figura 7: Tela para solicitação de um produto no portal de autosserviços.

Ambos JSONs serão salvos no DynamoDB, onde temos duas tabelas, uma chamada Products. com a configuração de todos os produtos que o portal de Auto Serviços irá disponibilizar, e a outra Deploy, com informações de todos os provisionamentos que foram solicitados de cada produto.

Após salvar os dados, inicia-se um fluxo de trabalho no AWS Step Functions e o primeiro passo é a aprovação manual por e-mail da implantação do produto. Caso aprovado, o fluxo segue para o deploy da StackSet e da StackInstance usando o template de CloudFormation com as variáveis informadas no momento da solicitação.

Figura 8: Fluxo no AWS Step Functions para deploy de produtos.

Consulte este material caso você não esteja familiarizado com os conceitos de CloudFormation de StackSet e StackInstance. E neste link tem maiores informações de como criar fluxos de trabalho interagindo com os serviços da AWS com o uso do Step Functions Workflow Studio.

Conclusão

Uma vez implementada a solução de portal, os times da organização podem ter mais autonomia para provisionarem seus próprios ambientes. Já o time de operação pode focar na criação, padronização e segurança dos produtos, sem ter a necessidade de ficarem processando chamados.


Sobre o autor

Cristiano Scandura trabalha com TI há mais de 20 anos e ingressou na AWS em 2018 atuando em projetos para clientes de grande porte no setor comercial. Atualmente, é Arquiteto de Soluções no seguimento de Educação em setor público.