Skip to content

Instantly share code, notes, and snippets.

@maskati
Last active January 9, 2025 07:07
Show Gist options
  • Save maskati/c6e762008d2e951159e91762dab152a7 to your computer and use it in GitHub Desktop.
Save maskati/c6e762008d2e951159e91762dab152a7 to your computer and use it in GitHub Desktop.
Service Bus Emulator on Azure Container Instance

Service Bus Emulator on Azure Container Instance

Deploys within an Azure Container Instance container group with Azure Service Bus Emulator and Azure SQL Edge.

Configures the emulator using Config.json.

You must accept the Service Bus Emulator EULA and Azure SQL Edge EULA.

Service Bus TCP 5672 is open to the internet without authentication. Parameter exposeMssqlPort defines if the MSSQL default port is open to the internet authenticated with mssqlSaPassword which is by default S3rv1c3Bu$Emul@t0r.

Caution

This is an unsecure deployment. Only use for testing.

Deploy to Azure

{
"$schema": "https://raw.githubusercontent.com/Azure/azure-service-bus-emulator-installer/refs/heads/main/ServiceBus-Emulator/Schema/Config-schema.json",
"UserConfig": {
"Namespaces": [
{
"Name": "sbemulatorns",
"Queues": [
{
"Name": "queue.1",
"Properties": {
"DeadLetteringOnMessageExpiration": false,
"DefaultMessageTimeToLive": "PT1H",
"DuplicateDetectionHistoryTimeWindow": "PT20S",
"ForwardDeadLetteredMessagesTo": "",
"ForwardTo": "",
"LockDuration": "PT1M",
"MaxDeliveryCount": 10,
"RequiresDuplicateDetection": false,
"RequiresSession": false
}
}
],
"Topics": [
{
"Name": "topic.1",
"Properties": {
"DefaultMessageTimeToLive": "PT1H",
"DuplicateDetectionHistoryTimeWindow": "PT20S",
"RequiresDuplicateDetection": false
},
"Subscriptions": [
{
"Name": "subscription.1",
"Properties": {
"DeadLetteringOnMessageExpiration": false,
"DefaultMessageTimeToLive": "PT1H",
"LockDuration": "PT1M",
"MaxDeliveryCount": 10,
"ForwardDeadLetteredMessagesTo": "",
"ForwardTo": "",
"RequiresSession": false
},
"Rules": [
{
"Name": "app-prop-filter-1",
"Properties": {
"FilterType": "Correlation",
"CorrelationFilter": {
"ContentType": "application/text",
"CorrelationId": "id1",
"Label": "subject1",
"MessageId": "msgid1",
"ReplyTo": "someQueue",
"ReplyToSessionId": "sessionId",
"SessionId": "session1",
"To": "xyz"
}
}
}
]
},
{
"Name": "subscription.2",
"Properties": {
"DeadLetteringOnMessageExpiration": false,
"DefaultMessageTimeToLive": "PT1H",
"LockDuration": "PT1M",
"MaxDeliveryCount": 10,
"ForwardDeadLetteredMessagesTo": "",
"ForwardTo": "",
"RequiresSession": false
},
"Rules": [
{
"Name": "user-prop-filter-1",
"Properties": {
"FilterType": "Correlation",
"CorrelationFilter": {
"Properties": {
"prop3": "value3"
}
}
}
}
]
},
{
"Name": "subscription.3",
"Properties": {
"DeadLetteringOnMessageExpiration": false,
"DefaultMessageTimeToLive": "PT1H",
"LockDuration": "PT1M",
"MaxDeliveryCount": 10,
"ForwardDeadLetteredMessagesTo": "",
"ForwardTo": "",
"RequiresSession": false
}
}
]
}
]
}
],
"Logging": {
"Type": "Console"
}
}
}
param location string = resourceGroup().location
@description('Accept the [Service Bus Emulator EULA](https://github.com/Azure/azure-service-bus-emulator-installer/blob/main/EMULATOR_EULA.txt).')
param acceptServiceBusEmulatorEula bool = true
@description('Accept the [Azure SQL Edge EULA](https://go.microsoft.com/fwlink/?linkid=2139274).')
param acceptAzureSqlEdgeEula bool = true
@description('The password for the MSSQL sa account. Must adhere to the [SQL Server password policy](https://learn.microsoft.com/en-us/sql/relational-databases/security/password-policy?view=sql-server-ver16).')
@minLength(8)
@maxLength(128)
#disable-next-line secure-secrets-in-params
param mssqlSaPassword string = 'S3rv1c3Bu$Emul@t0r'
@description('Expose the MSSQL port 1433 publicly. Allows you to connect with SQL Server Management Studio or Azure Data Studio.')
param exposeMssqlPort bool = true
resource containerInstance 'Microsoft.ContainerInstance/containerGroups@2024-10-01-preview' = {
name: 'servicebusemulator'
location: location
properties: {
sku: 'Standard'
osType: 'Linux'
restartPolicy: 'Never'
ipAddress: {
type: 'Public'
autoGeneratedDomainNameLabelScope: 'ResourceGroupReuse'
dnsNameLabel: 'servicebusemulator'
ports: exposeMssqlPort ? [
// mssql
{
port: 1433
}
// service bus amqp
{
port: 5672
}
] : [
// service bus amqp
{
port: 5672
}
]
}
containers: [
// https://learn.microsoft.com/en-us/azure/service-bus-messaging/overview-emulator
// https://learn.microsoft.com/en-us/azure/service-bus-messaging/test-locally-with-service-bus-emulator?tabs=automated-script
{
name: 'servicebus-emulator'
properties: {
image: 'mcr.microsoft.com/azure-messaging/servicebus-emulator:latest'
resources: {
requests: {
cpu: 1
memoryInGB: 1
}
}
environmentVariables: [
{
name: 'SQL_SERVER'
value: 'localhost'
}
{
name: 'MSSQL_SA_PASSWORD'
secureValue: mssqlSaPassword
}
{
name: 'ACCEPT_EULA'
value: acceptServiceBusEmulatorEula ? 'Y' : 'N'
}
]
ports: [
{
protocol: 'TCP'
port: 5672
}
]
volumeMounts: [
// mount /ServiceBus_Emulator/ConfigFiles/Config.json
{
name: 'configfilesvolume'
mountPath: '/ServiceBus_Emulator/ConfigFiles'
}
]
}
}
{
name: 'azure-sql-edge'
properties: {
image: 'mcr.microsoft.com/azure-sql-edge:latest'
resources: {
requests: {
cpu: 1
memoryInGB: 1
}
}
environmentVariables: [
{
name: 'MSSQL_SA_PASSWORD'
secureValue: mssqlSaPassword
}
{
name: 'ACCEPT_EULA'
value: acceptAzureSqlEdgeEula ? 'Y' : 'N'
}
]
ports: [
{
protocol: 'TCP'
port: 1433
}
]
}
}
]
volumes: [
{
name: 'configfilesvolume'
secret: {
// Config.json contains service bus emulator configuration
// https://learn.microsoft.com/en-us/azure/service-bus-messaging/test-locally-with-service-bus-emulator?tabs=docker-linux-container#run-the-emulator
'Config.json': loadFileAsBase64('config.json')
}
}
]
}
}
@description('Service Bus Emulator connection string.')
output serviceBusConnectionString string = 'Endpoint=sb://${containerInstance.properties.ipAddress.fqdn};SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;'
@description('Service Bus SQL connection string.')
#disable-next-line outputs-should-not-contain-secrets
output mssqlConnectionString string = 'Server=tcp://${containerInstance.properties.ipAddress.fqdn},1433;Database=master;User Id=sa;Password=${mssqlSaPassword};'
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"metadata": {
"_generator": {
"name": "bicep",
"version": "0.32.4.45862",
"templateHash": "16467593050127205516"
}
},
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"acceptServiceBusEmulatorEula": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Accept the [Service Bus Emulator EULA](https://github.com/Azure/azure-service-bus-emulator-installer/blob/main/EMULATOR_EULA.txt)."
}
},
"acceptAzureSqlEdgeEula": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Accept the [Azure SQL Edge EULA](https://go.microsoft.com/fwlink/?linkid=2139274)."
}
},
"mssqlSaPassword": {
"type": "string",
"defaultValue": "S3rv1c3Bu$Emul@t0r",
"minLength": 8,
"maxLength": 128,
"metadata": {
"description": "The password for the MSSQL sa account. Must adhere to the [SQL Server password policy](https://learn.microsoft.com/en-us/sql/relational-databases/security/password-policy?view=sql-server-ver16)."
}
},
"exposeMssqlPort": {
"type": "bool",
"defaultValue": true,
"metadata": {
"description": "Expose the MSSQL port 1433 publicly. Allows you to connect with SQL Server Management Studio or Azure Data Studio."
}
}
},
"variables": {
"$fxv#0": "ewogICIkc2NoZW1hIjogImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9BenVyZS9henVyZS1zZXJ2aWNlLWJ1cy1lbXVsYXRvci1pbnN0YWxsZXIvcmVmcy9oZWFkcy9tYWluL1NlcnZpY2VCdXMtRW11bGF0b3IvU2NoZW1hL0NvbmZpZy1zY2hlbWEuanNvbiIsCiAgIlVzZXJDb25maWciOiB7CiAgICAiTmFtZXNwYWNlcyI6IFsKICAgICAgewogICAgICAgICJOYW1lIjogInNiZW11bGF0b3JucyIsCiAgICAgICAgIlF1ZXVlcyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgIk5hbWUiOiAicXVldWUuMSIsCiAgICAgICAgICAgICJQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICJEZWFkTGV0dGVyaW5nT25NZXNzYWdlRXhwaXJhdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJEZWZhdWx0TWVzc2FnZVRpbWVUb0xpdmUiOiAiUFQxSCIsCiAgICAgICAgICAgICAgIkR1cGxpY2F0ZURldGVjdGlvbkhpc3RvcnlUaW1lV2luZG93IjogIlBUMjBTIiwKICAgICAgICAgICAgICAiRm9yd2FyZERlYWRMZXR0ZXJlZE1lc3NhZ2VzVG8iOiAiIiwKICAgICAgICAgICAgICAiRm9yd2FyZFRvIjogIiIsCiAgICAgICAgICAgICAgIkxvY2tEdXJhdGlvbiI6ICJQVDFNIiwKICAgICAgICAgICAgICAiTWF4RGVsaXZlcnlDb3VudCI6IDEwLAogICAgICAgICAgICAgICJSZXF1aXJlc0R1cGxpY2F0ZURldGVjdGlvbiI6IGZhbHNlLAogICAgICAgICAgICAgICJSZXF1aXJlc1Nlc3Npb24iOiBmYWxzZQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAiVG9waWNzIjogWwogICAgICAgICAgewogICAgICAgICAgICAiTmFtZSI6ICJ0b3BpYy4xIiwKICAgICAgICAgICAgIlByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgIkRlZmF1bHRNZXNzYWdlVGltZVRvTGl2ZSI6ICJQVDFIIiwKICAgICAgICAgICAgICAiRHVwbGljYXRlRGV0ZWN0aW9uSGlzdG9yeVRpbWVXaW5kb3ciOiAiUFQyMFMiLAogICAgICAgICAgICAgICJSZXF1aXJlc0R1cGxpY2F0ZURldGVjdGlvbiI6IGZhbHNlCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgICJTdWJzY3JpcHRpb25zIjogWwogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJOYW1lIjogInN1YnNjcmlwdGlvbi4xIiwKICAgICAgICAgICAgICAgICJQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAiRGVhZExldHRlcmluZ09uTWVzc2FnZUV4cGlyYXRpb24iOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgIkRlZmF1bHRNZXNzYWdlVGltZVRvTGl2ZSI6ICJQVDFIIiwKICAgICAgICAgICAgICAgICAgIkxvY2tEdXJhdGlvbiI6ICJQVDFNIiwKICAgICAgICAgICAgICAgICAgIk1heERlbGl2ZXJ5Q291bnQiOiAxMCwKICAgICAgICAgICAgICAgICAgIkZvcndhcmREZWFkTGV0dGVyZWRNZXNzYWdlc1RvIjogIiIsCiAgICAgICAgICAgICAgICAgICJGb3J3YXJkVG8iOiAiIiwKICAgICAgICAgICAgICAgICAgIlJlcXVpcmVzU2Vzc2lvbiI6IGZhbHNlCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgIlJ1bGVzIjogWwogICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgIk5hbWUiOiAiYXBwLXByb3AtZmlsdGVyLTEiLAogICAgICAgICAgICAgICAgICAgICJQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgIkZpbHRlclR5cGUiOiAiQ29ycmVsYXRpb24iLAogICAgICAgICAgICAgICAgICAgICAgIkNvcnJlbGF0aW9uRmlsdGVyIjogewogICAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudFR5cGUiOiAiYXBwbGljYXRpb24vdGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICJDb3JyZWxhdGlvbklkIjogImlkMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJMYWJlbCI6ICJzdWJqZWN0MSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJNZXNzYWdlSWQiOiAibXNnaWQxIiwKICAgICAgICAgICAgICAgICAgICAgICAgIlJlcGx5VG8iOiAic29tZVF1ZXVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIlJlcGx5VG9TZXNzaW9uSWQiOiAic2Vzc2lvbklkIiwKICAgICAgICAgICAgICAgICAgICAgICAgIlNlc3Npb25JZCI6ICJzZXNzaW9uMSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJUbyI6ICJ4eXoiCiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBdCiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAiTmFtZSI6ICJzdWJzY3JpcHRpb24uMiIsCiAgICAgICAgICAgICAgICAiUHJvcGVydGllcyI6IHsKICAgICAgICAgICAgICAgICAgIkRlYWRMZXR0ZXJpbmdPbk1lc3NhZ2VFeHBpcmF0aW9uIjogZmFsc2UsCiAgICAgICAgICAgICAgICAgICJEZWZhdWx0TWVzc2FnZVRpbWVUb0xpdmUiOiAiUFQxSCIsCiAgICAgICAgICAgICAgICAgICJMb2NrRHVyYXRpb24iOiAiUFQxTSIsCiAgICAgICAgICAgICAgICAgICJNYXhEZWxpdmVyeUNvdW50IjogMTAsCiAgICAgICAgICAgICAgICAgICJGb3J3YXJkRGVhZExldHRlcmVkTWVzc2FnZXNUbyI6ICIiLAogICAgICAgICAgICAgICAgICAiRm9yd2FyZFRvIjogIiIsCiAgICAgICAgICAgICAgICAgICJSZXF1aXJlc1Nlc3Npb24iOiBmYWxzZQogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICJSdWxlcyI6IFsKICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICJOYW1lIjogInVzZXItcHJvcC1maWx0ZXItMSIsCiAgICAgICAgICAgICAgICAgICAgIlByb3BlcnRpZXMiOiB7CiAgICAgICAgICAgICAgICAgICAgICAiRmlsdGVyVHlwZSI6ICJDb3JyZWxhdGlvbiIsCiAgICAgICAgICAgICAgICAgICAgICAiQ29ycmVsYXRpb25GaWx0ZXIiOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICJQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAgICAgICAgICJwcm9wMyI6ICJ2YWx1ZTMiCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIF0KICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICJOYW1lIjogInN1YnNjcmlwdGlvbi4zIiwKICAgICAgICAgICAgICAgICJQcm9wZXJ0aWVzIjogewogICAgICAgICAgICAgICAgICAiRGVhZExldHRlcmluZ09uTWVzc2FnZUV4cGlyYXRpb24iOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgIkRlZmF1bHRNZXNzYWdlVGltZVRvTGl2ZSI6ICJQVDFIIiwKICAgICAgICAgICAgICAgICAgIkxvY2tEdXJhdGlvbiI6ICJQVDFNIiwKICAgICAgICAgICAgICAgICAgIk1heERlbGl2ZXJ5Q291bnQiOiAxMCwKICAgICAgICAgICAgICAgICAgIkZvcndhcmREZWFkTGV0dGVyZWRNZXNzYWdlc1RvIjogIiIsCiAgICAgICAgICAgICAgICAgICJGb3J3YXJkVG8iOiAiIiwKICAgICAgICAgICAgICAgICAgIlJlcXVpcmVzU2Vzc2lvbiI6IGZhbHNlCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICBdCiAgICAgICAgICB9CiAgICAgICAgXQogICAgICB9CiAgICBdLAogICAgIkxvZ2dpbmciOiB7CiAgICAgICJUeXBlIjogIkNvbnNvbGUiCiAgICB9CiAgfQp9"
},
"resources": [
{
"type": "Microsoft.ContainerInstance/containerGroups",
"apiVersion": "2024-10-01-preview",
"name": "servicebusemulator",
"location": "[parameters('location')]",
"properties": {
"sku": "Standard",
"osType": "Linux",
"restartPolicy": "Never",
"ipAddress": {
"type": "Public",
"autoGeneratedDomainNameLabelScope": "ResourceGroupReuse",
"dnsNameLabel": "servicebusemulator",
"ports": "[if(parameters('exposeMssqlPort'), createArray(createObject('port', 1433), createObject('port', 5672)), createArray(createObject('port', 5672)))]"
},
"containers": [
{
"name": "servicebus-emulator",
"properties": {
"image": "mcr.microsoft.com/azure-messaging/servicebus-emulator:latest",
"resources": {
"requests": {
"cpu": 1,
"memoryInGB": 1
}
},
"environmentVariables": [
{
"name": "SQL_SERVER",
"value": "localhost"
},
{
"name": "MSSQL_SA_PASSWORD",
"secureValue": "[parameters('mssqlSaPassword')]"
},
{
"name": "ACCEPT_EULA",
"value": "[if(parameters('acceptServiceBusEmulatorEula'), 'Y', 'N')]"
}
],
"ports": [
{
"protocol": "TCP",
"port": 5672
}
],
"volumeMounts": [
{
"name": "configfilesvolume",
"mountPath": "/ServiceBus_Emulator/ConfigFiles"
}
]
}
},
{
"name": "azure-sql-edge",
"properties": {
"image": "mcr.microsoft.com/azure-sql-edge:latest",
"resources": {
"requests": {
"cpu": 1,
"memoryInGB": 1
}
},
"environmentVariables": [
{
"name": "MSSQL_SA_PASSWORD",
"secureValue": "[parameters('mssqlSaPassword')]"
},
{
"name": "ACCEPT_EULA",
"value": "[if(parameters('acceptAzureSqlEdgeEula'), 'Y', 'N')]"
}
],
"ports": [
{
"protocol": "TCP",
"port": 1433
}
]
}
}
],
"volumes": [
{
"name": "configfilesvolume",
"secret": {
"Config.json": "[variables('$fxv#0')]"
}
}
]
}
}
],
"outputs": {
"serviceBusConnectionString": {
"type": "string",
"metadata": {
"description": "Service Bus Emulator connection string."
},
"value": "[format('Endpoint=sb://{0};SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=SAS_KEY_VALUE;UseDevelopmentEmulator=true;', reference(resourceId('Microsoft.ContainerInstance/containerGroups', 'servicebusemulator'), '2024-10-01-preview').ipAddress.fqdn)]"
},
"mssqlConnectionString": {
"type": "string",
"metadata": {
"description": "Service Bus SQL connection string."
},
"value": "[format('Server=tcp://{0},1433;Database=master;User Id=sa;Password={1};', reference(resourceId('Microsoft.ContainerInstance/containerGroups', 'servicebusemulator'), '2024-10-01-preview').ipAddress.fqdn, parameters('mssqlSaPassword'))]"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment