Skip to content

Terraform module which creates Cost Explorer budget with notifications with optional SNS resources on AWS https://registry.terraform.io/modules/binbashar/cost-budget

License

Notifications You must be signed in to change notification settings

binbashar/terraform-aws-cost-budget

Repository files navigation

Binbash

AWS Budget Billing module: terraform-aws-cost-mgmt-budget-notif

Terraform module - creates an AWS Budget with notification via SNS enabled with optional sns topic creation (or use a pre-existing one) to alert when a U$S (currency actually configurable) budget forecasted threshold % is reached (currently 100% of the limit_amount).

Provides an AWS budget resource (aws_budgets_budget). Budgets use the cost visualisation provided by Cost Explorer to show you the status of your budgets, to provide forecasts of your estimated costs, and to track your AWS usage, including your free tier usage.

Releases

Requirements

Name Version
terraform >= 0.12.28
aws >= 2.70.0

Providers

Name Version
aws >= 2.70.0

Modules

No modules.

Resources

Name Type
aws_budgets_budget.budget_notifification resource
aws_sns_topic.sns_alert_topic resource
aws_sns_topic_policy.default resource
aws_iam_policy_document.sns-topic-policy data source

Inputs

Name Description Type Default Required
aws_env AWS environment you are deploying to. Will be appended to SNS topic and alarm name. (e.g. dev, stage, prod) any n/a yes
aws_sns_account_id The AWS Account ID which will host the SNS topic as owner string null no
cost_filters_service Budget service cost filter, eg: Amazon Elastic Compute Cloud - Compute / Amazon Relational Database Service / Amazon Redshift / Amazon ElastiCache/ Amazon Elasticsearch Service string null no
cost_type_include_credit A boolean value whether to include credits in the cost budget. bool true no
cost_type_include_discount Specifies whether a budget includes discounts. bool true no
cost_type_include_other_subscription A boolean value whether to include other subscription costs in the cost budget. bool true no
cost_type_include_recurring A boolean value whether to include recurring costs in the cost budget. bool true no
cost_type_include_refund A boolean value whether to include refunds in the cost budget. bool true no
cost_type_include_subscription A boolean value whether to include subscriptions in the cost budget. bool true no
cost_type_include_support A boolean value whether to include support costs in the cost budget. bool true no
cost_type_include_tax A boolean value whether to include support costs in the cost budget. bool true no
cost_type_include_upfront A boolean value whether to include support costs in the cost budget. bool true no
cost_type_use_amortized Specifies whether a budget uses the amortized rate. bool false no
cost_type_use_blended A boolean value whether to use blended costs in the cost budget. bool false no
create_sns_topic Creates a SNS Topic if true. bool true no
currency The unit of measurement used for the budget forecast, actual spend, or budget threshold, such as dollars. Currently COST budget_type is the only supported. string "USD" no
limit_amount The amount of cost or usage being measured for a budget. string n/a yes
notification_threshold % Threshold when the notification should be sent. string "100" no
sns_topic_arns List of SNS topic ARNs to be used. If create_sns_topic is true, it merges the created SNS Topic by this module with this list of ARNs list(string) [] no
tags A mapping of tags to assign to all resources map(string) {} no
time_period_end Time to end string null no
time_period_start Time to start string n/a yes
time_unit The length of time until a budget resets the actual and forecasted spend. Valid values: MONTHLY, QUARTERLY, ANNUALLY. string "MONTHLY" no

Outputs

Name Description
budget_notifications % Threshold when the notification should be sent.
sns_topic_arn List of SNS Topic ARN sto be subscribed to in order to delivery the budget billing notifications

Examples

Budget including all the services in the account

budget-notif-to-new-sns-all-services

module "cost_mgmt_notif" {
  source                = "../../cost-mgmt-budget-notif-bb"

  aws_env               = "${var.aws_profile}"
  currency              = "USD"
  limit_amount          = 500
  time_unit             = "MONTHLY"
  time_period_start     = "2019-01-01_00:00"
  aws_sns_account_id    = "111111111111"

}

output "sns_topic" {
  value = "${module.cost_mgmt_notif.sns_topic}"
}

# Will output the following:
# arn:aws:sns:us-east-1:111111111111:billing-alarm-notification-usd-dev

budget-notif-to-new-sns-all-services-with-time-end

module "cost_mgmt_notif" {
  source                = "../../cost-mgmt-budget-notif-bb"

  aws_env               = "${var.aws_profile}"
  currency              = "USD"
  limit_amount          = 500
  time_unit             = "MONTHLY"
  time_period_start     = "2019-01-01_00:00"
  time_period_end       = "2019-12-31_23:59"
  aws_sns_account_id    = "111111111111"

}

output "sns_topic" {
  value = "${module.cost_mgmt_notif.sns_topic}"
}

# Will output the following:
# arn:aws:sns:us-east-1:111111111111:cost-mgmt-budget-notification-usd-dev

budget-notif-to-pre-existing-sns-all-services

module "cost_mgmt_notif" {
  source                = "../../cost-mgmt-budget-notif-bb"

  aws_env               = "${var.aws_profile}"
  currency              = "USD"
  limit_amount          = 500
  time_unit             = "MONTHLY"
  time_period_start     = "2019-01-01_00:00"
  aws_sns_topic_arn     = "arn:aws:lambda:us-east-1:111111111111:function:bb-root-org-notify_slack"
}

output "sns_topic" {
  value = "${module.cost_mgmt_notif.sns_topic}"
}

# Will output the following:
# arn:aws:lambda:us-east-1:111111111111:function:bb-root-org-notify_slack

budget-notif-to-new-sns-all-services-with-time-end

module "cost_mgmt_notif" {
  source                = "../../cost-mgmt-budget-notif-bb"

  aws_env               = "${var.aws_profile}"
  currency              = "USD"
  limit_amount          = 500
  time_unit             = "MONTHLY"
  time_period_start     = "2019-01-01_00:00"
  time_period_end       = "2019-12-31_23:59"
  aws_sns_topic_arn     = "arn:aws:lambda:us-east-1:111111111111:function:bb-root-org-notify_slack"
}

output "sns_topic" {
  value = "${module.cost_mgmt_notif.sns_topic}"
}

# Will output the following:
# arn:aws:lambda:us-east-1:111111111111:function:bb-root-org-notify_slack

Budget including only specific services in the account

budget-notif-to-new-sns-specific-service

module "cost_mgmt_notif" {
  source                = "../../cost-mgmt-budget-notif-bb"

  aws_env               = "${var.aws_profile}"
  currency              = "USD"
  limit_amount          = 500
  time_unit             = "MONTHLY"
  time_period_start     = "2019-01-01_00:00"
  cost_filters_service  = "Amazon Elastic Compute Cloud - Compute"
  aws_sns_account_id    = "111111111111"

}

output "sns_topic" {
  value = "${module.cost_mgmt_notif.sns_topic}"
}

# Will output the following:
# arn:aws:sns:us-east-1:111111111111:cost-mgmt-budget-notification-usd-dev

budget-notif-to-new-sns-specific-service-with-time-end

module "cost_mgmt_notif" {
  source                = "../../cost-mgmt-budget-notif-bb"

  aws_env               = "${var.aws_profile}"
  currency              = "USD"
  limit_amount          = 500
  time_unit             = "MONTHLY"
  time_period_start     = "2019-01-01_00:00"
  time_period_end       = "2019-12-31_23:59"
  cost_filters_service  = "Amazon Elastic Compute Cloud - Compute"
  aws_sns_account_id    = "111111111111"

}

output "sns_topic" {
  value = "${module.cost_mgmt_notif.sns_topic}"
}

# Will output the following:
# arn:aws:sns:us-east-1:111111111111:cost-mgmt-budget-notification-usd-dev

budget-notif-to-pre-existing-sns-specific-service

module "cost_mgmt_notif" {
  source                = "../../cost-mgmt-budget-notif-bb"

  aws_env               = "${var.aws_profile}"
  currency              = "USD"
  limit_amount          = 500
  time_unit             = "MONTHLY"
  time_period_start     = "2019-01-01_00:00"
  cost_filters_service  = "Amazon Elastic Compute Cloud - Compute"
  aws_sns_topic_arn     = "arn:aws:lambda:us-east-1:111111111111:function:bb-root-org-notify_slack"
}

output "sns_topic" {
  value = "${module.cost_mgmt_notif.sns_topic}"
}

# Will output the following:
# arn:aws:lambda:us-east-1:111111111111:function:bb-root-org-notify_slack

