2025-04-22 11:46:24 +02:00
{
"$schema" : "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#" ,
"contentVersion" : "1.0.0.0" ,
"metadata" : {
"_generator" : {
"name" : "bicep" ,
2025-06-10 10:56:50 +02:00
"version" : "0.36.1.42791" ,
2025-07-22 13:52:54 +02:00
"templateHash" : "6903609709428763780"
2025-04-22 11:46:24 +02:00
}
} ,
"parameters" : {
"stackName" : {
"type" : "string" ,
"metadata" : {
"description" : "Stack name"
}
} ,
"certificateType" : {
"type" : "string" ,
"defaultValue" : "selfsigned" ,
"allowedValues" : [
"selfsigned" ,
"owncert" ,
"letsencrypt"
] ,
"metadata" : {
"description" : "[selfsigned] Not recommended for production use. If you don't have a FQDN, (DomainName parameter) you can use this option to generate a self-signed certificate.\n[owncert] Valid for productions environments. If you have a FQDN, (DomainName parameter)\nand an Elastic IP, you can use this option to use your own certificate.\n[letsencrypt] Valid for production environments. If you have a FQDN, (DomainName parameter)\nand an Elastic IP, you can use this option to generate a Let's Encrypt certificate.\n"
}
} ,
"domainName" : {
"type" : "string" ,
"metadata" : {
2025-05-13 11:01:22 +02:00
"description" : "Domain name for the OpenVidu Deployment."
2025-04-22 11:46:24 +02:00
}
} ,
"ownPublicCertificate" : {
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
"description" : "If certificate type is 'owncert', this parameter will be used to specify the public certificate"
}
} ,
"ownPrivateCertificate" : {
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
"description" : "If certificate type is 'owncert', this parameter will be used to specify the private certificate"
}
} ,
"letsEncryptEmail" : {
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
"description" : "If certificate type is 'letsencrypt', this email will be used for Let's Encrypt notifications"
}
} ,
2025-05-23 13:53:24 +02:00
"publicIpAddressObject" : {
"type" : "object" ,
2025-04-22 11:46:24 +02:00
"metadata" : {
"description" : "Name of the PublicIPAddress resource in Azure when using certificateType 'owncert' or 'letsencrypt'"
}
} ,
"turnDomainName" : {
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
"description" : "(Optional) Domain name for the TURN server with TLS. Only needed if your users are behind restrictive firewalls"
}
} ,
"turnOwnPublicCertificate" : {
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
"description" : "(Optional) This setting is applicable if the certificate type is set to 'owncert' and the TurnDomainName is specified."
}
} ,
"turnOwnPrivateCertificate" : {
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
"description" : "(Optional) This setting is applicable if the certificate type is set to 'owncert' and the TurnDomainName is specified."
}
} ,
"openviduLicense" : {
"type" : "securestring" ,
"metadata" : {
"description" : "Visit https://openvidu.io/account"
}
} ,
"rtcEngine" : {
"type" : "string" ,
"defaultValue" : "pion" ,
"allowedValues" : [
"pion" ,
"mediasoup"
] ,
"metadata" : {
"description" : "RTCEngine media engine to use"
}
} ,
"masterNodeInstanceType" : {
"type" : "string" ,
"defaultValue" : "Standard_B2s" ,
"allowedValues" : [
"Standard_B1s" ,
"Standard_B1ms" ,
"Standard_B2s" ,
"Standard_B2ms" ,
"Standard_B4ms" ,
"Standard_B8ms" ,
"Standard_D2_v3" ,
"Standard_D4_v3" ,
"Standard_D8_v3" ,
"Standard_D16_v3" ,
"Standard_D32_v3" ,
"Standard_D48_v3" ,
"Standard_D64_v3" ,
"Standard_D2_v4" ,
"Standard_D4_v4" ,
"Standard_D8_v4" ,
"Standard_D16_v4" ,
"Standard_D32_v4" ,
"Standard_D48_v4" ,
"Standard_D64_v4" ,
"Standard_D96_v4" ,
"Standard_D2_v5" ,
"Standard_D4_v5" ,
"Standard_D8_v5" ,
"Standard_D16_v5" ,
"Standard_D32_v5" ,
"Standard_D48_v5" ,
"Standard_D64_v5" ,
"Standard_D96_v5" ,
"Standard_F2" ,
"Standard_F4" ,
"Standard_F8" ,
"Standard_F16" ,
"Standard_F32" ,
"Standard_F64" ,
"Standard_F72" ,
"Standard_F2s_v2" ,
"Standard_F4s_v2" ,
"Standard_F8s_v2" ,
"Standard_F16s_v2" ,
"Standard_F32s_v2" ,
"Standard_F64s_v2" ,
"Standard_F72s_v2" ,
"Standard_E2_v3" ,
"Standard_E4_v3" ,
"Standard_E8_v3" ,
"Standard_E16_v3" ,
"Standard_E32_v3" ,
"Standard_E48_v3" ,
"Standard_E64_v3" ,
"Standard_E96_v3" ,
"Standard_E2_v4" ,
"Standard_E4_v4" ,
"Standard_E8_v4" ,
"Standard_E16_v4" ,
"Standard_E32_v4" ,
"Standard_E48_v4" ,
"Standard_E64_v4" ,
"Standard_E2_v5" ,
"Standard_E4_v5" ,
"Standard_E8_v5" ,
"Standard_E16_v5" ,
"Standard_E32_v5" ,
"Standard_E48_v5" ,
"Standard_E64_v5" ,
"Standard_E96_v5" ,
"Standard_M64" ,
"Standard_M128" ,
"Standard_M208ms_v2" ,
"Standard_M416ms_v2" ,
"Standard_L4s_v2" ,
"Standard_L8s_v2" ,
"Standard_L16s_v2" ,
"Standard_L32s_v2" ,
"Standard_L64s_v2" ,
"Standard_L80s_v2" ,
"Standard_NC6" ,
"Standard_NC12" ,
"Standard_NC24" ,
"Standard_NC24r" ,
"Standard_ND6s" ,
"Standard_ND12s" ,
"Standard_ND24s" ,
"Standard_ND24rs" ,
"Standard_NV6" ,
"Standard_NV12" ,
"Standard_NV24" ,
"Standard_H8" ,
"Standard_H16" ,
"Standard_H16r" ,
"Standard_H16mr" ,
"Standard_HB120rs_v2" ,
"Standard_HC44rs" ,
"Standard_DC2s" ,
"Standard_DC4s" ,
"Standard_DC2s_v2" ,
"Standard_DC4s_v2" ,
"Standard_DC8s_v2" ,
"Standard_DC16s_v2" ,
"Standard_DC32s_v2" ,
"Standard_A1_v2" ,
"Standard_A2_v2" ,
"Standard_A4_v2" ,
"Standard_A8_v2" ,
"Standard_A2m_v2" ,
"Standard_A4m_v2" ,
"Standard_A8m_v2"
] ,
"metadata" : {
"description" : "Specifies the EC2 instance type for your OpenVidu Master Node"
}
} ,
"masterNodesDiskSize" : {
"type" : "int" ,
"defaultValue" : 100 ,
"metadata" : {
"description" : "Size of the disk in GB"
}
} ,
"mediaNodeInstanceType" : {
"type" : "string" ,
"defaultValue" : "Standard_B2s" ,
"allowedValues" : [
"Standard_B1s" ,
"Standard_B1ms" ,
"Standard_B2s" ,
"Standard_B2ms" ,
"Standard_B4ms" ,
"Standard_B8ms" ,
"Standard_D2_v3" ,
"Standard_D4_v3" ,
"Standard_D8_v3" ,
"Standard_D16_v3" ,
"Standard_D32_v3" ,
"Standard_D48_v3" ,
"Standard_D64_v3" ,
"Standard_D2_v4" ,
"Standard_D4_v4" ,
"Standard_D8_v4" ,
"Standard_D16_v4" ,
"Standard_D32_v4" ,
"Standard_D48_v4" ,
"Standard_D64_v4" ,
"Standard_D96_v4" ,
"Standard_D2_v5" ,
"Standard_D4_v5" ,
"Standard_D8_v5" ,
"Standard_D16_v5" ,
"Standard_D32_v5" ,
"Standard_D48_v5" ,
"Standard_D64_v5" ,
"Standard_D96_v5" ,
"Standard_F2" ,
"Standard_F4" ,
"Standard_F8" ,
"Standard_F16" ,
"Standard_F32" ,
"Standard_F64" ,
"Standard_F72" ,
"Standard_F2s_v2" ,
"Standard_F4s_v2" ,
"Standard_F8s_v2" ,
"Standard_F16s_v2" ,
"Standard_F32s_v2" ,
"Standard_F64s_v2" ,
"Standard_F72s_v2" ,
"Standard_E2_v3" ,
"Standard_E4_v3" ,
"Standard_E8_v3" ,
"Standard_E16_v3" ,
"Standard_E32_v3" ,
"Standard_E48_v3" ,
"Standard_E64_v3" ,
"Standard_E96_v3" ,
"Standard_E2_v4" ,
"Standard_E4_v4" ,
"Standard_E8_v4" ,
"Standard_E16_v4" ,
"Standard_E32_v4" ,
"Standard_E48_v4" ,
"Standard_E64_v4" ,
"Standard_E2_v5" ,
"Standard_E4_v5" ,
"Standard_E8_v5" ,
"Standard_E16_v5" ,
"Standard_E32_v5" ,
"Standard_E48_v5" ,
"Standard_E64_v5" ,
"Standard_E96_v5" ,
"Standard_M64" ,
"Standard_M128" ,
"Standard_M208ms_v2" ,
"Standard_M416ms_v2" ,
"Standard_L4s_v2" ,
"Standard_L8s_v2" ,
"Standard_L16s_v2" ,
"Standard_L32s_v2" ,
"Standard_L64s_v2" ,
"Standard_L80s_v2" ,
"Standard_NC6" ,
"Standard_NC12" ,
"Standard_NC24" ,
"Standard_NC24r" ,
"Standard_ND6s" ,
"Standard_ND12s" ,
"Standard_ND24s" ,
"Standard_ND24rs" ,
"Standard_NV6" ,
"Standard_NV12" ,
"Standard_NV24" ,
"Standard_H8" ,
"Standard_H16" ,
"Standard_H16r" ,
"Standard_H16mr" ,
"Standard_HB120rs_v2" ,
"Standard_HC44rs" ,
"Standard_DC2s" ,
"Standard_DC4s" ,
"Standard_DC2s_v2" ,
"Standard_DC4s_v2" ,
"Standard_DC8s_v2" ,
"Standard_DC16s_v2" ,
"Standard_DC32s_v2" ,
"Standard_A1_v2" ,
"Standard_A2_v2" ,
"Standard_A4_v2" ,
"Standard_A8_v2" ,
"Standard_A2m_v2" ,
"Standard_A4m_v2" ,
"Standard_A8m_v2"
] ,
"metadata" : {
"description" : "Specifies the EC2 instance type for your OpenVidu Media Nodes"
}
} ,
"adminUsername" : {
"type" : "string" ,
"metadata" : {
"description" : "Username for the Virtual Machine."
}
} ,
"adminSshKey" : {
2025-05-23 13:53:24 +02:00
"type" : "secureObject" ,
2025-04-22 11:46:24 +02:00
"metadata" : {
"description" : "SSH Key for the Virtual Machine."
}
} ,
"initialNumberOfMediaNodes" : {
"type" : "int" ,
"defaultValue" : 1 ,
"metadata" : {
"description" : "Number of initial media nodes to deploy"
}
} ,
"minNumberOfMediaNodes" : {
"type" : "int" ,
"defaultValue" : 1 ,
"metadata" : {
"description" : "Minimum number of media nodes to deploy"
}
} ,
"maxNumberOfMediaNodes" : {
"type" : "int" ,
"defaultValue" : 5 ,
"metadata" : {
"description" : "Maximum number of media nodes to deploy"
}
} ,
"scaleTargetCPU" : {
"type" : "int" ,
"defaultValue" : 50 ,
"metadata" : {
"description" : "Target CPU percentage to scale up or down"
}
} ,
2025-06-18 16:26:50 +02:00
"additionalInstallFlags" : {
"type" : "string" ,
"defaultValue" : ""
} ,
2025-04-22 11:46:24 +02:00
"datetime" : {
"type" : "string" ,
"defaultValue" : "[utcNow('u')]"
} ,
"automationAccountName" : {
"type" : "string" ,
2025-05-27 11:18:05 +02:00
"defaultValue" : "" ,
2025-04-22 11:46:24 +02:00
"metadata" : {
"description" : "Automation Account Name to create a runbook inside it for scale in"
}
2025-04-23 13:26:33 +02:00
} ,
2025-05-13 11:01:22 +02:00
"storageAccountName" : {
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
"description" : "Name of an existing storage account. It is essential that this parameter is filled just when you want to save recordings and still using the same container after an update. If not specified, a new storage account will be generated."
}
} ,
2025-06-10 16:30:41 +02:00
"appDataContainerName" : {
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
"description" : "Name of the bucket where OpenVidu will store the recordings if a new Storage account is being creating. If not specified, a default bucket will be created. If you want to use an existing storage account, fill this parameter with the name of the container where the recordings are stored."
}
} ,
"clusterDataContainerName" : {
2025-04-23 13:26:33 +02:00
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
2025-05-20 18:46:31 +02:00
"description" : "Name of the bucket where OpenVidu will store the recordings if a new Storage account is being creating. If not specified, a default bucket will be created. If you want to use an existing storage account, fill this parameter with the name of the container where the recordings are stored."
2025-04-23 13:26:33 +02:00
}
2025-04-22 11:46:24 +02:00
}
} ,
"variables" : {
"masterNodeVMSettings" : {
"osDiskType" : "StandardSSD_LRS" ,
"osDiskSize" : "[parameters('masterNodesDiskSize')]" ,
"ubuntuOSVersion" : {
"publisher" : "Canonical" ,
"offer" : "0001-com-ubuntu-server-jammy" ,
"sku" : "22_04-lts-gen2" ,
"version" : "latest"
} ,
"linuxConfiguration" : {
"disablePasswordAuthentication" : true ,
"ssh" : {
"publicKeys" : [
{
"path" : "[format('/home/{0}/.ssh/authorized_keys', parameters('adminUsername'))]" ,
2025-05-23 13:53:24 +02:00
"keyData" : "[parameters('adminSshKey').sshPublicKey]"
2025-04-22 11:46:24 +02:00
}
]
}
}
} ,
"mediaNodeVMSettings" : {
"vmName" : "[format('{0}-VN-MediaNode', parameters('stackName'))]" ,
"osDiskType" : "StandardSSD_LRS" ,
"ubuntuOSVersion" : {
"publisher" : "Canonical" ,
"offer" : "0001-com-ubuntu-server-jammy" ,
"sku" : "22_04-lts-gen2" ,
"version" : "latest"
} ,
"linuxConfiguration" : {
"disablePasswordAuthentication" : true ,
"ssh" : {
"publicKeys" : [
{
"path" : "[format('/home/{0}/.ssh/authorized_keys', parameters('adminUsername'))]" ,
2025-05-23 13:53:24 +02:00
"keyData" : "[parameters('adminSshKey').sshPublicKey]"
2025-04-22 11:46:24 +02:00
}
]
}
}
} ,
"turnTLSIsEnabled" : "[not(equals(parameters('turnDomainName'), ''))]" ,
"fqdn" : "[parameters('domainName')]" ,
"keyVaultName" : "[format('{0}-keyvault', parameters('stackName'))]" ,
"location" : "[resourceGroup().location]" ,
"tenantId" : "[subscription().tenantId]" ,
"deploymentUser" : "[deployer().objectId]" ,
"stringInterpolationParamsMaster1" : {
"domainName" : "[parameters('domainName')]" ,
"turnDomainName" : "[parameters('turnDomainName')]" ,
"certificateType" : "[parameters('certificateType')]" ,
"letsEncryptEmail" : "[parameters('letsEncryptEmail')]" ,
"ownPublicCertificate" : "[parameters('ownPublicCertificate')]" ,
"ownPrivateCertificate" : "[parameters('ownPrivateCertificate')]" ,
"turnOwnPublicCertificate" : "[parameters('turnOwnPublicCertificate')]" ,
"turnOwnPrivateCertificate" : "[parameters('turnOwnPrivateCertificate')]" ,
"fqdn" : "[variables('fqdn')]" ,
"openviduLicense" : "[parameters('openviduLicense')]" ,
"rtcEngine" : "[parameters('rtcEngine')]" ,
"keyVaultName" : "[variables('keyVaultName')]" ,
2025-06-18 16:26:50 +02:00
"masterNodeNum" : "1" ,
"additionalInstallFlags" : "[parameters('additionalInstallFlags')]"
2025-04-22 11:46:24 +02:00
} ,
"stringInterpolationParamsMaster2" : {
"domainName" : "[parameters('domainName')]" ,
"turnDomainName" : "[parameters('turnDomainName')]" ,
"certificateType" : "[parameters('certificateType')]" ,
"letsEncryptEmail" : "[parameters('letsEncryptEmail')]" ,
"ownPublicCertificate" : "[parameters('ownPublicCertificate')]" ,
"ownPrivateCertificate" : "[parameters('ownPrivateCertificate')]" ,
"turnOwnPublicCertificate" : "[parameters('turnOwnPublicCertificate')]" ,
"turnOwnPrivateCertificate" : "[parameters('turnOwnPrivateCertificate')]" ,
"fqdn" : "[variables('fqdn')]" ,
"openviduLicense" : "[parameters('openviduLicense')]" ,
"rtcEngine" : "[parameters('rtcEngine')]" ,
"keyVaultName" : "[variables('keyVaultName')]" ,
2025-06-18 16:26:50 +02:00
"masterNodeNum" : "2" ,
"additionalInstallFlags" : "[parameters('additionalInstallFlags')]"
2025-04-22 11:46:24 +02:00
} ,
"stringInterpolationParamsMaster3" : {
"domainName" : "[parameters('domainName')]" ,
"turnDomainName" : "[parameters('turnDomainName')]" ,
"certificateType" : "[parameters('certificateType')]" ,
"letsEncryptEmail" : "[parameters('letsEncryptEmail')]" ,
"ownPublicCertificate" : "[parameters('ownPublicCertificate')]" ,
"ownPrivateCertificate" : "[parameters('ownPrivateCertificate')]" ,
"turnOwnPublicCertificate" : "[parameters('turnOwnPublicCertificate')]" ,
"turnOwnPrivateCertificate" : "[parameters('turnOwnPrivateCertificate')]" ,
"fqdn" : "[variables('fqdn')]" ,
"openviduLicense" : "[parameters('openviduLicense')]" ,
"rtcEngine" : "[parameters('rtcEngine')]" ,
"keyVaultName" : "[variables('keyVaultName')]" ,
2025-06-18 16:26:50 +02:00
"masterNodeNum" : "3" ,
"additionalInstallFlags" : "[parameters('additionalInstallFlags')]"
2025-04-22 11:46:24 +02:00
} ,
"stringInterpolationParamsMaster4" : {
"domainName" : "[parameters('domainName')]" ,
"turnDomainName" : "[parameters('turnDomainName')]" ,
"certificateType" : "[parameters('certificateType')]" ,
"letsEncryptEmail" : "[parameters('letsEncryptEmail')]" ,
"ownPublicCertificate" : "[parameters('ownPublicCertificate')]" ,
"ownPrivateCertificate" : "[parameters('ownPrivateCertificate')]" ,
"turnOwnPublicCertificate" : "[parameters('turnOwnPublicCertificate')]" ,
"turnOwnPrivateCertificate" : "[parameters('turnOwnPrivateCertificate')]" ,
"fqdn" : "[variables('fqdn')]" ,
"openviduLicense" : "[parameters('openviduLicense')]" ,
"rtcEngine" : "[parameters('rtcEngine')]" ,
"keyVaultName" : "[variables('keyVaultName')]" ,
2025-06-18 16:26:50 +02:00
"masterNodeNum" : "4" ,
"additionalInstallFlags" : "[parameters('additionalInstallFlags')]"
2025-04-22 11:46:24 +02:00
} ,
2025-06-26 22:02:58 +02:00
"installScriptTemplateMaster" : "#!/bin/bash -x\nset -e\nOPENVIDU_VERSION=main\nDOMAIN=\n\n# Assume azure cli is installed\n\napt-get update && apt-get install -y \\\n curl \\\n unzip \\\n jq \\\n wget\n\n# Configure Domain\nif [[ \"${domainName}\" == '' ]]; then\n DOMAIN=${fqdn}\nelse\n DOMAIN=${domainName}\nfi\n\n# Wait for the keyvault availability\nMAX_WAIT=100\nWAIT_INTERVAL=1\nELAPSED_TIME=0\nset +e\nwhile true; do\n # Check keyvault availability\n az keyvault secret list --vault-name ${keyVaultName} \n\n # If it is available, exit the loop\n if [ $? -eq 0 ]; then\n break\n fi\n\n # If not, wait and check again incrementing the time\n ELAPSED_TIME=$((ELAPSED_TIME + WAIT_INTERVAL))\n\n # If exceeded the maximum time, exit with error\n if [ $ELAPSED_TIME -ge $MAX_WAIT ]; then\n exit 1\n fi\n\n # Esperar antes de la próxima comprobación\n sleep $WAIT_INTERVAL\ndone\nset -e\n\nMASTER_NODE_NUM=${masterNodeNum}\n\n# Get own private IP\nPRIVATE_IP=$(curl -H Metadata:true --noproxy \"*\" \"http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress?api-version=2017-08-01&format=text\")\n\n# Store current private IP\nPRIVATE_IP=\"$(/usr/local/bin/store_secret.sh save MASTER-NODE-${masterNodeNum}-PRIVATE-IP $PRIVATE_IP)\"\n\n\nif [[ $MASTER_NODE_NUM -eq 1 ]] && [[ \"$ALL_SECRETS_GENERATED\" == \"\" || \"$ALL_SECRETS_GENERATED\" == \"false\" ]]; then\n DOMAIN=\"$(/usr/local/bin/store_secret.sh save DOMAIN-NAME \"${domainName}\")\"\n if [[ -n \"${turnDomainName}\" ]]; then\n LIVEKIT_TURN_DOMAIN_NAME=\"$(/usr/local/bin/store_secret.sh save LIVEKIT-TURN-DOMAIN-NAME \"${turnDomainName}\")\"\n fi\n if [[ \"${certificateType}\" == \"letsencrypt\" ]]; then\n LETSENCRYPT_EMAIL=$(/usr/local/bin/store_secret.sh save LETSENCRYPT-EMAIL \"${letsEncryptEmail}\")\n fi\n\n # Store usernames and generate random passwords\n OPENVIDU_PRO_LICENSE=\"$(/usr/local/bin/store_secret.sh save OPENVIDU-PRO-LICENSE \"${openviduLicense}\")\"\n OPENVIDU_RTC_ENGINE=\"$(/usr/local/bin/store_secret.sh save OPENVIDU-RTC-ENGINE \"${rtcEngine}\")\"\n REDIS_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate REDIS-PASSWORD)\"\n MONGO_ADMIN_USERNAME=\"$(/usr/local/bin/store_secret.sh save MONGO-ADMIN-USERNAME \"mongoadmin\")\"\n MONGO_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate MONGO-ADMIN-PASSWORD)\"\n MONGO_REPLICA_SET_KEY=\"$(/usr/local/bin/store_secret.sh generate MONGO-REPLICA-SET-KEY)\"\n MINIO_ACCESS_KEY=\"$(/usr/local/bin/store_secret.sh save MINIO-ACCESS-KEY \"minioadmin\")\"\n MINIO_SECRET_KEY=\"$(/usr/local/bin/store_secret.sh generate MINIO-SECRET-KEY)\"\n DASHBOARD_ADMIN_USERNAME=\"$(/usr/local/bin/store_secret.sh save DASHBOARD-ADMIN-USERNAME \"dashboardadmin\")\"\n DASHBOARD_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate DASHBOARD-ADMIN-PASSWORD)\"\n GRAFANA_ADMIN_USERNAME=\"$(/usr/local/bin/store_secret.sh save GRAFANA-ADMIN-USERNAME \"grafanaadmin\")\"\n GRAFANA_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate GRAFANA-ADMIN-PASSWORD)\"\n DEFAULT_APP_USERNAME=\"$(/usr/local/bin/store_secret.sh save DEFAULT-APP-USERNAME \"calluser\")\"\n DEFAULT_APP_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate DEFAULT-APP-PASSWORD)\"\n DEFAULT_APP_ADMIN_USERNAME=\"$(/usr/local/bin/store_secret.sh save DEFAULT-APP-ADMIN-USERNAME \"calladmin\")\"\n DEFAULT_APP_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate DEFAULT-APP-ADMIN-PASSWORD)\"\n LIVEKIT_API_KEY=\"$(/usr/local/bin/store_secret.sh generate LIVEKIT-API-KEY \"API\" 12)\"\n LIVEKIT_API_SECRET=\"$(/usr/local/bin/store_secret.sh generate LIVEKIT-API-SECRET)\"\n OPENVIDU_VERSION=\"$(/usr/local/bin/store_secret.sh save OPENVIDU-VERSION \"${OPENVIDU_VERSION}\")\"\n ENABLED_MODULES=\"$(/usr/local/bin/store_secret.sh save ENABLED-MODULES \"observability,app,v2compatibility\")\"\n ALL_SECRETS_GENERATED=\"$(/usr/local/bin/store_secret.sh save ALL-SECRETS-GENERATED \"true\")\" \ n f i \ n \ n w h i l e true ; d o \ n M A S T E R _ N O D E _ 1 _ P R I V A T E _ I P = $ ( a z k e y v a u l t s e c r e t s h o w - - v a u l t - n a m e $ { k e y V
2025-04-22 11:46:24 +02:00
"after_installScriptTemplateMaster" : "#!/bin/bash\nset -e\n\naz login --identity --allow-no-subscriptions > /dev/null\n\n# Generate URLs\nDOMAIN=$(az keyvault secret show --vault-name ${keyVaultName} --name DOMAIN-NAME --query value -o tsv)\nDASHBOARD_URL=\"https://${DOMAIN}/dashboard/\"\nGRAFANA_URL=\"https://${DOMAIN}/grafana/\"\nMINIO_URL=\"https://${DOMAIN}/minio-console/\"\n\n# Update shared secret\naz keyvault secret set --vault-name ${keyVaultName} --name DOMAIN-NAME --value $DOMAIN\naz keyvault secret set --vault-name ${keyVaultName} --name DASHBOARD-URL --value $DASHBOARD_URL\naz keyvault secret set --vault-name ${keyVaultName} --name GRAFANA-URL --value $GRAFANA_URL\naz keyvault secret set --vault-name ${keyVaultName} --name MINIO-URL --value $MINIO_URL\n\naz keyvault secret show --vault-name ${keyVaultName} --name MINIO-URL\n\nif [[ $? -ne 0 ]]; then\n echo \"Error updating keyvault\"\nfi\n" ,
"update_config_from_secretScriptTemplateMaster" : "#!/bin/bash\nset -e\n\naz login --identity --allow-no-subscriptions > /dev/null\n\n# Installation directory\nINSTALL_DIR=\"/opt/openvidu\"\nCLUSTER_CONFIG_DIR=\"${INSTALL_DIR}/config/cluster\"\nMASTER_NODE_CONFIG_DIR=\"${INSTALL_DIR}/config/node\"\n\n# Replace DOMAIN_NAME\nexport DOMAIN=$(az keyvault secret show --vault-name ${keyVaultName} --name DOMAIN-NAME --query value -o tsv)\nif [[ -n \"$DOMAIN\" ]]; then\n sed -i \"s/DOMAIN_NAME=.*/DOMAIN_NAME=$DOMAIN/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nelse\n exit 1\nfi\n\n# Replace LIVEKIT_TURN_DOMAIN_NAME\nexport LIVEKIT_TURN_DOMAIN_NAME=$(az keyvault secret show --vault-name ${keyVaultName} --name LIVEKIT-TURN-DOMAIN-NAME --query value -o tsv)\nif [[ -n \"$LIVEKIT_TURN_DOMAIN_NAME\" ]]; then\n sed -i \"s/LIVEKIT_TURN_DOMAIN_NAME=.*/LIVEKIT_TURN_DOMAIN_NAME=$LIVEKIT_TURN_DOMAIN_NAME/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nfi\n\nif [[ ${certificateType} == \"letsencrypt\" ]]; then\n export LETSENCRYPT_EMAIL=$(az keyvault secret show --vault-name ${keyVaultName} --name LETSENCRYPT-EMAIL --query value -o tsv)\n sed -i \"s/LETSENCRYPT_EMAIL=.*/LETSENCRYPT_EMAIL=$LETSENCRYPT_EMAIL/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nfi\n\n# Get the rest of the values\nexport REDIS_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name REDIS-PASSWORD --query value -o tsv)\nexport OPENVIDU_RTC_ENGINE=$(az keyvault secret show --vault-name ${keyVaultName} --name OPENVIDU-RTC-ENGINE --query value -o tsv)\nexport OPENVIDU_PRO_LICENSE=$(az keyvault secret show --vault-name ${keyVaultName} --name OPENVIDU-PRO-LICENSE --query value -o tsv)\nexport MONGO_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name MONGO-ADMIN-USERNAME --query value -o tsv)\nexport MONGO_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name MONGO-ADMIN-PASSWORD --query value -o tsv)\nexport MONGO_REPLICA_SET_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MONGO-REPLICA-SET-KEY --query value -o tsv)\nexport DASHBOARD_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name DASHBOARD-ADMIN-USERNAME --query value -o tsv)\nexport DASHBOARD_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name DASHBOARD-ADMIN-PASSWORD --query value -o tsv)\nexport MINIO_ACCESS_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MINIO-ACCESS-KEY --query value -o tsv)\nexport MINIO_SECRET_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MINIO-SECRET-KEY --query value -o tsv)\nexport GRAFANA_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name GRAFANA-ADMIN-USERNAME --query value -o tsv)\nexport GRAFANA_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name GRAFANA-ADMIN-PASSWORD --query value -o tsv)\nexport LIVEKIT_API_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name LIVEKIT-API-KEY --query value -o tsv)\nexport LIVEKIT_API_SECRET=$(az keyvault secret show --vault-name ${keyVaultName} --name LIVEKIT-API-SECRET --query value -o tsv)\nexport DEFAULT_APP_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name DEFAULT-APP-USERNAME --query value -o tsv)\nexport DEFAULT_APP_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name DEFAULT-APP-PASSWORD --query value -o tsv)\nexport DEFAULT_APP_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name DEFAULT-APP-ADMIN-USERNAME --query value -o tsv)\nexport DEFAULT_APP_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name DEFAULT-APP-ADMIN-PASSWORD --query value -o tsv)\nexport ENABLED_MODULES=$(az keyvault secret show --vault-name ${keyVaultName} --name ENABLED-MODULES --query value -o tsv)\n\n# Replace rest of the values\nsed -i \"s/REDIS_PASSWORD=.*/REDIS_PASSWORD=$REDIS_PASSWORD/\" \"${MASTER_NODE_CONFIG_DIR}/master_node.env\"\nsed -i \"s/OPENVIDU_RTC_ENGINE=.*/OPENVIDU_RTC_ENGINE=$OPENVIDU_RTC_ENGINE/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"
"update_secret_from_configScriptTemplateMaster" : "#!/bin/bash\nset -e\n\naz login --identity --allow-no-subscriptions > /dev/null\n\n# Installation directory\nINSTALL_DIR=\"/opt/openvidu\"\nCLUSTER_CONFIG_DIR=\"${INSTALL_DIR}/config/cluster\"\nMASTER_NODE_CONFIG_DIR=\"${INSTALL_DIR}/config/node\"\n\nif [[ ${certificateType} == \"letsencrypt\" ]]; then\n LETSENCRYPT_EMAIL=\"$(/usr/local/bin/get_value_from_config.sh LETSENCRYPT_EMAIL \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\n az keyvault secret set --vault-name ${keyVaultName} --name \"LETSENCRYPT-EMAIL\" --value $LETSENCRYPT_EMAIL\nfi\n\n# Get current values of the config\nREDIS_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh REDIS_PASSWORD \"${MASTER_NODE_CONFIG_DIR}/master_node.env\")\"\nDOMAIN_NAME=\"$(/usr/local/bin/get_value_from_config.sh DOMAIN_NAME \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nLIVEKIT_TURN_DOMAIN_NAME=\"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_TURN_DOMAIN_NAME \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nOPENVIDU_RTC_ENGINE=\"$(/usr/local/bin/get_value_from_config.sh OPENVIDU_RTC_ENGINE \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nOPENVIDU_PRO_LICENSE=\"$(/usr/local/bin/get_value_from_config.sh OPENVIDU_PRO_LICENSE \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nMONGO_ADMIN_USERNAME=\"$(/usr/local/bin/get_value_from_config.sh MONGO_ADMIN_USERNAME \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nMONGO_ADMIN_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh MONGO_ADMIN_PASSWORD \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nMONGO_REPLICA_SET_KEY=\"$(/usr/local/bin/get_value_from_config.sh MONGO_REPLICA_SET_KEY \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nMINIO_ACCESS_KEY=\"$(/usr/local/bin/get_value_from_config.sh MINIO_ACCESS_KEY \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nMINIO_SECRET_KEY=\"$(/usr/local/bin/get_value_from_config.sh MINIO_SECRET_KEY \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nDASHBOARD_ADMIN_USERNAME=\"$(/usr/local/bin/get_value_from_config.sh DASHBOARD_ADMIN_USERNAME \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nDASHBOARD_ADMIN_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh DASHBOARD_ADMIN_PASSWORD \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nGRAFANA_ADMIN_USERNAME=\"$(/usr/local/bin/get_value_from_config.sh GRAFANA_ADMIN_USERNAME \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nGRAFANA_ADMIN_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh GRAFANA_ADMIN_PASSWORD \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nLIVEKIT_API_KEY=\"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_API_KEY \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nLIVEKIT_API_SECRET=\"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_API_SECRET \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\nDEFAULT_APP_USERNAME=\"$(/usr/local/bin/get_value_from_config.sh CALL_USER \"${CLUSTER_CONFIG_DIR}/master_node/app.env\")\"\nDEFAULT_APP_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh CALL_SECRET \"${CLUSTER_CONFIG_DIR}/master_node/app.env\")\"\nDEFAULT_APP_ADMIN_USERNAME=\"$(/usr/local/bin/get_value_from_config.sh CALL_ADMIN_USER \"${CLUSTER_CONFIG_DIR}/master_node/app.env\")\"\nDEFAULT_APP_ADMIN_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh CALL_ADMIN_SECRET \"${CLUSTER_CONFIG_DIR}/master_node/app.env\")\"\nENABLED_MODULES=\"$(/usr/local/bin/get_value_from_config.sh ENABLED_MODULES \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\" \ n \ n # U p d a t e s h a r e d s e c r e t \ n a z k e y v a u l t s e c r e t s e t - - v a u l t - n a m e $ { k e y V a u l t N a m e } - - n a m e R E D I S - P A S S W O R D - - v a l u e $ R E D I S _ P A S S W O R D \ n a z k e y v a u l t s e c r e t s e t - - v a u l t - n a m e $ { k e y V a u l t N a m e } - - n a m e D O M A I N - N A M E - - v a l u e $ D O M A I N _ N A M E \ n a z k e y v a u l t s e c r e t s e t - - v a u l t - n a m e $ { k e y V a u l t N a m e } - - n a m e L I V E K I T - T U R N - D O M A I N - N A M E - - v a l u e $ L I V E K I T _ T U R N _ D O M A I N _ N A M E \ n a z k e y v a u l t s e c r e t s e t - - v a u l t - n a m e $ { k e y V a u l t N a m e } - - n a m e O P E N V I D U - R T C - E N G I N E - - v a l u e $ O P E N V I D U _ R T C _ E N G I N E \ n a z k e y v a u l t s e c r e t s e t - - v a u l t - n a m e $ { k e y V a u l t N a m e } - - n a m e O P E N V I D U - P R O - L I C E N S E - - v a l u e $ O P E N V I D U _ P R O _ L I C E N S E \ n a z k e y v a u l t s e c r e t s e t - - v a u l t - n a m e $ { k e y V a u l t N a m e } - - n a m e M O N G O - A D M I N - U S E R N A M E - - v a l u e $ M O N G O _ A D M I N _ U S E R N A M E \ n a z k e y v a u l t s e c r e t s e t - - v a u l t - n a m e $ { k e y V a u l t N a m e } - - n a m e M O N G O - A D M I N - P A S S W O R D - - v a l u e $ M O N G O _ A D M I N
"get_value_from_configScriptMaster" : "#!/bin/bash\nset -e\n\n# Function to get the value of a given key from the environment file\nget_value() {\n local key=\"$1\"\n local file_path=\"$2\"\n\n # Use grep to find the line with the key, ignoring lines starting with #\n # Use awk to split on '=' and print the second field, which is the value\n local value=$(grep -E \"^\\s*$key\\s*=\" \"$file_path\" | awk -F= '{print $2}' | sed 's/#.*//; s/^\\s*//; s/\\s*$//')\n\n # If the value is empty, return \"none\"\n if [ -z \"$value\" ]; then\n echo \"none\"\n else\n echo \"$value\"\n fi\n}\n\n# Check if the correct number of arguments are supplied\nif [ \"$#\" -ne 2 ]; then\n echo \"Usage: $0 <key> <file_path>\"\n exit 1\nfi\n\n# Get the key and file path from the arguments\nkey=\"$1\"\nfile_path=\"$2\"\n\n# Get and print the value\nget_value \"$key\" \"$file_path\"\n" ,
"store_secretScriptTemplateMaster" : "#!/bin/bash\nset -e\n\naz login --identity --allow-no-subscriptions > /dev/null\n\n# Modes: save, generate\n# save mode: save the secret in the secret manager\n# generate mode: generate a random password and save it in the secret manager\nMODE=\"$1\"\n\nif [[ \"$MODE\" == \"generate\" ]]; then\n SECRET_KEY_NAME=\"$2\"\n PREFIX=\"${3:-}\"\n LENGTH=\"${4:-44}\"\n RANDOM_PASSWORD=\"$(openssl rand -base64 64 | tr -d '+/=\\n' | cut -c -${LENGTH})\"\n RANDOM_PASSWORD=\"${PREFIX}${RANDOM_PASSWORD}\"\n az keyvault secret set --vault-name ${keyVaultName} --name $SECRET_KEY_NAME --value $RANDOM_PASSWORD > /dev/null\n if [[ $? -ne 0 ]]; then\n echo \"Error generating secret\"\n fi\n echo \"$RANDOM_PASSWORD\"\nelif [[ \"$MODE\" == \"save\" ]]; then\n SECRET_KEY_NAME=\"$2\"\n SECRET_VALUE=\"$3\"\n az keyvault secret set --vault-name ${keyVaultName} --name $SECRET_KEY_NAME --value $SECRET_VALUE > /dev/null\n if [[ $? -ne 0 ]]; then\n echo \"Error generating secret\"\n fi\n echo \"$SECRET_VALUE\"\nelse\n exit 1\nfi\n" ,
"check_app_readyScriptMaster" : "#!/bin/bash\nset -e\nwhile true; do\n HTTP_STATUS=$(curl -Ik http://localhost:7880/twirp/health | head -n1 | awk '{print $2}')\n if [ $HTTP_STATUS == 200 ]; then\n break\n fi\n sleep 5\ndone\n" ,
"restartScriptMaster" : "#!/bin/bash\nset -e\n# Stop all services\nsystemctl stop openvidu\n\n# Update config from secret\n/usr/local/bin/update_config_from_secret.sh\n\n# Start all services\nsystemctl start openvidu\n" ,
2025-05-13 11:01:22 +02:00
"config_blobStorageTemplate" : "#!/bin/bash\nset -e\n\n# Install dir and config dir\nINSTALL_DIR=\"/opt/openvidu\"\nCLUSTER_CONFIG_DIR=\"${INSTALL_DIR}/config/cluster\"\n\naz login --identity\n\n# Config azure blob storage\nAZURE_ACCOUNT_NAME=\"${storageAccountName}\"\nAZURE_ACCOUNT_KEY=$(az storage account keys list --account-name ${storageAccountName} --query '[0].value' -o tsv)\nAZURE_CONTAINER_NAME=\"${storageAccountContainerName}\"\n\nsed -i \"s|AZURE_ACCOUNT_NAME=.*|AZURE_ACCOUNT_NAME=$AZURE_ACCOUNT_NAME|\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s|AZURE_ACCOUNT_KEY=.*|AZURE_ACCOUNT_KEY=$AZURE_ACCOUNT_KEY|\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s|AZURE_CONTAINER_NAME=.*|AZURE_CONTAINER_NAME=$AZURE_CONTAINER_NAME|\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\n" ,
2025-04-22 11:46:24 +02:00
"installScriptMaster1" : "[reduce(items(variables('stringInterpolationParamsMaster1')), createObject('value', variables('installScriptTemplateMaster')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"installScriptMaster2" : "[reduce(items(variables('stringInterpolationParamsMaster2')), createObject('value', variables('installScriptTemplateMaster')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"installScriptMaster3" : "[reduce(items(variables('stringInterpolationParamsMaster3')), createObject('value', variables('installScriptTemplateMaster')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"installScriptMaster4" : "[reduce(items(variables('stringInterpolationParamsMaster4')), createObject('value', variables('installScriptTemplateMaster')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"after_installScriptMaster" : "[reduce(items(variables('stringInterpolationParamsMaster1')), createObject('value', variables('after_installScriptTemplateMaster')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"update_config_from_secretScriptMaster" : "[reduce(items(variables('stringInterpolationParamsMaster1')), createObject('value', variables('update_config_from_secretScriptTemplateMaster')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"update_secret_from_configScriptMaster" : "[reduce(items(variables('stringInterpolationParamsMaster1')), createObject('value', variables('update_secret_from_configScriptTemplateMaster')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"store_secretScriptMaster" : "[reduce(items(variables('stringInterpolationParamsMaster1')), createObject('value', variables('store_secretScriptTemplateMaster')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"base64installMaster1" : "[base64(variables('installScriptMaster1'))]" ,
"base64installMaster2" : "[base64(variables('installScriptMaster2'))]" ,
"base64installMaster3" : "[base64(variables('installScriptMaster3'))]" ,
"base64installMaster4" : "[base64(variables('installScriptMaster4'))]" ,
"base64after_installMaster" : "[base64(variables('after_installScriptMaster'))]" ,
"base64update_config_from_secretMaster" : "[base64(variables('update_config_from_secretScriptMaster'))]" ,
"base64update_secret_from_configMaster" : "[base64(variables('update_secret_from_configScriptMaster'))]" ,
"base64get_value_from_configMaster" : "[base64(variables('get_value_from_configScriptMaster'))]" ,
"base64store_secretMaster" : "[base64(variables('store_secretScriptMaster'))]" ,
"base64check_app_readyMaster" : "[base64(variables('check_app_readyScriptMaster'))]" ,
"base64restartMaster" : "[base64(variables('restartScriptMaster'))]" ,
2025-05-29 16:51:59 +02:00
"userDataTemplateMasterNode" : "#!/bin/bash -x\nset -eu -o pipefail\n\n# Introduce the scripts in the instance\n# install.sh\necho ${base64install} | base64 -d > /usr/local/bin/install.sh\nchmod +x /usr/local/bin/install.sh\n\n# after_install.sh\necho ${base64after_install} | base64 -d > /usr/local/bin/after_install.sh\nchmod +x /usr/local/bin/after_install.sh\n\n# update_config_from_secret.sh\necho ${base64update_config_from_secret} | base64 -d > /usr/local/bin/update_config_from_secret.sh\nchmod +x /usr/local/bin/update_config_from_secret.sh\n\n# update_secret_from_config.sh\necho ${base64update_secret_from_config} | base64 -d > /usr/local/bin/update_secret_from_config.sh\nchmod +x /usr/local/bin/update_secret_from_config.sh\n\n# get_value_from_config.sh\necho ${base64get_value_from_config} | base64 -d > /usr/local/bin/get_value_from_config.sh\nchmod +x /usr/local/bin/get_value_from_config.sh\n\n# store_secret.sh\necho ${base64store_secret} | base64 -d > /usr/local/bin/store_secret.sh\nchmod +x /usr/local/bin/store_secret.sh\n\n# check_app_ready.sh\necho ${base64check_app_ready} | base64 -d > /usr/local/bin/check_app_ready.sh\nchmod +x /usr/local/bin/check_app_ready.sh\n\n# restart.sh\necho ${base64restart} | base64 -d > /usr/local/bin/restart.sh\nchmod +x /usr/local/bin/restart.sh\n\necho ${base64config_blobStorage} | base64 -d > /usr/local/bin/config_blobStorage.sh\nchmod +x /usr/local/bin/config_blobStorage.sh\n\n# Install azure cli\ncurl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash\n\naz login --identity --allow-no-subscriptions\n\napt-get update && apt-get install -y\n\nexport HOME=\"/root\"\n\n# Install OpenVidu\n/usr/local/bin/install.sh || { echo \"[OpenVidu] error installing OpenVidu\"; exit 1; }\n\n#Config blob storage\n/usr/local/bin/config_blobStorage.sh || { echo \"[OpenVidu] error configuring Blob Storage\"; exit 1; }\n\n# Start OpenVidu\nsystemctl start openvidu || { echo \"[OpenVidu] error starting OpenVidu\"; exit 1; }\n\n# Update shared secret\n/usr/local/bin/after_install.sh || { echo \"[OpenVidu] error updating shared secret\"; exit 1; }\n\n# Launch on reboot\necho \"@reboot /usr/local/bin/restart.sh >> /var/log/openvidu-restart.log\" 2>&1 | crontab\n\nMASTER_NODE_NUM=${masterNodeNum}\nif [[ $MASTER_NODE_NUM -eq 4 ]]; then\n # Creating scale in lock\n set +e\n az storage blob upload --account-name ${storageAccountName} --container-name automation-locks --name lock.txt --file /dev/null --auth-mode key\n set -e\n\n #Finish all the nodes\n az keyvault secret set --vault-name ${keyVaultName} --name FINISH-MASTER-NODE --value \"true\"\nfi\n\n# Wait for the app\nsleep 150\n/usr/local/bin/check_app_ready.sh\n" ,
2025-04-22 11:46:24 +02:00
"installScriptTemplateMedia" : "#!/bin/bash -x\nDOMAIN=\n\n# Install dependencies\napt-get update && apt-get install -y \\\n curl \\\n unzip \\\n jq \\\n wget\n\n# Get own private IP\nPRIVATE_IP=$(curl -H Metadata:true --noproxy \"*\" \"http://169.254.169.254/metadata/instance/network/interface/0/ipv4/ipAddress/0/privateIpAddress?api-version=2017-08-01&format=text\")\n\nWAIT_INTERVAL=1\nMAX_WAIT=10000\nELAPSED_TIME=0\nset +e\nwhile true; do\n # get secret value\n FINISH_MASTER_NODE=$(az keyvault secret show --vault-name ${keyVaultName} --name FINISH-MASTER-NODE --query value -o tsv)\n\n # Check if all master nodes finished\n if [ \"$FINISH_MASTER_NODE\" == \"true\" ]; then\n break\n fi\n\n ELAPSED_TIME=$((ELAPSED_TIME + WAIT_INTERVAL))\n\n # Check if the maximum waiting time has been reached\n if [ $ELAPSED_TIME -ge $MAX_WAIT ]; then\n exit 1\n fi\n\n sleep $WAIT_INTERVAL\ndone\nset -e\n\nMASTER_NODE_1_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-1-PRIVATE-IP --query value -o tsv)\nMASTER_NODE_2_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-2-PRIVATE-IP --query value -o tsv)\nMASTER_NODE_3_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-3-PRIVATE-IP --query value -o tsv)\nMASTER_NODE_4_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-4-PRIVATE-IP --query value -o tsv)\nMASTER_NODE_PRIVATE_IP_LIST=\"$MASTER_NODE_1_PRIVATE_IP,$MASTER_NODE_2_PRIVATE_IP,$MASTER_NODE_3_PRIVATE_IP,$MASTER_NODE_4_PRIVATE_IP\"\nREDIS_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name REDIS-PASSWORD --query value -o tsv)\nENABLED_MODULES=$(az keyvault secret show --vault-name ${keyVaultName} --name ENABLED-MODULES --query value -o tsv)\nOPENVIDU_VERSION=$(az keyvault secret show --vault-name ${keyVaultName} --name OPENVIDU-VERSION --query value -o tsv)\n\n# Base command\nINSTALL_COMMAND=\"sh <(curl -fsSL http://get.openvidu.io/pro/ha/$OPENVIDU_VERSION/install_ov_media_node.sh)\"\n\n# Common arguments\nCOMMON_ARGS=(\n\"--no-tty\"\n\"--install\"\n\"--environment=azure\"\n\"--deployment-type='ha'\"\n\"--node-role='media-node'\"\n\"--master-node-private-ip-list=$MASTER_NODE_PRIVATE_IP_LIST\"\n\"--private-ip=$PRIVATE_IP\"\n\"--enabled-modules='$ENABLED_MODULES'\"\n\"--redis-password=$REDIS_PASSWORD\"\n)\n\n# Construct the final command with all arguments\nFINAL_COMMAND=\"$INSTALL_COMMAND $(printf \"%s \" \"${COMMON_ARGS[@]}\")\"\n\n# Install OpenVidu\nexec bash -c \"$FINAL_COMMAND\"\n" ,
"stopMediaNodeParams" : {
"subscriptionId" : "[subscription().subscriptionId]" ,
"resourceGroupName" : "[resourceGroup().name]" ,
"vmScaleSetName" : "[format('{0}-mediaNodeScaleSet', parameters('stackName'))]" ,
2025-05-13 11:59:15 +02:00
"storageAccountName" : "[if(variables('isEmptyStorageAccountName'), uniqueString(resourceGroup().id), parameters('storageAccountName'))]"
2025-04-22 11:46:24 +02:00
} ,
2025-06-25 19:03:01 +02:00
"stop_media_nodesScriptMediaTemplate" : "#!/bin/bash\nset -e\n\nif ! (set -o noclobber ; echo > /tmp/global.lock) ; then\n exit 1 # the global.lock already exists\nfi\n\n# Execute if docker is installed\nif [ -x \"$(command -v docker)\" ]; then\n\n echo \"Stopping media node services and waiting for termination...\"\n docker container kill --signal=SIGQUIT openvidu || true\n docker container kill --signal=SIGQUIT ingress || true\n docker container kill --signal=SIGQUIT egress || true\n for agent_container in $(docker ps --filter \"label=openvidu-agent=true\" --format '{{.Names}}'); do\n docker container kill --signal=SIGQUIT \"$agent_container\"\n done\n\n # Wait for running containers to not be openvidu, ingress or egress\n while [ $(docker ps --filter \"label=openvidu-agent=true\" -q | wc -l) -gt 0 ] || \\\n [ $(docker inspect -f '{{.State.Running}}' openvidu 2>/dev/null) == \"true\" ] || \\\n [ $(docker inspect -f '{{.State.Running}}' ingress 2>/dev/null) == \"true\" ] || \\\n [ $(docker inspect -f '{{.State.Running}}' egress 2>/dev/null) == \"true\" ]; do\n echo \"Waiting for containers to stop...\"\n sleep 5\n done\nfi\n\naz login --identity\n\nRESOURCE_GROUP_NAME=${resourceGroupName}\nVM_SCALE_SET_NAME=${vmScaleSetName}\nSUBSCRIPTION_ID=${subscriptionId}\nBEFORE_INSTANCE_ID=$(curl -H Metadata:true --noproxy \"*\" \"http://169.254.169.254/metadata/instance?api-version=2021-02-01\" | jq -r '.compute.resourceId')\nINSTANCE_ID=$(echo $BEFORE_INSTANCE_ID | awk -F'/' '{print $NF}')\nRESOURCE_ID=/subscriptions/$SUBSCRIPTION_ID/resourcegroups/$RESOURCE_GROUP_NAME/providers/Microsoft.Compute/virtualMachineScaleSets/$VM_SCALE_SET_NAME\n\nTIMESTAMP=$(date -u +\"%Y-%m-%dT%H:%M:%SZ\")\naz tag update --resource-id $RESOURCE_ID --operation replace --tags \"STATUS\"=\"HEALTHY\" \"InstanceDeleteTime\"=\"$TIMESTAMP\" \"storageAccount\"=\"${storageAccountName}\"\n\naz vmss delete-instances --resource-group $RESOURCE_GROUP_NAME --name $VM_SCALE_SET_NAME --instance-ids $INSTANCE_ID\n" ,
2025-06-10 10:56:50 +02:00
"delete_mediaNode_ScriptMediaTemplate" : "#!/bin/bash\nset -e\n\naz login --identity\n\nRESOURCE_GROUP_NAME=${resourceGroupName}\nVM_SCALE_SET_NAME=${vmScaleSetName}\nBEFORE_INSTANCE_ID=$(curl -H Metadata:true --noproxy \"*\" \"http://169.254.169.254/metadata/instance?api-version=2021-02-01\" | jq -r '.compute.resourceId')\nINSTANCE_ID=$(echo $BEFORE_INSTANCE_ID | awk -F'/' '{print $NF}')\n\n\naz vmss delete-instances --resource-group $RESOURCE_GROUP_NAME --name $VM_SCALE_SET_NAME --instance-ids $INSTANCE_ID\n" ,
"userDataMediaNodeTemplate" : "#!/bin/bash -x\nset -eu -o pipefail\n\n# Introduce the scripts in the instance\n# install.sh\necho ${base64install} | base64 -d > /usr/local/bin/install.sh\nchmod +x /usr/local/bin/install.sh\n\n# stop_media_nodes.sh\necho ${base64stop} | base64 -d > /usr/local/bin/stop_media_node.sh\nchmod +x /usr/local/bin/stop_media_node.sh\n\napt-get update && apt-get install -y \napt-get install -y jq\n\n# Install azure cli\ncurl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash\n\naz login --identity\n\n# Protect from scale in actions\nRESOURCE_GROUP_NAME=${resourceGroupName}\nVM_SCALE_SET_NAME=${vmScaleSetName}\nBEFORE_INSTANCE_ID=$(curl -H Metadata:true --noproxy \"*\" \"http://169.254.169.254/metadata/instance?api-version=2021-02-01\" | jq -r '.compute.resourceId')\nINSTANCE_ID=$(echo $BEFORE_INSTANCE_ID | awk -F'/' '{print $NF}')\naz vmss update --resource-group $RESOURCE_GROUP_NAME --name $VM_SCALE_SET_NAME --instance-id $INSTANCE_ID --protect-from-scale-in true\n\nexport HOME=\"/root\"\n\n# Install OpenVidu\n/usr/local/bin/install.sh || { echo \"[OpenVidu] error installing OpenVidu\"; /usr/local/bin/delete_media_node.sh; }\n\n# Start OpenVidu\nsystemctl start openvidu || { echo \"[OpenVidu] error starting OpenVidu\"; /usr/local/bin/delete_media_node.sh; }\n" ,
2025-04-22 11:46:24 +02:00
"stop_media_nodesScriptMedia" : "[reduce(items(variables('stopMediaNodeParams')), createObject('value', variables('stop_media_nodesScriptMediaTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
2025-06-10 10:56:50 +02:00
"delete_mediaNode_ScriptMedia" : "[reduce(items(variables('stopMediaNodeParams')), createObject('value', variables('delete_mediaNode_ScriptMediaTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
2025-04-22 11:46:24 +02:00
"base64stopMediaNode" : "[base64(variables('stop_media_nodesScriptMedia'))]" ,
2025-06-10 10:56:50 +02:00
"base64delete_mediaNode_ScriptMedia" : "[base64(variables('delete_mediaNode_ScriptMedia'))]" ,
2025-05-27 11:18:05 +02:00
"isEmptyAutomationAccountName" : "[equals(parameters('automationAccountName'), '')]" ,
2025-05-23 14:32:27 +02:00
"isEmptyIp" : "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'none')]" ,
2025-04-22 11:46:24 +02:00
"lbName" : "[format('{0}-loadBalancer', parameters('stackName'))]" ,
"lbFrontEndName" : "LoadBalancerFrontEnd" ,
"lbBackendPoolNameMasterNode" : "LoadBalancerBackEndMasterNode" ,
2025-05-23 13:53:24 +02:00
"ipExists" : "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'existing')]" ,
"ipNew" : "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'new')]" ,
2025-04-22 11:46:24 +02:00
"networkSettings" : {
"vNetAddressPrefix" : "10.0.0.0/16" ,
"subnetAddressPrefixMaster1" : "10.0.1.0/24" ,
"subnetAddressPrefixMaster2" : "10.0.2.0/24" ,
"subnetAddressPrefixMedia" : "10.0.0.0/24" ,
"vNetName" : "[format('{0}-virtualNetwork', parameters('stackName'))]"
2025-04-23 13:26:33 +02:00
} ,
2025-05-13 11:01:22 +02:00
"isEmptyStorageAccountName" : "[equals(parameters('storageAccountName'), '')]" ,
2025-06-10 16:30:41 +02:00
"isEmptyAppDataContainerName" : "[equals(parameters('appDataContainerName'), '')]" ,
"isEmptyClusterContainerName" : "[equals(parameters('clusterDataContainerName'), '')]"
2025-04-22 11:46:24 +02:00
} ,
"resources" : [
{
"type" : "Microsoft.KeyVault/vaults" ,
"apiVersion" : "2023-07-01" ,
"name" : "[variables('keyVaultName')]" ,
"location" : "[variables('location')]" ,
"properties" : {
"enabledForDeployment" : true ,
"enabledForDiskEncryption" : false ,
"enabledForTemplateDeployment" : true ,
"tenantId" : "[variables('tenantId')]" ,
"enableSoftDelete" : false ,
"accessPolicies" : [
{
"objectId" : "[reference(resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode1', parameters('stackName'))), '2023-09-01', 'full').identity.principalId]" ,
"tenantId" : "[variables('tenantId')]" ,
"permissions" : {
"secrets" : [
"get" ,
"set" ,
"list"
]
}
} ,
{
"objectId" : "[reference(resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode2', parameters('stackName'))), '2023-09-01', 'full').identity.principalId]" ,
"tenantId" : "[variables('tenantId')]" ,
"permissions" : {
"secrets" : [
"get" ,
"set" ,
"list"
]
}
} ,
{
"objectId" : "[reference(resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode3', parameters('stackName'))), '2023-09-01', 'full').identity.principalId]" ,
"tenantId" : "[variables('tenantId')]" ,
"permissions" : {
"secrets" : [
"get" ,
"set" ,
"list"
]
}
} ,
{
"objectId" : "[reference(resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode4', parameters('stackName'))), '2023-09-01', 'full').identity.principalId]" ,
"tenantId" : "[variables('tenantId')]" ,
"permissions" : {
"secrets" : [
"get" ,
"set" ,
"list"
]
}
} ,
{
"objectId" : "[reference(resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName'))), '2024-07-01', 'full').identity.principalId]" ,
"tenantId" : "[variables('tenantId')]" ,
"permissions" : {
"secrets" : [
"get"
]
}
} ,
{
"objectId" : "[variables('deploymentUser')]" ,
"tenantId" : "[variables('tenantId')]" ,
"permissions" : {
"secrets" : [
"get" ,
"list" ,
"set" ,
"delete" ,
"recover" ,
"backup" ,
"restore"
]
}
}
] ,
"sku" : {
"name" : "standard" ,
"family" : "A"
} ,
"networkAcls" : {
"defaultAction" : "Allow" ,
"bypass" : "AzureServices"
}
} ,
"dependsOn" : [
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode1', parameters('stackName')))]" ,
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode2', parameters('stackName')))]" ,
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode3', parameters('stackName')))]" ,
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode4', parameters('stackName')))]" ,
"[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Compute/virtualMachines" ,
"apiVersion" : "2023-09-01" ,
"name" : "[format('{0}-VM-MasterNode1', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"identity" : {
"type" : "SystemAssigned"
} ,
"properties" : {
"hardwareProfile" : {
"vmSize" : "[parameters('masterNodeInstanceType')]"
} ,
"storageProfile" : {
"osDisk" : {
"createOption" : "FromImage" ,
"managedDisk" : {
"storageAccountType" : "[variables('masterNodeVMSettings').osDiskType]"
} ,
"diskSizeGB" : "[variables('masterNodeVMSettings').osDiskSize]"
} ,
"imageReference" : "[variables('masterNodeVMSettings').ubuntuOSVersion]"
} ,
"networkProfile" : {
"networkInterfaces" : [
{
"id" : "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface1', parameters('stackName')))]"
}
]
} ,
"osProfile" : {
"computerName" : "[format('{0}-VM-MasterNode1', parameters('stackName'))]" ,
"adminUsername" : "[parameters('adminUsername')]" ,
"linuxConfiguration" : "[variables('masterNodeVMSettings').linuxConfiguration]"
} ,
2025-06-10 16:30:41 +02:00
"userData" : "[base64(reduce(items(createObject('base64install', variables('base64installMaster1'), 'base64after_install', variables('base64after_installMaster'), 'base64update_config_from_secret', variables('base64update_config_from_secretMaster'), 'base64update_secret_from_config', variables('base64update_secret_from_configMaster'), 'base64get_value_from_config', variables('base64get_value_from_configMaster'), 'base64store_secret', variables('base64store_secretMaster'), 'base64check_app_ready', variables('base64check_app_readyMaster'), 'base64restart', variables('base64restartMaster'), 'keyVaultName', variables('keyVaultName'), 'masterNodeNum', '1', 'base64config_blobStorage', base64(reduce(items(createObject('storageAccountName', if(variables('isEmptyStorageAccountName'), uniqueString(resourceGroup().id), parameters('storageAccountName')), 'storageAccountKey', listKeys(resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id)), '2021-04-01').keys[0].value, 'storageAccountContainerName', if(variables('isEmptyAppDataContainerName'), 'openvidu-appdata', format('{0}', parameters('appDataContainerName'))), 'storageAccountClusterContainerName', if(variables('isEmptyClusterContainerName'), 'openvidu-clusterdata', format('{0}', parameters('clusterDataContainerName'))))), createObject('value', variables('config_blobStorageTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value))), createObject('value', variables('userDataTemplateMasterNode')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value)]"
2025-04-22 11:46:24 +02:00
} ,
"dependsOn" : [
2025-05-29 16:51:59 +02:00
"[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface1', parameters('stackName')))]" ,
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]"
2025-04-22 11:46:24 +02:00
]
} ,
{
"type" : "Microsoft.Compute/virtualMachines" ,
"apiVersion" : "2023-09-01" ,
"name" : "[format('{0}-VM-MasterNode2', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"identity" : {
"type" : "SystemAssigned"
} ,
"properties" : {
"hardwareProfile" : {
"vmSize" : "[parameters('masterNodeInstanceType')]"
} ,
"storageProfile" : {
"osDisk" : {
"createOption" : "FromImage" ,
"managedDisk" : {
"storageAccountType" : "[variables('masterNodeVMSettings').osDiskType]"
} ,
"diskSizeGB" : "[variables('masterNodeVMSettings').osDiskSize]"
} ,
"imageReference" : "[variables('masterNodeVMSettings').ubuntuOSVersion]"
} ,
"networkProfile" : {
"networkInterfaces" : [
{
"id" : "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface2', parameters('stackName')))]"
}
]
} ,
"osProfile" : {
"computerName" : "[format('{0}-VM-MasterNode2', parameters('stackName'))]" ,
"adminUsername" : "[parameters('adminUsername')]" ,
"linuxConfiguration" : "[variables('masterNodeVMSettings').linuxConfiguration]"
} ,
2025-06-10 16:30:41 +02:00
"userData" : "[base64(reduce(items(createObject('base64install', variables('base64installMaster2'), 'base64after_install', variables('base64after_installMaster'), 'base64update_config_from_secret', variables('base64update_config_from_secretMaster'), 'base64update_secret_from_config', variables('base64update_secret_from_configMaster'), 'base64get_value_from_config', variables('base64get_value_from_configMaster'), 'base64store_secret', variables('base64store_secretMaster'), 'base64check_app_ready', variables('base64check_app_readyMaster'), 'base64restart', variables('base64restartMaster'), 'keyVaultName', variables('keyVaultName'), 'masterNodeNum', '2', 'base64config_blobStorage', base64(reduce(items(createObject('storageAccountName', if(variables('isEmptyStorageAccountName'), uniqueString(resourceGroup().id), parameters('storageAccountName')), 'storageAccountKey', listKeys(resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id)), '2021-04-01').keys[0].value, 'storageAccountContainerName', if(variables('isEmptyAppDataContainerName'), 'openvidu-appdata', format('{0}', parameters('appDataContainerName'))), 'storageAccountClusterContainerName', if(variables('isEmptyClusterContainerName'), 'openvidu-clusterdata', format('{0}', parameters('clusterDataContainerName'))))), createObject('value', variables('config_blobStorageTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value))), createObject('value', variables('userDataTemplateMasterNode')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value)]"
2025-04-22 11:46:24 +02:00
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface2', parameters('stackName')))]" ,
2025-05-29 16:51:59 +02:00
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode1', parameters('stackName')))]" ,
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]"
2025-04-22 11:46:24 +02:00
]
} ,
{
"type" : "Microsoft.Compute/virtualMachines" ,
"apiVersion" : "2023-09-01" ,
"name" : "[format('{0}-VM-MasterNode3', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"identity" : {
"type" : "SystemAssigned"
} ,
"properties" : {
"hardwareProfile" : {
"vmSize" : "[parameters('masterNodeInstanceType')]"
} ,
"storageProfile" : {
"osDisk" : {
"createOption" : "FromImage" ,
"managedDisk" : {
"storageAccountType" : "[variables('masterNodeVMSettings').osDiskType]"
} ,
"diskSizeGB" : "[variables('masterNodeVMSettings').osDiskSize]"
} ,
"imageReference" : "[variables('masterNodeVMSettings').ubuntuOSVersion]"
} ,
"networkProfile" : {
"networkInterfaces" : [
{
"id" : "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface3', parameters('stackName')))]"
}
]
} ,
"osProfile" : {
"computerName" : "[format('{0}-VM-MasterNode3', parameters('stackName'))]" ,
"adminUsername" : "[parameters('adminUsername')]" ,
"linuxConfiguration" : "[variables('masterNodeVMSettings').linuxConfiguration]"
} ,
2025-06-10 16:30:41 +02:00
"userData" : "[base64(reduce(items(createObject('base64install', variables('base64installMaster3'), 'base64after_install', variables('base64after_installMaster'), 'base64update_config_from_secret', variables('base64update_config_from_secretMaster'), 'base64update_secret_from_config', variables('base64update_secret_from_configMaster'), 'base64get_value_from_config', variables('base64get_value_from_configMaster'), 'base64store_secret', variables('base64store_secretMaster'), 'base64check_app_ready', variables('base64check_app_readyMaster'), 'base64restart', variables('base64restartMaster'), 'keyVaultName', variables('keyVaultName'), 'masterNodeNum', '3', 'base64config_blobStorage', base64(reduce(items(createObject('storageAccountName', if(variables('isEmptyStorageAccountName'), uniqueString(resourceGroup().id), parameters('storageAccountName')), 'storageAccountKey', listKeys(resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id)), '2021-04-01').keys[0].value, 'storageAccountContainerName', if(variables('isEmptyAppDataContainerName'), 'openvidu-appdata', format('{0}', parameters('appDataContainerName'))), 'storageAccountClusterContainerName', if(variables('isEmptyClusterContainerName'), 'openvidu-clusterdata', format('{0}', parameters('clusterDataContainerName'))))), createObject('value', variables('config_blobStorageTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value))), createObject('value', variables('userDataTemplateMasterNode')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value)]"
2025-04-22 11:46:24 +02:00
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface3', parameters('stackName')))]" ,
2025-05-29 16:51:59 +02:00
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode2', parameters('stackName')))]" ,
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]"
2025-04-22 11:46:24 +02:00
]
} ,
{
"type" : "Microsoft.Compute/virtualMachines" ,
"apiVersion" : "2023-09-01" ,
"name" : "[format('{0}-VM-MasterNode4', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"identity" : {
"type" : "SystemAssigned"
} ,
"properties" : {
"hardwareProfile" : {
"vmSize" : "[parameters('masterNodeInstanceType')]"
} ,
"storageProfile" : {
"osDisk" : {
"createOption" : "FromImage" ,
"managedDisk" : {
"storageAccountType" : "[variables('masterNodeVMSettings').osDiskType]"
} ,
"diskSizeGB" : "[variables('masterNodeVMSettings').osDiskSize]"
} ,
"imageReference" : "[variables('masterNodeVMSettings').ubuntuOSVersion]"
} ,
"networkProfile" : {
"networkInterfaces" : [
{
"id" : "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface4', parameters('stackName')))]"
}
]
} ,
"osProfile" : {
"computerName" : "[format('{0}-VM-MasterNode4', parameters('stackName'))]" ,
"adminUsername" : "[parameters('adminUsername')]" ,
"linuxConfiguration" : "[variables('masterNodeVMSettings').linuxConfiguration]"
} ,
2025-06-10 16:30:41 +02:00
"userData" : "[base64(reduce(items(createObject('base64install', variables('base64installMaster4'), 'base64after_install', variables('base64after_installMaster'), 'base64update_config_from_secret', variables('base64update_config_from_secretMaster'), 'base64update_secret_from_config', variables('base64update_secret_from_configMaster'), 'base64get_value_from_config', variables('base64get_value_from_configMaster'), 'base64store_secret', variables('base64store_secretMaster'), 'base64check_app_ready', variables('base64check_app_readyMaster'), 'base64restart', variables('base64restartMaster'), 'keyVaultName', variables('keyVaultName'), 'masterNodeNum', '4', 'storageAccountName', if(variables('isEmptyStorageAccountName'), uniqueString(resourceGroup().id), parameters('storageAccountName')), 'base64config_blobStorage', base64(reduce(items(createObject('storageAccountName', if(variables('isEmptyStorageAccountName'), uniqueString(resourceGroup().id), parameters('storageAccountName')), 'storageAccountKey', listKeys(resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id)), '2021-04-01').keys[0].value, 'storageAccountContainerName', if(variables('isEmptyAppDataContainerName'), 'openvidu-appdata', format('{0}', parameters('appDataContainerName'))), 'storageAccountClusterContainerName', if(variables('isEmptyClusterContainerName'), 'openvidu-clusterdata', format('{0}', parameters('clusterDataContainerName'))))), createObject('value', variables('config_blobStorageTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value))), createObject('value', variables('userDataTemplateMasterNode')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value)]"
2025-04-22 11:46:24 +02:00
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface4', parameters('stackName')))]" ,
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode3', parameters('stackName')))]" ,
2025-04-23 13:26:33 +02:00
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]"
2025-04-22 11:46:24 +02:00
]
} ,
{
"type" : "Microsoft.Compute/virtualMachineScaleSets" ,
"apiVersion" : "2024-07-01" ,
"name" : "[format('{0}-mediaNodeScaleSet', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"tags" : {
"InstanceDeleteTime" : "[parameters('datetime')]" ,
2025-05-13 11:59:15 +02:00
"storageAccount" : "[if(variables('isEmptyStorageAccountName'), uniqueString(resourceGroup().id), parameters('storageAccountName'))]"
2025-04-22 11:46:24 +02:00
} ,
"identity" : {
"type" : "SystemAssigned"
} ,
"sku" : {
"name" : "[parameters('mediaNodeInstanceType')]" ,
"tier" : "Standard" ,
"capacity" : "[parameters('initialNumberOfMediaNodes')]"
} ,
"properties" : {
"overprovision" : true ,
"upgradePolicy" : {
"mode" : "Automatic"
} ,
"singlePlacementGroup" : true ,
"platformFaultDomainCount" : 1 ,
"virtualMachineProfile" : {
"storageProfile" : {
"osDisk" : {
"createOption" : "FromImage" ,
"managedDisk" : {
"storageAccountType" : "[variables('mediaNodeVMSettings').osDiskType]"
} ,
"diskSizeGB" : 50
} ,
"imageReference" : "[variables('mediaNodeVMSettings').ubuntuOSVersion]"
} ,
"osProfile" : {
"computerNamePrefix" : "[variables('mediaNodeVMSettings').vmName]" ,
"adminUsername" : "[parameters('adminUsername')]" ,
"linuxConfiguration" : "[variables('mediaNodeVMSettings').linuxConfiguration]"
} ,
"networkProfile" : {
"networkInterfaceConfigurations" : [
{
"name" : "[format('{0}-mediaNodeNetInterface', parameters('stackName'))]" ,
"properties" : {
"primary" : true ,
"ipConfigurations" : [
{
"name" : "ipconfigMediaNode" ,
"properties" : {
"subnet" : {
"id" : "[reference(resourceId('Microsoft.Network/virtualNetworks', variables('networkSettings').vNetName), '2023-11-01').subnets[0].id]"
} ,
"applicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"publicIPAddressConfiguration" : {
"name" : "publicIPAddressMediaNode" ,
"properties" : {
"publicIPAddressVersion" : "IPv4"
}
}
}
}
] ,
"networkSecurityGroup" : {
"id" : "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]"
}
}
}
]
} ,
2025-06-10 10:56:50 +02:00
"userData" : "[base64(reduce(items(createObject('base64install', base64(reduce(items(createObject('privateIPMasterNode1', reference(resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface1', parameters('stackName'))), '2023-11-01').ipConfigurations[0].properties.privateIPAddress, 'privateIPMasterNode2', reference(resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface2', parameters('stackName'))), '2023-11-01').ipConfigurations[0].properties.privateIPAddress, 'privateIPMasterNode3', reference(resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface3', parameters('stackName'))), '2023-11-01').ipConfigurations[0].properties.privateIPAddress, 'privateIPMasterNode4', reference(resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface4', parameters('stackName'))), '2023-11-01').ipConfigurations[0].properties.privateIPAddress, 'keyVaultName', variables('keyVaultName'))), createObject('value', variables('installScriptTemplateMedia')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value), 'base64stop', variables('base64stopMediaNode'), 'base64delete_mediaNode', variables('base64delete_mediaNode_ScriptMedia'), 'resourceGroupName', resourceGroup().name, 'vmScaleSetName', format('{0}-mediaNodeScaleSet', parameters('stackName')))), createObject('value', variables('userDataMediaNodeTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value)]"
2025-04-22 11:46:24 +02:00
}
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface1', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface2', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface3', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface4', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]" ,
2025-04-23 13:26:33 +02:00
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]" ,
2025-04-22 11:46:24 +02:00
"[resourceId('Microsoft.Network/virtualNetworks', variables('networkSettings').vNetName)]"
]
} ,
{
"type" : "Microsoft.Insights/autoscalesettings" ,
"apiVersion" : "2022-10-01" ,
"name" : "[format('{0}-autoscaleSettings', parameters('stackName'))]" ,
"location" : "[resourceGroup().location]" ,
"properties" : {
"profiles" : [
{
"name" : "openvidu-medianode-autoscale" ,
"capacity" : {
"minimum" : "[string(parameters('minNumberOfMediaNodes'))]" ,
"maximum" : "[string(parameters('maxNumberOfMediaNodes'))]" ,
"default" : "[string(parameters('initialNumberOfMediaNodes'))]"
} ,
"rules" : [
{
"metricTrigger" : {
"metricName" : "Percentage CPU" ,
"metricNamespace" : "Microsoft.Compute/virtualMachineScaleSets" ,
"metricResourceUri" : "[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName')))]" ,
"statistic" : "Average" ,
"operator" : "GreaterThan" ,
"threshold" : "[parameters('scaleTargetCPU')]" ,
"timeAggregation" : "Average" ,
"timeWindow" : "PT5M" ,
"timeGrain" : "PT1M"
} ,
"scaleAction" : {
"direction" : "Increase" ,
"type" : "ChangeCount" ,
"value" : "1" ,
"cooldown" : "PT5M"
}
} ,
{
"metricTrigger" : {
"metricName" : "Percentage CPU" ,
"metricNamespace" : "Microsoft.Compute/virtualMachineScaleSets" ,
"metricResourceUri" : "[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName')))]" ,
"statistic" : "Average" ,
"operator" : "LessThan" ,
"threshold" : "[parameters('scaleTargetCPU')]" ,
"timeAggregation" : "Average" ,
"timeWindow" : "PT5M" ,
"timeGrain" : "PT1M"
} ,
"scaleAction" : {
"direction" : "Decrease" ,
"type" : "ChangeCount" ,
"value" : "1" ,
"cooldown" : "PT5M"
}
}
]
}
] ,
"enabled" : true ,
"targetResourceUri" : "[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName')))]"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName')))]"
]
} ,
2025-05-29 17:43:37 +02:00
{
"type" : "Microsoft.Authorization/roleAssignments" ,
"apiVersion" : "2022-04-01" ,
"name" : "[guid(format('roleAssignmentForMasterNode{0}', format('{0}-VM-MasterNode1', parameters('stackName'))))]" ,
"properties" : {
"roleDefinitionId" : "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" ,
"principalId" : "[reference(resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode1', parameters('stackName'))), '2023-09-01', 'full').identity.principalId]"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode1', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Authorization/roleAssignments" ,
"apiVersion" : "2022-04-01" ,
"name" : "[guid(format('roleAssignmentForMasterNode{0}', format('{0}-VM-MasterNode2', parameters('stackName'))))]" ,
"properties" : {
"roleDefinitionId" : "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" ,
"principalId" : "[reference(resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode2', parameters('stackName'))), '2023-09-01', 'full').identity.principalId]"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode2', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Authorization/roleAssignments" ,
"apiVersion" : "2022-04-01" ,
"name" : "[guid(format('roleAssignmentForMasterNode{0}', format('{0}-VM-MasterNode3', parameters('stackName'))))]" ,
"properties" : {
"roleDefinitionId" : "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" ,
"principalId" : "[reference(resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode3', parameters('stackName'))), '2023-09-01', 'full').identity.principalId]"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode3', parameters('stackName')))]"
]
} ,
2025-04-22 11:46:24 +02:00
{
"type" : "Microsoft.Authorization/roleAssignments" ,
"apiVersion" : "2022-04-01" ,
"name" : "[guid(format('roleAssignmentForMasterNode{0}', format('{0}-VM-MasterNode4', parameters('stackName'))))]" ,
"properties" : {
"roleDefinitionId" : "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" ,
"principalId" : "[reference(resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode4', parameters('stackName'))), '2023-09-01', 'full').identity.principalId]"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode4', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Authorization/roleAssignments" ,
"apiVersion" : "2022-04-01" ,
"name" : "[guid(format('roleAssignmentForScaleSet{0}', format('{0}-mediaNodeScaleSet', parameters('stackName'))))]" ,
"properties" : {
"roleDefinitionId" : "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" ,
"principalId" : "[reference(resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName'))), '2024-07-01', 'full').identity.principalId]"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Insights/actionGroups" ,
"apiVersion" : "2023-01-01" ,
"name" : "actiongrouptest" ,
"location" : "global" ,
"properties" : {
"groupShortName" : "scaleinag" ,
"enabled" : true ,
"automationRunbookReceivers" : [
{
"name" : "scalein" ,
"useCommonAlertSchema" : false ,
"automationAccountId" : "[reference(resourceId('Microsoft.Resources/deployments', 'WebhookDeployment'), '2022-09-01').outputs.automationAccountId.value]" ,
"runbookName" : "scaleInRunbook" ,
"webhookResourceId" : "[reference(resourceId('Microsoft.Resources/deployments', 'WebhookDeployment'), '2022-09-01').outputs.webhookId.value]" ,
"isGlobalRunbook" : false ,
"serviceUri" : "[reference(resourceId('Microsoft.Resources/deployments', 'WebhookDeployment'), '2022-09-01').outputs.webhookUri.value]"
}
]
} ,
"dependsOn" : [
"[resourceId('Microsoft.Resources/deployments', 'WebhookDeployment')]"
]
} ,
{
"type" : "Microsoft.Insights/activityLogAlerts" ,
"apiVersion" : "2020-10-01" ,
"name" : "ScaleInAlertRule" ,
"location" : "global" ,
"properties" : {
"scopes" : [
"[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName')))]"
] ,
"condition" : {
"allOf" : [
{
"field" : "category" ,
"equals" : "Administrative"
} ,
{
"field" : "operationName" ,
"equals" : "Microsoft.Compute/virtualMachineScaleSets/write"
} ,
{
"field" : "level" ,
"containsAny" : [
"error"
]
} ,
{
"field" : "status" ,
"containsAny" : [
"failed"
]
} ,
{
"field" : "caller" ,
"equals" : "42628537-ebd8-40bf-941a-dddd338e1fe9"
}
]
} ,
"actions" : {
"actionGroups" : [
{
"actionGroupId" : "[resourceId('Microsoft.Insights/actionGroups', 'actiongrouptest')]"
}
]
} ,
"enabled" : true
} ,
"dependsOn" : [
"[resourceId('Microsoft.Insights/actionGroups', 'actiongrouptest')]" ,
"[resourceId('Microsoft.Compute/virtualMachineScaleSets', format('{0}-mediaNodeScaleSet', parameters('stackName')))]"
]
} ,
{
"condition" : "[equals(variables('isEmptyIp'), true())]" ,
"type" : "Microsoft.Network/publicIPAddresses" ,
"apiVersion" : "2024-05-01" ,
"name" : "[format('{0}-publicIPAddressLoadBalancer', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"sku" : {
"name" : "Standard"
} ,
"properties" : {
"publicIPAddressVersion" : "IPv4" ,
"publicIPAllocationMethod" : "Static"
}
} ,
{
"type" : "Microsoft.Network/loadBalancers" ,
"apiVersion" : "2024-05-01" ,
"name" : "[variables('lbName')]" ,
"location" : "[variables('location')]" ,
"sku" : {
"name" : "Standard"
} ,
"properties" : {
"frontendIPConfigurations" : [
{
"name" : "[variables('lbFrontEndName')]" ,
"properties" : {
"publicIPAddress" : {
2025-05-23 13:53:24 +02:00
"id" : "[if(variables('isEmptyIp'), resourceId('Microsoft.Network/publicIPAddresses', format('{0}-publicIPAddressLoadBalancer', parameters('stackName'))), if(variables('ipNew'), resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name), resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name)))]"
2025-04-22 11:46:24 +02:00
}
}
}
] ,
"backendAddressPools" : [
{
"name" : "[variables('lbBackendPoolNameMasterNode')]"
}
] ,
"loadBalancingRules" : [
{
"name" : "HTTPSRuleforMasterNode" ,
"properties" : {
"frontendIPConfiguration" : {
"id" : "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('lbName'), variables('lbFrontEndName'))]"
} ,
"backendAddressPool" : {
"id" : "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('lbBackendPoolNameMasterNode'))]"
} ,
"frontendPort" : 443 ,
"backendPort" : 443 ,
"enableFloatingIP" : false ,
"protocol" : "Tcp" ,
"enableTcpReset" : true ,
"loadDistribution" : "Default" ,
"disableOutboundSnat" : true ,
"probe" : {
"id" : "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), 'probeForHTTPSRuleMasterNode')]"
}
}
} ,
{
"name" : "RTMPRuleforMasterNode" ,
"properties" : {
"frontendIPConfiguration" : {
"id" : "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('lbName'), variables('lbFrontEndName'))]"
} ,
"backendAddressPool" : {
"id" : "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('lbBackendPoolNameMasterNode'))]"
} ,
"frontendPort" : 1935 ,
"backendPort" : 1945 ,
"enableFloatingIP" : false ,
"protocol" : "Tcp" ,
"enableTcpReset" : true ,
"loadDistribution" : "Default" ,
"disableOutboundSnat" : true ,
"probe" : {
"id" : "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), 'probeForRTMPRuleMasterNode')]"
}
}
} ,
{
"name" : "HTTPRuleforMasterNode" ,
"properties" : {
"frontendIPConfiguration" : {
"id" : "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('lbName'), variables('lbFrontEndName'))]"
} ,
"backendAddressPool" : {
"id" : "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('lbBackendPoolNameMasterNode'))]"
} ,
"frontendPort" : 80 ,
"backendPort" : 80 ,
"enableFloatingIP" : false ,
"protocol" : "Tcp" ,
"enableTcpReset" : true ,
"loadDistribution" : "Default" ,
"disableOutboundSnat" : true ,
"probe" : {
"id" : "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), 'probeForHTTPSRuleMasterNode')]"
}
}
}
] ,
"probes" : [
{
"name" : "probeForHTTPSRuleMasterNode" ,
"properties" : {
"protocol" : "Http" ,
"requestPath" : "/health/caddy" ,
"port" : 7880 ,
"probeThreshold" : 3 ,
"intervalInSeconds" : 10 ,
"numberOfProbes" : 5
}
} ,
{
"name" : "probeForRTMPRuleMasterNode" ,
"properties" : {
"protocol" : "Tcp" ,
"port" : 1945 ,
"intervalInSeconds" : 5 ,
"numberOfProbes" : 2
}
}
] ,
"outboundRules" : [ ]
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/publicIPAddresses', format('{0}-publicIPAddressLoadBalancer', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/natGateways" ,
"apiVersion" : "2021-05-01" ,
"name" : "[format('{0}-natGateway', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"sku" : {
"name" : "Standard"
} ,
"properties" : {
"idleTimeoutInMinutes" : 4 ,
"publicIpAddresses" : [
{
"id" : "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}-publicIPnatGateway', parameters('stackName')))]"
}
]
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/publicIPAddresses', format('{0}-publicIPnatGateway', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/publicIPAddresses" ,
"apiVersion" : "2021-05-01" ,
"name" : "[format('{0}-publicIPnatGateway', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"sku" : {
"name" : "Standard"
} ,
"properties" : {
"publicIPAddressVersion" : "IPv4" ,
"publicIPAllocationMethod" : "Static" ,
"idleTimeoutInMinutes" : 4
}
} ,
{
"type" : "Microsoft.Network/virtualNetworks" ,
"apiVersion" : "2023-11-01" ,
"name" : "[variables('networkSettings').vNetName]" ,
"location" : "[variables('location')]" ,
"properties" : {
"addressSpace" : {
"addressPrefixes" : [
"[variables('networkSettings').vNetAddressPrefix]"
]
} ,
"subnets" : [
{
"name" : "subnetForMediaNodes" ,
"properties" : {
"addressPrefix" : "[variables('networkSettings').subnetAddressPrefixMedia]" ,
"privateEndpointNetworkPolicies" : "Disabled" ,
"privateLinkServiceNetworkPolicies" : "Enabled" ,
"networkSecurityGroup" : {
"id" : "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]"
}
}
}
]
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/virtualNetworks/subnets" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', variables('networkSettings').vNetName, 'firstSubnetForMasterNodes')]" ,
"properties" : {
"addressPrefix" : "[variables('networkSettings').subnetAddressPrefixMaster1]" ,
"privateEndpointNetworkPolicies" : "Disabled" ,
"privateLinkServiceNetworkPolicies" : "Enabled" ,
"natGateway" : {
"id" : "[resourceId('Microsoft.Network/natGateways', format('{0}-natGateway', parameters('stackName')))]"
}
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/natGateways', format('{0}-natGateway', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/virtualNetworks', variables('networkSettings').vNetName)]"
]
} ,
{
"type" : "Microsoft.Network/virtualNetworks/subnets" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', variables('networkSettings').vNetName, 'secondSubnetForMasterNodes')]" ,
"properties" : {
"addressPrefix" : "[variables('networkSettings').subnetAddressPrefixMaster2]" ,
"privateEndpointNetworkPolicies" : "Disabled" ,
"privateLinkServiceNetworkPolicies" : "Enabled" ,
"natGateway" : {
"id" : "[resourceId('Microsoft.Network/natGateways', format('{0}-natGateway', parameters('stackName')))]"
}
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/natGateways', format('{0}-natGateway', parameters('stackName')))]" ,
2025-06-10 12:17:10 +02:00
"[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, 'firstSubnetForMasterNodes')]" ,
2025-04-22 11:46:24 +02:00
"[resourceId('Microsoft.Network/virtualNetworks', variables('networkSettings').vNetName)]"
]
} ,
{
"type" : "Microsoft.Network/networkInterfaces" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}-masterNodeNetInterface1', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"properties" : {
"ipConfigurations" : [
{
"name" : "primaryIPConfig" ,
"properties" : {
"privateIPAllocationMethod" : "Dynamic" ,
"subnet" : {
"id" : "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, 'firstSubnetForMasterNodes')]"
} ,
"applicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"loadBalancerBackendAddressPools" : [
{
"id" : "[reference(resourceId('Microsoft.Network/loadBalancers', variables('lbName')), '2024-05-01').backendAddressPools[0].id]"
}
]
}
}
] ,
"networkSecurityGroup" : {
"id" : "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
}
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/loadBalancers', variables('lbName'))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, 'firstSubnetForMasterNodes')]"
]
} ,
{
"type" : "Microsoft.Network/networkInterfaces" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}-masterNodeNetInterface2', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"properties" : {
"ipConfigurations" : [
{
"name" : "primaryIPConfig" ,
"properties" : {
"privateIPAllocationMethod" : "Dynamic" ,
"subnet" : {
"id" : "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, 'secondSubnetForMasterNodes')]"
} ,
"applicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"loadBalancerBackendAddressPools" : [
{
"id" : "[reference(resourceId('Microsoft.Network/loadBalancers', variables('lbName')), '2024-05-01').backendAddressPools[0].id]"
}
]
}
}
] ,
"networkSecurityGroup" : {
"id" : "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
}
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/loadBalancers', variables('lbName'))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, 'secondSubnetForMasterNodes')]"
]
} ,
{
"type" : "Microsoft.Network/networkInterfaces" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}-masterNodeNetInterface3', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"properties" : {
"ipConfigurations" : [
{
"name" : "primaryIPConfig" ,
"properties" : {
"privateIPAllocationMethod" : "Dynamic" ,
"subnet" : {
"id" : "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, 'firstSubnetForMasterNodes')]"
} ,
"applicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"loadBalancerBackendAddressPools" : [
{
"id" : "[reference(resourceId('Microsoft.Network/loadBalancers', variables('lbName')), '2024-05-01').backendAddressPools[0].id]"
}
]
}
}
] ,
"networkSecurityGroup" : {
"id" : "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
}
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/loadBalancers', variables('lbName'))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, 'firstSubnetForMasterNodes')]"
]
} ,
{
"type" : "Microsoft.Network/networkInterfaces" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}-masterNodeNetInterface4', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"properties" : {
"ipConfigurations" : [
{
"name" : "primaryIPConfig" ,
"properties" : {
"privateIPAllocationMethod" : "Dynamic" ,
"subnet" : {
"id" : "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, 'secondSubnetForMasterNodes')]"
} ,
"applicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"loadBalancerBackendAddressPools" : [
{
"id" : "[reference(resourceId('Microsoft.Network/loadBalancers', variables('lbName')), '2024-05-01').backendAddressPools[0].id]"
}
]
}
}
] ,
"networkSecurityGroup" : {
"id" : "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
}
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/loadBalancers', variables('lbName'))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, 'secondSubnetForMasterNodes')]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}-masterNodeNSG', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"properties" : {
"securityRules" : [
{
"name" : "SSH" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "22" ,
"access" : "Allow" ,
"priority" : 100 ,
"direction" : "Inbound"
}
} ,
{
"name" : "ProbeAPI" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "AzureLoadBalancer" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "7880" ,
"access" : "Allow" ,
"priority" : 500 ,
"direction" : "Inbound"
}
} ,
{
"name" : "HTTP" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "80" ,
"access" : "Allow" ,
"priority" : 510 ,
"direction" : "Inbound"
}
}
]
}
} ,
{
"type" : "Microsoft.Network/applicationSecurityGroups" ,
"apiVersion" : "2024-03-01" ,
"name" : "[format('{0}-masterNodeASG', parameters('stackName'))]" ,
"location" : "[variables('location')]"
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'loadBalancer_to_masterNode_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "443" ,
"access" : "Allow" ,
"priority" : 110 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_REDIS_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "7000" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "7001" ,
"access" : "Allow" ,
"priority" : 120 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'mediaNode_to_masterNode_REDIS_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "7000" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "7001" ,
"access" : "Allow" ,
"priority" : 130 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_MINIO_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "9100" ,
"access" : "Allow" ,
"priority" : 140 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_MINIO_CONSOLE_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "9101" ,
"access" : "Allow" ,
"priority" : 150 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'mediaNode_to_masterNode_MINIO_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "9100" ,
"access" : "Allow" ,
"priority" : 160 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_MONGO_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "20000" ,
"access" : "Allow" ,
"priority" : 170 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'mediaNode_to_masterNode_MONGO_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "20000" ,
"access" : "Allow" ,
"priority" : 180 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_MIMIRGRPC_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "9095" ,
"access" : "Allow" ,
"priority" : 190 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_MIMIRGOSSIP_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "7946" ,
"access" : "Allow" ,
"priority" : 200 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'mediaNode_to_masterNode_MIMIR_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "9009" ,
"access" : "Allow" ,
"priority" : 210 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_LOKIGRPC_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "9096" ,
"access" : "Allow" ,
"priority" : 220 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_LOKIGOSSIP_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "7947" ,
"access" : "Allow" ,
"priority" : 230 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_DASHBOARD_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "5000" ,
"access" : "Allow" ,
"priority" : 240 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_GRAFANA_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "3000" ,
"access" : "Allow" ,
"priority" : 250 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'mediaNode_to_masterNode_LOKI_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "3100" ,
"access" : "Allow" ,
"priority" : 260 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_V2COMPATIBILITY_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "4443" ,
"access" : "Allow" ,
"priority" : 270 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'mediaNode_to_masterNode_V2COMPATIBILITY_WEBHOOK_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "4443" ,
"access" : "Allow" ,
"priority" : 280 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'masterNode_to_masterNode_DEFAULTAPP_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "6080" ,
"access" : "Allow" ,
"priority" : 290 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-masterNodeNSG', parameters('stackName')), 'mediaNode_to_masterNode_DEFAULTAPP_WEBHOOK_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "6080" ,
"access" : "Allow" ,
"priority" : 300 ,
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-masterNodeNSG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}-mediaNodeNSG', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"properties" : {
"securityRules" : [
{
"name" : "SSH" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "22" ,
"access" : "Allow" ,
"priority" : 100 ,
"direction" : "Inbound"
}
} ,
{
"name" : "TURN" ,
"properties" : {
"protocol" : "Udp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "443" ,
"access" : "Allow" ,
"priority" : 110 ,
"direction" : "Inbound"
}
} ,
{
"name" : "WebRTC_over_TCP" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "7881" ,
"access" : "Allow" ,
"priority" : 120 ,
"direction" : "Inbound"
}
} ,
{
"name" : "WebRTC_using_WHIP" ,
"properties" : {
"protocol" : "Udp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "7885" ,
"access" : "Allow" ,
"priority" : 130 ,
"direction" : "Inbound"
}
} ,
{
"name" : "WebRTC_traffic_UDP" ,
"properties" : {
"protocol" : "Udp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRanges" : [
"50000" ,
"60000"
] ,
"access" : "Allow" ,
"priority" : 140 ,
"direction" : "Inbound"
}
2025-07-11 21:33:05 +02:00
} ,
{
"name" : "WebRTC_traffic_TCP" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRanges" : [
"50000" ,
"60000"
] ,
"access" : "Allow" ,
"priority" : 150 ,
"direction" : "Inbound"
}
2025-04-22 11:46:24 +02:00
}
]
}
} ,
{
"type" : "Microsoft.Network/applicationSecurityGroups" ,
"apiVersion" : "2024-03-01" ,
"name" : "[format('{0}-mediaNodeASG', parameters('stackName'))]" ,
"location" : "[variables('location')]"
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-mediaNodeNSG', parameters('stackName')), 'loadBalancer_to_mediaNode_RTMP_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "AzureLoadBalancer" ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "1945" ,
"access" : "Allow" ,
2025-07-22 13:52:54 +02:00
"priority" : 160 ,
2025-04-22 11:46:24 +02:00
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-mediaNodeNSG', parameters('stackName')), 'loadBalancer_to_mediaNode_HEALTHCHECK_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "AzureLoadBalancer" ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "9092" ,
"access" : "Allow" ,
2025-07-22 13:52:54 +02:00
"priority" : 170 ,
2025-04-22 11:46:24 +02:00
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]"
]
} ,
{
"condition" : "[equals(variables('turnTLSIsEnabled'), true())]" ,
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-mediaNodeNSG', parameters('stackName')), 'loadbalancer_to_mediaNode_TURN_TLS_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "AzureLoadBalancer" ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "5349" ,
"access" : "Allow" ,
2025-07-22 13:52:54 +02:00
"priority" : 180 ,
2025-04-22 11:46:24 +02:00
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]"
]
} ,
{
"condition" : "[equals(variables('turnTLSIsEnabled'), true())]" ,
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-mediaNodeNSG', parameters('stackName')), 'masterNode_to_mediaNode_TURN_TLSHEALTHCHECK_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "AzureLoadBalancer" ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "7880" ,
"access" : "Allow" ,
2025-07-22 13:52:54 +02:00
"priority" : 190 ,
2025-04-22 11:46:24 +02:00
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-mediaNodeNSG', parameters('stackName')), 'masterNode_to_mediaNode_SERVER_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "7880" ,
"access" : "Allow" ,
2025-07-22 13:52:54 +02:00
"priority" : 200 ,
2025-04-22 11:46:24 +02:00
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups/securityRules" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}/{1}', format('{0}-mediaNodeNSG', parameters('stackName')), 'masterNode_to_mediaNode_CLIENT_INGRESS')]" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]"
}
] ,
"sourcePortRange" : "*" ,
"destinationApplicationSecurityGroups" : [
{
"id" : "[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]"
}
] ,
"destinationPortRange" : "8080" ,
"access" : "Allow" ,
2025-07-22 13:52:54 +02:00
"priority" : 210 ,
2025-04-22 11:46:24 +02:00
"direction" : "Inbound"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-masterNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/applicationSecurityGroups', format('{0}-mediaNodeASG', parameters('stackName')))]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-mediaNodeNSG', parameters('stackName')))]"
]
} ,
{
2025-05-13 11:01:22 +02:00
"condition" : "[equals(variables('isEmptyStorageAccountName'), true())]" ,
2025-04-22 11:46:24 +02:00
"type" : "Microsoft.Storage/storageAccounts" ,
"apiVersion" : "2023-01-01" ,
2025-04-23 13:26:33 +02:00
"name" : "[uniqueString(resourceGroup().id)]" ,
2025-04-22 11:46:24 +02:00
"location" : "[resourceGroup().location]" ,
"sku" : {
"name" : "Standard_LRS"
} ,
"kind" : "StorageV2" ,
"properties" : {
"accessTier" : "Cool" ,
"supportsHttpsTrafficOnly" : true
}
} ,
{
2025-05-13 11:01:22 +02:00
"condition" : "[equals(variables('isEmptyStorageAccountName'), true())]" ,
2025-04-22 11:46:24 +02:00
"type" : "Microsoft.Storage/storageAccounts/blobServices/containers" ,
"apiVersion" : "2023-01-01" ,
2025-04-23 13:26:33 +02:00
"name" : "[format('{0}/default/automation-locks', uniqueString(resourceGroup().id))]" ,
"properties" : {
"publicAccess" : "None"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]"
]
} ,
{
2025-05-13 11:01:22 +02:00
"condition" : "[equals(variables('isEmptyStorageAccountName'), true())]" ,
2025-04-23 13:26:33 +02:00
"type" : "Microsoft.Storage/storageAccounts/blobServices/containers" ,
"apiVersion" : "2023-01-01" ,
2025-06-10 16:30:41 +02:00
"name" : "[if(variables('isEmptyAppDataContainerName'), format('{0}/default/openvidu-appdata', uniqueString(resourceGroup().id)), format('{0}/default/{1}', uniqueString(resourceGroup().id), parameters('appDataContainerName')))]" ,
"properties" : {
"publicAccess" : "None"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]"
]
} ,
{
"condition" : "[equals(variables('isEmptyStorageAccountName'), true())]" ,
"type" : "Microsoft.Storage/storageAccounts/blobServices/containers" ,
"apiVersion" : "2023-01-01" ,
"name" : "[if(variables('isEmptyClusterContainerName'), format('{0}/default/openvidu-clusterdata', uniqueString(resourceGroup().id)), format('{0}/default/{1}', uniqueString(resourceGroup().id), parameters('clusterDataContainerName')))]" ,
2025-04-22 11:46:24 +02:00
"properties" : {
"publicAccess" : "None"
} ,
"dependsOn" : [
2025-04-23 13:26:33 +02:00
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]"
2025-04-22 11:46:24 +02:00
]
} ,
{
"type" : "Microsoft.Resources/deployments" ,
"apiVersion" : "2022-09-01" ,
"name" : "WebhookDeployment" ,
"properties" : {
"expressionEvaluationOptions" : {
"scope" : "inner"
} ,
"mode" : "Incremental" ,
"parameters" : {
2025-05-27 11:18:05 +02:00
"automationAccountName" : "[if(variables('isEmptyAutomationAccountName'), createObject('value', uniqueString(resourceGroup().id, resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode1', parameters('stackName'))))), createObject('value', parameters('automationAccountName')))]" ,
2025-04-22 11:46:24 +02:00
"runbookName" : {
"value" : "scaleInRunbook"
} ,
"webhookName" : {
"value" : "webhookForScaleIn"
} ,
"WebhookExpiryTime" : {
"value" : "2035-03-30T00:00:00Z"
} ,
"_artifactsLocation" : {
2025-04-23 13:26:33 +02:00
"value" : "https://raw.githubusercontent.com/OpenVidu/openvidu/refs/heads/master/openvidu-deployment/pro/shared/scaleInRunbook.ps1"
2025-04-22 11:46:24 +02:00
}
} ,
"template" : {
"$schema" : "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#" ,
"contentVersion" : "1.0.0.0" ,
"parameters" : {
"automationAccountName" : {
"type" : "String" ,
"metadata" : {
"description" : "Automation account name"
}
} ,
"webhookName" : {
"type" : "String" ,
"metadata" : {
"description" : "Webhook Name"
}
} ,
"runbookName" : {
"type" : "String" ,
"metadata" : {
"description" : "Runbook Name for which webhook will be created"
}
} ,
"WebhookExpiryTime" : {
"type" : "String" ,
"metadata" : {
"description" : "Webhook Expiry time"
}
} ,
"_artifactsLocation" : {
2025-04-23 13:26:33 +02:00
"defaultValue" : "https://raw.githubusercontent.com/OpenVidu/openvidu/refs/heads/master/openvidu-deployment/pro/shared/scaleInRunbook.ps1" ,
2025-04-22 11:46:24 +02:00
"type" : "String" ,
"metadata" : {
"description" : "URI to artifacts location"
}
}
} ,
"resources" : [
{
"type" : "Microsoft.Automation/automationAccounts" ,
"apiVersion" : "2020-01-13-preview" ,
"name" : "[parameters('automationAccountName')]" ,
"location" : "[resourceGroup().location]" ,
"identity" : {
"type" : "SystemAssigned"
} ,
"properties" : {
"sku" : {
"name" : "Basic"
}
} ,
"resources" : [
{
"type" : "runbooks" ,
"apiVersion" : "2018-06-30" ,
"name" : "[parameters('runbookName')]" ,
"location" : "[resourceGroup().location]" ,
"dependsOn" : [
"[parameters('automationAccountName')]"
] ,
"properties" : {
"runbookType" : "PowerShell72" ,
"logProgress" : "true" ,
"description" : "Scale In Runbook" ,
"publishContentLink" : {
"uri" : "[parameters('_artifactsLocation')]" ,
"version" : "1.0.0.0"
}
}
} ,
{
"type" : "webhooks" ,
"apiVersion" : "2018-06-30" ,
"name" : "[parameters('webhookName')]" ,
"dependsOn" : [
"[parameters('automationAccountName')]" ,
"[parameters('runbookName')]"
] ,
"properties" : {
"isEnabled" : true ,
"expiryTime" : "[parameters('WebhookExpiryTime')]" ,
"runbook" : {
"name" : "[parameters('runbookName')]"
}
}
}
]
} ,
{
"type" : "Microsoft.Authorization/roleAssignments" ,
"apiVersion" : "2022-04-01" ,
"name" : "[guid(format('roleAutomationContributorAssignmentAutomationAccount{0}', parameters('automationAccountName')))]" ,
"properties" : {
"roleDefinitionId" : "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" ,
"principalId" : "[reference(resourceId('Microsoft.Automation/automationAccounts', parameters('automationAccountName')), '2023-11-01', 'full').identity.principalId]" ,
"principalType" : "ServicePrincipal"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Automation/automationAccounts', parameters('automationAccountName'))]"
]
}
] ,
"outputs" : {
"webhookUri" : {
"type" : "String" ,
"value" : "[reference(parameters('webhookName')).uri]"
} ,
"automationAccountId" : {
"type" : "string" ,
"value" : "[resourceId('Microsoft.Automation/automationAccounts', parameters('automationAccountName'))]"
} ,
"webhookId" : {
"type" : "string" ,
"value" : "[resourceId('Microsoft.Automation/automationAccounts/webhooks', parameters('automationAccountName'), parameters('webhookName'))]"
}
}
}
2025-05-27 11:18:05 +02:00
} ,
"dependsOn" : [
"[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode1', parameters('stackName')))]"
]
2025-04-22 11:46:24 +02:00
}
]
}