Gerando relatório de Rightsizing de Instâncias via Lambda
Tags: aws, python, lambda, ptbr
Published: 2023-01-29 12:40:44

## Introdução

Ainda na pegada de otimização de custos na AWS, este post complementa o [post anterior](https://dev.to/isaque21/gerando-relatorio-de-precos-de-reservas-de-instancias-via-lambda-4mjn) onde geramos um relatório de preços de reservas das instâncias do seu ambiente através de um script em Python executado via Lambda. 

Neste post utilizaremos a mesma abordagem, porém com o script um pouco mais “turbinado”, onde adicionamos alguns recursos do AWS Compute Optimizer na jogada. 

Com isso, será gerado um outro relatório com recomendações de rightsizing para suas instâncias EC2 juntamente com os preços sob demanda e de reservas como no relatório anterior. O relatório traz também uma comparação de utilização de CPU e memória da família atual com uma estimativa de uso da família recomendada pelo Compute Optimizer.

## O AWS Compute Optimizer

O AWS Compute Optimizer ajuda você a evitar o provisionamento excessivo ou insuficiente de alguns recursos da AWS. Acesse a documentação [neste link](https://aws.amazon.com/pt/compute-optimizer/) para saber mais.

Alguns casos de uso do AWS Compute Optimizer:

- Avalie as oportunidades estimadas de economia e melhoria de performance no nível da conta para recursos do Amazon EC2, Amazon EBS e AWS Lambda.
- Obtenha recomendações aprimoradas para otimizar instâncias do EC2 e grupos do Auto Scaling usando três meses de dados históricos.
- Encontre as workloads do EC2 que fornecerão o maior retorno pelo menor esforço de migração em uma mudança para CPUs AWS Graviton.
- Aumente a economia e o reconhecimento da performance configurando métricas de terceiros a partir de suas ferramentas de Monitoramento de performance de aplicações (APM).

É importante ressaltar que a opção padrão do Compute Optimizer analisa as métricas do Amazon CloudWatch durante os últimos 14 dias para fornecer recomendações. Caso você queira estender esse período por até 3 meses, é necessário ativar as métricas de infraestrutura avançadas do Compute Optimizer, que é um recurso pago. Entenda a definição de preços [aqui](https://aws.amazon.com/pt/compute-optimizer/pricing/).

## Bora pro trampo!

**1 - Criar bucket**

O primeiro ponto será a criação do nosso bucket onde ficarão os arquivos que serão gerados pelo script.

Acesse o console do Amazon S3 e clique em Create bucket. Dê um nome para seu bucket e escolha a região de sua preferência. Deixe o restante das opções como padrão e clique em Create bucket.


![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p9jpevuktav13risxd3g.png)

O nome do bucket é globalmente exclusivo, portanto use um nome diferente do meu e anote. Vamos usar esse nome na política que criaremos na próxima etapa.

**2 - Criar uma função do IAM**

No console do IAM, clique em Policies no menu lateral esquerdo e depois em Create policy. Clique na guia JSON e substitua o código JSON por este:

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::ec2-recommendations-reports/*"
        }
    ]
}

```

Substitua o nome do bucket na linha `"Resource": "arn:aws:s3:::ec2-recommendations-reports/*"` pelo nome do bucket que você criou anteriormente. Avance para a parte de Review para dar um nome à sua Policy e depois clique em Create Policy.

Vamos então criar uma Role e atachar a Policy criada junto com outras necessárias para o funcionamento do script. Clique em Roles no menu lateral esquerdo e depois em Create Role.  Em Trusted entity type escolha AWS service, marque o serviço Lambda e avance para atachar as policies necessárias. 

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4tos0mfzpn5zsu4t4csc.png)

Em Add permissions pesquise pela policy que você criou anteriormente e marque a caixa ao lado do nome para selecioná-la. Faça o mesmo processo para as seguintes policies:

- AWSPriceListServiceFullAccess
- ComputeOptimizerReadOnlyAccess
- AmazonEC2ReadOnlyAccess
- AmazonSSMReadOnlyAccess
- AWSLambdaBasicExecutionRole

Avance para escolher um nome para sua Role e revise as Policies atachadas.

**3 - Criar função Lambda**

Acesse o console do Lambda e clique em Create function. Escolha a opção Author from scratch para iniciar com um exemplo de código. Dê um nome para sua Função Lambda e escolha o Runtime Python 3.9 ou superior.


![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rwnuq09zso5210hcx0cf.png)

Em Change default execution role escolha Use an existing role e selecione a Role que você criou no passo anterior. Feito isso clique em Create function.


![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jiacy5rhiu5x4iyid36o.png)

Agora que você criou a Função, substitua o código de exemplo pelo código que está [neste repositório](https://github.com/isaque21/lambda/blob/main/get-recommendations/lambda_function.py). Após inserir o código, clique em Deploy para Salvar as alterações.

Feito isso, vá para a aba Configuration e mude o Timeout para 2 minutos (configure um tempo maior ou menor de acordo com a quantidade de instâncias do ambiente).

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhxq2kl0ycz80ausvymj.png)

Vá para a aba Test para configurar um novo teste. Dê um nome ao evento e clique em Save.

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5gje5dbmjhfviahzw7l3.png)

**4 - Configuração do script**

Volte para a aba Code. Vamos analisar algumas linhas do código que precisam ser alteradas:

**Região dos recursos na AWS**

Escolha as regiões onde suas instâncias estão. O script verifica todas instâncias EC2 nas regiões setadas na variável `AWS_REGIONS` e adiciona todas no mesmo arquivo csv.

```
# Define AWS Region
AWS_REGIONS = ['us-east-1', 'sa-east-1']
```
**Região do endpoint da API de preços**

Conforme dito anteriormente, a API de preços da AWS fornece dois endpoints com duas regiões diferentes. Aqui usaremos a região da Virgínia, mas você pode trabalhar com outra se preferir.

```
# Define AWS Pricing Rregion (us-east-1 or ap-south-1)
AWS_PRICING_REGION = 'us-east-1'
```
**Tipo de reserva que será utilizada no relatório**

Você pode trabalhar com o tipo de reservas padrão ou conversível. Para entender a diferença entre os dois, consulte [este link](https://aws.amazon.com/pt/ec2/pricing/reserved-instances/).

```
# Define reservation type (standard or convertible)
OFFERING_CLASS = 'standard'
```
**Nome do bucket onde serão armazenados os arquivos csv do relatório**

Altere esta opção e insira o nome do bucket que você criou. Como o bucket é globalmente exclusivo, você terá que mudar de qualquer jeito.

```
# Enter your BUCKET name, e.g 'mybucket'
BUCKET = 'mybucket'
```
**Nome do arquivo CSV que será criado pelo script**

Defina um nome para o arquivo de relatório que será gerado pelo script.

```
# KEY path, e.g.'myec2report'
KEY = 'myec2report'
```

Obs.: esse nome será concatenado com o tipo de reserva e uma hash de identificação única para não haver sobreposição do arquivo ao executar a função novamente.

Ex: **myec2report**_standard_1684081195342122923.csv

Após executar a função Lambda, seu bucket S3 deverá estar parecido com esse:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g29suxr3ge0z4avw6314.png)

Podemos ver o arquivo que foi gerado pelo script (com uma sequência numérica no final).

O arquivo de relatório gerado nos traz os mesmos tipos de preços sob demanda e de reservas para todas as instâncias da região inserida no código, porém desta vez os preços são para a família de instâncias recomendadas pelo Compute Optimizer. Também é possível ver uma comparação de utilização de CPU e memória da família atual com uma estimativa de uso da família recomendada pelo Compute Optimizer.

![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8oe6ayjtrsbhi8b62bav.png)

A coluna Fiding fornece um status dos seus recursos durante o período analisado, podendo ser _Under-provisioned_, _Over-provisioned_ ou _Optimized_. Entenda cada um desses status [aqui](https://docs.aws.amazon.com/compute-optimizer/latest/ug/viewing-dashboard.html#dashboard-findings-classifications).

## Considerações

O script lista as recomendações de instâncias baseado na arquitetura atual da instância (Intel, AMD e Arm). Para alterar esta configuração, adicione o parâmetro `"cpuVendorArchitectures": [ "string" ]` na chamada da API em `COMPUTE_OPTIMIZER.get_ec2_instance_recommendations()`. Veja a documentação [aqui](https://docs.aws.amazon.com/compute-optimizer/latest/APIReference/API_GetEC2InstanceRecommendations.html).

Em alguns casos, o Compute Optimizer recomenda a troca de família mesmo a instância estando como _Optimized_, pois a geração recomendada é mais nova que a atual e isso gera uma redução de uso da capacidade computacional e até mesmo de custo.

Outro ponto importante é que para a obtenção de métricas de memória, é necessário ter o _CloudWatch Agent_ instalado nas instâncias. Caso contrário, tanto a coluna de métricas de memória atual quanto a estimada serão preenchidas com "_Not available_".

Em algumas ocasiões o Compute Optimizer necessita que as instâncias permaneçam ligadas por um período mínimo de tempo. Em meus testes de laboratório, foi  preciso mantê-las ligadas por no mínimo 24 horas sem interrupções.

## Conclusão

Novamente, é IMPORTANTE sempre validar os preços gerados pelo script com os valores da [calculadora de preços da AWS](https://calculator.aws/#/).

Isso é tudo por hoje!
Se tiver dúvidas ou quer mandar um feedback fique a vontade para comentar.
Abraços!