Como publicar uma aplicação Web usando AWS

Gravatar publicou em

Programação Tutoriais

Este artigo foi escrito para o minicurso de Infraestrutura em nuvem com Amazon Web Services, realizado durante a SEnEC 2014, na Poli-USP.

Introdução

Este tutorial irá guiá-lo pelos passos envolvidos na publicação de uma aplicação Web utilizando componentes de infraestrutura da AWS (Amazon Web Services).

Serão utilizados componentes básicos para publicar uma aplicação Web simples mas escalável. Estes componentes, descritos brevemente no primeiro dia do minicurso, são:

  • EC2 (Elastic Compute Cloud): servidores virtuais
  • RDS (Relational Database Service): banco de dados
  • S3 (Simple Storage Service): armazenamento de arquivos
  • ELB (Elastic Load Balancing): balanceador de carga
  • Auto Scaling: escalabilidade automática

Antes de começarmos a falar dos detalhes, é importante que você tenha em mente qual é o objetivo desta atividade e quais são os passos, definidos em linhas gerais, que precisaremos executar para alcançá-lo.

Em primeiro lugar, é necessário conhecer a aplicação que será publicada. Ela pode ser acessada aqui: http://senec-demo.infosimples.com.br/.

É uma aplicação muito simples, cuja principal funcionalidade é permitir o upload (envio) de arquivos associados a um nome.

Dada a aplicação, o nosso objetivo é colocá-la no ar usando a seguinte arquitetura:

Para entender esta arquitetura e os componentes envolvidos, imagine a sequência de interações que acontece quando o usuário realiza alguma ação no site, enviando uma nova imagem, por exemplo:

  1. O usuário, ao clicar no botão de upload, sinaliza que deseja enviar uma requisição, contendo um arquivo de imagem, para o endereço  http://senec-demo.infosimples.com.br/.
  2. Uma vez que, na Internet, os computadores são encontrados pelo seu endereço IP, o navegador precisa encontrar o endereço IP correspondente ao host senec-demo.infosimples.com. Essa tradução é possibilitada pelo serviço de DNS da AWS, chamado Route 53.
  3. De posse do endereço IP, o navegador envia uma requisição para, por exemplo, o endereço 54.88.103.207, que é o endereço do primeiro componente: o balanceador de carga (ELB).
  4. O ELB recebe a requisição e, usando um algoritmo interno, decide para qual instância EC2 encaminhar esta requisição.
  5. A instância EC2 designada pelo ELB recebe a requisição de upload de imagem e envia o arquivo que foi recebido para o S3 (serviço de armazenamento), onde este será guardado em um repositório, ou bucket. Além disso, a aplicação armazena no banco de dados (RDS) a informação de que aquele arquivo possui um nome específico, fornecido pelo usuário.
  6. Após a requisição ter sido processada com sucesso pelo servidor, este envia uma resposta para o navegador, que exibirá, por exemplo, uma mensagem de sucesso.

Ok – agora que já está claro o que estamos tentando alcançar, mãos à obra!

1. Acesso a uma conta da AWS

O primeiro passo para fazer qualquer coisa na AWS é, claro, ter um cadastro ativo. Para este minicurso, você tem a opção de criar e utilizar a sua própria conta da AWS ou usar uma conta temporária criada pela Infosimples.

As duas formas de acesso estão descritas a seguir.

1.1 Criação da sua própria conta

  1. Acesse http://aws.amazon.com/, faça o cadastro e ativação por telefone;
  2. Faça o login em https://console.aws.amazon.com.

1.2 Utilização de conta temporária

  1. Fale com um instrutor para obter as suas credenciais;
  2. Faça o login em https://console.aws.amazon.com.

Os passos seguintes assumem que você está logado no painel da AWS e com uma conta 100% funcional.

2. Configuração do S3

Este passo envolve a configuração do S3, componente de armazenamento de arquivos. É necessário criar o repositório (bucket) onde ficarão os arquivos e criar chaves de acesso para que os servidores tenham permissão de escrita no bucket.

2.1. Criação do bucket

Crie um bucket no S3 com o nome senec-demo-{SEU-NÚMERO-USP} (exemplo: senec-demo-5950333).

Clique aqui para ver o vídeo com o passo-a-passo.

2.2. Criação das chaves de acesso

Obervando novamente o diagrama de arquitetura, podemos perceber que as instâncias EC2, que receberão requisições dos usuários, precisarão ter acesso ao S3 para enviar os arquivos que serão armazenados. Para habilitar este acesso, será necessária a criação de Security Credentials, que, na prática são duas strings: uma Access Key ID e uma Secret Access Key.

Clique aqui para ver o vídeo com o passo-a-passo.

Observação: ao longo da criação das credenciais, você verá que esta forma de acesso não é recomendada pela Amazon, por ser uma opção menos segura do que o uso de outra solução, IAM Users & Roles. No entanto, esta foi a solução adotada para simplificar o tutorial.

3. Criação de Security Groups

Por questões de segurança, o ideal é que, em uma infraestrutura de produção, o acesso a qualquer máquina seja o mais restrito possível, limitando-se ao essencial para que a máquina possa exercer sua função.

Na AWS, a restrição de acesso é implementada usando grupos de segurança (Security Groups). Cada grupo de segurança possui regras de acesso de entrada e saída de dados (Inbound & Outbound Rules) e qualquer máquina incluída em um grupo de segurança estará sujeita às regras do grupo.

Sabendo disso, e revendo a arquitetura que está sendo construída, percebemos que é possível dividir as máquinas em 3 grupos de segurança:

  1. Security Group 1 (senec-application): neste grupo ficarão as instâncias EC2 do grupo de Auto Scaling. O acesso a estas instâncias deve ser limitado a: a) receber requições HTTP e b) permitir login remoto via SSH.
  2. Security Group 2 (senec-rds): neste grupo ficarão as instâncias RDS (banco de dados). O único acesso necessário é ao servidor de banco de dados MySQL, que, por padrão, recebe conexões TCP na porta 3306.
  3. Security Group 3 (senec-elb): neste grupo ficará a instância do balanceador de carga (ELB). O único acesso necessário é para receber requisições HTTP na porta 80, que é onde chegarão as requisições enviadas pelos navegadores que se conectarem à aplicação.

Veja o vídeo que mostra como criar estes Security Groups, considerando as regras de acesso definidas acima.

4. Criação da instância RDS (banco de dados)

Para o servidor de banco de dados, vamos utilizar o serviço RDS (Relational Database Service), que permite a criação e configuração de máquinas cuja única função é ter uma instalação do MySQL acessível.

MySQL é um sistema de gerenciamento de banco de dados (SGBD) de código aberto, e é uma das soluções de bancos de dados relacionais mais utilizadas no mundo.

Veja o vídeo que mostra como criar a instância RDS para a nossa aplicação.

5. Criação da instância EC2

Com os componentes de banco de dados e armazenamento já estão criados, o próximo passo é criar o componente que irá utilizá-los: os servidores Web.

Nesta etapa, iremos criar e testar o funcionamento de uma máquina virtual (instância EC2) cuja função será executar um servidor Web, responsável por atender às requisições enviadas pelo ELB ou diretamente pela Internet.

5.1 Geração de um Key Pair para acesso remoto (SSH)

O primeiro passo, antes de iniciar qualquer instância EC2 na AWS, é ter um Key Pair (literalmente, um par de chaves de acesso) que será usado para fazer login remoto na instância, que é simplesmente um servidor Linux. 

Para criar seu Key Pair, siga os passos abaixo ou veja o vídeo.

  1. Acesse o painel EC2;
  2. Clique em Key Pairs (sob Network & Security);
  3. Clique em Create Key Pair, dê o nome de ec2-senec e clique em "Create".
  4. Salve o arquivo gerado (ec2-senec.pem).

5.2 Criação de uma máquina virtual

Toda máquina virtual (ou instância EC2) da AWS é criada a partir de uma imagem, que, no ecossistema AWS, chama-se AMI (Amazon Machine Image). Esta imagem contém softwares básicos já instalados. Você pode usar desde uma AMI disponibilizada pela Amazon, que vem com uma configuração mínima (basicamente, apenas o sistema operacional instalado), até AMI preparada por você, que já tem todos os requisitos para rodar a sua aplicação.

