2 Answers
- Newest
- Most votes
- Most comments
1
Hi,
You are looking for Budget Actions. Please start from here https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-controls.html#budgets-action-role
0
Please, check Terraform and CloudFormation stacks here: https://hands-on.cloud/aws-solutions/aws-budget-sqs-lambda-trigger/. Change the Lambda function based on your needs.
Terraform
# Terraform backend
# Replace to your own configuration:
# https://github.com/hands-on-cloud/cloudformation-templates/tree/master/terraform-remote-state-infrastructure
terraform {
backend "s3" {
bucket = "hands-on-cloud-terraform-remote-state-s3"
key = "budget-lambda-trigger-demo.tfstate"
region = "us-west-2"
encrypt = "true"
dynamodb_table = "hands-on-cloud-terraform-remote-state-dynamodb"
}
}
provider "aws" {
region = "us-east-1"
}
locals {
prefix = "budget-lambda-trigger-demo"
}
data "archive_file" "lambda_zip" {
type = "zip"
source_file = "${path.module}/lambda_function.py"
output_path = "${path.module}/lambda_function.zip"
}
resource "aws_lambda_function" "budget_alert_lambda" {
filename = data.archive_file.lambda_zip.output_path
function_name = "${local.prefix}-lambda"
role = aws_iam_role.lambda_exec_role.arn
handler = "lambda_function.lambda_handler"
source_code_hash = data.archive_file.lambda_zip.output_base64sha256
runtime = "python3.11"
}
resource "aws_iam_role" "lambda_exec_role" {
name = "${local.prefix}-lambda-exec-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "lambda.amazonaws.com"
}
},
]
})
}
resource "aws_sns_topic" "budget_alert_topic" {
name = "${local.prefix}-budget-alert-topic"
}
resource "aws_sns_topic_subscription" "budget_alert_subscription" {
topic_arn = aws_sns_topic.budget_alert_topic.arn
protocol = "lambda"
endpoint = aws_lambda_function.budget_alert_lambda.arn
}
resource "aws_lambda_permission" "allow_sns_to_call_lambda" {
statement_id = "AllowExecutionFromSNS"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.budget_alert_lambda.function_name
principal = "sns.amazonaws.com"
source_arn = aws_sns_topic.budget_alert_topic.arn
}
resource "aws_budgets_budget" "account" {
name = "${local.prefix}-budget-aws-monthly"
budget_type = "COST"
limit_amount = "10"
limit_unit = "USD"
time_period_end = "2087-06-15_00:00"
time_period_start = "2024-01-01_00:00"
time_unit = "MONTHLY"
notification {
comparison_operator = "GREATER_THAN"
threshold = 90
threshold_type = "PERCENTAGE"
notification_type = "FORECASTED"
subscriber_sns_topic_arns = [ aws_sns_topic.budget_alert_topic.arn ]
}
}
CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Description: An AWS CloudFormation stack to trigger a Lambda function on AWS budget alerts.
Resources:
AccountBudget:
Type: AWS::Budgets::Budget
Properties:
Budget:
BudgetName: budget-lambda-trigger-demo-budget-aws-monthly
BudgetLimit:
Amount: 10
Unit: USD
TimeUnit: MONTHLY
BudgetType: COST
TimePeriod:
Start: '1609459200' # Equivalent to 2024-01-01_00:00 in epoch seconds
End: '3666288000' # Equivalent to 2087-06-15_00:00 in epoch seconds
NotificationsWithSubscribers:
- Notification:
NotificationType: FORECASTED
ComparisonOperator: GREATER_THAN
Threshold: 90
ThresholdType: PERCENTAGE
Subscribers:
- SubscriptionType: SNS
Address: !Ref BudgetAlertTopic
BudgetAlertLambda:
Type: AWS::Lambda::Function
Properties:
Handler: index.lambda_handler
Role: !GetAtt LambdaExecutionRole.Arn
Runtime: python3.8
Code:
ZipFile: |
import json
def lambda_handler(event, context):
message = json.loads(event['Records'][0]['Sns']['Message'])
print(f"Budget Alert: {message}")
return {
'statusCode': 200,
'body': json.dumps('Budget alert processed.')
}
Timeout: 10
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: LambdaLoggingPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: arn:aws:logs:*:*:*
BudgetAlertTopic:
Type: AWS::SNS::Topic
LambdaInvokePermission:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref BudgetAlertLambda
Action: lambda:InvokeFunction
Principal: sns.amazonaws.com
SourceArn: !Ref BudgetAlertTopic
BudgetAlertSubscription:
Type: AWS::SNS::Subscription
Properties:
Protocol: lambda
TopicArn: !Ref BudgetAlertTopic
Endpoint: !GetAtt BudgetAlertLambda.Arn
answered 9 months ago
Relevant content
- Accepted Answerasked 4 months ago
- asked 3 years ago
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated 3 years ago
- How can I use a Lambda function to automatically start an AWS Glue job when a crawler run completes?AWS OFFICIALUpdated 2 years ago