terraform-azurerm-servciebusnamespace code:
main.tf
resource "azurerm_servicebus_namespace" "servicebus_namespace" {
name = regex("^[-\\w\\._\\(\\)]+$", substr("sbns-${var.environment_name}-${var.application_name}-${var.location}", 0, 50))
resource_group_name = var.resource_group_name
location = var.location
sku = var.sku
capacity = var.capacity
tags = local.tags
public_network_access_enabled = false
minimum_tls_version = "1.2"
local_auth_enabled = false
identity = var.identity
customer_managed_key {
key_vault_key_id = var.key_vault_key_id
identity_id = var.identity_id
}
}
outputs.tf
output "id" {
value = azurerm_servicebus_namespace.servicebus_namespace.id
}
output "endpoint" {
value = azurerm_servicebus_namespace.servicebus_namespace.endpoint
}
variables.tf
variable "location" {
type = string
description = "Location of the resource group"
}
variable "environment_name" {
type = string
description = <<EOT
(Optional) The name of the environment where the resources will be deployed.
Options:
- dev
- uat
- test
- prod
Default: dev
EOT
default = "dev"
validation {
condition = can(regex("(dev|uat|test|prod)", var.environment_name))
error_message = "Err: environment name is not valid."
}
}
variable "department" {
type = string
description = "Name of the department"
}
variable "cost_centre" {
type = string
description = "Cost Centre for the Resource or Resource Group"
}
variable "application_name" {
type = string
description = "Name of the application"
}
variable "resource_group_name" {
type = string
description = "Name of the Resource Group where service plan is to be deployed"
}
variable "sku" {
type = string
description = "(Required) Defines which tier to use. Options are Basic, Standard or Premium. Please note that setting this field to Premium will force the creation of a new resource."
validation {
condition = can(index(["Basic", "Standard", "Premium"], var.sku))
error_message = "Invalid value for my_variable. Allowed values are value1, value2, or value3."
}
}
variable "capacity" {
type = number
description = "(Optional) Specifies the capacity. When sku is Premium, capacity can be 1, 2, 4, 8, or 16. When sku is Basic or Standard, capacity can be 0 only."
default = 0 # Set a default value, assuming Basic or Standard sku
validation {
condition = var.sku == "Premium" ? can(index([1, 2, 4, 8, 16], var.capacity)) : var.capacity == 0
error_message = "Invalid value for capacity. When sku is Premium, capacity can be 1, 2, 4, 8, or 16. When sku is Basic or Standard, capacity can be 0 only."
}
}
variable "zone_redundant" {
type = bool
description = "(Optional) Whether or not this resource is zone redundant. sku needs to be Premium. Changing this forces a new resource to be created."
default = false # Set a default value
validation {
condition = var.sku == "Premium" ? !var.zone_redundant : var.zone_redundant
error_message = "Invalid value for zone_redundant. When sku is Premium, zone_redundant should be true. When sku is Basic or Standard, zone_redundant should be false."
}
}
variable "identity" {
type = any
default = null
}
locals.tf
locals {
tags = {
"Environment" = var.environment_name
"Department" = var.department
"Managed By" = "Terraform Open Source"
"Cost Centre" = var.cost_centre
}
}
I am now calling the code in a module as below, unfortunately, it reports errors below
module "servicebus_namespace" {
source = "./.."
location = "australiaeast"
environment_name = "dev"
department = "Data Services"
cost_centre = "ABC101"
application_name = "demo"
resource_group_name = "rg-dev-demo-australiaeast"
}
Error:
terraform init
Initializing the backend...
Initializing modules...
There are some problems with the configuration, described below.
The Terraform configuration must be valid before initialization so that
Terraform can determine which modules and providers need to be installed.
╷
│ Error: Invalid reference in variable validation
│
│ on ../variables.tf line 64, in variable "capacity":
│ 64: condition = var.sku == "Premium" ? can(index([1, 2, 4, 8, 16], var.capacity)) : var.capacity == 0
│
│ The condition for variable "capacity" can only refer to the variable itself, using var.capacity.
╵
╷
│ Error: Invalid reference in variable validation
│
│ on ../variables.tf line 75, in variable "zone_redundant":
│ 75: condition = var.sku == "Premium" ? !var.zone_redundant : var.zone_redundant
│
│ The condition for variable "zone_redundant" can only refer to the variable itself, using var.zone_redundant.
Unable to understand how to resolve this error as I want capacity dependent on what user chooses SKU. Same situation for zone_redundant thing.
The following way of validating one variable inside other is not possible AFAIk:
variables.tf:
variable "capacity" {
type = number
description = "(Optional) Specifies the capacity. When sku is Premium, capacity can be 1, 2, 4, 8, or 16. When sku is Basic or Standard, capacity can be 0 only."
default = 0 # Set a default value, assuming Basic or Standard SKU
validation {
condition = var.sku == "Premium" ? contains([1, 2, 4, 8, 16], var.capacity) : var.capacity == 0
error_message = "Invalid .... capacity can be 1, 2, 4, 8, or 16. When SKU is Basic or Standard, capacity can be 0 only."
}
}
Modify variable validation with different value to validate only self value.
Variables.tf
variable "sku" {
type = string
description = "(Required) Defines which tier to use. Options are Basic, Standard or Premium. Please note that setting this field to Premium will force the creation of a new resource."
validation {
condition = can(index(["Basic", "Standard", "Premium"], var.sku))
error_message = "Invalid value for my_variable. Allowed values are value1, value2, or value3."
}
}
variable "capacity" {
type = number
description = "(Optional) Specifies the capacity. When sku is Premium, capacity can be 1, 2, 4, 8, or 16. When sku is Basic or Standard, capacity can be 0 only."
validation {
condition = can(index([1, 2, 4, 8, 16], var.capacity))
error_message = "Invalid value for capacity. When sku is Premium, capacity can be 1, 2, 4, 8, or 16. When sku is Basic or Standard, capacity can be 0 only."
}
}
Check the following way which worked for me to validate capacity based on sku
Using validate_capacity in locals
Main.tf:
provider "azurerm" {
features {
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
locals {
validate_capacity = var.sku == "Premium" ? can(index([1, 2, 4, 8, 16], var.capacity)) : var.capacity == 0
}
Main.tf:
resource "azurerm_servicebus_namespace" "servicebus_namespace" {
name = "mxxxxxbnme"
resource_group_name = data.azurerm_resource_group.example.name
location = data.azurerm_resource_group.example.location
sku = var.sku
capacity = var.capacity
public_network_access_enabled = false
minimum_tls_version = "1.2"
local_auth_enabled = false
identity = var.identity
customer_managed_key {
...
}
}
output "id" {
value = azurerm_servicebus_namespace.servicebus_namespace.id
}
output "endpoint" {
value = azurerm_servicebus_namespace.servicebus_namespace.endpoint
}
with terraform apply
*executed code:*
**`terraform apply`**
*Acquiring state lock. This may take a few moments...*
**var.application_name**
Name of the application
Enter a value: mynewappn
**var.capacity**
(Optional) Specifies the capacity. When sku is Premium, capacity can be 1, 2, 4, 8, or 16. When sku is Basic or Standard, capacity can be 0 only.
**Enter a value**: 1
**var.cost_centre**
Cost Centre for the Resource or Resource Group
Enter a value: premium
****var.department**
Name of the department**
**Enter a value:** depmuh
var.sku
(Required) Defines which tier to use. Options are Basic, Standard or Premium. Please note that setting this field to Premium will force the creation of a new resource.
Enter a value: Premium
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
**Terraform will perform the following actions:**
azurerm_servicebus_namespace.servicebus_namespace will be created
resource "azurerm_servicebus_namespace" "servicebus_namespace" {
+ capacity = 1
+ default_primary_connection_string = (sensitive value)
+ default_primary_key = (sensitive value)
+ default_secondary_connection_string = (sensitive value)
+ default_secondary_key = (sensitive value)
+ endpoint = (known after apply)
+ id = (known after apply)
+ local_auth_enabled = false
+ location = "westus2"
+ minimum_tls_version = "1.2"
+ name = "mysvbnme"
+ public_network_access_enabled = false
+ resource_group_name = "vttre"
+ sku
= "Premium"
}
**Plan: 1 to add, 0 to change, 0 to destroy.**
**Changes to Outputs:**
+ endpoint = (known after apply)
+ id = (known after apply)
**Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.**
**Enter a value:** yes
**azurerm_servicebus_namespace.servicebus_namespace: Creating....**
Successfully, validated the sku and capacity value which is given as 1 is accepted:
if unsupported values are given for capacity in regards with sku, it triggers error as below: