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

Add servicebus #525

Merged
merged 16 commits into from
Sep 24, 2021
Merged
Show file tree
Hide file tree
Changes from 10 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
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
}

helayoty marked this conversation as resolved.
Show resolved Hide resolved
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
}

helayoty marked this conversation as resolved.
Show resolved Hide resolved
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" {
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
}
}
}
description = "All topics with the corresponding subscriptions"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: description should be first in the output block to be consistent with the other outputs.

}
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