Skip to content
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
<!-- markdownlint-disable MD041 -->
## (Unreleased)

* _No changes yet_
ENHANCEMENTS:
* new option to Destroy Service Bus to reduce costs when using make `tre-stop`. This also stops function apps and web apps in core rg to prevent excessive error logs due to the missing service bus. ([#3953](https://github.com/microsoft/AzureTRE/issues/3953))

BUG FIXES:

## (0.28.0) (March 2, 2026)
**BREAKING CHANGES**
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ tre-start: ## ⏩ Start the TRE Service
&& ${MAKEFILE_DIR}/devops/scripts/control_tre.sh start

# Description: Stop the TRE Service.
# Arguments: DELETE_SERVICE_BUS - if set to true, the service bus will also be deleted to save costs.
# # This will deallocate the Azure Firewall public IP and stop the Azure Application Gateway service, stopping billing of both services.
# Example: make tre-stop
tre-stop: ## ⛔ Stop the TRE Service
Expand Down
65 changes: 63 additions & 2 deletions devops/scripts/control_tre.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,19 @@ fi
az config set extension.use_dynamic_install=yes_without_prompt
az --version

if [[ "$1" == *"start"* ]]; then
# shellcheck disable=SC1091
# source "${SCRIPT_DIR}/kv_add_network_exception.sh"

COMMAND="${1:-}"
DELETE_SERVICE_BUS="${DELETE_SERVICE_BUS:-false}"

if [[ "$COMMAND" == "start" ]]; then
# Check if Service Bus exists
if [[ $(az servicebus namespace list --resource-group "${core_rg_name}" --query "[?name=='sb-${TRE_ID}'] | length(@)") == 0 ]]; then
echo -e "\e[33mService Bus namespace 'sb-${TRE_ID}' does not exist.\e[0m"
echo -e "\e[33mIf you ran 'make tre-start' you will also need to run 'make deploy-core' to reprovision the Service Bus.\e[0m"
fi

if [[ $(az network firewall list --output json --query "[?resourceGroup=='${core_rg_name}'&&name=='${fw_name}'] | length(@)") != 0 ]]; then
CURRENT_PUBLIC_IP=$(az network firewall ip-config list -f "${fw_name}" -g "${core_rg_name}" --query "[0].publicIpAddress" -o tsv)
if [ -z "$CURRENT_PUBLIC_IP" ]; then
Expand Down Expand Up @@ -70,9 +82,58 @@ if [[ "$1" == *"start"* ]]; then
az vm start --resource-group "${core_rg_name}" --name "${vm_name}" &
done

echo "Starting Function Apps"
az functionapp list --resource-group "${core_rg_name}" --query "[?state=='Stopped'].name" -o tsv |
while read -r name; do
echo "Starting Function App ${name}"
az functionapp start --resource-group "${core_rg_name}" --name "${name}" &
done

echo "Starting Web Apps"
az webapp list --resource-group "${core_rg_name}" --query "[?state=='Stopped'].name" -o tsv |
while read -r name; do
echo "Starting Web App ${name}"
az webapp start --resource-group "${core_rg_name}" --name "${name}" &
done

# We don't start workspace VMs despite maybe stopping them because we don't know if they need to be on.

elif [[ "$1" == *"stop"* ]]; then
elif [[ "$COMMAND" == "stop" ]]; then

echo "Stopping Function Apps"
az functionapp list --resource-group "${core_rg_name}" --query "[?state=='Running'].name" -o tsv |
while read -r name; do
echo "Stopping Function App ${name}"
az functionapp stop --resource-group "${core_rg_name}" --name "${name}" &
done

echo "Stopping Web Apps"
az webapp list --resource-group "${core_rg_name}" --query "[?state=='Running'].name" -o tsv |
while read -r name; do
echo "Stopping Web App ${name}"
az webapp stop --resource-group "${core_rg_name}" --name "${name}" &
done

# Destroy Service Bus
if [[ "${DELETE_SERVICE_BUS}" == "true" ]]; then
sb_id=$(az servicebus namespace show --name "sb-${TRE_ID}" --resource-group "${core_rg_name}" --query id -o tsv 2>/dev/null || true)
if [[ -n "${sb_id}" ]]; then
echo "Deleting diagnostic settings for Service Bus"
# shellcheck disable=SC2015
{ az monitor diagnostic-settings list --resource "${sb_id}" --query "value[].name" -o tsv 2>/dev/null \
&& az monitor diagnostic-settings list --resource "${sb_id}" --query "[].name" -o tsv 2>/dev/null ; } |
while read -r diag_name; do
if [[ -n "${diag_name}" ]]; then
echo "Deleting diagnostic setting ${diag_name}"
az monitor diagnostic-settings delete --resource "${sb_id}" --name "${diag_name}" --output none || true
fi
done

echo "Destroying Service Bus"
az servicebus namespace delete --name "sb-${TRE_ID}" --resource-group "${core_rg_name}" &
fi
fi

if [[ $(az network firewall list --output json --query "[?resourceGroup=='${core_rg_name}'&&name=='${fw_name}'] | length(@)") != 0 ]]; then
IPCONFIG_NAME=$(az network firewall ip-config list -f "${fw_name}" -g "${core_rg_name}" --query "[0].name" -o tsv)

Expand Down
2 changes: 1 addition & 1 deletion devops/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.6.3"
__version__ = "0.6.4"