Start with Required Attributes - GlennChia/terraform-azurerm-caf GitHub Wiki
It is advisable to first create the directories and files for the new module before developing the module and examples. This page covers the following:
- Directory structure
- Upgrade provider version if needed
- Add Examples
- Connect the files
- Implement the resource with the required attributes
Directory structure
The following structure shows all the files that are relevant for this feature. Some of these files already exist in the repository. Essentially the new files and directories that must be created are:
- examples/consumption_budget/100-consumption-budget-rg/configuration.tfvars
- modules/consumption_budget/*
- consumption_budgets.tf
├───.github
│ └───workflows
│ └───standalone-scenarios.json
├───examples
│ |───consumption_budget
│ | └───100-consumption-budget-rg
| | └───configuration.tfvars
│ |───module.tf
│ └───variables.tf
│───modules
│ └───consumption_budget
│ └───resource_group
│ ├───main.tf
│ ├───output.tf
│ ├───resource_group_budget.tf
│ └───variables.tf
│───consumption_budgets.tf
│───main.tf
│───locals.combined_objects.tf
└───locals.tf
Upgrade provider version if needed
In the previous section, it was identified that the azurerm
version needed to be 2.61.0
. This is changed in the main.tf
file at the root level
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 2.61.0"
}
}
}
Add Examples
Start with the examples/consumption_budget/100-consumption-budget-rg/configuration.tfvars
file, implementing only the required attributes for a start. An example is:
global_settings = {
default_region = "region1"
regions = {
region1 = "southeastasia"
}
random_length = 5
}
resource_groups = {
test = {
name = "test"
}
}
consumption_budgets = {
test_budget = {
resource_group = {
# accepts either id or key to get resource group id
# id = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1"
key = "test"
}
name = "example"
amount = 1000
time_grain = "Monthly"
time_period = {
# uncomment to customize start_date
# start_date = "2022-06-01T00:00:00Z"
}
notifications = {
contact_email = {
enabled = true
threshold = 90.0
operator = "EqualTo"
contact_emails = [
"[email protected]",
"[email protected]",
]
}
}
}
}
Notice that contact_email
is added as an example although it is optional. This is because at apply
time, Terraform produces an error if there isn't an instance of either contact_emails
, contact_groups
, or contact_roles
.
Connect the files
examples
variables.tf
variable "consumption_budgets" {
default = {}
}
- Accepts the variables from the
configuration.tfvars
file defined earlier
module.tf
module "example" {
source = "../.."
# truncated
shared_services = {
consumption_budgets = var.consumption_budgets
# truncated
}
}
root
locals.tf
locals {
# truncated
shared_services = {
consumption_budgets = try(var.shared_services.consumption_budgets, {})
# truncated
}
}
consumption_budgets.tf
module "consumption_budgets" {
source = "./modules/consumption_budget"
for_each = local.shared_services.consumption_budgets
resource_group_id = coalesce(
try(local.combined_objects_resource_groups[try(each.value.resource_group.lz_key, local.client_config.landingzone_key)][each.value.resource_group.key].id, null),
try(each.value.resource_group.id, null)
)
settings = each.value
}
- The
for_each
iterates through each individualconsumption_budget
inconsumption_budgets
and maps those values tosettings
. Thissettings
is important for referencing individual variables in the resource. - The pattern for
resource_group_id
allows theid
to be retrieved from an attribute calledresource_group.key
orresource_group.id
defined in theconfiguration.tfvars
file
Implement the resource with the required attributes
This is done in the modules directory
modules/consumption_budget
variables.tf
variable "settings" {
description = "Configuration object for the consumption budget resource group"
}
variable "resource_group_id" {
description = "The ID of the Resource Group to create the consumption budget for in the form of /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/resourceGroup1"
type = string
}
resource_group_budget.tf
resource "azurerm_consumption_budget_resource_group" "this" {
name = var.settings.name
resource_group_id = var.resource_group_id
amount = var.settings.amount
time_grain = var.settings.time_grain
time_period {
start_date = try(var.settings.time_period.start_date, join("", [formatdate("YYYY-MM", timestamp()), "-01T00:00:00Z"]))
end_date = try(var.settings.time_period.end_date, null)
}
dynamic "notification" {
for_each = var.settings.notifications
content {
operator = notification.value.operator
threshold = notification.value.threshold
contact_emails = try(notification.value.contact_emails, [])
contact_roles = try(notification.value.contact_roles, [])
enabled = try(notification.value.enabled, true)
}
}
}
- Implement the attributes that allow the variables from the
configuration.tfvars
file to be injected. The injection comes fromvar.settings
time_period
is specified in the Terraform Registry documentation as a single required block.notification
is defined as a required block that can have multiple instances
output.tf
output "id" {
description = "The ID of the Resource Group Consumption Budget"
value = azurerm_consumption_budget_resource_group.this.id
}