Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
15 changes: 15 additions & 0 deletions messaging/azure-service-bus/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Terraform
.terraform/
*.tfstate
*.tfstate.backup
.terraform.lock.hcl
*.tfvars
*.auto.tfvars
*.tfvars.json

# Dynamically generated backend config
deployment/backend.tf
permissions/backend.tf

# Build output directory
output/
36 changes: 36 additions & 0 deletions messaging/azure-service-bus/deployment/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
data "azurerm_servicebus_namespace" "existing" {
name = var.servicebus_namespace_name
resource_group_name = var.resource_group_name
}

resource "azurerm_servicebus_queue" "queues" {
for_each = { for q in var.queues : q.name => q }

name = each.value.name
namespace_id = data.azurerm_servicebus_namespace.existing.id
}

resource "azurerm_servicebus_topic" "topics" {
for_each = { for t in var.topics : t.name => t }

name = each.value.name
namespace_id = data.azurerm_servicebus_namespace.existing.id
}

resource "azurerm_servicebus_subscription" "subscriptions" {
for_each = {
for item in flatten([
for t in var.topics : [
for s in t.subscriptions : {
key = "${t.name}--${s.name}"
topic_name = t.name
sub_name = s.name
}
]
]) : item.key => item
}

name = each.value.sub_name
topic_id = azurerm_servicebus_topic.topics[each.value.topic_name].id
max_delivery_count = 10
}
29 changes: 29 additions & 0 deletions messaging/azure-service-bus/deployment/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
output "namespace_name" {
description = "Service Bus namespace name"
value = data.azurerm_servicebus_namespace.existing.name
}

output "namespace_id" {
description = "Service Bus namespace resource ID"
value = data.azurerm_servicebus_namespace.existing.id
}

output "queues" {
description = "Created queues"
value = [
for name, queue in azurerm_servicebus_queue.queues : {
name = name
id = queue.id
}
]
}

output "topics" {
description = "Created topics with their subscriptions"
value = [
for name, topic in azurerm_servicebus_topic.topics : {
name = name
id = topic.id
}
]
}
13 changes: 13 additions & 0 deletions messaging/azure-service-bus/deployment/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}

provider "azurerm" {
features {}
subscription_id = var.subscription_id
}
33 changes: 33 additions & 0 deletions messaging/azure-service-bus/deployment/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
variable "subscription_id" {
description = "Azure subscription ID"
type = string
}

variable "resource_group_name" {
description = "Resource group where the Service Bus namespace exists"
type = string
}

variable "servicebus_namespace_name" {
description = "Existing Service Bus namespace name"
type = string
}

variable "queues" {
description = "List of queues to create in the namespace"
type = list(object({
name = string
}))
default = []
}

variable "topics" {
description = "List of topics to create with their subscriptions"
type = list(object({
name = string
subscriptions = list(object({
name = string
}))
}))
default = []
}
52 changes: 52 additions & 0 deletions messaging/azure-service-bus/entrypoint/entrypoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash
set -euo pipefail

if [ -z "${NP_ACTION_CONTEXT:-}" ]; then
echo "NP_ACTION_CONTEXT is not set. Exiting."
exit 1
fi

CLEAN_CONTEXT=$(echo "$NP_ACTION_CONTEXT" | sed "s/^'//;s/'$//")
export NP_ACTION_CONTEXT="$CLEAN_CONTEXT"

export CONTEXT=$(echo "$CLEAN_CONTEXT" | jq '.notification')
export SERVICE_ACTION=$(echo "$CONTEXT" | jq -r '.slug')
export SERVICE_ACTION_TYPE=$(echo "$CONTEXT" | jq -r '.type')
export NOTIFICATION_ACTION=$(echo "$CONTEXT" | jq -r '.action')
export LINK=$(echo "$CONTEXT" | jq '.link')

ACTION_SOURCE=service
IS_LINK_ACTION=$(echo "$CONTEXT" | jq '.link != null')

if [ "$IS_LINK_ACTION" = "true" ]; then
ACTION_SOURCE=link
fi

export WORKING_DIRECTORY="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

SERVICE_PATH=""
OVERRIDES_PATH=""

for arg in "$@"; do
case $arg in
--service-path=*)
SERVICE_PATH="${arg#*=}"
;;
--overrides-path=*)
OVERRIDES_PATH="${arg#*=}"
;;
*)
echo "Unknown argument: $arg"
exit 1
;;
esac
done

SERVICE_PATH="${SERVICE_PATH:-$(dirname "$WORKING_DIRECTORY")}"
OVERRIDES_PATH="${OVERRIDES_PATH:-$SERVICE_PATH/overrides}"

export SERVICE_PATH
export OVERRIDES_PATH
export ACTION_SOURCE

np service-action exec --live-output --live-report --script="$WORKING_DIRECTORY/$ACTION_SOURCE"
34 changes: 34 additions & 0 deletions messaging/azure-service-bus/entrypoint/link
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

