How can I configure a Lambda function to automatically trigger when the budget for an AWS account exceeds a specific threshold?

0

I've created a Lambda script that monitors the budget and triggers when it exceeds a certain range. However, I want the Lambda function to be triggered automatically when the budget exceeds a specific threshold. How can I achieve this using AWS services or configurations?

2 Antworten
1
profile picture
EXPERTE
beantwortet vor 3 Monaten
profile picture
EXPERTE
überprüft vor 3 Monaten
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
beantwortet vor 3 Monaten

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen