Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(subscription): add subscription budgets. #352

Merged
merged 10 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ The following requirements are needed by this module:

The following Modules are called:

### <a name="module_budget"></a> [budget](#module\_budget)

Source: ./modules/budget

Version:

### <a name="module_resourcegroup"></a> [resourcegroup](#module\_resourcegroup)

Source: ./modules/resourcegroup
Expand Down Expand Up @@ -207,6 +213,89 @@ Type: `string`

The following input variables are optional (have default values):

### <a name="input_budget_enabled"></a> [budget\_enabled](#input\_budget\_enabled)

Description: Whether to create budgets.
If enabled, supply the list of budgets in `var.budgets`.

Type: `bool`

Default: `false`

### <a name="input_budgets"></a> [budgets](#input\_budgets)

Description: Map of budgets to create for the subscription.

- `amount` - The total amount of cost to track with the budget.
- `time_grain` - The time grain for the budget. Must be one of Annually, BillingAnnual, BillingMonth, BillingQuarter, Monthly, or Quarterly.
- `time_period_start` - The start date for the budget.
- `time_period_end` - The end date for the budget.
- `relative_scope` - (optional) Scope relative to the created subscription. Omit, or leave blank for subscription scope.
- `notifications` - (optional) The notifications to create for the budget.
- `enabled` - Whether the notification is enabled.
- `operator` - The operator for the notification. Must be one of GreaterThan or GreaterThanOrEqualTo.
- `threshold` - The threshold for the notification. Must be between 0 and 1000.
- `threshold_type` - The threshold type for the notification. Must be one of Actual or Forecasted.
- `contact_emails` - The contact emails for the notification.
- `contact_roles` - The contact roles for the notification.
- `contact_groups` - The contact groups for the notification.
- `locale` - The locale for the notification. Must be in the format xx-xx.

time\_period\_start and time\_period\_end must be UTC in RFC3339 format, e.g. 2018-05-13T07:44:12Z.

Example value:

```terraform
subscription_budgets = {
budget1 = {
amount = 150
time_grain = "Monthly"
time_period_start = "2024-01-01T00:00:00Z"
time_period_end = "2027-12-31T23:59:59Z"
notifications = {
eightypercent = {
enabled = true
operator = "GreaterThan"
threshold = 80
threshold_type = "Actual"
contact_emails = ["[email protected]"]
}
budgetexceeded = {
enabled = true
operator = "GreaterThan"
threshold = 120
threshold_type = "Forecasted"
contact_groups = ["Owner"]
}
}
}
}
```

Type:

```hcl
map(object({
amount = number
time_grain = string
time_period_start = string
time_period_end = string
relative_scope = optional(string, "")
notifications = optional(map(object({
enabled = bool
operator = string
threshold = number
threshold_type = optional(string, "Actual")
contact_emails = optional(list(string), [])
contact_roles = optional(list(string), [])
contact_groups = optional(list(string), [])
locale = optional(string, "en-us")
})), {})
}))
```

Default: `{}`

### <a name="input_disable_telemetry"></a> [disable\_telemetry](#input\_disable\_telemetry)

Description: To disable tracking, we have included this variable with a simple boolean flag.
Expand Down
2 changes: 1 addition & 1 deletion locals.version.tf.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"locals": {
"module_version": "4.0.2"
"module_version": "4.1.0"
}
}
22 changes: 22 additions & 0 deletions main.budget.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# The budget module creates budgets from the data
# supplied in the var.budgets variable
module "budget" {
source = "./modules/budget"
depends_on = [
module.resourcegroup_networkwatcherrg,
module.resourcegroup,
module.subscription,
module.usermanagedidentity,
module.virtualnetwork,
]
for_each = { for k, v in var.budgets : k => v if var.budget_enabled }
budget_name = each.key
budget_scope = "${local.subscription_resource_id}${each.value.relative_scope}"
budget_amount = each.value.amount
budget_time_grain = each.value.time_grain
budget_notifications = each.value.notifications
budget_time_period = {
end_date = each.value.time_period_end
start_date = each.value.time_period_start
}
}
123 changes: 123 additions & 0 deletions modules/budget/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<!-- BEGIN_TF_DOCS -->
# Landing zone budget submodule

## Overview

Creates a budget in Azure. Designed to be instantiated multiple times to create multiple budgets.

## Notes