budget-notif-to-pre-existing-sns-specific-service-with-time-end

module "cost_mgmt_notif" {
  source                = "../../cost-mgmt-budget-notif-bb"

  aws_env               = "${var.aws_profile}"
  currency              = "USD"
  limit_amount          = 500
  time_unit             = "MONTHLY"
  time_period_start     = "2019-01-01_00:00"
  time_period_end       = "2019-12-31_23:59"
  cost_filters_service  = "Amazon Elastic Compute Cloud - Compute"
  aws_sns_topic_arn     = "arn:aws:lambda:us-east-1:111111111111:function:bb-root-org-notify_slack"
}

output "sns_topic" {
  value = "${module.cost_mgmt_notif.sns_topic}"
}

# Will output the following:
# arn:aws:lambda:us-east-1:111111111111:function:bb-root-org-notify_slack

Important Considerations

  • If aws_sns_topic_arn = "" the alarm action is automatically set to the created SNS topic, billing-alarm-notification-${lower(currency)}-${aws_env}. YOU MUST MANUALLY SUBSCRIBE TO THIS SNS TOPIC.

    !! MANUAL STEP : !! Subscribe emails to arn:aws:sns:us-east-1:111111111111:billing-alarm-notification-usd-dev for billing alarms

  • If using a pre-existing sns topic please consider the code at sns.tf file as reference. Which will result in a policy most probably similar too

{
  "Version": "2012-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "_budgets_service_access_ID",
      "Effect": "Allow",
      "Principal": {
        "Service": "budgets.amazonaws.com"
      },
      "Action": "SNS:Publish",
      "Resource": "arn:aws:sns:us-east-1:111111111111:sns-topic-slack-notify"
    },
    {
      "Sid": "__default_statement_ID",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SNS:Subscribe",
        "SNS:SetTopicAttributes",
        "SNS:RemovePermission",
        "SNS:Receive",
        "SNS:Publish",
        "SNS:ListSubscriptionsByTopic",
        "SNS:GetTopicAttributes",
        "SNS:DeleteTopic",
        "SNS:AddPermission"
      ],
      "Resource": "arn:aws:sns:us-east-1:111111111111:sns-topic-slack-notify",
      "Condition": {
        "StringEquals": {
          "AWS:SourceOwner": "111111111111"
        }
      }
    }
  ]
}

Binbash Leverage | DevOps Automation Code Library Integration

In order to get the full automated potential of the Binbash Leverage DevOps Automation Code Library
you should initialize all the necessary helper Makefiles.

How?

You must execute the make init-makefiles command at the root context

╭─delivery at delivery-I7567 in ~/terraform/terraform-aws-backup-by-tags on master✔ 20-09-17
╰─⠠⠵ make
Available Commands:
 - init-makefiles     initialize makefiles

Why?

You'll get all the necessary commands to automatically operate this module via a dockerized approach, example shown below

╭─delivery at delivery-I7567 in ~/terraform/terraform-aws-backup-by-tags on master✔ 20-09-17
╰─⠠⠵ make
Available Commands:
 - circleci-validate-config  ## Validate A CircleCI Config (https
 - format-check        ## The terraform fmt is used to rewrite tf conf files to a canonical format and style.
 - format              ## The terraform fmt is used to rewrite tf conf files to a canonical format and style.
 - tf-dir-chmod        ## run chown in ./.terraform to gran that the docker mounted dir has the right permissions
 - version             ## Show terraform version
 - init-makefiles      ## initialize makefiles
╭─delivery at delivery-I7567 in ~/terraform/terraform-aws-backup-by-tags on master✔ 20-09-17
╰─⠠⠵ make format-check
docker run --rm -v /home/delivery/Binbash/repos/Leverage/terraform/terraform-aws-backup-by-tags:"/go/src/project/":rw -v :/config -v /common.config:/common-config/common.config -v ~/.ssh:/root/.ssh -v ~/.gitconfig:/etc/gitconfig -v ~/.aws/bb:/root/.aws/bb -e AWS_SHARED_CREDENTIALS_FILE=/root/.aws/bb/credentials -e AWS_CONFIG_FILE=/root/.aws/bb/config --entrypoint=/bin/terraform -w "/go/src/project/" -it binbash/terraform-awscli-slim:0.12.28 fmt -check

Release Management

CircleCi PR auto-release job

leverage-circleci