DEV Community

Cover image for AWS Elastic Beanstalk + Go
Odilon Jonathan Kröger
Odilon Jonathan Kröger

Posted on

AWS Elastic Beanstalk + Go

Foto de capa: Gelgas Airlangga

Vamos lá para um pequeno tutorial ensinando o passo-a-passo de como subir uma aplicação Go no serviço Elastic Beanstalk da AWS.
Vou utilizar o AWS CLI porque acho legal para a pessoa que está iniciando saber exatamente todas as coisas que acontecem. Até porque se você em algum momento quiser utilizar Terraform, já tem uma boa idéia do que você vai precisar utilizar da AWS.

Antes de começarmos a ver código e comandos, quero pontuar aqui algumas coisas:

  • Estou escrevendo este tutorial considerando que você já tem uma conta na aws. Para resumir, aqui não estou ensinando a criar uma conta.
  • Também considero que você já tem instalado o AWS CLI. Se não tiver, basta seguir a documentação oficial em português que não tem mistério.
  • Por fim considero que você está ciente que a execução destes serviços na AWS podem resultar em custos. No meu caso, só para rodar os comandos desse tutorial para validar que está tudo funcionando me custou U$0.10 e eu terminei tudo logo em seguida para não gerar mais custos.

Hoje a trilha sonora é Anti-Flag - Turncoat.


Escrevendo a aplicação para usar de exemplo

O código do exemplo é uma coisa bastante simples, apenas 2 endpoints: um de health check e outro para hello world.
Vamos criar um arquivo chamado application.go e escrever o código abaixo.

package main

import (
    "fmt"
    "net/http"
)

func main() {
    fmt.Println("Hello World")
    http.HandleFunc("/hello-world", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello world!")
    })
    http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "OK")
    })
    _ = http.ListenAndServe(":5000", nil)
}
Enter fullscreen mode Exit fullscreen mode

Caso você ainda não conheça muito de Go, o código dentro da função main está mapeando 2 endereços, no caso /hello-world e /health. As linhas com fmt.Fprintf são responsáveis pela mensagem que será exibida na tela.
Logo depois do mapeamento estamos dizendo que a aplicação vai ficar ouvindo a porta 5000.

Atençãããão!!! Tem alguns detalhes até aqui.

Por que o arquivo se chama application.go e não maldicao.go?

A documentação da AWS diz que existem algumas formas de fazer deploy da aplicação.
A que eu escolhi para este exemplo eu achei ser a mais simples de todas, que é dar o nome de application.go para o arquivo principal. Isso porque quando o Elastic Beanstalk for construir ("buildar") a aplicação, ele vai rodar por padrão esse comando aqui: go build -o bin/application application.go, ou seja, o Elastic Beanstalk já ta lá esperando encontrar esse arquivo com esse nome.

E a porta, por que é 5000 e não 8123?

Mesma situação que o nome do arquivo. Por padrão o Elastic Beanstalk inicia a aplicação na porta 5000.

Clique aqui caso queira ler a documentação oficial da AWS sobre isso que expliquei acima.
Aliás, eu recomendo pare para ler a documentação sempre que estiver estudando algo. Ás vezes a pessoa que está escrevendo o tutorial, tipo eu agora, acaba deixando algo passar, ou entendeu algo errado ou ainda o tutorial pode estar desatualizado, então crie o hábito de validar na documentação. Isso vai agregar um conhecimento legal para você! :)

Ah, antes de irmos para os comandos AWS CLI, também vamos precisar criar um arquivo chamado options.json. Ele é necessário para informar qual profile IAM nossa aplicação vai utilizar. Se você não sabe o que é IAM, não se preocupe, isto é assunto para outro tutorial.
Coloque isto dentro do arquivo:

[
  {
      "Namespace": "aws:autoscaling:launchconfiguration",
      "OptionName": "IamInstanceProfile",
      "Value": "aws-elasticbeanstalk-ec2-role"
  }
]
Enter fullscreen mode Exit fullscreen mode

Utilizando Elastic Beanstalk

Beleza! Código feito, vamos para a parte tão aguardada: como fazer deploy desse código no Elastic Beanstalk.

Passo 1: gerar um .zip com o nosso código fonte. Este .zip será enviado para a AWS e pode ter o nome que você preferir.
No caso do meu exemplo eu só tenho dois arquivos para colocar no .zip: application.go e go.mod.

No terminal, navege até a raiz do projeto e execute:

zip -r application.zip .
Enter fullscreen mode Exit fullscreen mode

Passo 2: criar um S3 Bucket para enviar o arquivo .zip. Você pode criar com o nome que você quiser, eu fiz uma mistura de nome legível + o final de um UUID que gerei no Google e ficou assim: beanstalk-app-660390121deb.
O comando para criar o Bucket:

aws s3api create-bucket --bucket beanstalk-app-660390121deb --create-bucket-configuration LocationConstraint=us-west-2
Enter fullscreen mode Exit fullscreen mode

No caso --bucket serve para dizer qual é o nome desejado. Caso você esteja utilizando alguma região diferente de us-east-1, é necessário também adicionar o --create-bucket-configuration LocationConstraint=AQUI_A_SUA_REGIAO para indicar a região correta.

Passo 3: enviar o .zip para o Bucket.
Esse passo é muito fácil, só executar aí:

aws s3 cp application.zip s3://beanstalk-app-660390121deb/
Enter fullscreen mode Exit fullscreen mode

Passo 4: chegou a hora de criar uma aplicação dentro do Elastic Beanstalk. Esse passo também é bastante simples:

aws elasticbeanstalk create-application --application-name minha-app-muito-legal --region us-west-2
Enter fullscreen mode Exit fullscreen mode

Passo 5: criar uma versão da aplicação no Elastic Beanstalk, apontando para o arquivo .zip no S3 Bucket.
Na real, isso significa que você está falando que a v1 por exemplo, utiliza o arquivo minha_app_v1.zip por exemplo. Aí depois se você for mexer no seu código e quiser subir uma v2, você poderia subir no Bucket um arquivo minha_app_v2.zip e fazer esse "link" com este comando aqui gerando uma v2, só precisaria alterar aqui no comando o parâmetro passado em --version-label.
O comando para criar a versão v1:

aws elasticbeanstalk create-application-version --application-name minha-app-muito-legal --version-label v1 --source-bundle S3Bucket=beanstalk-app-660390121deb,S3Key=application.zip
Enter fullscreen mode Exit fullscreen mode

Passo 6: chegou a hora de criar um environment no Elastic Beanstalk. O comando é:

aws elasticbeanstalk create-environment --application-name minha-app-muito-legal --environment-name staging --option-settings file://options.json --version-label v1 --solution-stack-name "64bit Amazon Linux 2 v3.1.4 running Go 1"
Enter fullscreen mode Exit fullscreen mode

Explicando melhor: estamos passando por parâmetro o nome da aplicação que estamos ligando neste novo environment. No --application-name eu digo qual é a aplicação que eu quero rodar, no --environment-name eu posso colocar o nome que eu quiser para o meu ambiente, no caso chamei de staging. Agora o --solution-stack-name é que requer um pouco mais de atenção. Este é o nome da stack que será utilizada no ambiente e deve ter um valor conhecido pelo Elastic Beanstalk. Você pode encontrar todas as opções disponíveis nesta documentação. Basta clicar na linguagem que você tiver curiosidade que a doc vai mostrar as opções válidas.
Aqui também foi utilizado o arquivo options.json que criamos anteriormente e passamos no comando --version-label v1 para dizer que o ambiente vai utilizar aquela versão que criamos no Passo 5. Se você deu um nome diferente de v1, vai precisar alterar aqui também.

PRONTO! Agora você já tem a aplicação rodando no Elastic Beanstalk.
Para o deploy acontecer (ou terminar os serviços), ás vezes demora um pouco. Você pode conferir o status pelo terminal com o comando abaixo:

aws elasticbeanstalk describe-environments
Enter fullscreen mode Exit fullscreen mode

Ou se preferir, basta acessar o serviço Elastic Beanstalk no Console da AWS.

Na imagem abaixo que mostra o Console da AWS, fica fácil de obter diversas informações.
Console da AWS mostrando Elastic Beanstalk

Quando health mudar para OK, sabemos que acabou o deploy e podemos testar a aplicação.
Já na coluna URL temos o endereço da aplicação que vamos usar para testar.

Assim que a coluna health ficar OK (talvez seja necessário recarregar a página), você já pode testar. É só copiar a URL ali da tabela e adicionar no final /health ou /hello-world que são os 2 endpoints disponíveis na aplicação.

Se deu tudo certo, você vai ver algo parecido com a imagem a seguir:
Browser com tela mostrando Hello world!

Agora digamos que você queira adicionar um novo endpoint, ou remover. Vai precisar criar uma nova versão. Para isso você vai precisar repetir o Passo 1, criando um novo arquivo .zip, em seguida vai precisar executar o Passo 3 para enviar esse arquivo para o S3 Bucket. Em seguida vai precisar executar novamente o Passo 5 alterando o nome da versão no --version-label. E finalmente será necessário fazer a atualização da versão no environment com o comando abaixo, alterando --version-label para a versão desejada:

aws elasticbeanstalk update-environment --application-name minha-app-muito-legal --environment-name staging --version-label v2
Enter fullscreen mode Exit fullscreen mode

NAO ESQUEÇA DE TERMINAR A APLICAÇÃO!

Para evitar custos desnecessários, nunca esqueça de parar suas aplicações na AWS.
No nosso caso podemos fazer isso da seguinte forma para remover o environment:

aws elasticbeanstalk terminate-environment --environment-name staging
Enter fullscreen mode Exit fullscreen mode

Agora vamos remover a aplicação do Elastic Beanstalk:

aws elasticbeanstalk delete-application --application-name minha-app-muito-legal
Enter fullscreen mode Exit fullscreen mode

E por fim para remover o S3 Bucket:

aws s3 rb s3://beanstalk-app-660390121deb --force
Enter fullscreen mode Exit fullscreen mode

Nesse caso é necessário utilizar --force para remover o Bucket e deletar os arquivos existentes. Sem este parâmetro é necessário primeiro esvaziar o Bucket para depois remover ele.


The horns

Agora você já conhece todos comandos necessários para realizar o deploy utilizando AWS CLI.
Este foi um exemplo bastante simples. Agora você pode expandir conforme a necessidade, adicionando na aplicação um banco de dados ou fila SQS, por exemplo.

Outra possibilidade de continuação dos estudos seria transformar todos estes comandos em "receitinhas" no Terraform.

Espero que você tenha curtido essa experiência! Tudo de bom para você! :)

Top comments (1)

Collapse
 
renatosuero profile image
Renato Suero

muito massa o posto, gosto muito da forma que passa a informação :) obrigado por compartilhar