diff --git a/terraform/modules/az-asb/README.md b/terraform/modules/az-asb/README.md new file mode 100644 index 00000000..18611740 --- /dev/null +++ b/terraform/modules/az-asb/README.md @@ -0,0 +1,45 @@ +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [azurerm](#provider\_azurerm) | 3.96.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [azurerm_servicebus_namespace.asb](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/servicebus_namespace) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [capacity](#input\_capacity) | The capacity of the Azure Service Bus Namespace | `number` | `1` | no | +| [cmk\_key\_vault\_key\_id](#input\_cmk\_key\_vault\_key\_id) | The Key Vault Key Id to associate with the Azure Service Bus Namespace | `string` | `null` | no | +| [identity\_ids](#input\_identity\_ids) | A list of identities associated with the Azure Service Bus Namespace | `list(string)` | `[]` | no | +| [location](#input\_location) | Azure Region Location | `string` | n/a | yes | +| [minimum\_tls\_version](#input\_minimum\_tls\_version) | The minimum TLS version for the Azure Service Bus Namespace | `string` | `"1.2"` | no | +| [name](#input\_name) | Name of the azure bus namespace | `any` | n/a | yes | +| [network\_rules\_default\_action](#input\_network\_rules\_default\_action) | The default action of the network rules | `string` | `"Deny"` | no | +| [premium\_messaging\_partitions](#input\_premium\_messaging\_partitions) | The number of messaging partitions for the Azure Service Bus Namespace | `number` | `1` | no | +| [public\_network\_access\_enabled](#input\_public\_network\_access\_enabled) | Is public network access enabled for the Azure Service Bus Namespace | `bool` | `false` | no | +| [resource\_group\_name](#input\_resource\_group\_name) | Resource group name of the azure bus namespace | `any` | n/a | yes | +| [sku](#input\_sku) | The SKU of the Azure Service Bus Namespace | `string` | `"Premium"` | no | +| [subnet\_ids](#input\_subnet\_ids) | The list of subnet ids to associate with the Azure Service Bus Namespace | `list(string)` | `[]` | no | +| [tags](#input\_tags) | Tags to associate with resources. | `map(string)` | n/a | yes | +| [trusted\_services\_allowed](#input\_trusted\_services\_allowed) | The list of trusted services allowed | `bool` | `false` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [endpoint](#output\_endpoint) | The endpoint for the Service Bus Namespace. | +| [id](#output\_id) | The ID of the Service Bus Namespace. | diff --git a/terraform/modules/az-asb/checkov.yml b/terraform/modules/az-asb/checkov.yml new file mode 100644 index 00000000..21984293 --- /dev/null +++ b/terraform/modules/az-asb/checkov.yml @@ -0,0 +1,2 @@ +skip-path: + - tests diff --git a/terraform/modules/az-asb/main.tf b/terraform/modules/az-asb/main.tf new file mode 100644 index 00000000..2ee830c1 --- /dev/null +++ b/terraform/modules/az-asb/main.tf @@ -0,0 +1,47 @@ +resource "azurerm_servicebus_namespace" "asb" { + name = var.name + location = var.location + resource_group_name = var.resource_group_name + sku = var.sku + capacity = var.capacity + premium_messaging_partitions = var.premium_messaging_partitions + + public_network_access_enabled = var.public_network_access_enabled + local_auth_enabled = false + minimum_tls_version = var.minimum_tls_version + + dynamic "network_rule_set" { + for_each = length(var.subnet_ids) > 0 ? [1] : [] + content { + public_network_access_enabled = var.public_network_access_enabled + default_action = var.network_rules_default_action + trusted_services_allowed = var.trusted_services_allowed + + dynamic "network_rules" { + for_each = var.subnet_ids + content { + subnet_id = network_rules.value + } + } + } + } + + dynamic "identity" { + for_each = length(var.identity_ids) > 0 ? [1] : [] + content { + type = "UserAssigned" + identity_ids = var.identity_ids + } + } + + dynamic "customer_managed_key" { + for_each = var.cmk_key_vault_key_id != null && length(var.identity_ids) > 0 ? [1] : [] + content { + key_vault_key_id = var.cmk_key_vault_key_id + identity_id = var.identity_ids[0] + infrastructure_encryption_enabled = true + } + } + + tags = var.tags +} diff --git a/terraform/modules/az-asb/outputs.tf b/terraform/modules/az-asb/outputs.tf new file mode 100644 index 00000000..d59af4fc --- /dev/null +++ b/terraform/modules/az-asb/outputs.tf @@ -0,0 +1,9 @@ +output "id" { + description = "The ID of the Service Bus Namespace." + value = azurerm_servicebus_namespace.asb.id +} + +output "endpoint" { + description = "The endpoint for the Service Bus Namespace." + value = azurerm_servicebus_namespace.asb.endpoint +} diff --git a/terraform/modules/az-asb/tests/premium_bus.tftest.hcl b/terraform/modules/az-asb/tests/premium_bus.tftest.hcl new file mode 100644 index 00000000..b664e47f --- /dev/null +++ b/terraform/modules/az-asb/tests/premium_bus.tftest.hcl @@ -0,0 +1,115 @@ +provider "azurerm" { + features { + key_vault { + purge_soft_delete_on_destroy = false + recover_soft_deleted_key_vaults = true + } + } +} + +run "setup" { + module { + source = "./tests/setup_premium" + } +} + +run "plan" { + + command = plan + + variables { + name = "azasbstandard" + location = run.setup.resource_group_location + resource_group_name = run.setup.resource_group_name + + subnet_ids = [run.setup.subnet_id] + + tags = { Environment = "Test" } + } + + assert { + condition = azurerm_servicebus_namespace.asb.name == var.name + error_message = "azurerm_servicebus_namespace name must be set" + } + + assert { + condition = azurerm_servicebus_namespace.asb.resource_group_name == var.resource_group_name + error_message = "azurerm_servicebus_namespace resource_group_name must be set" + } + + assert { + condition = azurerm_servicebus_namespace.asb.location == var.location + error_message = "azurerm_servicebus_namespace location must be set" + } + + assert { + condition = azurerm_servicebus_namespace.asb.sku == "Premium" + error_message = "azurerm_servicebus_namespace sku must be set to Premium by default" + } + + assert { + condition = azurerm_servicebus_namespace.asb.minimum_tls_version == "1.2" + error_message = "azurerm_servicebus_namespace min_tls_version must be set to 1.2" + } + + assert { + condition = azurerm_servicebus_namespace.asb.capacity == 1 + error_message = "azurerm_servicebus_namespace capacity must be set to 1" + } + + assert { + condition = azurerm_servicebus_namespace.asb.public_network_access_enabled == false + error_message = "azurerm_servicebus_namespace public_network_access_enabled must be set to false" + } + + assert { + condition = azurerm_servicebus_namespace.asb.local_auth_enabled == false + error_message = "azurerm_servicebus_namespace local_auth_enabled must be set to false" + } + + assert { + condition = length(azurerm_servicebus_namespace.asb.tags) == 1 + error_message = "azurerm_servicebus_namespace tags must contains one element" + } + +} + +run "apply" { + + command = apply + + variables { + name = "azasbstandard" + location = run.setup.resource_group_location + resource_group_name = run.setup.resource_group_name + + subnet_ids = [run.setup.subnet_id] + + tags = { Environment = "Test" } + } + + assert { + condition = length(azurerm_servicebus_namespace.asb.network_rule_set) == 1 + error_message = "acazurerm_servicebus_namespacer network_rule_set array must contains 1 element" + } + + assert { + condition = length(azurerm_servicebus_namespace.asb.identity) == 0 + error_message = "acazurerm_servicebus_namespacer identity array must contains 0 element" + } + + assert { + condition = length(azurerm_servicebus_namespace.asb.customer_managed_key) == 0 + error_message = "acazurerm_servicebus_namespacer customer_managed_key array must contains 0 element" + } + + assert { + condition = output.id != "" && output.id != null + error_message = "output id is empty" + } + + assert { + condition = output.endpoint != "" && output.endpoint != null + error_message = "output endpoint is empty" + } +} \ No newline at end of file diff --git a/terraform/modules/az-asb/tests/setup_premium/main.tf b/terraform/modules/az-asb/tests/setup_premium/main.tf new file mode 100644 index 00000000..36ef0117 --- /dev/null +++ b/terraform/modules/az-asb/tests/setup_premium/main.tf @@ -0,0 +1,36 @@ +data "azurerm_resource_group" "test" { + name = "tf-test-rg" +} + +resource "azurerm_virtual_network" "asb" { + name = "system-az-asb-vnet" + location = data.azurerm_resource_group.test.location + resource_group_name = data.azurerm_resource_group.test.name + address_space = ["10.0.0.0/16"] + + tags = { + environment = "Test" + } +} + +resource "azurerm_subnet" "asb" { + name = "ResourcesSubnet" + resource_group_name = data.azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.asb.name + address_prefixes = ["10.0.0.0/23"] + + service_endpoints = ["Microsoft.ServiceBus"] +} + + +output "resource_group_name" { + value = data.azurerm_resource_group.test.name +} + +output "resource_group_location" { + value = data.azurerm_resource_group.test.location +} + +output "subnet_id" { + value = azurerm_subnet.asb.id +} diff --git a/terraform/modules/az-asb/tests/setup_standard/main.tf b/terraform/modules/az-asb/tests/setup_standard/main.tf new file mode 100644 index 00000000..c3343148 --- /dev/null +++ b/terraform/modules/az-asb/tests/setup_standard/main.tf @@ -0,0 +1,11 @@ +data "azurerm_resource_group" "test" { + name = "tf-test-rg" +} + +output "resource_group_name" { + value = data.azurerm_resource_group.test.name +} + +output "resource_group_location" { + value = data.azurerm_resource_group.test.location +} diff --git a/terraform/modules/az-asb/tests/standard_bus.tftest.hcl b/terraform/modules/az-asb/tests/standard_bus.tftest.hcl new file mode 100644 index 00000000..73d5d65b --- /dev/null +++ b/terraform/modules/az-asb/tests/standard_bus.tftest.hcl @@ -0,0 +1,121 @@ +provider "azurerm" { + features { + key_vault { + purge_soft_delete_on_destroy = false + recover_soft_deleted_key_vaults = true + } + } +} + +run "setup" { + module { + source = "./tests/setup_standard" + } +} + +run "plan" { + + command = plan + + variables { + name = "azasbstandard" + location = run.setup.resource_group_location + resource_group_name = run.setup.resource_group_name + + sku = "Standard" + capacity = 0 + premium_messaging_partitions = 0 + public_network_access_enabled = true + + tags = { Environment = "Test" } + } + + assert { + condition = azurerm_servicebus_namespace.asb.name == var.name + error_message = "azurerm_servicebus_namespace name must be set" + } + + assert { + condition = azurerm_servicebus_namespace.asb.resource_group_name == var.resource_group_name + error_message = "azurerm_servicebus_namespace resource_group_name must be set" + } + + assert { + condition = azurerm_servicebus_namespace.asb.location == var.location + error_message = "azurerm_servicebus_namespace location must be set" + } + + assert { + condition = azurerm_servicebus_namespace.asb.sku == "Standard" + error_message = "azurerm_servicebus_namespace sku must be set to Standard" + } + + assert { + condition = azurerm_servicebus_namespace.asb.minimum_tls_version == "1.2" + error_message = "azurerm_servicebus_namespace min_tls_version must be set to 1.2" + } + + assert { + condition = azurerm_servicebus_namespace.asb.capacity == 0 + error_message = "azurerm_servicebus_namespace capacity must be set to 0" + } + + assert { + condition = azurerm_servicebus_namespace.asb.public_network_access_enabled == true + error_message = "azurerm_servicebus_namespace public_network_access_enabled must be set to true" + } + + assert { + condition = azurerm_servicebus_namespace.asb.local_auth_enabled == false + error_message = "azurerm_servicebus_namespace local_auth_enabled must be set to false" + } + + assert { + condition = length(azurerm_servicebus_namespace.asb.tags) == 1 + error_message = "azurerm_servicebus_namespace tags must contains one element" + } + +} + +run "apply" { + + command = apply + + variables { + name = "azasbstandard" + location = run.setup.resource_group_location + resource_group_name = run.setup.resource_group_name + + sku = "Standard" + capacity = 0 + premium_messaging_partitions = 0 + public_network_access_enabled = true + + tags = { Environment = "Test" } + } + + assert { + condition = length(azurerm_servicebus_namespace.asb.network_rule_set) == 1 + error_message = "acazurerm_servicebus_namespacer network_rule_set array must contains 1 element" + } + + assert { + condition = length(azurerm_servicebus_namespace.asb.identity) == 0 + error_message = "acazurerm_servicebus_namespacer identity array must contains 0 element" + } + + assert { + condition = length(azurerm_servicebus_namespace.asb.customer_managed_key) == 0 + error_message = "acazurerm_servicebus_namespacer customer_managed_key array must contains 0 element" + } + + assert { + condition = output.id != "" && output.id != null + error_message = "output id is empty" + } + + assert { + condition = output.endpoint != "" && output.endpoint != null + error_message = "output endpoint is empty" + } +} \ No newline at end of file diff --git a/terraform/modules/az-asb/variables.tf b/terraform/modules/az-asb/variables.tf new file mode 100644 index 00000000..ebbcc717 --- /dev/null +++ b/terraform/modules/az-asb/variables.tf @@ -0,0 +1,77 @@ +variable "name" { + description = "Name of the azure bus namespace" +} + +variable "location" { + description = "Azure Region Location" + type = string +} + +variable "resource_group_name" { + description = "Resource group name of the azure bus namespace" +} + +variable "sku" { + description = "The SKU of the Azure Service Bus Namespace" + type = string + default = "Premium" +} + +variable "capacity" { + description = "The capacity of the Azure Service Bus Namespace" + type = number + default = 1 +} + +variable "premium_messaging_partitions" { + description = "The number of messaging partitions for the Azure Service Bus Namespace" + type = number + default = 1 +} + +variable "public_network_access_enabled" { + description = "Is public network access enabled for the Azure Service Bus Namespace" + type = bool + default = false +} + +variable "subnet_ids" { + description = "The list of subnet ids to associate with the Azure Service Bus Namespace" + type = list(string) + default = [] +} + +variable "network_rules_default_action" { + description = "The default action of the network rules" + type = string + default = "Deny" +} + +variable "trusted_services_allowed" { + description = "The list of trusted services allowed" + type = bool + default = false +} + +variable "identity_ids" { + description = "A list of identities associated with the Azure Service Bus Namespace" + type = list(string) + default = [] +} + +variable "cmk_key_vault_key_id" { + description = "The Key Vault Key Id to associate with the Azure Service Bus Namespace" + type = string + default = null +} + +variable "minimum_tls_version" { + description = "The minimum TLS version for the Azure Service Bus Namespace" + type = string + default = "1.2" +} + +variable "tags" { + description = "Tags to associate with resources." + type = map(string) +}