See [README.md](https://github.com/Azure/terraform-azurerm-lz-vending#readme) in the parent module for more information.

## Example

```terraform
module "budget" {
source = "Azure/lz-vending/azurerm/modules/roleassignment"
version = "<version>" # change this to your desired version, https://www.terraform.io/language/expressions/version-constraints

budget_name = "budget1"
budget_amount = 100
budget_scope = "/subscriptions/00000000-0000-0000-0000-000000000000"
budget_time_grain = "Monthly"
budget_time_period = {
start_date = "2024-01-01"
end_date = "2025-01-01"
}
}
```

## Documentation
<!-- markdownlint-disable MD033 -->

## Requirements

The following requirements are needed by this module:

- <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) (>= 1.3.0)

- <a name="requirement_azapi"></a> [azapi](#requirement\_azapi) (>= 1.11.0)

## Modules

No modules.

<!-- markdownlint-disable MD013 -->
## Required Inputs

The following input variables are required:

### <a name="input_budget_amount"></a> [budget\_amount](#input\_budget\_amount)

Description: The total amount of cost to track with the budget.

Type: `number`

### <a name="input_budget_name"></a> [budget\_name](#input\_budget\_name)

Description: The name of the budget.

Type: `string`

### <a name="input_budget_scope"></a> [budget\_scope](#input\_budget\_scope)

Description: The scope of the budget.

Type: `string`

### <a name="input_budget_time_grain"></a> [budget\_time\_grain](#input\_budget\_time\_grain)

Description: The time grain of the budget.

Type: `string`

### <a name="input_budget_time_period"></a> [budget\_time\_period](#input\_budget\_time\_period)

Description: The time period of the budget.

Type:

```hcl
object({
start_date = string
end_date = string
})
```

## Optional Inputs

The following input variables are optional (have default values):

### <a name="input_budget_notifications"></a> [budget\_notifications](#input\_budget\_notifications)

Description: The notifications for the budget.

Type:

```hcl
map(object({
enabled = bool
operator = string
threshold = number
threshold_type = optional(string, "Actual")
contact_emails = optional(list(string), [])
contact_roles = optional(list(string), [])
contact_groups = optional(list(string), [])
locale = optional(string, "en-us")
}))
```

Default: `{}`

## Resources

The following resources are used by this module:

- [azapi_resource.budget](https://registry.terraform.io/providers/azure/azapi/latest/docs/resources/resource) (resource)

## Outputs

No outputs.

<!-- markdownlint-enable -->
<!-- END_TF_DOCS -->
Empty file added modules/budget/footer.md
Empty file.
27 changes: 27 additions & 0 deletions modules/budget/header.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Landing zone budget submodule

## Overview

Creates a budget in Azure. Designed to be instantiated multiple times to create multiple budgets.

## Notes

See [README.md](https://github.com/Azure/terraform-azurerm-lz-vending#readme) in the parent module for more information.

## Example

```terraform
module "budget" {
source = "Azure/lz-vending/azurerm/modules/roleassignment"
version = "<version>" # change this to your desired version, https://www.terraform.io/language/expressions/version-constraints

budget_name = "budget1"
budget_amount = 100
budget_scope = "/subscriptions/00000000-0000-0000-0000-000000000000"
budget_time_grain = "Monthly"
budget_time_period = {
start_date = "2024-01-01"
end_date = "2025-01-01"
}
}
```
15 changes: 15 additions & 0 deletions modules/budget/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
locals {
notifications = {
for key, notification in var.budget_notifications :
key => {
enabled = notification.enabled
operator = notification.operator
threshold = notification.threshold
thresholdType = notification.threshold_type
contactEmails = notification.contact_emails
contactRoles = notification.contact_roles
contactGroups = notification.contact_groups
locale = notification.locale
}
}
}
19 changes: 19 additions & 0 deletions modules/budget/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
resource "azapi_resource" "budget" {
type = "Microsoft.Consumption/budgets@2021-10-01"
name = var.budget_name
parent_id = var.budget_scope
body = jsonencode({
properties = {
amount = var.budget_amount
category = "Cost"
notifications = local.notifications
timeGrain = var.budget_time_grain
timePeriod = {
endDate = var.budget_time_period.end_date
startDate = var.budget_time_period.start_date
}
}
})
}


1 change: 1 addition & 0 deletions modules/budget/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

9 changes: 9 additions & 0 deletions modules/budget/terraform.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = ">= 1.3.0"
required_providers {
azapi = {
source = "azure/azapi"
version = ">= 1.11.0"
}
}
}
Loading
Loading