<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Isaque Alcantara</title>
    <description>The latest articles on DEV Community by Isaque Alcantara (@isaque21).</description>
    <link>https://dev.to/isaque21</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F964581%2F3acda19c-3062-4c79-9862-6c46bb813c01.jpeg</url>
      <title>DEV Community: Isaque Alcantara</title>
      <link>https://dev.to/isaque21</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/isaque21"/>
    <language>en</language>
    <item>
      <title>Obter tempo de disponibilidade de instâncias EC2 na AWS</title>
      <dc:creator>Isaque Alcantara</dc:creator>
      <pubDate>Thu, 13 Jul 2023 11:44:15 +0000</pubDate>
      <link>https://dev.to/isaque21/obter-tempo-de-disponibilidade-de-instancias-ec2-na-aws-1ooh</link>
      <guid>https://dev.to/isaque21/obter-tempo-de-disponibilidade-de-instancias-ec2-na-aws-1ooh</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Este artigo descreve a primeira parte do desenvolvimento de um sistema web para obter e visualizar o tempo de disponibilidade e indisponibilidade de instâncias EC2 na AWS.&lt;/p&gt;

&lt;p&gt;O sistema consiste em duas partes: um backend onde utilizaremos um script em python para obter e tratar os dados necessários para gerar os relatórios e um frontend composto por uma página simples que utilizará HTML, Javascript e CSS, para fornecer um dashboard com gráficos e insights sobre as instâncias EC2 de todas as regiões da conta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arquitetura proposta
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ual0d1fe7eruuydsws8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9ual0d1fe7eruuydsws8.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com esta arquitetura, teremos uma Função Lambda que fará a coleta de métricas de &lt;strong&gt;StatusCheckFailed&lt;/strong&gt; vindas do CloudWatch para todas as instâncias da conta. Após coletá-las, o Lambda irá tratá-las e armazenar os resultados em um Bucket S3. O Bucket armazenará esses resultados em arquivos .csv juntamente com os arquivos HTML, Javascript e CSS que irão compor o sistema. Utilizaremos o CloudFront para distribuir o conteúdo e também proteger os acessos para somente usuários autorizados. &lt;/p&gt;

&lt;p&gt;Com isso teremos um Dashboard com o total, em horas, de tempo disponível e indisponível de todas as instâncias EC2. Também será possível baixar esse relatório em formato CSV para melhor administração.&lt;/p&gt;

&lt;h2&gt;
  
  
  Métricas de Status Check
&lt;/h2&gt;

&lt;p&gt;As métricas de status check na AWS são uma forma de monitorar a saúde e o desempenho das instâncias do Amazon EC2 (Elastic Compute Cloud) em uma região específica. Essas métricas fornecem informações sobre a integridade dos componentes da instância, como a camada de virtualização, a conectividade de rede e o sistema operacional.&lt;/p&gt;

&lt;p&gt;Vamos passar rapidamente sobre o papel de cada uma:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;StatusCheckFailed&lt;/strong&gt;: Essa métrica relata se a instância passou tanto na verificação de status da instância quanto na verificação de status do sistema no último minuto. Ela tem um valor binário, onde 0 significa que passou e 1 significa que falhou. Por padrão, essa métrica está disponível gratuitamente a cada um minuto. As unidades dessa métrica são contagem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;StatusCheckFailed_Instance&lt;/strong&gt;: Essa métrica informa se a instância passou na verificação de status da instância no último minuto. Similar à métrica anterior, ela possui um valor binário de 0 (passou) ou 1 (falhou). Também está disponível gratuitamente a cada um minuto e suas unidades são contagem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;StatusCheckFailed_System&lt;/strong&gt;: Essa métrica indica se a instância passou na verificação de status do sistema no último minuto. Mais uma vez, ela possui um valor binário de 0 (passou) ou 1 (falhou). A disponibilidade gratuita e a frequência de um minuto também se aplicam a essa métrica, e suas unidades são contagem.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ao acompanhar essas métricas, é possível identificar problemas e tomar medidas corretivas quando ocorrerem falhas nos status checks.&lt;/p&gt;

&lt;p&gt;Com base nas métricas de status check registradas no CloudWatch, podemos calcular o tempo de disponibilidade das instâncias. Ao monitorar as falhas nos status checks e calcular o tempo em que as instâncias estão passando nesses checks, é possível ter uma estimativa do tempo em que as instâncias estiveram disponíveis.&lt;/p&gt;

&lt;p&gt;No entanto, é importante destacar que essa abordagem é uma estimativa e depende de vários fatores, como a frequência de verificação das métricas, por exemplo. Além disso, existem outros fatores que podem afetar a disponibilidade das instâncias, como atualizações de sistema operacional, manutenção programada, eventos de força maior, entre outros.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calculando o tempo de Downtime e Uptime
&lt;/h2&gt;

&lt;p&gt;Para calcular o tempo de disponibilidade das instâncias, utilizaremos um código em Python para rodar em uma função Lambda, que tem como propósito principal gerar um relatório de disponibilidade das instâncias do Amazon EC2 em várias regiões da AWS. Ele utiliza a biblioteca boto3 para interagir com os serviços da AWS, como o CloudWatch e o S3.&lt;/p&gt;

&lt;p&gt;O código itera sobre cada região configurada e, em seguida, obtém informações sobre as instâncias EC2 presentes em cada região. Para cada instância, são coletadas métricas de falha de status usando o CloudWatch. Com base nessas métricas, o código calcula o tempo de disponibilidade e indisponibilidade de cada instância.&lt;/p&gt;

&lt;p&gt;Após processar todas as regiões e instâncias, os dados são armazenados em uma lista e, em seguida, enviados como um arquivo CSV para um bucket S3 especificado. O relatório contém informações como ID da instância, nome, tipo, plataforma, tempo de disponibilidade, tempo de indisponibilidade e porcentagem de disponibilidade.&lt;/p&gt;

&lt;p&gt;Baixe o código &lt;a href="https://github.com/isaque21/lambda/tree/main/ec2-availability-time/backend" rel="noopener noreferrer"&gt;neste&lt;/a&gt; repositório.&lt;/p&gt;

&lt;p&gt;Hora de colocar a mão na massa. Vamos lá!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 - Criar bucket S3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Acesse o console do Amazon S3 e clique em &lt;strong&gt;Create bucket&lt;/strong&gt;. Dê um nome para seu bucket e escolha a região de sua preferência.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90iyw1xn8brgs3d3zxig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F90iyw1xn8brgs3d3zxig.png" width="800" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deixe o restante das opções como padrão e clique em &lt;strong&gt;Create bucket&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38kia6jp90juw8qhqskq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38kia6jp90juw8qhqskq.png" width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2 - Criar uma função do IAM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No console do IAM, clique em &lt;strong&gt;Policies&lt;/strong&gt; no menu lateral esquerdo e depois em &lt;strong&gt;Create policy&lt;/strong&gt;. Clique na guia JSON e substitua o código JSON por este:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::your-bucket-name-123456/*"
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Desta forma, a função Lambda que usará essa IAM role terá acesso restrito somente ao bucket em questão.&lt;/p&gt;

&lt;p&gt;Substitua o nome do bucket na linha &lt;code&gt;"Resource": "arn:aws:s3:::your-bucket-name-123456/*"&lt;/code&gt; pelo nome do bucket que você criou anteriormente. Avance para a parte de &lt;strong&gt;Review&lt;/strong&gt; para dar um nome à sua Policy e depois clique em &lt;strong&gt;Create Policy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vamos então criar uma Role e atachar a Policy criada junto com outras necessárias para o funcionamento do script. Clique em &lt;strong&gt;Roles&lt;/strong&gt; no menu lateral esquerdo e depois em &lt;strong&gt;Create Role&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm92mtdhm05y8jqawg6kr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm92mtdhm05y8jqawg6kr.png" width="800" height="227"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em &lt;strong&gt;Trusted entity type&lt;/strong&gt; escolha &lt;strong&gt;AWS service&lt;/strong&gt;, marque o serviço &lt;strong&gt;Lambda&lt;/strong&gt; e avance para atachar as policies necessárias.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8qdnvs5d8twrxucsse8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz8qdnvs5d8twrxucsse8.png" width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em &lt;strong&gt;Add permissions&lt;/strong&gt; 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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudWatchLogsReadOnlyAccess&lt;/li&gt;
&lt;li&gt;AmazonEC2ReadOnlyAccess&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkt79tgea9br8dgcvmlcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkt79tgea9br8dgcvmlcw.png" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Avance para escolher um nome para sua Role e revise as Policies atachadas. Feito isso, clique em &lt;strong&gt;Create role&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3 - Criar função Lambda&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Acesse o console do Lambda e clique em &lt;strong&gt;Create function&lt;/strong&gt;. Escolha a opção &lt;strong&gt;Author from scratch&lt;/strong&gt; para iniciar com um exemplo de código. Dê um nome para sua Função Lambda e escolha o Runtime &lt;strong&gt;Python 3.10&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fur40tf9hkoozyy1se96c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fur40tf9hkoozyy1se96c.png" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em &lt;strong&gt;Change default execution role&lt;/strong&gt; escolha &lt;strong&gt;Use an existing role&lt;/strong&gt; e selecione a Role que você criou no passo anterior. Feito isso clique em &lt;strong&gt;Create function&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3bo8jylxu28khwuby95c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3bo8jylxu28khwuby95c.png" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que você criou a Função, substitua o código de exemplo pelo código que está &lt;a href="https://github.com/isaque21/lambda/tree/main/ec2-availability-time/backend" rel="noopener noreferrer"&gt;neste&lt;/a&gt; repositório. Após inserir o código, clique em &lt;strong&gt;Deploy&lt;/strong&gt; para Salvar as alterações.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1v2fsyqq47b6nc1ohrr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi1v2fsyqq47b6nc1ohrr.png" width="800" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lembre-se de alterar as &lt;strong&gt;regiões&lt;/strong&gt;, o &lt;strong&gt;nome do bucket&lt;/strong&gt; e o &lt;strong&gt;nome do arquivo&lt;/strong&gt; no script.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3asdmaowquty2o1iq447.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3asdmaowquty2o1iq447.png" width="626" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vá para a aba &lt;strong&gt;Test&lt;/strong&gt; para configurar um novo teste. Dê um nome ao evento e clique em &lt;strong&gt;Save&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyxujtxngs5zthcenkkgl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyxujtxngs5zthcenkkgl.png" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após salvar, execute um teste. Se tudo correr bem você verá uma saída como a imagem abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5tbbeappio9sgq6jwgno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5tbbeappio9sgq6jwgno.png" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3 - Configurar EventBridge&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Na parte superior da página da função, em &lt;strong&gt;Function Overview&lt;/strong&gt;, clique em &lt;strong&gt;Add trigger&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyj8lsznkpaaix8k1mtr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyj8lsznkpaaix8k1mtr.png" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em &lt;strong&gt;Trigger configuration&lt;/strong&gt; selecione &lt;strong&gt;EventBridge (CloudWatch Events)&lt;/strong&gt;. Crie uma nova regra, dê um nome para a regra e em seguida selecione &lt;strong&gt;Schedule expression&lt;/strong&gt; para inserir uma Cron.&lt;br&gt;
Aqui você pode configurar uma expressão que melhor atende a sua necessidade. Neste exemplo usei uma expressão que chamará a função Lambda de 30 em 30 minutos.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cron(0/30 * * * ? *)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Após inserir o valor clique em &lt;strong&gt;Add&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd1m8rl1p5ja5hmwxam6e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd1m8rl1p5ja5hmwxam6e.png" width="800" height="644"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 - Baixe o relatório gerado&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Volte ao bucket criado, navegue até a pasta “data/” e faça download do arquivo .csv gerado pelo script. &lt;/p&gt;

&lt;p&gt;As primeiras colunas do arquivo dizem respeito às especificações das instâncias como ID, nome, tamanho e sistema operacional.&lt;/p&gt;

&lt;p&gt;As informações sobre disponibilidade estão nas colunas uptime_hours, downtime_hours e hours_used.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;uptime_hours&lt;/strong&gt;: tempo em que a instância ficou disponível e operante.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;downtime_hours&lt;/strong&gt;: tempo em que a instância ficou indisponível e não operante (devido a alguma falha detectada pelas métricas de status check).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hours_used&lt;/strong&gt;: tempo total em que a instância permaneceu ligada, independente de estar operante ou não operante.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Por fim, temos as colunas start_date e end_date que representam o período em que o relatório se baseia. Por configuração do script, o relatório sempre começará no primeiro dia do mês às 00:00 horas e terminará no último horário de execução da função lambda, segmentando cada relatório por mês atual.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8t9iztwf9c6tve3cqcl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi8t9iztwf9c6tve3cqcl.png" width="800" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Concluímos a primeira parte de nosso sistema. Com isso, temos um backend que nos traz um relatório de tempo de disponibilidade e indisponibilidade das instâncias EC2 da conta.&lt;/p&gt;

&lt;p&gt;Na parte 2 deste artigo, vamos criar um frontend utilizando HTML, Javascript e CSS para poder exibir esse relatório de forma mais apreciativa, e claro, vamos utilizar dos serviços da AWS que são próprios para isso, visando o mínimo custo possível. Até lá!&lt;/p&gt;

</description>
      <category>aws</category>
      <category>python</category>
      <category>lambda</category>
      <category>ec2</category>
    </item>
    <item>
      <title>Verificar rotinas de Snapshots via Lambda</title>
      <dc:creator>Isaque Alcantara</dc:creator>
      <pubDate>Sat, 11 Feb 2023 16:05:52 +0000</pubDate>
      <link>https://dev.to/isaque21/verificar-rotinas-de-snapshots-via-lambda-17jl</link>
      <guid>https://dev.to/isaque21/verificar-rotinas-de-snapshots-via-lambda-17jl</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;O backup é peça chave nas operações de qualquer ambiente e deixar de realizar alguma rotina pode resultar em surpresas desagradáveis em algum procedimento de recuperação.&lt;/p&gt;

&lt;p&gt;Existem diversas formas de realizar backups dos seus recursos e serviços na AWS. Quando se trata de Instâncias EC2 e RDS, a AWS oferece ferramentas como o &lt;a href="https://aws.amazon.com/pt/backup/" rel="noopener noreferrer"&gt;AWS Backup&lt;/a&gt; ou serviço de backup integrado no próprio recurso, como é o caso do RDS por exemplo.&lt;/p&gt;

&lt;p&gt;Apesar da facilidade em manter seus backups em dia, sabemos que sempre tem aquela exceção(zinha) que foge à regra e com o tempo pode acabar no limbo. Pensando nisso, elaborei este script em Python para poder verificar se os volumes de suas contas estão com o snapshot em dia. 🙂&lt;/p&gt;

&lt;h2&gt;
  
  
  Vamos aos passos
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1 - Criar uma função do IAM para o Lambda&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Acesse o console do &lt;strong&gt;IAM&lt;/strong&gt;, no menu lateral esquerdo clique em &lt;strong&gt;Roles&lt;/strong&gt; e depois clique no botão &lt;strong&gt;Create role&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hf2vmimd5zc1rfh4eag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8hf2vmimd5zc1rfh4eag.png" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em &lt;strong&gt;Select trusted entity&lt;/strong&gt; selecione &lt;strong&gt;AWS service&lt;/strong&gt;, &lt;strong&gt;Lambda&lt;/strong&gt; e clique em &lt;strong&gt;Next&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdthxh38gsqt4n09hgerg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdthxh38gsqt4n09hgerg.png" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clique no botão &lt;strong&gt;Create policy&lt;/strong&gt;. Uma nova guia será aberta para criação da policy. Vá na guia &lt;strong&gt;JSON&lt;/strong&gt; do editor, cole o seguinte código abaixo e depois clique em &lt;strong&gt;Next&lt;/strong&gt; para avançar para a parte de &lt;strong&gt;Review policy&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "cloudwatch:PutMetricData",
                "ec2:DescribeInstances",
                "ec2:DescribeVolumeStatus",
                "ec2:DescribeSnapshotAttribute",
                "ec2:DescribeRegions",
                "ec2:DescribeVolumes",
                "ec2:DescribeVolumesModifications",
                "ec2:DescribeSnapshots",
                "ec2:DescribeVolumeAttribute"
            ],
            "Resource": [
                "*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:*:*:*"
            ],
            "Effect": "Allow"
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hu2j8owpicefj8bjzhv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hu2j8owpicefj8bjzhv.png" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dê um nome para sua Policy e clique em &lt;strong&gt;Create policy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feeuhxhkgrd8vphue42pw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feeuhxhkgrd8vphue42pw.png" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Volte para a guia da criação da Role em seu navegador e atualize a lista de policies. Pesquise pela policy criada anteriormente, selecione-a e clique em &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg43we8l6wjl8hm1p144s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg43we8l6wjl8hm1p144s.png" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dê um nome para sua Role e clique em &lt;strong&gt;Create role&lt;/strong&gt;. Pronto, sua Role está criada.&lt;/p&gt;

&lt;h2&gt;
  
  
  2 - Criar função Lambda
&lt;/h2&gt;

&lt;p&gt;Abra o console do &lt;strong&gt;Lambda&lt;/strong&gt;, no menu lateral esquerdo clique em &lt;strong&gt;Functions&lt;/strong&gt; e depois no botão &lt;strong&gt;Create function&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsaj3btosax159u0dv2dj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsaj3btosax159u0dv2dj.png" width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selecione &lt;strong&gt;Author from scratch&lt;/strong&gt;, dê um nome para sua função e escolha o &lt;strong&gt;Runtime Python 3.9&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F853d4hd9czfqbfe65jiz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F853d4hd9czfqbfe65jiz.png" width="800" height="311"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em &lt;strong&gt;Permissions&lt;/strong&gt;, selecione o item &lt;strong&gt;Use an existing role&lt;/strong&gt; e no campo de seleção escolha a Role criada anteriormente. Feito isso clique em &lt;strong&gt;Create function&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqu0t5kkc2u16mxxgojv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqu0t5kkc2u16mxxgojv0.png" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com isso sua função está criada. Agora vamos substituir o código de exemplo da função pelo código &lt;a href="https://github.com/isaque21/lambda/blob/main/ebs-check-snapshots/lambda_function.py" rel="noopener noreferrer"&gt;deste repositório&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Este código seleciona todos os volumes da conta e verifica se cada um deles possui ou não algum snapshot realizado. &lt;/p&gt;

&lt;p&gt;Caso NÃO possua algum snapshot realizado, será impresso a seguinte mensagem nos logs de execução: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;[ALERT] The Volume-ID: vol-a1b2c3d4e5f6g7 does not have a Snapshot.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Se o volume possuir algum snapshot mas esse for mais antigo do que a quantidade de dias inserida na constante de verificação &lt;code&gt;DAYS = x&lt;/code&gt; será impresso a mensagem: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;[ALERT] The last Snapshot of Volume-ID: vol-a1b2c3d4e5f6g7 was in 2022-09-23 01:33:04.596000+00:00.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Se por algum motivo você quiser excluir algum volume da verificação, basta adicionar a tag &lt;code&gt;snapshot:false&lt;/code&gt; no volume desejado. Então verá na saída de logs a mensagem: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;[WARNING] Volume-ID: vol-a1b2c3d4e5f6g7 excluded from snapshot routine.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Por padrão, o código verifica se os snapshots mais recentes possuem mais de 3 dias, mas você pode alterar esse valor na constante &lt;code&gt;DAYS = x&lt;/code&gt; no início do código.&lt;/p&gt;

&lt;p&gt;Caso a saída do código &lt;strong&gt;não retorne nada&lt;/strong&gt; significa que seus volumes estão com o snapshot &lt;strong&gt;em dia&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Após substituir o código, clique em &lt;strong&gt;Deploy&lt;/strong&gt; para salvar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u6oz4ps9jiwyayg79wq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5u6oz4ps9jiwyayg79wq.png" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após salvar o código, vá até a guia &lt;strong&gt;Configuration&lt;/strong&gt; e clique em &lt;strong&gt;Edit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkv9260nwwce3owrnk9rm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkv9260nwwce3owrnk9rm.png" width="800" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Altere o &lt;strong&gt;Timeout&lt;/strong&gt; para 1 minuto e 30 segundos (pode ser necessário um tempo maior dependendo da quantidade de volumes na conta) e depois clique em &lt;strong&gt;Save&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lpuxlz6h69n6bmu2ylz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lpuxlz6h69n6bmu2ylz.png" width="800" height="361"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Volte na guia &lt;strong&gt;Code&lt;/strong&gt;, clique em &lt;strong&gt;Test&lt;/strong&gt; para configurar um novo evento de teste.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fap5k171ht58rs86i0k6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fap5k171ht58rs86i0k6c.png" width="778" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dê um nome ao evento, mantenha o restante das configurações padrão e clique em &lt;strong&gt;Save&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqw1udl3dflbv6z5jlg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqw1udl3dflbv6z5jlg0.png" width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Após salvar o Evento, clique no botão &lt;strong&gt;Test&lt;/strong&gt; novamente para executar sua função Lambda.&lt;/p&gt;

&lt;h2&gt;
  
  
  3 - Analisando os Logs
&lt;/h2&gt;

&lt;p&gt;Após executar a função, você verá uma saída parecida com esta abaixo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdhtj4yc9v8yz3hofc8u6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdhtj4yc9v8yz3hofc8u6.png" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para uma visualização mais completa, vamos analisar essa saída no &lt;strong&gt;Log Groups&lt;/strong&gt; do &lt;strong&gt;CloudWatch&lt;/strong&gt;. Para isso clique na guia &lt;strong&gt;Monitor&lt;/strong&gt; e depois em &lt;strong&gt;View CloudWatch logs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvmthd5hlk4tqwprcvp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvmthd5hlk4tqwprcvp9.png" width="800" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Com isso você será redirecionado para o Grupo de logs da função Lambda que você criou. Clique no &lt;strong&gt;Log stream&lt;/strong&gt; mais recente para visualizar a saída completa da Função.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1lrsrsgs9ca48d6nm2m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1lrsrsgs9ca48d6nm2m.png" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dessa forma você pode ter uma visão completa, o que dependendo do seu ambiente pode ser bem extensa.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezacj0nc6tr7zf9tx00e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezacj0nc6tr7zf9tx00e.png" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A partir dos logs no &lt;strong&gt;CloudWatch&lt;/strong&gt; podemos criar alarmes com base em filtros de métricas e assim termos uma monitoria de backup de todos os volumes da conta, mas isso é um assunto para um próximo post. &lt;/p&gt;

&lt;p&gt;Vou ficando por aqui e qualquer feedback só deixar nos comentários. &lt;/p&gt;

</description>
      <category>career</category>
      <category>education</category>
      <category>finance</category>
    </item>
    <item>
      <title>Gerando relatório de Rightsizing de Instâncias via Lambda</title>
      <dc:creator>Isaque Alcantara</dc:creator>
      <pubDate>Sun, 29 Jan 2023 12:40:44 +0000</pubDate>
      <link>https://dev.to/isaque21/gerando-relatorio-de-rightsizing-de-instancias-via-lambda-2nlb</link>
      <guid>https://dev.to/isaque21/gerando-relatorio-de-rightsizing-de-instancias-via-lambda-2nlb</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Ainda na pegada de otimização de custos na AWS, este post complementa o &lt;a href="https://dev.to/isaque21/gerando-relatorio-de-precos-de-reservas-de-instancias-via-lambda-4mjn"&gt;post anterior&lt;/a&gt; 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. &lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  O AWS Compute Optimizer
&lt;/h2&gt;

&lt;p&gt;O AWS Compute Optimizer ajuda você a evitar o provisionamento excessivo ou insuficiente de alguns recursos da AWS. Acesse a documentação &lt;a href="https://aws.amazon.com/pt/compute-optimizer/" rel="noopener noreferrer"&gt;neste link&lt;/a&gt; para saber mais.&lt;/p&gt;

&lt;p&gt;Alguns casos de uso do AWS Compute Optimizer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;Obtenha recomendações aprimoradas para otimizar instâncias do EC2 e grupos do Auto Scaling usando três meses de dados históricos.&lt;/li&gt;
&lt;li&gt;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.&lt;/li&gt;
&lt;li&gt;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).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;É 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 &lt;a href="https://aws.amazon.com/pt/compute-optimizer/pricing/" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bora pro trampo!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1 - Criar bucket&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O primeiro ponto será a criação do nosso bucket onde ficarão os arquivos que serão gerados pelo script.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9jpevuktav13risxd3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp9jpevuktav13risxd3g.png" width="768" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2 - Criar uma função do IAM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::ec2-recommendations-reports/*"
        }
    ]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Substitua o nome do bucket na linha &lt;code&gt;"Resource": "arn:aws:s3:::ec2-recommendations-reports/*"&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tos0mfzpn5zsu4t4csc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tos0mfzpn5zsu4t4csc.png" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWSPriceListServiceFullAccess&lt;/li&gt;
&lt;li&gt;ComputeOptimizerReadOnlyAccess&lt;/li&gt;
&lt;li&gt;AmazonEC2ReadOnlyAccess&lt;/li&gt;
&lt;li&gt;AmazonSSMReadOnlyAccess&lt;/li&gt;
&lt;li&gt;AWSLambdaBasicExecutionRole&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avance para escolher um nome para sua Role e revise as Policies atachadas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3 - Criar função Lambda&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwnuq09zso5210hcx0cf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwnuq09zso5210hcx0cf.png" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiacy5rhiu5x4iyid36o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiacy5rhiu5x4iyid36o.png" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que você criou a Função, substitua o código de exemplo pelo código que está &lt;a href="https://github.com/isaque21/lambda/blob/main/get-recommendations/lambda_function.py" rel="noopener noreferrer"&gt;neste repositório&lt;/a&gt;. Após inserir o código, clique em Deploy para Salvar as alterações.&lt;/p&gt;

&lt;p&gt;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).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhxq2kl0ycz80ausvymj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhxq2kl0ycz80ausvymj.png" width="800" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vá para a aba Test para configurar um novo teste. Dê um nome ao evento e clique em Save.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gje5dbmjhfviahzw7l3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gje5dbmjhfviahzw7l3.png" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 - Configuração do script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Volte para a aba Code. Vamos analisar algumas linhas do código que precisam ser alteradas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Região dos recursos na AWS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Escolha as regiões onde suas instâncias estão. O script verifica todas instâncias EC2 nas regiões setadas na variável &lt;code&gt;AWS_REGIONS&lt;/code&gt; e adiciona todas no mesmo arquivo csv.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Define AWS Region
AWS_REGIONS = ['us-east-1', 'sa-east-1']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Região do endpoint da API de preços&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Define AWS Pricing Rregion (us-east-1 or ap-south-1)
AWS_PRICING_REGION = 'us-east-1'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tipo de reserva que será utilizada no relatório&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Você pode trabalhar com o tipo de reservas padrão ou conversível. Para entender a diferença entre os dois, consulte &lt;a href="https://aws.amazon.com/pt/ec2/pricing/reserved-instances/" rel="noopener noreferrer"&gt;este link&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Define reservation type (standard or convertible)
OFFERING_CLASS = 'standard'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nome do bucket onde serão armazenados os arquivos csv do relatório&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Enter your BUCKET name, e.g 'mybucket'
BUCKET = 'mybucket'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nome do arquivo CSV que será criado pelo script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Defina um nome para o arquivo de relatório que será gerado pelo script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# KEY path, e.g.'myec2report'
KEY = 'myec2report'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Ex: &lt;strong&gt;myec2report&lt;/strong&gt;_standard_1684081195342122923.csv&lt;/p&gt;

&lt;p&gt;Após executar a função Lambda, seu bucket S3 deverá estar parecido com esse:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg29suxr3ge0z4avw6314.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg29suxr3ge0z4avw6314.png" alt="Image description" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver o arquivo que foi gerado pelo script (com uma sequência numérica no final).&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8oe6ayjtrsbhi8b62bav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8oe6ayjtrsbhi8b62bav.png" width="800" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A coluna Fiding fornece um status dos seus recursos durante o período analisado, podendo ser &lt;em&gt;Under-provisioned&lt;/em&gt;, &lt;em&gt;Over-provisioned&lt;/em&gt; ou &lt;em&gt;Optimized&lt;/em&gt;. Entenda cada um desses status &lt;a href="https://docs.aws.amazon.com/compute-optimizer/latest/ug/viewing-dashboard.html#dashboard-findings-classifications" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações
&lt;/h2&gt;

&lt;p&gt;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 &lt;code&gt;"cpuVendorArchitectures": [ "string" ]&lt;/code&gt; na chamada da API em &lt;code&gt;COMPUTE_OPTIMIZER.get_ec2_instance_recommendations()&lt;/code&gt;. Veja a documentação &lt;a href="https://docs.aws.amazon.com/compute-optimizer/latest/APIReference/API_GetEC2InstanceRecommendations.html" rel="noopener noreferrer"&gt;aqui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Em alguns casos, o Compute Optimizer recomenda a troca de família mesmo a instância estando como &lt;em&gt;Optimized&lt;/em&gt;, 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.&lt;/p&gt;

&lt;p&gt;Outro ponto importante é que para a obtenção de métricas de memória, é necessário ter o &lt;em&gt;CloudWatch Agent&lt;/em&gt; instalado nas instâncias. Caso contrário, tanto a coluna de métricas de memória atual quanto a estimada serão preenchidas com "&lt;em&gt;Not available&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Novamente, é IMPORTANTE sempre validar os preços gerados pelo script com os valores da &lt;a href="https://calculator.aws/#/" rel="noopener noreferrer"&gt;calculadora de preços da AWS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Isso é tudo por hoje!&lt;br&gt;
Se tiver dúvidas ou quer mandar um feedback fique a vontade para comentar.&lt;br&gt;
Abraços!&lt;/p&gt;

</description>
      <category>tooling</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Gerando relatório de preços de reservas de Instâncias via Lambda</title>
      <dc:creator>Isaque Alcantara</dc:creator>
      <pubDate>Sat, 21 Jan 2023 16:13:13 +0000</pubDate>
      <link>https://dev.to/isaque21/gerando-relatorio-de-precos-de-reservas-de-instancias-via-lambda-4mjn</link>
      <guid>https://dev.to/isaque21/gerando-relatorio-de-precos-de-reservas-de-instancias-via-lambda-4mjn</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Talvez você já tenha se deparado com a necessidade de avaliar preços para possíveis reservas de instâncias para o seu ambiente e dependendo da quantidade de instâncias, esta pode não ser uma tarefa muito agradável.&lt;/p&gt;

&lt;p&gt;Em um ambiente que contém dezenas ou talvez centenas de instâncias em uso, gerar relatório de preço de reserva para cada uma pode levar dias se feito de forma manual, cuja tarefa seria: verificar a família da instância, ir até a calculadora da AWS, coletar os preços para as diferentes modalidades (de reservas e pagamento) e incluir todas essas informações em uma planilha. Suado, viu… &lt;/p&gt;

&lt;p&gt;Pensando em uma forma de automatizar este processo, elaborei um script em Python para rodar em uma função Lambda e gerar esse lindo relatório para nós. 😀&lt;/p&gt;

&lt;p&gt;Este script utiliza a API de preços da AWS para preencher um arquivo em CSV com os preços Sob Demanda e de Reservas com as diferentes modalidades de pagamento (sem pagamento adiantado, parcialmente adiantado e totalmente adiantado) para 1 e 3 anos. Também é possível escolher entre os tipos de reservas padrão e conversível, para melhor atender a sua necessidade.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sobre a API de preços da AWS
&lt;/h2&gt;

&lt;p&gt;A AWS oferece duas APIs que você pode usar para consultar preços. Você pode consultar a documentação &lt;a href="https://docs.aws.amazon.com/pt_br/awsaccountbilling/latest/aboutv2/price-changes.html" rel="noopener noreferrer"&gt;neste link&lt;/a&gt;, mas em resumo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Com a API Price List Bulk da AWS, você pode consultar os preços de serviços da AWS em massa. Essa API retorna um arquivo JSON ou CSV. A API em massa retém todas as versões históricas da lista de preços.&lt;/li&gt;
&lt;li&gt;Com a API Price List Query da AWS, é possível consultar informações específicas sobre serviços, produtos e preços da AWS usando um AWS SDK ou a AWS CLI. Essa API é capaz de recuperar informações sobre determinados produtos ou preços, em vez de recuperar preços em massa. Isso permite obter informações de preços em ambientes que talvez não consigam processar uma lista de preços em massa, como em aplicações móveis ou baseadas em navegador da Web. Por exemplo, é possível utilizar a API de consulta para buscar informações de preços de instâncias do Amazon EC2 com 64 vCPUs, 256 GiB de memória e o SQL Server Enterprise pré-instalado na região Ásia-Pacífico (Mumbai). A API de consulta retorna os preços atuais e não retém preços históricos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para esse script será utilizada a segunda opção nas APIs descritas acima. Passando alguns atributos das instâncias que compõem o seu ambiente como parâmetros na chamada dessa API, ela nos retornará os preços da instância em questão.&lt;/p&gt;

&lt;p&gt;A API Price List Query da AWS fornece os dois endpoints a seguir:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://api.pricing.us-east-1.amazonaws.com" rel="noopener noreferrer"&gt;https://api.pricing.us-east-1.amazonaws.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://api.pricing.ap-south-1.amazonaws.com" rel="noopener noreferrer"&gt;https://api.pricing.ap-south-1.amazonaws.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Mão na massa!
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1 - Criar bucket&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O primeiro ponto será a criação do nosso bucket onde ficarão os arquivos que serão gerados pelo script.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk61pnbzda8ddqcg6e5kz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk61pnbzda8ddqcg6e5kz.png" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2 - Criar uma função do IAM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": "arn:aws:s3:::ec2-princing-reports/*"
        }
    ]
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Substitua o nome do bucket na linha &lt;code&gt;"Resource": "arn:aws:s3:::ec2-princing-reports/*"&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tos0mfzpn5zsu4t4csc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4tos0mfzpn5zsu4t4csc.png" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWSPriceListServiceFullAccess&lt;/li&gt;
&lt;li&gt;AmazonEC2ReadOnlyAccess&lt;/li&gt;
&lt;li&gt;AmazonSSMReadOnlyAccess&lt;/li&gt;
&lt;li&gt;AWSLambdaBasicExecutionRole&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avance para escolher um nome para sua Role e revise as Policies atachadas. As permissões da sua Role devem se parecer com esta:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzetcjbi0p6grt730wn3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzetcjbi0p6grt730wn3.png" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3 - Criar função Lambda&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwnuq09zso5210hcx0cf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwnuq09zso5210hcx0cf.png" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiacy5rhiu5x4iyid36o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjiacy5rhiu5x4iyid36o.png" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que você criou a Função, substitua o código de exemplo pelo código que está &lt;a href="https://github.com/isaque21/lambda/blob/main/get-price/lambda_function.py" rel="noopener noreferrer"&gt;neste repositório&lt;/a&gt;. Após inserir o código, clique em Deploy para Salvar as alterações.&lt;/p&gt;

&lt;p&gt;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).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhxq2kl0ycz80ausvymj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnhxq2kl0ycz80ausvymj.png" width="800" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vá para a aba Test para configurar um novo teste. Dê um nome ao evento e clique em Save.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gje5dbmjhfviahzw7l3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gje5dbmjhfviahzw7l3.png" width="800" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 - Configuração do script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Volte para a aba Code. Vamos analisar algumas linhas do código que precisam ser alteradas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Região dos recursos na AWS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Escolha as regiões onde suas instâncias estão. O script verifica todas instâncias EC2 nas regiões setadas na variável &lt;code&gt;AWS_REGIONS&lt;/code&gt; e adiciona todas no mesmo arquivo csv.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Define AWS Region
AWS_REGIONS = ['us-east-1', 'sa-east-1']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Região do endpoint da API de preços&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Define AWS Pricing Rregion (us-east-1 or ap-south-1)
AWS_PRICING_REGION = 'us-east-1'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tipo de reserva que será utilizada no relatório&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Você pode trabalhar com o tipo de reservas padrão ou conversível. Para entender a diferença entre os dois, consulte &lt;a href="https://aws.amazon.com/pt/ec2/pricing/reserved-instances/" rel="noopener noreferrer"&gt;este link&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Define reservation type (standard or convertible)
OFFERING_CLASS = 'standard'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nome do bucket onde serão armazenados os arquivos csv do relatório&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Enter your BUCKET name, e.g 'mybucket'
BUCKET = 'mybucket'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nome do arquivo CSV que será criado pelo script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Defina um nome para o arquivo de relatório que será gerado pelo script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# KEY path, e.g.'myec2report'
KEY = 'myec2report'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Ex: &lt;strong&gt;myec2report&lt;/strong&gt;_standard_1684081195342122923.csv&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5 - Entendendo o filtro&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para que a API retorne os preços correspondentes à nossa instância é preciso passar alguns parâmetros como filtro. Esse filtro é aplicado na seção “product” do arquivo JSON que é retornado pela API. Veja um exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"product": {
       "productFamily": "Compute Instance",
       "attributes": {
           "enhancedNetworkingSupported": "No",
           "intelTurboAvailable": "Yes",
           "memory": "1 GiB",
           "dedicatedEbsThroughput": "Up to 2085 Mbps",
           "vcpu": "2",
           "classicnetworkingsupport": "false",
           "capacitystatus": "Used",
           "locationType": "AWS Region",
           "storage": "EBS only",
           "instanceFamily": "General purpose",
           "operatingSystem": "Linux",
           "intelAvx2Available": "Yes",
           "regionCode": "us-east-1",
           "physicalProcessor": "Intel Skylake E5 2686 v5",
           "clockSpeed": "3.1 GHz",
           "ecu": "Variable",
           "networkPerformance": "Up to 5 Gigabit",
           "servicename": "Amazon Elastic Compute Cloud",
           "vpcnetworkingsupport": "true",
           "instanceType": "t3.micro",
           "tenancy": "Shared",
           "usagetype": "BoxUsage:t3.micro",
           "normalizationSizeFactor": "0.5",
           "intelAvxAvailable": "Yes",
           "processorFeatures": "AVX; AVX2; Intel AVX; Intel AVX2; Intel AVX512; Intel Turbo",
           "servicecode": "AmazonEC2",
           "licenseModel": "No License required",
           "currentGeneration": "Yes",
           "preInstalledSw": "NA",
           "location": "US East (N. Virginia)",
           "processorArchitecture": "64-bit",
           "marketoption": "OnDemand",
           "operation": "RunInstances",
           "availabilityzone": "NA"
       },
       "sku": "CRAJUW7BTXFMT2UJ"
   },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As chaves principais da seção “products” são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tenancy&lt;/li&gt;
&lt;li&gt;preInstalledSw&lt;/li&gt;
&lt;li&gt;operatingSystem&lt;/li&gt;
&lt;li&gt;licenseModel&lt;/li&gt;
&lt;li&gt;capacitystatus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para refinar ainda mais nosso filtro, passamos mais alguns parâmetros, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;location&lt;/li&gt;
&lt;li&gt;instanceType&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Observe o trecho do código que contém os parâmetros do filtro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Filters=[
           {
               'Type': 'TERM_MATCH',
               'Field': 'location',
               'Value': region
           },
           {
               'Type': 'TERM_MATCH',
               'Field': 'capacitystatus',
               'Value': 'Used'
           },
           {
               'Type': 'TERM_MATCH',
               'Field': 'tenancy',
               'Value': 'Shared'
           },
           {
               'Type': 'TERM_MATCH',
               'Field': 'instanceType',
               'Value': typeEc2
           },
           {
               'Type': 'TERM_MATCH',
               'Field': 'preInstalledSw',
               'Value': preInstalledSw
           },
           {
               'Type': 'TERM_MATCH',
               'Field': 'operatingSystem',
               'Value': operatingSystem
           },
           {
               'Type': 'TERM_MATCH',
               'Field': 'licenseModel',
               'Value': 'No License required'
           }
       ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6 - Executando a Função&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Feito as alterações necessárias no código, faça um novo Deploy para salvar e depois clique no botão Test. Se tudo correu bem, o resultado do teste será parecido com este:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvirf2j6uajz42ajo8e20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvirf2j6uajz42ajo8e20.png" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Volte ao bucket e veja que um novo arquivo (com uma sequência numérica no final) foi gerado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9a3mo9cgrqydyzifsqt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9a3mo9cgrqydyzifsqt.png" width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Abrindo o arquivo podemos ver que o conteúdo é um lindo relatório com os preços Sob Demanda e de Reservas para todas as Instâncias da região inserida no código. Além dos preços, podemos conferir outros atributos como ID, nome, AZ, tipo, memória, vCPU e outros.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj02k1y5811azjkf02i6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj02k1y5811azjkf02i6a.png" width="800" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Espero que este script possa te ajudar a poupar tempo e esforço coletando esses dados manualmente, assim como tem me ajudado.&lt;/p&gt;

&lt;p&gt;Importante: SEMPRE valide os valores do relatório gerado com os valores da &lt;a href="https://calculator.aws/#/" rel="noopener noreferrer"&gt;calculadora de preços da AWS&lt;/a&gt;. Não posso garantir que não haja nenhuma divergência, embora seja muito difícil.&lt;/p&gt;

&lt;p&gt;E por falar em calculadora da AWS, se você observar a planilha de exemplo acima, verá que contém alguns campos com o valor “not available” para a modalidade de preço “no upfront”. Experimente validar esses valores lá na calculadora da AWS. No momento em que escrevo este post, ao selecionar a família da instância e a modalidade de reserva e preço, por não ter disponível, a caixa de preços de instâncias reservadas desaparece e só volta se você atualizar a página. 😀 &lt;/p&gt;

&lt;p&gt;Isso é tudo por hoje!&lt;br&gt;
Se tiver dúvidas ou quer mandar um feedback fique a vontade para comentar.&lt;br&gt;
Abraços!&lt;/p&gt;

</description>
      <category>html</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Implantar rotinas periódicas de Start/Stop em Instâncias EC2 via Lambda</title>
      <dc:creator>Isaque Alcantara</dc:creator>
      <pubDate>Sat, 14 Jan 2023 15:36:18 +0000</pubDate>
      <link>https://dev.to/isaque21/implantar-rotinas-periodicas-de-startstop-em-instancias-ec2-via-lambda-4bbn</link>
      <guid>https://dev.to/isaque21/implantar-rotinas-periodicas-de-startstop-em-instancias-ec2-via-lambda-4bbn</guid>
      <description>&lt;p&gt;&lt;em&gt;Este é meu primeiro post para o DEV e venho trazer uma solução simples, embora muito útil. Mostrarei uma abordagem para gerenciar rotinas de start e stop com a possibilidade de configurar diferentes períodos de dias e horários para uma determinada Instância EC2 através do AWS Lambda.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Introdução&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Suponha que você tenha um Lambda que faz o start/stop de várias instâncias em seu ambiente filtrando-as através de Tags. Se todas as instâncias funcionarem no mesmo período (dias da semana, hora que liga e hora que desliga) tudo bem. Bastaria apenas uma configuração no EventBridge para cuidar do acionamento.&lt;br&gt;
Agora, e se você precisar que apenas algumas instâncias específicas funcionem em um período diferente? Faria outra função com outro EventBridge? E se você tivesse 100 instâncias, cada uma com um período de funcionamento diferente da outra? Já pensou como seria?&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Objetivo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;O objetivo desse Lambda é oferecer uma maneira de gerenciar o Start/Stop de suas instâncias EC2 em diferentes períodos de dias e horários, além de reduzir seus custos na AWS para ambientes onde você possa interromper esses recursos, como ambiente de DEV, homologação e outros usados para testes. Usaremos uma única função Lambda que irá filtrar as EC2 através de tags, sendo acionada de tempos em tempos conforme agendamento no EventBridge.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Vamos aos passos:&lt;/strong&gt;
&lt;/h2&gt;
&lt;h2&gt;
  
  
  1 - Criar função IAM com permissões para a Função do Lambda.
&lt;/h2&gt;

&lt;p&gt;A primeira parte será dar as devidas permissões para a execução da Função Lambda. Para isso, abra o console do IAM e clique em Roles no menu lateral esquerdo e depois em Create role.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonwwb64fh94820x2dbvi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonwwb64fh94820x2dbvi.png" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Selecione AWS service, em seguida selecione Lambda e depois clique em Next.&lt;br&gt;
Clique em Create policy. Uma nova guia será aberta, não feche a anterior. Clique na aba JSON da nova guia aberta e cole o seguinte código:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
  "Version": "2012-10-17", 
  "Statement": [  
    { 
      "Effect": "Allow", 
      "Action": [ 
            "ec2:DescribeInstances",
            "ec2:DescribeTags",
            "ec2:DescribeInstanceTypes",
            "ec2:DescribeInstanceStatus",
            "ec2:StartInstances",
            "ec2:StopInstances"
      ], 
      "Resource": "*" 
    } 
  ] 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clique em Next e avance para dar um nome para a Policy e depois clique em Create policy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vnc5bg1e6ean9jt3g3t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6vnc5bg1e6ean9jt3g3t.png" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Volte na guia anterior, clique no botão de refresh e pesquise pela policy criada. Marque a caixa ao lado do nome da policy e selecione também a seguinte policy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CloudWatchFullAccessV2 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dê um nome para sua Role e clique em Create role.&lt;br&gt;
Mais detalhes sobre como criar uma Role, acesse &lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-json-editor" rel="noopener noreferrer"&gt;esse link&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  2 - Criar Função Lambda
&lt;/h2&gt;

&lt;p&gt;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.12.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fts454hszlu5teg414jfs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fts454hszlu5teg414jfs.png" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1b97zg5dsbzpqndi2dv9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1b97zg5dsbzpqndi2dv9.png" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Agora que você criou a Função, substitua o código de exemplo pelo código que está &lt;a href="https://github.com/isaque21/lambda/blob/main/start-stop-routines/start-stop-ec2/lambda_function.py" rel="noopener noreferrer"&gt;neste repositório&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Após inserir o código, clique em Deploy para Salvar as alterações.&lt;br&gt;
Feito isso, vá para a aba Configuration e mude o Timeout para 30 segundos (pode ser necessário um tempo maior de acordo com a quantidade de instâncias do ambiente).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vsrtdyhq3e9ch7xutpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0vsrtdyhq3e9ch7xutpi.png" alt="Image description" width="800" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ainda em Configuration, configure as variáveis de ambientes conforme a imagem a seguir:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pvgsgtsa4oc2ood7exg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pvgsgtsa4oc2ood7exg.png" alt="Image description" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ALARMS_MANAGER&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Define se os alarmes do CloudWatch referente as instâncias serão habilitados/desabilitados junto com a ação de start/stop.&lt;/p&gt;

&lt;p&gt;O valor chave True define que a fução irá alterar o status dos alarmes. Caso não queira alterar o status dos alarmes, altere o valor para False.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REGIONS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Define as regiões que a função irá percorrer e listar as instâncias.&lt;/p&gt;

&lt;p&gt;O valor deve estar como uma lista de regiões da AWS, separadas por vírgulas (por exemplo: us-east-1,sa-east-1).&lt;/p&gt;
&lt;h2&gt;
  
  
  3 - Configurar EventBridge
&lt;/h2&gt;

&lt;p&gt;Na parte superior da página da função, em Function Overview, clique em Add trigger.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ux4ewi0kysix2y515xt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ux4ewi0kysix2y515xt.png" alt="Image description" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Em Trigger configuration selecione EventBridge (CloudWatch Events). Crie uma nova regra, dê um nome para a regra e em seguida selecione Schedule expression para inserir uma Cron.&lt;br&gt;
Aqui você pode configurar uma expressão que melhor atende a sua necessidade. Neste exemplo usei uma expressão que chamará a função Lambda de 5 em 5 minutos.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cron(0/5 * * * ? *)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Após inserir o valor clique em Add.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm97gwloyw0w0g71xwqtq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm97gwloyw0w0g71xwqtq.png" alt="Image description" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Para mais detalhes sobre Cron Expressions consulte &lt;a href="https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html" rel="noopener noreferrer"&gt;este link&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  4 - Adicionando Tags
&lt;/h2&gt;

&lt;p&gt;Para incluir suas instâncias na rotina de Start/Stop é necessário adicionar Tags que definem o acionamento e os períodos em que serão executadas.&lt;/p&gt;

&lt;p&gt;No console de gerenciamento do EC2, no menu lateral esquerdo selecione Instances. Selecione a instância que deseja incluir na rotina de Start/Stop, vá até a aba Tags e clique em Manage tags. Adicione as seguintes tags (alterando o período e os horários de acordo com sua necessidade) e clique em Save.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scheduled      : Active
Period-1       : Monday-Friday
ScheduleStart-1: 08:00
ScheduleStop-1 : 18:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função tentará filtrar as instâncias que contêm uma Tag chamada '&lt;em&gt;Scheduled&lt;/em&gt;' definida como '&lt;em&gt;Active&lt;/em&gt;'.&lt;/p&gt;

&lt;p&gt;A função utiliza um período de dias da semana para comparar a tag '&lt;em&gt;Period-x&lt;/em&gt;' e verifica se o dia atual está dentro do período. Se esta condição for atendida, a função irá comparar a hora atual (H:M) com um valor das tags adicionais que definem o gatilho '&lt;em&gt;ScheduleStop-x&lt;/em&gt;' ou '&lt;em&gt;ScheduleStart-x&lt;/em&gt;'.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8thnfmign1bi1mavqq7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp8thnfmign1bi1mavqq7.png" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;IMPORTANTE!!!&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;As tags devem seguir a nomenclatura em inglês e são case-sensitive;&lt;/li&gt;
&lt;li&gt;O período começa no domingo e termina no sábado;&lt;/li&gt;
&lt;li&gt;O valor 'Period-x' deve estar no seguinte formato 'Sunday-Saturday';&lt;/li&gt;
&lt;li&gt;O valor de 'ScheduleStop-x' ou 'ScheduleStart-x' deve estar no seguinte formato 'H:M';&lt;/li&gt;
&lt;li&gt;O valor de ‘x' das tags 'ScheduleStop-x' e 'ScheduleStart-x' devem corresponder ao mesmo valor do 'period-x’;&lt;/li&gt;
&lt;li&gt;Não há limite de períodos a serem adicionados;&lt;/li&gt;
&lt;li&gt;Para acionar esta função, certifique-se de configurar o EventBridge para que seja executado em um intervalo de sua escolha (a cada 5 minutos é recomendado);&lt;/li&gt;
&lt;li&gt;Esta função está configurada para funcionar com horário local (UTC-3).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;current_time = datetime.now()-timedelta(hours=3)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caso queira retirar uma instância da rotina, basta alterar a tag ‘Scheduled’ para ‘Inactive’.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Exemplos de tags de instância do EC2&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scheduled       : Active

Period-1        : Monday-Friday
ScheduleStart-1 : 06:00
ScheduleStop-1  : 18:00

Period-2        : Saturday
ScheduleStart-2 : 09:00

Period-3        : Sunday
ScheduleStop-3  : 02:00

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusão&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Espero que este artigo possa ajudar a implantar uma rotina de Start/Stop de recursos de forma centralizada e simplificada. &lt;br&gt;
Feedbacks são bem-vindos ;)&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
  </channel>
</rss>
