Skip to content

Commit

Permalink
Add servicebus (#525)
Browse files Browse the repository at this point in the history
* Add servicebus terratest module

* Add tests and terraform module for service bus

* Remove unused func

* Add default values for required variables

* fix format

* Address code review comments

* add test as param

* add `sb` to the resource gourp name

* move postfix to optional variables

* address PR review comments

* fix servicebus_test.go fmt

* address pr comments

Co-authored-by: Hadwa Abdelhalem <[email protected]>
Co-authored-by: Hadwa Gaber <[email protected]>
  • Loading branch information
3 people authored Sep 24, 2021
1 parent 6d96ad5 commit c321790
Show file tree
Hide file tree
Showing 7 changed files with 857 additions and 0 deletions.
31 changes: 31 additions & 0 deletions examples/azure/terraform-azure-servicebus-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Terraform Azure Service Bus Example

This folder contains a Terraform module that deploys resources in [Azure](https://azure.microsoft.com/) to demonstrate how you can use Terratest to write automated tests for your Azure Terraform code. This module deploys a Service Bus.

- A [Service Bus](https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messaging-overview) with the namespace specified in the `namespace_name` variable.

Check out [test/azure/terraform_azure_servicebus_example_test.go](./../../../test/azure/terraform_azure_servicebus_example_test.go) to see how you can write automated tests for this module and validate the configuration of the parameters and options.

**WARNING**: This module and the automated tests for it deploy real resources into your Azure account which can cost you money. The resources are all part of the [Azure Free Account](https://azure.microsoft.com/en-us/free/), so if you haven't used that up,
it should be free, but you are completely responsible for all Azure charges.

## Running this module manually
1. Sign up for [Azure](https://azure.microsoft.com/).
1. Configure your Azure credentials using one of the [supported methods for Azure CLI
tools](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest)
1. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH`.
1. Ensure [environment variables](../README.md#review-environment-variables) are available
1. Run `terraform init`
1. Run `terraform apply`
1. When you're done, run `terraform destroy`.


## Running automated tests against this module
1. Sign up for [Azure](https://azure.microsoft.com/)
1. Configure your Azure credentials using one of the [supported methods for Azure CLI
tools](https://docs.microsoft.com/en-us/cli/azure/azure-cli-configuration?view=azure-cli-latest)
1. Install [Terraform](https://www.terraform.io/) and make sure it's on your `PATH`
1. Configure your Terratest [Go test environment](../README.md)
1. `cd test/azure`
1. `go build terraform_azure_servicebus_example_test.go`
1. `go test -v -run TestTerraformAzureServiceBusExample`
159 changes: 159 additions & 0 deletions examples/azure/terraform-azure-servicebus-example/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AN AZURE SERVICE BUS
# This is an example of how to deploy an Azure service bus.
# See test/terraform_azure_example_test.go for how to write automated tests for this code.
# ---------------------------------------------------------------------------------------------------------------------


# ---------------------------------------------------------------------------------------------------------------------
# CONFIGURE OUR AZURE CONNECTION
# ---------------------------------------------------------------------------------------------------------------------

provider "azurerm" {
version = "~>2.29"
features {}
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY A RESOURCE GROUP
# ---------------------------------------------------------------------------------------------------------------------

resource "azurerm_resource_group" "servicebus_rg" {
name = "terratest-sb-rg-${var.postfix}"
location = var.location
}

# ---------------------------------------------------------------------------------------------------------------------
# Define locals variables
# ---------------------------------------------------------------------------------------------------------------------
locals {
topic_authorization_rules = flatten([
for topic in var.topics : [
for rule in topic.authorization_rules :
merge(
rule, {
topic_name = topic.name
})
]
])

topic_subscriptions = flatten([
for topic in var.topics : [
for subscription in topic.subscriptions :
merge(
subscription, {
topic_name = topic.name
})
]
])

topic_subscription_rules = flatten([
for subscription in local.topic_subscriptions :
merge({
filter_type = ""
sql_filter = ""
action = ""
}, subscription, {
topic_name = subscription.topic_name
subscription_name = subscription.name
})
if subscription.filter_type != null
])
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AZURE Service Bus Namespace
# ---------------------------------------------------------------------------------------------------------------------
resource "azurerm_servicebus_namespace" "servicebus" {
name = "terratest-namespace-${var.namespace_name}"
location = azurerm_resource_group.servicebus_rg.location
resource_group_name = azurerm_resource_group.servicebus_rg.name
sku = var.sku
tags = var.tags
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AZURE Service Bus Namespace Authorization Rule
# ---------------------------------------------------------------------------------------------------------------------
resource "azurerm_servicebus_namespace_authorization_rule" "sbnamespaceauth" {
count = length(var.namespace_authorization_rules)

name = var.namespace_authorization_rules[count.index].policy_name
namespace_name = azurerm_servicebus_namespace.servicebus.name
resource_group_name = azurerm_resource_group.servicebus_rg.name

listen = var.namespace_authorization_rules[count.index].claims.listen
send = var.namespace_authorization_rules[count.index].claims.send
manage = var.namespace_authorization_rules[count.index].claims.manage
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AZURE Service Bus Topic
# ---------------------------------------------------------------------------------------------------------------------
resource "azurerm_servicebus_topic" "sptopic" {
count = length(var.topics)

name = var.topics[count.index].name
resource_group_name = azurerm_resource_group.servicebus_rg.name
namespace_name = azurerm_servicebus_namespace.servicebus.name

requires_duplicate_detection = var.topics[count.index].requires_duplicate_detection
default_message_ttl = var.topics[count.index].default_message_ttl
enable_partitioning = var.topics[count.index].enable_partitioning
support_ordering = var.topics[count.index].support_ordering
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AZURE Service Bus Topic Authorization Rule
# ---------------------------------------------------------------------------------------------------------------------
resource "azurerm_servicebus_topic_authorization_rule" "topicaauth" {
count = length(local.topic_authorization_rules)

name = local.topic_authorization_rules[count.index].policy_name
resource_group_name = azurerm_resource_group.servicebus_rg.name
namespace_name = azurerm_servicebus_namespace.servicebus.name
topic_name = local.topic_authorization_rules[count.index].topic_name

listen = local.topic_authorization_rules[count.index].claims.listen
send = local.topic_authorization_rules[count.index].claims.send
manage = local.topic_authorization_rules[count.index].claims.manage

depends_on = [azurerm_servicebus_topic.sptopic]
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AZURE Service Bus Subscription
# ---------------------------------------------------------------------------------------------------------------------
resource "azurerm_servicebus_subscription" "subscription" {
count = length(local.topic_subscriptions)

name = local.topic_subscriptions[count.index].name
resource_group_name = azurerm_resource_group.servicebus_rg.name
namespace_name = azurerm_servicebus_namespace.servicebus.name
topic_name = local.topic_subscriptions[count.index].topic_name

max_delivery_count = local.topic_subscriptions[count.index].max_delivery_count
lock_duration = local.topic_subscriptions[count.index].lock_duration
forward_to = local.topic_subscriptions[count.index].forward_to
dead_lettering_on_message_expiration = local.topic_subscriptions[count.index].dead_lettering_on_message_expiration

depends_on = [azurerm_servicebus_topic.sptopic]
}

# ---------------------------------------------------------------------------------------------------------------------
# DEPLOY AZURE Service Bus Subscription Rules
# ---------------------------------------------------------------------------------------------------------------------
resource "azurerm_servicebus_subscription_rule" "subrules" {
count = length(local.topic_subscription_rules)

name = local.topic_subscription_rules[count.index].name
resource_group_name = azurerm_resource_group.servicebus_rg.name
namespace_name = azurerm_servicebus_namespace.servicebus.name
topic_name = local.topic_subscription_rules[count.index].topic_name
subscription_name = local.topic_subscription_rules[count.index].subscription_name
filter_type = local.topic_subscription_rules[count.index].filter_type != "" ? "SqlFilter" : null
sql_filter = local.topic_subscription_rules[count.index].sql_filter
action = local.topic_subscription_rules[count.index].action

depends_on = [azurerm_servicebus_subscription.subscription]
}
66 changes: 66 additions & 0 deletions examples/azure/terraform-azure-servicebus-example/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
output "resource_group" {
description = "The resource group name of the Service Bus namespace."
value = azurerm_resource_group.servicebus_rg.name
}

output "namespace_name" {
description = "The namespace name."
value = azurerm_servicebus_namespace.servicebus.name
}

output "namespace_id" {
description = "The namespace ID."
value = azurerm_servicebus_namespace.servicebus.id
sensitive = true
}

output "namespace_authorization_rules" {
description = "List of namespace authorization rules."
value = {
for auth in azurerm_servicebus_namespace_authorization_rule.sbnamespaceauth :
auth.name => {
listen = auth.listen
send = auth.send
manage = auth.manage
}
}
sensitive = true
}

output "service_bus_namespace_default_primary_key" {
description = "The primary access key for the authorization rule RootManageSharedAccessKey which is created automatically by Azure."
value = azurerm_servicebus_namespace.servicebus.default_primary_key
sensitive = true
}

output "service_bus_namespace_default_connection_string" {
description = "The primary connection string for the authorization rule RootManageSharedAccessKey which is created automatically by Azure."
value = azurerm_servicebus_namespace.servicebus.default_primary_connection_string
sensitive = true
}


output "topics" {
description = "All topics with the corresponding subscriptions"
value = {
for topic in azurerm_servicebus_topic.sptopic :
topic.name => {
id = topic.id
name = topic.name
authorization_rules = {
for auth in azurerm_servicebus_topic_authorization_rule.topicaauth :
auth.name => {
listen = auth.listen
send = auth.send
manage = auth.manage
} if topic.name == auth.topic_name
}
subscriptions = {
for subscription in azurerm_servicebus_subscription.subscription :
subscription.name => {
name = subscription.name
} if topic.name == subscription.topic_name
}
}
}
}
85 changes: 85 additions & 0 deletions examples/azure/terraform-azure-servicebus-example/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# ---------------------------------------------------------------------------------------------------------------------
# ENVIRONMENT VARIABLES
# Define these secrets as environment variables
# ---------------------------------------------------------------------------------------------------------------------

# ARM_CLIENT_ID
# ARM_CLIENT_SECRET
# ARM_SUBSCRIPTION_ID
# ARM_TENANT_ID

# ---------------------------------------------------------------------------------------------------------------------
# REQUIRED PARAMETERS
# You must provide a value for each of these parameters.
# ---------------------------------------------------------------------------------------------------------------------

# ---------------------------------------------------------------------------------------------------------------------
# OPTIONAL PARAMETERS
# These parameters have reasonable defaults.
# ---------------------------------------------------------------------------------------------------------------------

variable "location" {
description = "The supported azure location where the resource exists"
type = string
default = "West US2"
}

variable "postfix" {
description = "string mitigate resource name collisions."
type = string
default = "servicebus"
}

variable "namespace_name" {
description = "The name of the namespace."
type = string
default = "testservicebus101"
}

variable "sku" {
description = "The SKU of the namespace. The options are: `Basic`, `Standard`, `Premium`."
type = string
default = "Standard"
}

variable "tags" {
description = " A mapping of tags to assign to the resource."
type = map(string)
default = {}
}

variable "namespace_authorization_rules" {
description = "List of namespace authorization rules."
type = list(object({
policy_name = string
claims = object({ listen = bool, manage = bool, send = bool })
}))
default = []
}

variable "topics" {
description = "topics list"
type = list(object({
name = string
default_message_ttl = string //ISO 8601 format
enable_partitioning = bool
requires_duplicate_detection = bool
support_ordering = bool
authorization_rules = list(object({
policy_name = string
claims = object({ listen = bool, manage = bool, send = bool })

}))
subscriptions = list(object({
name = string
max_delivery_count = number
lock_duration = string //ISO 8601 format
forward_to = string //set with the topic name that will be used for forwarding. Otherwise, set to ""
dead_lettering_on_message_expiration = bool
filter_type = string // SqlFilter is the only supported type now.
sql_filter = string //Required when filter_type is set to SqlFilter
action = string
}))
}))
default = []
}
Loading

0 comments on commit c321790

Please sign in to comment.