echo "Executing link action=$SERVICE_ACTION type=$SERVICE_ACTION_TYPE"

ACTION_TO_EXECUTE="$SERVICE_ACTION_TYPE"

case "$SERVICE_ACTION_TYPE" in
"custom")
ACTION_TO_EXECUTE="$SERVICE_ACTION"
;;
"create")
ACTION_TO_EXECUTE="link"
;;
"delete")
ACTION_TO_EXECUTE="unlink"
;;
esac

WORKFLOW_PATH="$SERVICE_PATH/workflows/azure/$ACTION_TO_EXECUTE.yaml"
OVERRIDES_WORKFLOW_PATH="$OVERRIDES_PATH/workflows/azure/$ACTION_TO_EXECUTE.yaml"
VALUES_PATH="$SERVICE_PATH/values.yaml"

CMD="np service workflow exec --workflow $WORKFLOW_PATH"

if [[ -f "$VALUES_PATH" ]]; then
CMD="$CMD --values $VALUES_PATH"
fi

if [[ -f "$OVERRIDES_WORKFLOW_PATH" ]]; then
CMD="$CMD --overrides $OVERRIDES_WORKFLOW_PATH"
fi

echo "Executing command: $CMD"
eval "$CMD"
28 changes: 28 additions & 0 deletions messaging/azure-service-bus/entrypoint/service
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

echo "Executing service action=$SERVICE_ACTION type=$SERVICE_ACTION_TYPE"

ACTION_TO_EXECUTE="$SERVICE_ACTION_TYPE"

case "$SERVICE_ACTION_TYPE" in
"custom")
ACTION_TO_EXECUTE="$SERVICE_ACTION"
;;
esac

WORKFLOW_PATH="$SERVICE_PATH/workflows/azure/$ACTION_TO_EXECUTE.yaml"
OVERRIDES_WORKFLOW_PATH="$OVERRIDES_PATH/workflows/azure/$ACTION_TO_EXECUTE.yaml"
VALUES_PATH="$SERVICE_PATH/values.yaml"

CMD="np service workflow exec --workflow $WORKFLOW_PATH"

if [[ -f "$VALUES_PATH" ]]; then
CMD="$CMD --values $VALUES_PATH"
fi

if [[ -f "$OVERRIDES_WORKFLOW_PATH" ]]; then
CMD="$CMD --overrides $OVERRIDES_WORKFLOW_PATH"
fi

echo "Executing command: $CMD"
eval "$CMD"
8 changes: 8 additions & 0 deletions messaging/azure-service-bus/permissions/locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
locals {
# Azure built-in role names for Service Bus
role_names = {
sender = "Azure Service Bus Data Sender"
receiver = "Azure Service Bus Data Receiver"
owner = "Azure Service Bus Data Owner"
}
}
15 changes: 15 additions & 0 deletions messaging/azure-service-bus/permissions/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
data "azurerm_servicebus_namespace" "existing" {
name = var.servicebus_namespace_name
resource_group_name = var.resource_group_name
}

data "azurerm_linux_web_app" "app" {
name = var.app_name
resource_group_name = var.app_resource_group
}

resource "azurerm_role_assignment" "servicebus_access" {
scope = data.azurerm_servicebus_namespace.existing.id
role_definition_name = local.role_names[var.access_level]
principal_id = data.azurerm_linux_web_app.app.identity[0].principal_id
}
24 changes: 24 additions & 0 deletions messaging/azure-service-bus/permissions/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
output "namespace_id" {
description = "Service Bus namespace resource ID"
value = data.azurerm_servicebus_namespace.existing.id
}

output "namespace_name" {
description = "Service Bus namespace name"
value = data.azurerm_servicebus_namespace.existing.name
}

output "app_principal_id" {
description = "The principal ID of the app's managed identity"
value = data.azurerm_linux_web_app.app.identity[0].principal_id
}

output "role_assignment_id" {
description = "Role assignment resource ID"
value = azurerm_role_assignment.servicebus_access.id
}

output "access_level" {
description = "Granted access level"
value = var.access_level
}
13 changes: 13 additions & 0 deletions messaging/azure-service-bus/permissions/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
}
}

provider "azurerm" {
features {}
subscription_id = var.subscription_id
}
35 changes: 35 additions & 0 deletions messaging/azure-service-bus/permissions/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
variable "subscription_id" {
description = "Azure subscription ID"
type = string
}

variable "resource_group_name" {
description = "Resource group where the Service Bus namespace exists"
type = string
}

variable "servicebus_namespace_name" {
description = "Service Bus namespace name"
type = string
}

variable "app_name" {
description = "Azure App Service name (the NP scope consuming this service)"
type = string
}

variable "app_resource_group" {
description = "Resource group where the Azure App Service lives"
type = string
}

variable "access_level" {
description = "Access level to grant: sender, receiver, or owner"
type = string
default = "receiver"

validation {
condition = contains(["sender", "receiver", "owner"], var.access_level)
error_message = "access_level must be one of: sender, receiver, owner."
}
}
Loading