No nosso caso, a abordagem será usar uma AMI da Amazon para construir a nossa própria AMI, que, ao final, terá todos os requisitos necessários para executar a aplicação.

Para começar, vamos iniciar uma instância EC2 a partir da AMI de Ubuntu Server da Amazon.

Para fazer isso, siga os passos abaixo ou veja o vídeo.

No painel EC2, clique em "Launch Instance", e na sequência que será apresentada, escolha as seguintes opções:

  • Step 1 (AMI): Ubuntu Server 14.04 LTS (HVM), SSD Volume Type (ami-864d84ee)
  • Step 2 (Instance Type): t2.micro
  • Step 3 (Instance Details): não alterar nenhum valor
  • Step 4 (Storage): não alterar, manter 8 GiB de General Purpose SSD.
  • Step 5 (Tag Instance): preencher o campo "Value" com "Base Instance"
  • Step 6 (Security Group): escolha "Select an existing security group" e selecione o grupo previamente criado, senec-application.
  • Step 7 (Review Instance Launch): clique em Launch.
    •  Selecione "Choose an existing key pair" e, em seguida, o key pair criado anteriormente (ec2-senec).

Após alguns instantes, a sua instância estará disponível para uso e aparecerá no painel de instâncias.

5.3 Preparação da instância (configuração e instalação de softwares)

Esta etapa envolve a execução de uma série de comandos para:

  1. Instalar softwares básicos e fazer configurações globais; e
  2. Baixar o código da aplicação e realizar configurações específicas para o projeto. 

Estes comando devem ser executados na própria instância, o que significa que, antes de começar, você precisará conectar-se remotamente, via SSH, à instância recém-criada, usando o Key Pair criado no item 5.1.

Para isso, abra um terminal (no Linux) ou uma nova janela do Git Bash (no Windows) e execute:

ssh ubuntu@{IP_DA_INSTÂNCIA} -i {CAMINHO-ATÉ-EC2-SENEC.PEM}

Ou seja, algo como:

ssh ubuntu@54.88.103.207 -i ~/.ssh/keys/ec2-senec.pem

No comando acima, você vai precisar do IP que a Amazon atribuiu à sua instância. Para obtê-lo, veja o vídeo.

Após conectar-se à instância, você precisará executar, nesta ordem:

  1. Os comando descritos no arquivo 01-setup.sh, disponível aqui.
  2. Os comandos descritos no arquivo 02-pplication-setup.sh, disponível aqui.

5.4 Teste da instância

Após a etapa acima, a sua aplicação já estará no ar e funcionando. Para confirmar, acesse o endereço IP da instância pelo seu navegador e verifique se a aplicação está funcionando corretamente.

5.5 Criação de uma AMI a partir da instância-base

Neste passo, será criada uma imagem da máquina que, agora, já está totalmente pronta para executar a aplicação e ser usada como imagem-base para as instâncias do grupo de Auto Scaling.

Para criar uma AMI a partir desta instância, acesse o painel de instâncias e:

  • Selecione a instância;
  • Clique em "Actions" > "Create Image";
  • Dê o nome de senec-demo-{ano}{mês}{dia}-{hora} (exemplo: senec-demo-20140924-1433).
  • Clique em "Create Image".

Dentro de alguns instantes, a AMI estará pronta para ser usada. Enquanto isso, você pode continuar executando os próximos passos.

6. Criação do balanceador de carga (ELB)

O balanceador de carga da AWS é uma instância EC2 que possui um propósito específico: encaminhar requisições que chegam até ele para um determinado grupo de instâncias.

Balanceadores de carga são muito utilizados em aplicações que precisam escalar de forma dinâmica, porque os usuários precisam conhecer apenas um endereço IP (o endereço do balanceador de carga), e este se encarrega de repassar todas as requisições que chegam para um grupo de máquinas (que pode ter 2 ou 20 máquinas, dependendo do tráfego da sua aplicação), usando um algoritmo para distribuir, da melhor maneira possível, a carga entre as máquinas disponíveis.

O balanceador deve ser criado com as seguintes configurações:

  • Name: senec-web-elb
  • Listeners:
    • HTTP / 80 -> HTTP / 80
  • Health Check:
    • Ping Protocol: HTTP
    • Ping Port: 80
    • Ping Path: /ping
    • Response Timeout: 5
    • Health Check Interval: 30
    • Unhealthy Threashold: 4
    • Healthy Threashold: 4
  • Security Group: senec-elb
  • EC2 instances: não adicionar nenhuma instância (serão adicionadas pelo grupo de Auto Scaling).

