-->

27/11/2023

Azure FinOps using Terraform and Infracost - Finding the hourly or monthly cost before Azure DevOps Deployments

A while ago i created a demo for Azure VWAN using  terraform and Azure DevOps. I dive headfirst without realizing that i am using premium SKU for firewalls and my Dev teant is shutdown for a month in few days due to my billing cap of 230 NZD.

Next time when i create a demo for APIM instances, i dint realize Premium SKU costs 7500 NZD/month. Even before i finish my POC, the teant again shutdown in few hours this time.

Our objective is to find the cost of the IAC we are deploying even before we deploy. 
In this post i will show how we can utilize Infracost a opensource plugin in both VSCode and how we can make it part of our Azure DevOps pipelines to manage cost of the resources we are going to deploy.

Like this :

or like this:

VS Code:

To use Infracost in VSCode, go to infracost.io and download the Infracost.exe and place it in c:\windows folder.

As soon as you did above step, reopen your VS Code and you can start seing the cost of individual components as shown above. But we want to see the cost of the whole deployment, not just resource by resource. 

Now either use your own code base, or you can download my AzureVWAN codebase from my GitRepo. Dont worry i chnaged the SKUs to basic and we are not deploying anything. Our objective is to find cost even before deploying.

Open your TF source code in VS Code and open terminal and runn your tfplan command as shown below:

We need tfplan output into a file, because in VS Code the cost is generated based on the plan. Above command will generate the plan output into a file in current working folder.

Now run below command to authenticate InfraCost.

This will open the web browser for authentication with your Infracost account. This will autamtically get the API token from Infracost and save it in VScode settings. 

Now run below command :

This will utilize the plan file generated earlier and will give you cost of each component and final mothly cost of your deployment as shown below.


When you are doing a multiple versions of build, you can use below command to find the difference of the costs based on your base build. More on this here.


Azure DevOps Pipeline

Unlike we cannot use interactive authentication in middle of your devOps pieline execution, we need a API token to authenticate Infracost API.

Once you done with Infracost.exe, signup on Infracost.io using your Github account or gmail account. Its free, opensource. Finishing signup it will send a Access token(Infracostaccesstoken) to your email Else log onto InfraCost.io and go to Organization settings and you can reteive your API key. 

Go to your Azure DevOps organization settings and install InfraCost extension. If it is not installed earlier, go to "Browse marketplace".


then


Now take any existing Repo on Azure Devops, I am using the same AzureVWAN project on my devops repos.
Create a new pipeline => Azure repos Git => select current project =>  Starter Pipeline.

Copy paste below code:

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
main

pool:
  vmImageubuntu-latest

stages:

########### Prod Deployment ###########  
    - stage"terraform_cost_plan"
      displayName"terraform-cost-plan"
      jobs:
        - jobinfracost
          displayNameRun Infracost          
          steps:
          # If you use private modules, add a base 64 encoded secret
          # called gitSshKeyBase64 with your private key, so Infracost can access
          # private repositories (similar to how Terraform/Terragrunt does).
          # - bash: |
          #     ssh-agent -a $(SSH_AUTH_SOCK)
          #     mkdir -p ~/.ssh
          #     echo "$(echo $GIT_SSH_KEY_BASE_64 | base64 -d)" | tr -d '\r' | ssh-add -
          #     # Update this to github.com, gitlab.com, bitbucket.org, ssh.dev.azure.com or your source control server's domain
          #     ssh-keyscan github.com >> ~/.ssh/known_hosts
          #   displayName: Add GIT_SSH_KEY
          #   env:
          #     GIT_SSH_KEY_BASE_64: $(gitSshKeyBase64)

            # Install the Infracost CLI, see https://github.com/infracost/infracost-azure-devops#infracostsetup
            # for other inputs such as version, and pricingApiEndpoint (for self-hosted users).
            - taskInfracostSetup@2
              displayNameSetup Infracost
              inputs:
                apiKey$(infracostApiKey)

            # Clone the base branch of the pull request (e.g. main/master) into a temp directory.
            - bash: |
                branch=$(System.PullRequest.TargetBranch)
                branch=${branch#refs/heads/}
                git clone $(Build.Repository.Uri) --branch="main" --single-branch /tmp/base --config http.extraheader="AUTHORIZATION: bearer $(System.AccessToken)"
              displayNameCheckout base branch


            # Generate an Infracost cost estimate baseline from the comparison branch, so that Infracost can compare the cost difference.
            - bash: |
                infracost breakdown --path=/tmp/base/$(TF_ROOT) \
                                    --format=json \
                                    --out-file=/tmp/infracost-base.json
              displayNameGenerate Infracost cost estimate baseline

            - bash: |
                sudo apt install jq
              displayNameInstalling JQ to prettyfy output

            - bash: |
                jq . /tmp/infracost-base.json
              displayNamePrinting Baseline cost estimate

            # Generate an Infracost diff and save it to a JSON file.
            - bash: |
                infracost diff --path=$(TF_ROOT) \
                              --format=json \
                              --compare-to=/tmp/infracost-base.json \
                              --out-file=/tmp/infracost.json
              displayNameGenerate Infracost diff

            - bash: |
                      jq . /tmp/infracost-base.json
              displayNamePrinting cost difference estimate


Before you save the pipeline, click varaibles button on top right corner and add a variable with name "infracostapikey" and the value should be the API key you saved/generated/copied earlier from infracost organization settings.

Now save and run the pipeline.
Boom: 

I have even embedded the code to give you the diff next time when you run with chnages to your build.

You can make this pipeline as a one of the build validation task everytime when main or master branch was updated and can create chnage management / goverance / FinOps arround your Azure DevOps deployments. 












No comments:

Post a Comment