It is crucial to monitor Azure costs to ensure that you stay within your budget and avoid unexpected expenses. Azure offers several tools to help monitor and optimize costs, such as Azure Cost Management and Azure Advisor.
Azure Cost Management allows you to track your spending and identify cost-saving opportunities, such as unused resources or inefficient usage patterns. Azure Advisor provides personalized recommendations for optimizing your resources, improving performance, and reducing costs. Additionally, Azure offers tools such as Azure Monitor and Azure Log Analytics to help you monitor and manage your infrastructure’s performance and usage, which can have an impact on your costs.
But today , we can put all that away if the goal was just to see costs in a second , yes we can do this .
Last day , I was scrolling in linked-in where i found this amazing azure-cost-cli that will do this job for us .
azure-cost accumulatedCost -s #########################
Now , I said why not use this command is a use case ?
Use Case
Mr X, who is responsible for managing the costs of the company, understands the importance of monitoring the expenses on a daily basis. However, he prefers not to use the Azure portal, Azure Monitor, or Azure Cost Management tools. Recently, he came across an incredible tool on LinkedIn that provides the same results as these tools, but without having to manually run the command every day. Mr X has requested our assistance in setting up an automated system that sends him an email every day at 18:00 with the cost details.
To meet Mr X’s requirement, we can use Azure Automation ,or azure piplines to run a PowerShell script that retrieves the cost details and sends them via email. We can schedule the script to run daily at a specific time and configure it to send the email to Mr X. This approach will save Mr X time and effort by automating the entire process, ensuring he receives the cost details without any manual intervention.
Pipeline
To provide Mr X with a more readable format of the cost data, you have decided to utilize Azure Pipelines to generate a report. The report will be saved daily in a JSON file format, which will then be used to generate an HTML file with a well-formatted view of the data. This approach will allow Mr X to quickly and easily view the cost data in a more user-friendly manner.
By using Azure Pipelines, you can automate the report generation process, ensuring that the latest cost data is always available in the JSON file. Once the JSON file is generated, you can use tools such as PowerShell or Python scripts to convert it into an HTML file that provides a clear and concise view of the data. This approach will save Mr X valuable time and effort, as he will no longer need to manually interpret the cost data from the JSON file.
we will be saving the file in azure storage account and we will be using azure Logic App in order to send email .
Prerequisites :
- azure
- azure storage account
- azure logic app
- azure Devops organisation
- App registration with service connection to azure devops (with role to app registration as Cost Management Reader)
schedules: - cron: "0 18 * * *" displayName: Daily at 6:00 PM branches: include: - master always: true trigger: batch: true branches: include: - master pool: vmImage: 'windows-latest' steps: - task: AzureCLI@2 displayName: 'Generate Report' inputs: azureSubscription: 'terrafromspn' scriptType: 'ps' scriptLocation: 'inlineScript' inlineScript: | try { dotnet tool install --global azure-cost-cli azure-cost accumulatedCost -s $(subscriptoonid) $path ="$(Build.ArtifactStagingDirectory)\result.json" azure-cost accumulatedCost -s $(subscriptoonid) -o json > $path } catch { # If an error occurs, output the error message Write-Output "Error: $($_.Exception.Message)" } - task: AzurePowerShell@5 displayName: 'Rename Report' inputs: azureSubscription: 'terrafromspn' ScriptType: 'InlineScript' Inline: | $date = Get-Date -Format 'yyyyMMdd' $filename = "result_$($date).json" $filenamehtml = "result.html" Write-Output "Setting file name to $filename" Rename-Item -Path "$(Build.ArtifactStagingDirectory)\result.json" -NewName $filename Write-Output "##vso[task.setvariable variable=ResultFileName]$filename" Write-Output "##vso[task.setvariable variable=ResultFileNamehtml]$filenamehtml" Write-Output "Renamed file to '$newFileName'" # Load the JSON file $json = Get-Content -Raw -Path "$(Build.ArtifactStagingDirectory)\$filename" | ConvertFrom-Json # Start building the HTML table $table = "<table style='border-collapse: collapse; width: 100%;'><thead style='background-color: #f2f2f2;'><tr><th style='padding: 8px; text-align: left;'>Date</th><th style='padding: 8px; text-align: left;'>Cost</th><th style='padding: 8px; text-align: left;'>Currency</th></tr></thead><tbody>" # Add rows to the table for the "cost" data foreach ($cost in $json.cost) { $table += "<tr style='border-bottom: 1px solid #ddd;'><td style='padding: 8px;'>$($cost.Date)</td><td style='padding: 8px;'>$($cost.Cost)</td><td style='padding: 8px;'>$($cost.Currency)</td></tr>" } # End the table $table += "</tbody></table>" # Output the table $table | Out-File -FilePath "$(Build.ArtifactStagingDirectory)\$filenamehtml" azurePowerShellVersion: 'LatestVersion' - task: PublishBuildArtifacts@1 inputs: PathtoPublish: '$(Build.ArtifactStagingDirectory)' ArtifactName: 'result' publishLocation: 'Container' TargetPath: '$(Build.ArtifactStagingDirectory)/$(ResultFileName)' displayName: 'Publish result artifact' - task: AzureFileCopy@3 displayName: 'copy json file' inputs: SourcePath: '$(Build.ArtifactStagingDirectory)/$(ResultFileName)' azureSubscription: 'terrafromspn' Destination: 'AzureBlob' storage: 'azurecostdemo' ContainerName: 'costs' sasTokenTimeOutInMinutes: '640' - task: AzureFileCopy@3 displayName: 'copy html file' inputs: SourcePath: '$(Build.ArtifactStagingDirectory)/$(ResultFileNamehtml)' azureSubscription: 'terrafromspn' Destination: 'AzureBlob' storage: 'azurecostdemo' ContainerName: 'costs' sasTokenTimeOutInMinutes: '640'
Logic APP
The logic app role is so simple , it monitor the storage account , When a blob is added or modified it’s launched in order to send an email to Mr X
Now , Mr X , everyday he will be happy receiving and email that will look like this :
Now Mr X is happy that we have done this quickly , and we can continue working in order to improve our script or add more features to it .
Comments 1