O vídeo mostrando com o passo-a-passo está disponível aqui.

7. Configuração do Auto Scaling

Este é o último passo para a configuração do ambiente escalável que estamos construindo. O serviço de Auto Scaling da AWS permite que novas instâncias sejam criadas ou destruídas automaticamente, de acordo com parâmetros definidos na configuração do grupo de Auto Scaling.

Para entender o uso do Auto Scaling, imagine uma aplicação como o Facebook, que esteja disponível apenas no Brasil. É de se imaginar que, durante a madrugada, existe um tráfego muito baixo e mais ou menos constante de usuários. Por outro lado, durante a hora do almoço e no início da noite, podemos supor que haverá um pico de acessos, o que significa que mais servidores (instâncias EC2) deverão estar disponíveis para atender as requisições que chegarem.

Idealmente, gostaríamos que a infraestrutura fosse "auto-gerenciável", isto é, não queremos ter que, todo dia, ligar máquinas na hora do almoço, delsligar máquinas após o almoço, ligá-las novamente no final da tarde, etc... Já deu para perceber que seria um trabalho grande, que pode ser automatizado com o uso do Auto Scaling. Além disso, se surgirem picos de tráfego que não estão previstos (por exemplo, um meme que ficou viral muito rapidamente!), o Auto Scaling também dará conta de atender aos usuários.

A configuração do Auto Scaling acontece em dois passos:

  1. Criação de uma Launch Configuration (que define como serão criadas novas instâncias); e
  2. Criação do Auto Scaling Group (que define quando instâncias serão criadas ou encerradas).

Estes passos estão descritos a seguir.

7.1 Criação da Launch Configuration

A criação de uma Launch Configuration é muito parecida com a criação de uma nova instância EC2, justamente porque o objetivo é "ensinar" o Auto Scaling a criar novas instâncias da forma que você as criaria manualmente.

Serão usadas as seguintes configurações:

  • Step 1 (AMI): escolha a AMI criada por você;
  • Step 2 (Instance Type): t2.micro;
  • Step 3 (Details):
    • Name: asg-lc-senec-[region]-[year]-[month]-[day]. Exemplo: asg-lc-senec-us-east-1-2014-09-24.
    • Monitoring: selecionar "Enable CloudWatch detailed monitoring".
    • Em "Advanced Details":
      • User data: colar o conteúdo do arquivo 04-auto-scaling-user-data.sh.
      • IP Address Type: selecionar "Assign a public IP address to every instance.".
  • Step 4 (Storage): manter o valor padrão de 8 GB de General Purpose SSD;
  • Step 5 (Security Group): escolher o grupo existente senec-application;
  • Step 6 (Review): clicar em "Create launch configuration" e escolher o key pair ec2-senec (criado anteriormente).

Você pode acompanhar a executar destes passos no vídeo, aqui.

7.3 Criação de alarmes do ELB

A AWS permite o monitoramento da maioria dos recursos utilizados. Dependendo do recurso, são disponibilizadas métricas diferentes, que fazem sentido para o recurso que está sendo monitorado.

No caso de balanceadores de carga (ELBs), é possível monitorar métricas como: número de requisições, número de requisições com sucesso ou com erro, latência média das requisições, etc. Estas são métricas adequadas porque o ELB é um recurso que lida, basicamente, com o encaminhamento de requisições.

Além disso, é possível criar alarmes que usam estas métricas e, com base nestes alarmes, é possível tomar alguma ação (automática ou manual). Neste exemplo, vamos usar alarmes do ELB para iniciar ou encerrar novas instâncias no grupo de Auto Scaling. Serão necessários apenas dois alarmes:

  • O primeiro, denominado awselb-senec-web-elb-High-Sum-Requests, será disparado quando houver muitas requisições em um período curto de tempo, sinalizando para o Auto Scaling que é necessário iniciar novas máquinas.
  • O segundo, denominado awselb-senec-web-elb-Low-Sum-Requests, será disparado quando houver poucas requisições, sinalizando para o Auto Scaling que é necessário terminar algumas máquinas, para evitar desperdício de recursos.

