Arquitetura com AWS ECS, Fargate, ALB e SQS com AWS CDK

Infraestrutura como código, ou IaC, não é algo novo, mas está recebendo mais atenção da maioria dos desenvolvedores de cloud computing nos últimos anos. Se você não sabe o que é IaC, este é o conceito principal:

IaC é o processo de modelagem e provisionamento de infraestrutura em cloud computing usando linguagens de programação de alto nível.

Neste artigo, você aprenderá como criar um serviço no AWS ECS, o Elastic Container Service, com AWS Fargate, o Serverless compute for containers da AWS, usando o AWS Cloud Development Kit, ou CDK, incluindo outros recursos, como:

  • As definições de tarefas e serviços do ECS, incluindo sua CPU, memória e número de instâncias a serem usadas;
  • Como passar variáveis ​​de ambiente para a execução do serviço;
  • A definição do grupo de log do CloudWatch;
  • Como conceder permissões ao serviço para acessar outros recursos da AWS;
  • A definição do balanceador de carga da aplicação;
  • E como configurar o target group para monitorar as instâncias da aplicação.

O mais importante aqui: usando AWS CDK, não há necessidade de criar modelos YAML ou JSON do CloudFormation. Toda a infraestrutura será criada usando, adivinhe, Java!

Claro, esses modelos ainda existem, em alguma parte do processo em segundo plano do AWS CDK, mas o desenvolvedor só precisa escrever o código Java para definir a infraestrutura de serviço do AWS ECS.

Se você precisa preparar seu ambiente de desenvolvimento para usar o CDK, aqui está um bom tutorial passo a passo.

Portanto, vamos supor que já tenhamos o AWS Cluster criado em outra stack, o que, obviamente, é um parâmetro necessário para criar o serviço ECS.

Criação da stack:

Tudo começa com a definição de uma nova stack, que pode ser feita por uma nova classe que estende de Stack:

Observe que o cluster é um dos parâmetros no construtor da nova stack do serviço. Esse construtor também tem uma fila, que usaremos aqui apenas como exemplo, sobre como conceder permissão a esse novo serviço para acessar algum outro recurso da AWS.

Definindo as variáveis de ambiente:

Dentro do segundo construtor, vamos criar um mapa a ser usado como a variável de ambiente a ser passada ao nosso serviço:

Aqui, estamos definindo a região da AWS onde o serviço pertence e o nome da fila SQS, que consumirá algumas mensagens. Essa variável será usada na criação do serviço.

Parâmetros para os logs no CloudWatch:

Como mencionado antes, queremos definir alguns parâmetros de log do CloudWatch para esse novo serviço, como o nome do grupo de log. Para fazer isso, crie uma definição LogDriver:

Esse LogDriver será usado na definição de tarefa abaixo.

Aqui, estamos definindo o nome do grupo de log do CloudWatch como Service01. Dessa forma, todos os logs gerados por esse serviço estarão nesse grupo de logs. Essa é uma boa estratégia para localizar os logs de serviço no CloudWatch Insights, por exemplo.

Além disso, estamos definindo a política de remoção para DESTROY, que não preservará os logs se a stack for destruída.

Criando a definição da tarefa:

E agora a definição da tarefa, que obviamente define onde está a imagem do contêiner, deve ser criada. Para definí-la, podemos usar o construtor ApplicationLoadBalancedTaskImageOptions:

Aqui estamos definindo os seguintes parâmetros para a tarefa:

  • o nome do contêiner como aws_project01;
  • onde está a imagem Docker, que nesse caso é um dos meus repositórios no DockerHub;
  • a porta do contêiner a ser exposta;
  • o LogDriver criado acima;
  • e as variáveis ​​de ambiente a serem passadas para a aplicação, conforme mencionado acima.

Criação da definição do serviço:

Agora, vamos criar o próprio serviço. Graças aos valores padrão do CDK, podemos criar todas as coisas e, acredite, são muitos recursos a serem criados, com algumas linhas de código:

Na verdade, essa é a definição do balanceador de carga da aplicação, que inclui o serviço ECS. Aqui estamos definindo os seguintes parâmetros:

  • o nome do serviço como service-01;
  • o cluster AWS ao qual ele pertence;
  • 512 unidades de CPU a serem alocadas ao serviço;
  • 1024 MB de RAM a serem alocados ao serviço;
  • 2 instâncias desejadas do serviço;
  • a porta 8080 HTTP, para expor o serviço a receber requisições da Internet;
  • as opções de imagem da tarefa, criadas acima;
  • e, finalmente, expondo o balanceador de carga da aplicação para toda a Internet.

Definindo o mecanismo de health check do target group:

Com a variável service01 criada acima, é possível configurar o target group com os valores adequados para monitorar nossa aplicação:

Aqui, estamos configurando o mecanismo de verificação de integridade, para manter sempre as instâncias saudáveis ​​de nosso serviço em execução. Ele aponta para um endpoint especial em nossa aplicação e para a porta do contêiner.

Concedendo permissões ao serviço:

E, finalmente, podemos conceder ao nosso serviço uma permissão para acessar o SQS passado como parâmetro para esta stack:

Isso é feito fornecendo permissão de consumo para o papel da definição da tarefa.

Conclusão:

O AWS Cloud Development Kit é definitivamente uma boa maneira de modelar recursos complexos da AWS, como um serviço ECS. Com algumas linhas de código é possível criá-lo, graças aos valores padrões do AWS CDK.

Eu diria que, para criar uma infraestrutura como essa, é necessário um enorme arquivo template do CloudFormation, talvez com mais de 500 linhas de código. Na verdade, existe uma pasta chamada cdk.out dentro do projeto CDK, onde todos esses arquivos são gerados, durante o processo de implantação, portanto, é fácil comparar com o código Java criado aqui.

Referência:

Esse artigo foi baseado nos conceitos ministrados nesse curso online: Curso criando serviços em Java com AWS ECS e Fargate

Quem sou eu:

  • Trabalhei diariamente com as tecnologias apresentadas nesse blog por quase 3 anos, atuando como desenvolvedor de soluções hospedadas na AWS;
  • Tenho lecionado disciplinas de cloud computing, principalmente AWS, em curso de pós-graduação há quase 10 anos;
  • Tenho livros publicados sobre o assunto;
  • Faço parte da comunidade global AWS Community Builder 2020/2021, criada pela própria AWS.