Descobrindo os custos da sua infraestrutura utilizando Infracost
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! ✌🏼