Creating an AWS Budget with Pulumi

Posted July 10, 2024 by Trevor Roberts Jr ‐ 4 min read

It finally happened to me...I forgot to delete an AWS resource. I am usually pretty good about my dev environment clean-up, but this can still happen to the best of us 😅. I decided right then and there to deploy AWS budget alerts and to automate this task with Pulumi. Read on to see how quick and easy it can be...

Introduction

AWS Billing and Cost Management has a handy Budgets capability to allow users to receive alerts based on pre-defined threshold. i.e. send me an alert when I'm at 75% of a monthly spend of $100. You can trigger your alerts based on actual consumption as well as forecasted consumption. Also, your alerts can be sent via e-mail, SNS, or Chatbot.

My Budget...powered by Pulumi

Setting up the budget was fairly straightforward. In your Pulumi resource definition, you provide inputs for the following items:

  • Budget Type: Do you want to base your budget on spend or utilization? Spend is my priority. So, I specified COST here.
BudgetType:      pulumi.String("COST")
  • Limit Amount: The maximum amount that I want to spend per month. I set this relatively low ($15) since this account is for experimentation only.
LimitAmount:     pulumi.String("15.00")
  • Limit Unit: Your currency
LimitUnit:       pulumi.String("USD")
  • Time Period Start: which date and time you wish to start monitoring from
TimePeriodStart: pulumi.String("2024-05-01_00:00")
  • Time Unit: Which interval of time do you want to use when monitoring your budget
TimeUnit:        pulumi.String("MONTHLY")

Next, we configure how to get notified about budget overages.

Notifications

You provide a few inputs that the service needs to get going including your e-mail address and the budget threshold(s) that you wwant to be notified at. For my use case, I wanted to receive a notification at the 75% and 100% thresholds. So, I provided an array of budget notification parameters:

Notifications: budgets.BudgetNotificationArray{
  &budgets.BudgetNotificationArgs{
    ComparisonOperator: pulumi.String("GREATER_THAN"),
    Threshold:          pulumi.Float64(75),
    ThresholdType:      pulumi.String("PERCENTAGE"),
    NotificationType:   pulumi.String("ACTUAL"),
    SubscriberEmailAddresses: pulumi.StringArray{
      pulumi.String(myEmail),
    },
  },
  &budgets.BudgetNotificationArgs{
    ComparisonOperator: pulumi.String("GREATER_THAN"),
    Threshold:          pulumi.Float64(100),
    ThresholdType:      pulumi.String("PERCENTAGE"),
    NotificationType:   pulumi.String("ACTUAL"),
    SubscriberEmailAddresses: pulumi.StringArray{
      pulumi.String(myEmail),
    },
  },
},

My AWS Budget Lives!

After running the pulumi up command, I can see my budget in the AWS console.

Figure 01: Budget Overview
Figure 01: Budget Overview

I can scroll down to the Budget History graph to observe spend levels in previous months including my overage in May 😅

Figure 02: Budget History
Figure 02: Budget History

Finally, I can confirm the budget thresholds that the service will alert me on.

Figure 03: Budget Alerts
Figure 03: Budget Alerts

Pulumi Stack Source Code

The entire Pulumi stack source code can be found below and on GitHub.

package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/budgets"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		// The email addresses to receive notifications.
		const myEmail = "aws_admin@random.domain.com"

		// Create a new budget.
		_, err := budgets.NewBudget(ctx, "budget", &budgets.BudgetArgs{
			Name:            pulumi.String("My Pulumi Budget"),
			BudgetType:      pulumi.String("COST"),
			LimitAmount:     pulumi.String("15.00"), // Monthly budget amount in USD.
			LimitUnit:       pulumi.String("USD"),
			TimePeriodStart: pulumi.String("2024-05-01_00:00"),
			TimeUnit:        pulumi.String("MONTHLY"),
			Notifications: budgets.BudgetNotificationArray{
				&budgets.BudgetNotificationArgs{
					ComparisonOperator: pulumi.String("GREATER_THAN"),
					Threshold:          pulumi.Float64(75),
					ThresholdType:      pulumi.String("PERCENTAGE"),
					NotificationType:   pulumi.String("ACTUAL"),
					SubscriberEmailAddresses: pulumi.StringArray{
						pulumi.String(myEmail),
					},
				},
				&budgets.BudgetNotificationArgs{
					ComparisonOperator: pulumi.String("GREATER_THAN"),
					Threshold:          pulumi.Float64(100),
					ThresholdType:      pulumi.String("PERCENTAGE"),
					NotificationType:   pulumi.String("ACTUAL"),
					SubscriberEmailAddresses: pulumi.StringArray{
						pulumi.String(myEmail),
					},
				},
			},
		})
		if err != nil {
			return err
		}

		return nil
	})
}

Wrapping Things Up...

In this blog post, we discussed how easy it can be to deploy an AWS Budget to help you avoid unexpected spending. Seriously, please consider implementing this in your account regardless of whether it is a prod, dev, or personal use environment.

If you found this article useful, let me know on Twitter!