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-serverless-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:
- Faça login no console do AWS CloudFormation
- Selecione Criar Stack.
- 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).
- Procure o arquivo yaml
- Escolha Open (Abrir) e Next (Próximo).
- Em Specify Details (Especificar detalhes), insira um Stack name (Nome da pilha).
- Em Parameters (Parâmetros), insira:
- endereço de E-mail válido de uma pessoa ou time para aprovar as requisições;
- endereço de E-mail válido de uma pessoa vai administrar o pool de usuários no Cognito;
- endereço de E-mail válido de uma pessoa ou time ou ferramenta para receber notificações;
- o Organization Id que terá permissão de consulta no bucket S3 com os templates de CloudFormation.
- selecione Next (Próximo).
- Na página Options (Opções), role para baixo e selecione Next (Próximo).
- 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. Todos os recursos serão criados através de produtos em um portfólio do AWS Service Catalog, para criar uma camada de isolamento.
No script de CloudFormation samples/templates/ServiceCatalogBaseline.yaml, criamos um produto de Amazon Workspaces no Service Catalog. Antes de continuar é preciso editar este arquivo e alterar o nome do bucket na linha 35 do atributo LoadTemplateFromURL com o valor da chave 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.
Workspaces:
Type: "AWS::ServiceCatalog::CloudFormationProduct"
Properties:
...
Info:
# CHANGE THE S3 BUCKET HERE LoadTemplateFromURL :
"https://s3.amazonaws.com/#S3VendingMachineTemplatesBucket#/workspaces-sc-template.yaml"
Preste atenção no arquivo /samples/templates/workspaces-sc-template.yaml, é um script CloudFormation com todas as instruções para criar o produto do Amazon Workspace, você pode personalizar este arquivo para criar o VPC, adicionar TAGs, usuários, funções, chaves, etc.
Para implementar o catalogo de serviços nas contas da organização, salve os arquivos da pasta samples/templates para o bucket S3 e execute os comandos abaixo ajustando o nome do bucket S3, regiões e o ID da organização:
aws s3 cp samples/templates/* \
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
O portal de autosserviços vai usar o arquivo samples/templates/product-workspaces.yaml como script para implementar um desktop virtual solicitado por um usuário, através do produto do catalogo de serviço.
Resources:
Workspaces:
Type: "AWS::ServiceCatalog::CloudFormationProvisionedProduct"
Properties:
ProductName: "Workspace"
ProvisioningArtifactName: "Workspace Template"
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 segmento de Educação em setor público.