Veja o vídeo do passo-a-passo para a criação destes alarmes.

7.4 Criação do Auto Scaling Group (ASG)

O próximo passo é criar um grupo de Auto Scaling usando a Launch Configuration criada no passo anterior, usando as seguintes especificações:

  • Step 1 (Auto Scaling group details):
    • Launch Configuration: selecionar a LC criada anteriormente.
    • Group Name: asg-senec-web
    • Group Size: 1 instances
    • Subnet: selecionar todas as subnets disponíveis, uma por vez.
    • Em "Advanced Details":
      • Load Balancing: selecionar "Receive traffic from Elastic Load Balancer(s)" e inserir o nome do ELB criado anteriormente (senec-web-elb)
      • Health Check Type: ELB
      • Health Check Grace Period: 180
      • Selecionar "Enable CloudWatch detailed monitoring"
  • Step 2 (Scaling policies):
    • Selecionar "Use scaling policies to adjust the capacity of this group"
    • Scale between 1 and 5 instances;
    • Em "Increase Group":
      • Execute policy when: selecionar o alarme awselb-senec-web-elb-High-Sum-Requests
      • Action: Add 1 instance
    • Em "Decrease Group":
      • Execute policy when: selecionar o alarme awselb-senec-web-elb-Low-Sum-Requests
      • Action: Remove 1 instance
  • Step 3 (Notifications): não criar notificações
  • Step 4 (Tags): adicionar a seguinte tag:
    • Key: ASG
    • Value: ASG SEnEC Web
    • Selecionar "Tag New Instances"

Você também pode executar os passos acompanhando o vídeo, aqui.

Ao final destes passos, você poderá ver, no painel de instâncias, que uma nova máquina está sendo iniciada, porque o tamanho mínimo definido para este grupo foi 1.

O Auto Scaling sempre manterá o número de instâncias do grupo dentro dos valores máximo e mínimo especificados. O valor real, denominado "desired", ficará entre o máximo e o mínimo, de acordo com os alarmes que forem disparados.

8. Teste da infraestrutura

Após a execução dos passos acima, a aplicação Web já estará disponível e acessível através do endereço do ELB, que será algo parecido com http://senec-web-elb-2078541719.us-west-2.elb.amazonaws.com. Este endereço pode ser obtido de maneira similar ao que foi feito para obter o endereço IP de uma instância (veja aqui).

Além de verificar que a aplicação está funcionando, podemos realizar testes de carga, para verificar se os alarmes do ELB serão disparados e novas instâncias serão iniciadas e terminadas conforme a demanda.

Para estes testes, você pode usar o script 05-stress-test.sh, disponível aqui, da seguinte forma:

  1. Crie um arquivo, no seu computador, com o conteúdo deste script.
  2. Abra uma janela do terminal (no Linux) ou do Git Bash (no Windows) e execute os seguintes comandos:
# Tornar o arquivo executável
chmod u+x {CAMINHO-ATÉ-O-ARQUIVO}

# Executar o script 
{CAMINHO-ATÉ-O-ARQUIVO}

Por exemplo:

# Tornar o arquivo executável
chmod u+x ~/Dev/senec/stress-test.sh

# Executar o script.
~/Dev/senec/stress-test.sh

Este script é um loop infinito que fica enviando requisições para a página inicial da aplicação. Deixe o script rodando por alguns minutos para observar a criação de novas instâncias.

Em seguida, pare o script (Ctrl+C) e aguarde alguns minutos para observar o Auto Scaling encerrando algumas instâncias, até que o ambiente volte ao estado inicial (apenas 1 instância).

9. Conclusão

Parabéns! Se você chegou até aqui, é porque conseguiu publicar, com sucesso, uma aplicação Web na Amazon Web Services e, além disso, com uma infraestrutura muito escalável para aguentar os milhões de usuários da sua aplicação ;)

Pensando em um cenário real, uma das vantagens de utilizar a AWS é que, conforme uma aplicação evolui e ganha novas funcionalidades, outros componentes da AWS podem ser adicionados e operar em conjunto; mas isso é algo que ficará para futuros tutoriais!





Leia mais sobre: