Descobrindo os custos da sua infraestrutura utilizando Infracost
Pedro H. Santos
Posted on July 7, 2022
Introdução
Um dos maiores problemas na jornada de uma empresa quando decide migrar seu ambiente e aplicações para a Cloud é: Quanto vai custar? 💸
Temos algumas formas de calcular e ter uma previsão dos gastos em nuvem utilizado as calculadoras dos próprios providers, porém, na minha visão a forma mais interessante de ter uma previsão de custos é utilizando o infracost.io.
O que é o Infracost? 💰
O Infracost é uma ferramenta utilizada junto com o seu Terraform, ou seja, você terá uma previsão de quanto a sua infraestrutura vai custar assim que executar o terraform plan
no seu projeto.
Alguns benefícios ao utilizar o Infracost:
- Maior conscientização sobre custos: Os engenheiros recebem antecipadamente o custo estimado da infraestrutura, antes que quaisquer recursos sejam lançados ou alterados. Eles podem fazer escolhas econômicas enquanto mantêm a velocidade de entrega de software.
- Visibilidade de custo para equipes de plataforma: O impacto de custo de módulos compartilhados que são usados em muitas equipes pode ser avaliado pelas equipes de plataforma.
- Retrabalho de infraestrutura reduzido: O Infracost integrado a sua pipeline CI/CD fornece as informações necessárias para tomar as decisões corretas. Os orçamentos não são quebrados e menos retrabalho é necessário para consertar a infraestrutura para alinhar com os orçamentos após o lançamento.
- Orçamentos e custos alinhados: Se as mudanças na infraestrutura ou o lançamento de um novo produto quebrarem os orçamentos, a comunicação pode acontecer antecipadamente, não após a chegada da fatura.
Mão na massa 💻
Neste laboratório vamos utilizar o projeto que criamos no artigo: Pipeline IaC com Terraform e GitHub Actions. Se você não acompanhou o post anterior faça o clone do projeto: git clone https://github.com/santospedroh/iac-pipeline.git
.
Vamos alterar o workflow do GitHub Action para adicionar os recursos do Infracost, assim vamos poder analisar quando o terraform plan
for executado quais os custos da nossa infraestrutura.
Instalação e configuração do CLI 🛠
O Infracost tem uma documentação bem completa e simples com Get started super legal. No meu caso estou utilizando um MacOS e vou fazer a instalação utilizando o gerenciador de pacotes Homebrew.
➜ iac-pipeline git:(main) brew install infracost
Após a instalação você precisa criar uma API KEY para o Infracost gerar os custos estimados da infraestrutura, será necessário executar o comando infracost register
e informa seu nome e e-mail para gerar a API KEY.
➜ iac-pipeline git:(main) infracost register
Please enter your name and email address to get an API key.
See our FAQ (https://www.infracost.io/docs/faq) for more details.
Name: Pedro Santos
Email: santos.pedroh@gmail.com
Thanks Pedro Santos! Your API key is: <SUA_API_KEY_VAI_APARECER_AQUI>
This was saved to /Users/santospedroh/.config/infracost/credentials.yml
Follow https://infracost.io/docs to use Infracost.
Agora já podemos executar o Infracost e verificar a estimativa de custos do projeto Terraform utilizando o comando infracost breakdown --path .
para gerar a estimativa de custos direto no terminal.
➜ iac-pipeline git:(main) ✗ infracost breakdown --path .
Evaluating Terraform directory at .
✔ Downloading Terraform modules
✔ Evaluating Terraform directory
✔ Retrieving cloud prices to calculate costs
Project: santospedroh/iac-pipeline/.
Name Monthly Qty Unit Monthly Cost
module.ec2_instance.aws_instance.this[0]
├─ Instance usage (Linux/UNIX, on-demand, t3.micro) 730 hours $7.59
└─ root_block_device
└─ Storage (general purpose SSD, gp2) 8 GB $0.80
OVERALL TOTAL $8.39
──────────────────────────────────
10 cloud resources were detected:
∙ 1 was estimated, it includes usage-based costs, see https://infracost.io/usage-file
∙ 9 were free, rerun with --show-skipped to see details
Também podemos alterar o formato o qual as informações de custos são exibidas. Para gerar um arquivo html por exemplo, utilize o comando infracost breakdown --path . --format html > infracost.html
um arquivo html vai ser criado.
Mais detalhes sobre os formatos pode ser verificados na documentação.
➜ iac-pipeline git:(main) infracost breakdown --path . --format html > infracost.html
Evaluating Terraform directory at .
✔ Downloading Terraform modules
✔ Evaluating Terraform directory
✔ Retrieving cloud prices to calculate costs
➜ iac-pipeline git:(main) ✗ ls -ltr *.html
-rw-r--r-- 1 santospedroh staff 16269 6 Jul 16:09 infracost.html
Arquivo HTML com a previsão de custos do projeto.
Podemos ver que o custo da infraestrutura atual utilizando uma instância t3.micro é de $8.39
Integração com o GitHub Action 🤖
Agora chegou o momento de integrarmos o Infracost com o nosso workflow no GitHub Action para recebemos os valores estimados direto nas Pull Request's que forem criadas. O primeiro passo para a integração é criar uma secret da sua API KEY do Infracost no repositório do projeto, assim como fizemos no artigo anterior.
Vamos utilizar o Infracost Actions oficial como referência para editar o nosso workflow plan.yml que já temos em nosso projeto.
name: "Plan"
on:
pull_request:
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
jobs:
terraform:
name: "Terraform"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 0.15.5
- name: Terraform Init
id: init
run: terraform init
- name: Terraform Validate
id: validate
run: terraform validate -no-color
# Aqui vamos gerar o terraform plan em arquivo para passar para o infracost
- name: Terraform Plan
id: plan
run: terraform plan -out tfplan.binary
- name: Terraform show
id: show
run: terraform show -json tfplan.binary > plan.json
working-directory: ${{ env.working-directory }}
- uses: actions/github-script@v6
if: github.event_name == 'pull_request'
env:
PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\`
#### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
#### Terraform Validation 🤖\`${{ steps.validate.outcome }}\`
#### Terraform Plan 📖\`${{ steps.plan.outcome }}\`
<details><summary>Show Plan</summary>
\`\`\`\n
${process.env.PLAN}
\`\`\`
</details>
*Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
- name: Terraform Plan Status
if: steps.plan.outcome == 'failure'
run: exit 1
# Chamar a action do infracost passando a nossa secret
- name: Setup Infracost
uses: infracost/actions/setup@v1
with:
api-key: ${{ secrets.INFRACOST_API_KEY }}
# Passar o arquivo plan.json para o infracost gerar os custos
- name: Generate Infracost JSON
run: infracost breakdown --path plan.json --format json --out-file /tmp/infracost.json
- name: Infracost Actions
uses: infracost/actions/comment@v1
with:
path: /tmp/infracost.json
behavior: update
Enviando um Pull Request para alteração da infraestrutura 📈
Agora vamos simular um aumento da capacidade computacional com 2 instâncias EC2, atualmente estamos utilizando apenas uma instância do tipo t3.micro que tem 2 vCPU e 1GB de memória RAM e vamos para 2 instâncias do tipo m5.large que tem 2 vCPU e 4GB de memória RAM.
Vamos criar uma nova branch no projeto com o nome infracost
para fazer as alterações e enviar o Pull Request.
➜ iac-pipeline git:(main) git checkout -b infracost
Switched to a new branch 'infracost'
➜ iac-pipeline git:(infracost)
Atualizar o arquivo main.ft com as novas instâncias do tipo m5.large
module "ec2_instance" {
source = "terraform-aws-modules/ec2-instance/aws"
for_each = toset(["server-01", "server-02"]) # Duas instâncias ec2
name = "snake-game-${each.key}"
ami = "ami-0cff7528ff583bf9a"
instance_type = "m5.large" # Tipo das instâncias m5.large
vpc_security_group_ids = [aws_security_group.game_snake_sg.id]
subnet_id = module.vpc.public_subnets[0]
user_data = file("userdata.sh")
tags = {
Name = "snake-game-ec2"
Terraform = "true"
Environment = "prod"
Team = "gamer-development"
Application = "snake-game"
Language = "javascript"
}
}
Vamos fazer o commit e o push e criar o Pull Request no GitHub
➜ iac-pipeline git:(infracost) git add .
➜ iac-pipeline git:(infracost) git commit -m "Infra com 2 instancias do tipo m5.large"
[infracost 1d900e7] Infra com 2 instancias do tipo m5.large
4 files changed, 28 insertions(+), 10 deletions(-)
create mode 100644 .terraform.lock.hcl
➜ iac-pipeline git:(infracost) git push origin infracost
Enumerating objects: 14, done.
Counting objects: 100% (14/14), done.
Delta compression using up to 12 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (8/8), 1.59 KiB | 1.59 MiB/s, done.
Total 8 (delta 4), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (4/4), completed with 4 local objects.
To github.com:santospedroh/iac-pipeline.git
8e2c8e8..1d900e7 infracost -> infracost
Após a execução do workflow plan podemos ver nos comentários do Pull Request a estimativa de custo do Infracost.
O valor da nova infra ficou estimado em $142
Conclusão
Utilizando o Infracost dificilmente você vai ter surpresas ao receber a fatura do seu cloud provider, podemos saber a estimativa de custo de cada projeto Terraform, podemos avaliar e discutir os valores em cada Pull Request enviada podendo aprovar ou não o Merge para a branch principal do projeto antes de qualquer mudança ser aplicada.
Todos esses benefícios ajudam bastante no dia a dia de um time que utiliza as práticas DevOps e FinOps.
Espero que tenha gostado desse hands-on, aproveitem bem o Infracost, até a próxima! ✌🏼
Posted on July 7, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.