2025-05-29 15:58:41 +02:00
{
"$schema" : "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#" ,
"contentVersion" : "1.0.0.0" ,
"metadata" : {
"_generator" : {
"name" : "bicep" ,
2025-08-28 13:58:03 +02:00
"version" : "0.37.4.10188" ,
2025-09-07 19:56:14 +02:00
"templateHash" : "3418583908087340763"
2025-05-29 15:58:41 +02:00
}
} ,
"parameters" : {
"stackName" : {
"type" : "string" ,
"metadata" : {
"description" : "Stack name"
}
} ,
"certificateType" : {
"type" : "string" ,
2025-09-07 19:56:14 +02:00
"defaultValue" : "letsencrypt" ,
2025-05-29 15:58:41 +02:00
"allowedValues" : [
"selfsigned" ,
"owncert" ,
"letsencrypt"
] ,
"metadata" : {
2025-09-07 19:56:14 +02:00
"description" : "[selfsigned] Not recommended for production use. Just for testing purposes or development environments. You don't need a FQDN to use this option.\n[owncert] Valid for production environments. Use your own certificate. You need a FQDN to use this option.\n[letsencrypt] Valid for production environments. Can be used with or without a FQDN (if no FQDN is provided, a random sslip.io domain will be used).\n"
2025-05-29 15:58:41 +02:00
}
} ,
"publicIpAddressObject" : {
"type" : "object" ,
"metadata" : {
"description" : "Previously created Public IP address for the OpenVidu Deployment. Blank will generate a public IP"
}
} ,
"domainName" : {
"type" : "string" ,
"defaultValue" : "" ,
"metadata" : {
"description" : "Domain name for the OpenVidu Deployment. Blank will generate default domain"
}
} ,
"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"
}
} ,
"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"
}
} ,
"instanceType" : {
"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 azure vm size for your OpenVidu instance"
}
} ,
"adminUsername" : {
"type" : "string" ,
"metadata" : {
"description" : "Username for the Virtual Machine."
}
} ,
"adminSshKey" : {
"type" : "secureObject" ,
"metadata" : {
"description" : "SSH Key or password for the Virtual Machine."
}
} ,
2025-06-18 16:26:50 +02:00
"additionalInstallFlags" : {
"type" : "string" ,
"defaultValue" : ""
} ,
2025-05-29 15:58:41 +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."
}
} ,
"containerName" : {
"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."
}
}
} ,
"variables" : {
"isEmptyIp" : "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'none')]" ,
"isEmptyDomain" : "[equals(parameters('domainName'), '')]" ,
"networkSettings" : {
"privateIPaddressNetInterface" : "10.0.0.5" ,
"vNetAddressPrefix" : "10.0.0.0/16" ,
"subnetAddressPrefix" : "10.0.0.0/24" ,
"netInterfaceName" : "[format('{0}-netInteface', parameters('stackName'))]" ,
"vNetName" : "[format('{0}-vnet', parameters('stackName'))]" ,
"subnetName" : "default"
} ,
"openviduVMSettings" : {
2025-09-07 19:56:14 +02:00
"vmName" : "[format('{0}-VM-Pro', parameters('stackName'))]" ,
2025-05-29 15:58:41 +02:00
"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'))]" ,
"keyData" : "[parameters('adminSshKey').sshPublicKey]"
}
]
}
}
} ,
"keyVaultName" : "[format('{0}-keyvault', parameters('stackName'))]" ,
"location" : "[resourceGroup().location]" ,
"tenantId" : "[subscription().tenantId]" ,
"deploymentUser" : "[deployer().objectId]" ,
2025-09-07 19:56:14 +02:00
"stringInterpolationParams" : {
"domainName" : "[parameters('domainName')]" ,
"turnDomainName" : "[parameters('turnDomainName')]" ,
"certificateType" : "[parameters('certificateType')]" ,
"ownPublicCertificate" : "[parameters('ownPublicCertificate')]" ,
"ownPrivateCertificate" : "[parameters('ownPrivateCertificate')]" ,
"turnOwnPublicCertificate" : "[parameters('turnOwnPublicCertificate')]" ,
"turnOwnPrivateCertificate" : "[parameters('turnOwnPrivateCertificate')]" ,
"keyVaultName" : "[variables('keyVaultName')]" ,
"openviduLicense" : "[parameters('openviduLicense')]" ,
"rtcEngine" : "[parameters('rtcEngine')]" ,
"additionalInstallFlags" : "[parameters('additionalInstallFlags')]"
} ,
"installScriptTemplate" : "#!/bin/bash -x\nOPENVIDU_VERSION=main\nDOMAIN=\n\napt-get update && apt-get install -y \\\n curl \\\n unzip \\\n jq \\\n wget\n\n# Configure Domain\nif [[ \"${domainName}\" == '' ]]; then\n [ ! -d \"/usr/share/openvidu\" ] && mkdir -p /usr/share/openvidu\n # Get public IP using the get_public_ip.sh script\n PUBLIC_IP=$(/usr/local/bin/get_public_ip.sh 2>/dev/null)\n if [[ $? -ne 0 || -z \"${PUBLIC_IP}\" ]]; then\n echo \"Could not determine public IP.\"\n exit 1\n fi\n\n RANDOM_DOMAIN_STRING=$(tr -dc 'a-z' < /dev/urandom | head -c 8)\n DOMAIN=\"openvidu-$RANDOM_DOMAIN_STRING-$(echo \"$PUBLIC_IP\" | tr '.' '-').sslip.io\"\n TURN_DOMAIN_NAME_SSLIP_IO=\"turn-$RANDOM_DOMAIN_STRING-$(echo \"$PUBLIC_IP\" | tr '.' '-').sslip.io\"\n echo $RANDOM_DOMAIN_STRING > /usr/share/openvidu/random-domain-string\n echo $PUBLIC_IP > /usr/share/openvidu/public-ip\nelse\n DOMAIN=${domainName}\nfi\n\nDOMAIN=\"$(/usr/local/bin/store_secret.sh save DOMAIN-NAME \"$DOMAIN\")\"\nOPENVIDU_PRO_LICENSE=\"$(/usr/local/bin/store_secret.sh save OPENVIDU-PRO-LICENSE \"${openviduLicense}\")\"\nOPENVIDU_RTC_ENGINE=\"$(/usr/local/bin/store_secret.sh save OPENVIDU-RTC-ENGINE \"${rtcEngine}\")\"\nREDIS_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate REDIS-PASSWORD)\"\nMONGO_ADMIN_USERNAME=\"$(/usr/local/bin/store_secret.sh save MONGO-ADMIN-USERNAME \"mongoadmin\")\"\nMONGO_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate MONGO-ADMIN-PASSWORD)\"\nMONGO_REPLICA_SET_KEY=\"$(/usr/local/bin/store_secret.sh generate MONGO-REPLICA-SET-KEY)\"\nMINIO_ACCESS_KEY=\"$(/usr/local/bin/store_secret.sh save MINIO-ACCESS-KEY \"minioadmin\")\"\nMINIO_SECRET_KEY=\"$(/usr/local/bin/store_secret.sh generate MINIO-SECRET-KEY)\"\nDASHBOARD_ADMIN_USERNAME=\"$(/usr/local/bin/store_secret.sh save DASHBOARD-ADMIN-USERNAME \"dashboardadmin\")\"\nDASHBOARD_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate DASHBOARD-ADMIN-PASSWORD)\"\nGRAFANA_ADMIN_USERNAME=\"$(/usr/local/bin/store_secret.sh save GRAFANA-ADMIN-USERNAME \"grafanaadmin\")\"\nGRAFANA_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate GRAFANA-ADMIN-PASSWORD)\"\nMEET_INITIAL_ADMIN_USER=\"$(/usr/local/bin/store_secret.sh save MEET-INITIAL-ADMIN-USER \"meetadmin\")\"\nMEET_INITIAL_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate MEET-INITIAL-ADMIN-PASSWORD)\"\nMEET_INITIAL_API_KEY=\"$(/usr/local/bin/store_secret.sh generate MEET-INITIAL-API-KEY)\"\nLIVEKIT_API_KEY=\"$(/usr/local/bin/store_secret.sh generate LIVEKIT-API-KEY \"API\" 12)\"\nLIVEKIT_API_SECRET=\"$(/usr/local/bin/store_secret.sh generate LIVEKIT-API-SECRET)\"\nENABLED_MODULES=\"$(/usr/local/bin/store_secret.sh save ENABLED-MODULES \"observability,openviduMeet,v2compatibility\")\"\n\n# Base command\nINSTALL_COMMAND=\"sh <(curl -fsSL http://get.openvidu.io/community/singlenode/$OPENVIDU_VERSION/install.sh)\"\n\n# Common arguments\nCOMMON_ARGS=(\n \"--no-tty\"\n \"--install\"\n \"--environment=azure\"\n \"--deployment-type=single_node_pro\"\n \"--openvidu-pro-license=$OPENVIDU_PRO_LICENSE\"\n \"--domain-name=$DOMAIN\"\n \"--enabled-modules='$ENABLED_MODULES'\"\n \"--rtc-engine=$OPENVIDU_RTC_ENGINE\"\n \"--redis-password=$REDIS_PASSWORD\"\n \"--mongo-admin-user=$MONGO_ADMIN_USERNAME\"\n \"--mongo-admin-password=$MONGO_ADMIN_PASSWORD\"\n \"--mongo-replica-set-key=$MONGO_REPLICA_SET_KEY\"\n \"--minio-access-key=$MINIO_ACCESS_KEY\"\n \"--minio-secret-key=$MINIO_SECRET_KEY\"\n \"--dashboard-admin-user=$DASHBOARD_ADMIN_USERNAME\"\n \"--dashboard-admin-password=$DASHBOARD_ADMIN_PASSWORD\"\n \"--grafana-admin-user=$GRAFANA_ADMIN_USERNAME\"\n \"--grafana-admin-password=$GRAFANA_ADMIN_PASSWORD\"\n \"--meet-initial-admin-user=$MEET_INITIAL_ADMIN_USER\"\n \"--meet-initial-admin-password=$MEET_INITIAL_ADMIN_PASSWORD\"\n \"--meet-initial-api-key=$MEET_INITIAL_API_KEY\"\n \"--livekit-api-key=$LIVEKIT_API_KEY\"\n \"--livekit-api-secret=$LIVEKIT_API_SECRET\"\n)\n\n# Include additional installer flags provided by the user\nif [[ \"${additionalInstallFlags}\" != \"\" ] ] ; t h e n
"after_installScriptTemplate" : "#!/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)\nOPENVIDU_URL=\"https://${DOMAIN}/\"\nLIVEKIT_URL=\"wss://${DOMAIN}/\"\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 OPENVIDU-URL --value $OPENVIDU_URL\naz keyvault secret set --vault-name ${keyVaultName} --name LIVEKIT-URL --value $LIVEKIT_URL\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_secretScriptTemplate" : "#!/bin/bash -x\nset -e\n\naz login --identity --allow-no-subscriptions > /dev/null\n\n# Installation directory\nINSTALL_DIR=\"/opt/openvidu\"\nCONFIG_DIR=\"${INSTALL_DIR}/config\"\n\n# Replace DOMAIN_NAME\nexport DOMAIN=$(az keyvault secret show --vault-name ${keyVaultName} --name DOMAIN-NAME --query value -o tsv)\nif [[ $DOMAIN == *\"sslip.io\"* ]] || [[ -z $DOMAIN ]]; then\n PUBLIC_IP=$(/usr/local/bin/get_public_ip.sh 2>/dev/null || echo \"\")\n\n if [[ -n \"$PUBLIC_IP\" ]] && [[ -f \"/usr/share/openvidu/random-domain-string\" ]]; then\n RANDOM_DOMAIN_STRING=$(cat /usr/share/openvidu/random-domain-string)\n DOMAIN=\"openvidu-$RANDOM_DOMAIN_STRING-$(echo \"$PUBLIC_IP\" | tr '.' '-').sslip.io\"\n fi\nfi\nif [[ -n \"$DOMAIN\" ]]; then\n sed -i \"s/DOMAIN_NAME=.*/DOMAIN_NAME=$DOMAIN/\" \"${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 [[ $LIVEKIT_TURN_DOMAIN_NAME == *\"sslip.io\"* ]] || [[ -z $LIVEKIT_TURN_DOMAIN_NAME ]]; then\n PUBLIC_IP=$(/usr/local/bin/get_public_ip.sh 2>/dev/null || echo \"\")\n\n if [[ -n \"$PUBLIC_IP\" ]] && [[ -f \"/usr/share/openvidu/random-domain-string\" ]]; then\n RANDOM_DOMAIN_STRING=$(cat /usr/share/openvidu/random-domain-string)\n LIVEKIT_TURN_DOMAIN_NAME=\"turn-$RANDOM_DOMAIN_STRING-$(echo \"$PUBLIC_IP\" | tr '.' '-').sslip.io\"\n fi\nfi\nif [[ -n \"$LIVEKIT_TURN_DOMAIN_NAME\" ]]; then\n sed -i \"s/LIVEKIT_TURN_DOMAIN_NAME=.*/LIVEKIT_TURN_DOMAIN_NAME=$LIVEKIT_TURN_DOMAIN_NAME/\" \"${CONFIG_DIR}/openvidu.env\" \ n f i \ n \ n # G e t t h e r e s t o f t h e v a l u e s \ n e x p o r t R E D I S _ P A S S W O R D = $ ( 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 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 - - q u e r y v a l u e - o t s v ) \ n e x p o r t O P E N V I D U _ R T C _ E N G I N E = $ ( 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 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 - - q u e r y v a l u e - o t s v ) \ n e x p o r t O P E N V I D U _ P R O _ L I C E N S E = $ ( 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 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 - - q u e r y v a l u e - o t s v ) \ n e x p o r t M O N G O _ A D M I N _ U S E R N A M E = $ ( 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 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 - - q u e r y v a l u e - o t s v ) \ n e x p o r t M O N G O _ A D M I N _ P A S S W O R D = $ ( 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 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 - - q u e r y v a l u e - o t s v ) \ n e x p o r t M O N G O _ R E P L I C A _ S E T _ K E Y = $ ( 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 a u l t N a m e } - - n a m e M O N G O - R E P L I C A - S E T - K E Y - - q u e r y v a l u e - o t s v ) \ n e x p o r t D A S H B O A R D _ A D M I N _ U S E R N A M E = $ ( 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 a u l t N a m e } - - n a m e D A S H B O A R D - A D M I N - U S E R N A M E - - q u e r y v a l u e - o t s v ) \ n e x p o r t D A S H B O A R D _ A D M I N _ P A S S W O R D = $ ( 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 a u l t N a m e } - - n a m e D A S H B O A R D - A D M I N - P A S S W O R D - - q u e r y v a l u e - o t s v ) \ n e x p o r t M I N I O _ A C C E S S _ K E Y = $ ( 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 a u l t N a m e } - - n a m e M I N I O - A C C E S S - K E Y - - q u e r y v a l u e - o t s v ) \ n e x p o r t M I N I O _ S E C R E T _ K E Y = $ ( 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 a u l t N a m e } - - n a m e M I N I O - S E C R E T - K E Y - - q u e r y v a l u e - o t s v ) \ n e x p o r t G R A F A N A _ A D M I N _ U S E R N A M E = $ ( 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 a u l t N a m e } - - n a m e G R A F A N A - A D M I N - U S E R N A M E - - q u e r y v a l u e - o t s v ) \ n e x p o r t G R A F A N A _ A D M I N _ P A S S W O R D = $ ( 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 a u l t N a m e } - - n a m e G R A F A N A - A D M I N - P A S S W O R D - - q u e r y v a l u e - o t s v ) \ n e x p o r t L I V E K I T _ A P I _ K E Y = $ ( 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 a u l t N a m e } - - n a m e L I V E K I T - A P I - K E Y - - q u e r y v a l u e - o t s v ) \ n e x p o r t L I V E K I T _ A P I _ S E C R E T = $ ( 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 a u l t N a m e } - - n a m e L I V E K I T - A P I - S E C R E T - - q u e r y v a l u e - o t s v ) \ n e x p o r t M E E T _ I N I T I A L _ A D M I N _ U S E R = $ ( 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 a u l t N a m e } - - n a m e M E E T - I N I T I A L - A D M I N - U S E R - - q u e r y v a l u e - o t s v ) \ n e x p o r t M E E T _ I N I T I A L _ A D M I N _ P A S S W O R D = $ ( 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 a u l t N a m e } - - n a m e M E E T - I N I T I A L - A D M I N - P A S S W O R D - - q u e r y v a l u e - o t s v ) \ n e x p o r t M E E T _ I N I T I A L _ A P I _ K E Y = $ ( 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 a u l t N a m e } - - n a m e M E E T - I N I T I A L - A P I - K E Y - - q u e r y v a l u e - o t s v ) \ n e x p o r t E N A B L E D _ M O D U L E S = $ ( 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
2025-08-28 13:58:03 +02:00
"update_secret_from_configScriptTemplate" : "#!/bin/bash\nset -e\n\naz login --identity --allow-no-subscriptions > /dev/null\n\n# Installation directory\nINSTALL_DIR=\"/opt/openvidu\"\nCONFIG_DIR=\"${INSTALL_DIR}/config\"\n\nif [[ ${certificateType} == \"letsencrypt\" ]]; then\n LETSENCRYPT_EMAIL=\"$(/usr/local/bin/get_value_from_config.sh LETSENCRYPT_EMAIL \"${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 \"${CONFIG_DIR}/openvidu.env\")\"\nDOMAIN_NAME=\"$(/usr/local/bin/get_value_from_config.sh DOMAIN_NAME \"${CONFIG_DIR}/openvidu.env\")\"\nLIVEKIT_TURN_DOMAIN_NAME=\"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_TURN_DOMAIN_NAME \"${CONFIG_DIR}/openvidu.env\")\"\nOPENVIDU_RTC_ENGINE=\"$(/usr/local/bin/get_value_from_config.sh OPENVIDU_RTC_ENGINE \"${CONFIG_DIR}/openvidu.env\")\"\nOPENVIDU_PRO_LICENSE=\"$(/usr/local/bin/get_value_from_config.sh OPENVIDU_PRO_LICENSE \"${CONFIG_DIR}/openvidu.env\")\"\nMONGO_ADMIN_USERNAME=\"$(/usr/local/bin/get_value_from_config.sh MONGO_ADMIN_USERNAME \"${CONFIG_DIR}/openvidu.env\")\"\nMONGO_ADMIN_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh MONGO_ADMIN_PASSWORD \"${CONFIG_DIR}/openvidu.env\")\"\nMONGO_REPLICA_SET_KEY=\"$(/usr/local/bin/get_value_from_config.sh MONGO_REPLICA_SET_KEY \"${CONFIG_DIR}/openvidu.env\")\"\nMINIO_ACCESS_KEY=\"$(/usr/local/bin/get_value_from_config.sh MINIO_ACCESS_KEY \"${CONFIG_DIR}/openvidu.env\")\"\nMINIO_SECRET_KEY=\"$(/usr/local/bin/get_value_from_config.sh MINIO_SECRET_KEY \"${CONFIG_DIR}/openvidu.env\")\"\nDASHBOARD_ADMIN_USERNAME=\"$(/usr/local/bin/get_value_from_config.sh DASHBOARD_ADMIN_USERNAME \"${CONFIG_DIR}/openvidu.env\")\"\nDASHBOARD_ADMIN_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh DASHBOARD_ADMIN_PASSWORD \"${CONFIG_DIR}/openvidu.env\")\"\nGRAFANA_ADMIN_USERNAME=\"$(/usr/local/bin/get_value_from_config.sh GRAFANA_ADMIN_USERNAME \"${CONFIG_DIR}/openvidu.env\")\"\nGRAFANA_ADMIN_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh GRAFANA_ADMIN_PASSWORD \"${CONFIG_DIR}/openvidu.env\")\"\nLIVEKIT_API_KEY=\"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_API_KEY \"${CONFIG_DIR}/openvidu.env\")\"\nLIVEKIT_API_SECRET=\"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_API_SECRET \"${CONFIG_DIR}/openvidu.env\")\"\nMEET_INITIAL_ADMIN_USER=\"$(/usr/local/bin/get_value_from_config.sh MEET_INITIAL_ADMIN_USER \"${CONFIG_DIR}/meet.env\")\"\nMEET_INITIAL_ADMIN_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh MEET_INITIAL_ADMIN_PASSWORD \"${CONFIG_DIR}/meet.env\")\"\nMEET_INITIAL_API_KEY=\"$(/usr/local/bin/get_value_from_config.sh MEET_INITIAL_API_KEY \"${CONFIG_DIR}/meet.env\")\"\nENABLED_MODULES=\"$(/usr/local/bin/get_value_from_config.sh ENABLED_MODULES \"${CONFIG_DIR}/openvidu.env\")\" \ n \ 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 _ 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 M O N G O - R E P L I C A - S E T - K E Y - - v a l u e $ M O N G O _ R E P L I C A _ S E T _ K E Y \ 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 I N I O - A C C E S S - K E Y - - v a l u e $ M I N I O _ A C C E S S _ K E Y \ 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 I N I O - S E C R E T - K E Y - - v a l u e $ M I N I O _ S E C R E T _ K E Y \ 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 } -
2025-05-29 15:58:41 +02:00
"get_value_from_configScript" : "#!/bin/bash -x\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_secretScriptTemplate" : "#!/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" ,
2025-09-07 19:56:14 +02:00
"get_public_ip" : "#!/bin/bash\n\n# List of services to check public IP\nservices=(\n \"https://checkip.amazonaws.com\"\n \"https://ifconfig.me/ip\"\n \"https://ipinfo.io/ip\"\n \"https://api.ipify.org\"\n \"https://icanhazip.com\"\n)\n\nfor service in \"${services[@]}\"; do\n ip=$(curl -s --max-time 5 \"$service\")\n if [[ -n \"$ip\" && \"$ip\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then\n echo \"$ip\"\n exit 0\n else\n echo \"Failed to get IP from $service\" >&2\n fi\ndone\n\necho \"Could not retrieve public IP from any service.\" >&2\nexit 1\n" ,
2025-05-29 15:58:41 +02:00
"check_app_ready" : "#!/bin/bash\nwhile true; do\n HTTP_STATUS=$(curl -Ik http://localhost:7880 | head -n1 | awk '{print $2}')\n if [ $HTTP_STATUS == 200 ]; then\n break\n fi\n sleep 5\ndone\n" ,
"restart" : "#!/bin/bash -x\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" ,
"config_blobStorageTemplate" : "#!/bin/bash\nset -e\n\n# Install dir and config dir\nINSTALL_DIR=\"/opt/openvidu\"\nCONFIG_DIR=\"${INSTALL_DIR}/config\"\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|\" \"${CONFIG_DIR}/openvidu.env\"\nsed -i \"s|AZURE_ACCOUNT_KEY=.*|AZURE_ACCOUNT_KEY=$AZURE_ACCOUNT_KEY|\" \"${CONFIG_DIR}/openvidu.env\"\nsed -i \"s|AZURE_CONTAINER_NAME=.*|AZURE_CONTAINER_NAME=$AZURE_CONTAINER_NAME|\" \"${CONFIG_DIR}/openvidu.env\"\n" ,
2025-09-07 19:56:14 +02:00
"formattedTemplateInstallScript" : "[reduce(items(variables('stringInterpolationParams')), createObject('value', variables('installScriptTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"after_installScriptMaster" : "[reduce(items(variables('stringInterpolationParams')), createObject('value', variables('after_installScriptTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"update_config_from_secretScript" : "[reduce(items(variables('stringInterpolationParams')), createObject('value', variables('update_config_from_secretScriptTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"update_secret_from_configScript" : "[reduce(items(variables('stringInterpolationParams')), createObject('value', variables('update_secret_from_configScriptTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"store_secretScript" : "[reduce(items(variables('stringInterpolationParams')), createObject('value', variables('store_secretScriptTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value]" ,
"base64install" : "[base64(variables('formattedTemplateInstallScript'))]" ,
"base64after_install" : "[base64(variables('after_installScriptMaster'))]" ,
"base64update_config_from_secret" : "[base64(variables('update_config_from_secretScript'))]" ,
"base64update_secret_from_config" : "[base64(variables('update_secret_from_configScript'))]" ,
2025-05-29 15:58:41 +02:00
"base64get_value_from_config" : "[base64(variables('get_value_from_configScript'))]" ,
2025-09-07 19:56:14 +02:00
"base64store_secret" : "[base64(variables('store_secretScript'))]" ,
"base64get_public_ip" : "[base64(variables('get_public_ip'))]" ,
2025-05-29 15:58:41 +02:00
"base64check_app_ready" : "[base64(variables('check_app_ready'))]" ,
"base64restart" : "[base64(variables('restart'))]" ,
2025-09-07 19:56:14 +02:00
"userDataTemplate" : "#!/bin/bash -x\nset -eu -o pipefail\n\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# get_public_ip.sh\necho ${base64get_public_ip} | base64 -d > /usr/local/bin/get_public_ip.sh\nchmod +x /usr/local/bin/get_public_ip.sh\n\necho ${base64check_app_ready} | base64 -d > /usr/local/bin/check_app_ready.sh\nchmod +x /usr/local/bin/check_app_ready.sh\n\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\n# Wait for the app\n/usr/local/bin/check_app_ready.sh\n" ,
2025-05-29 15:58:41 +02:00
"ipExists" : "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'existing')]" ,
"ipNew" : "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'new')]" ,
"isEmptyStorageAccountName" : "[equals(parameters('storageAccountName'), '')]" ,
"isEmptyContainerName" : "[equals(parameters('containerName'), '')]"
} ,
"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', variables('openviduVMSettings').vmName), '2023-09-01', 'full').identity.principalId]" ,
"tenantId" : "[variables('tenantId')]" ,
"permissions" : {
"secrets" : [
"get" ,
"set" ,
"list"
]
}
} ,
{
"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', variables('openviduVMSettings').vmName)]"
]
} ,
{
"type" : "Microsoft.Compute/virtualMachines" ,
"apiVersion" : "2023-09-01" ,
"name" : "[variables('openviduVMSettings').vmName]" ,
"location" : "[variables('location')]" ,
"identity" : {
"type" : "SystemAssigned"
} ,
"properties" : {
"hardwareProfile" : {
"vmSize" : "[parameters('instanceType')]"
} ,
"storageProfile" : {
"osDisk" : {
"createOption" : "FromImage" ,
"managedDisk" : {
"storageAccountType" : "[variables('openviduVMSettings').osDiskType]"
} ,
"diskSizeGB" : 100
} ,
"imageReference" : "[variables('openviduVMSettings').ubuntuOSVersion]"
} ,
"networkProfile" : {
"networkInterfaces" : [
{
"id" : "[resourceId('Microsoft.Network/networkInterfaces', variables('networkSettings').netInterfaceName)]"
}
]
} ,
"osProfile" : {
"computerName" : "[variables('openviduVMSettings').vmName]" ,
"adminUsername" : "[parameters('adminUsername')]" ,
"linuxConfiguration" : "[variables('openviduVMSettings').linuxConfiguration]"
} ,
2025-09-07 19:56:14 +02:00
"userData" : "[base64(reduce(items(createObject('base64install', variables('base64install'), 'base64after_install', variables('base64after_install'), 'base64update_config_from_secret', variables('base64update_config_from_secret'), 'base64update_secret_from_config', variables('base64update_secret_from_config'), 'base64get_value_from_config', variables('base64get_value_from_config'), 'base64store_secret', variables('base64store_secret'), 'base64get_public_ip', variables('base64get_public_ip'), 'base64check_app_ready', variables('base64check_app_ready'), 'base64restart', variables('base64restart'), '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('isEmptyContainerName'), 'openvidu-appdata', format('{0}', parameters('containerName'))))), 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('userDataTemplate')), lambda('curr', 'next', createObject('value', replace(lambdaVariables('curr').value, format('${{{0}}}', lambdaVariables('next').key), lambdaVariables('next').value)))).value)]"
2025-05-29 15:58:41 +02:00
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/networkInterfaces', variables('networkSettings').netInterfaceName)]" ,
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]"
]
} ,
{
"type" : "Microsoft.Authorization/roleAssignments" ,
"apiVersion" : "2022-04-01" ,
"name" : "[guid(format('roleAssignmentForOpenViduServer{0}', variables('openviduVMSettings').vmName))]" ,
"properties" : {
"roleDefinitionId" : "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')]" ,
"principalId" : "[reference(resourceId('Microsoft.Compute/virtualMachines', variables('openviduVMSettings').vmName), '2023-09-01', 'full').identity.principalId]" ,
"principalType" : "ServicePrincipal"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Compute/virtualMachines', variables('openviduVMSettings').vmName)]"
]
} ,
{
2025-09-07 19:56:14 +02:00
"condition" : "[equals(variables('ipNew'), true())]" ,
2025-05-29 15:58:41 +02:00
"type" : "Microsoft.Network/publicIPAddresses" ,
"apiVersion" : "2023-11-01" ,
2025-09-07 19:56:14 +02:00
"name" : "[parameters('publicIpAddressObject').name]" ,
2025-05-29 15:58:41 +02:00
"location" : "[variables('location')]" ,
"sku" : {
"name" : "Standard" ,
"tier" : "Regional"
} ,
"properties" : {
"publicIPAddressVersion" : "IPv4" ,
"publicIPAllocationMethod" : "Static" ,
"dnsSettings" : {
2025-09-07 19:56:14 +02:00
"domainNameLabel" : "[if(variables('isEmptyDomain'), toLower(format('{0}', parameters('stackName'))), null())]"
2025-05-29 15:58:41 +02:00
}
}
} ,
{
"type" : "Microsoft.Network/virtualNetworks" ,
"apiVersion" : "2023-11-01" ,
"name" : "[variables('networkSettings').vNetName]" ,
"location" : "[variables('location')]" ,
"properties" : {
"addressSpace" : {
"addressPrefixes" : [
"[variables('networkSettings').vNetAddressPrefix]"
]
} ,
"subnets" : [
{
"name" : "[variables('networkSettings').subnetName]" ,
"properties" : {
"addressPrefix" : "[variables('networkSettings').subnetAddressPrefix]" ,
"privateEndpointNetworkPolicies" : "Disabled" ,
"privateLinkServiceNetworkPolicies" : "Enabled" ,
"networkSecurityGroup" : {
"id" : "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-nsg', parameters('stackName')))]"
}
}
}
]
} ,
"dependsOn" : [
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-nsg', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkInterfaces" ,
"apiVersion" : "2023-11-01" ,
"name" : "[variables('networkSettings').netInterfaceName]" ,
"location" : "[variables('location')]" ,
"properties" : {
"ipConfigurations" : [
{
"name" : "ipconfig1" ,
"properties" : {
"privateIPAllocationMethod" : "Dynamic" ,
"subnet" : {
"id" : "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('networkSettings').vNetName, variables('networkSettings').subnetName)]"
} ,
2025-09-07 19:56:14 +02:00
"publicIPAddress" : "[if(variables('isEmptyIp'), null(), createObject('id', if(variables('ipNew'), resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name), resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name))))]"
2025-05-29 15:58:41 +02:00
}
}
] ,
"networkSecurityGroup" : {
"id" : "[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-nsg', parameters('stackName')))]"
}
} ,
"dependsOn" : [
2025-09-07 19:56:14 +02:00
"[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name)]" ,
2025-05-29 15:58:41 +02:00
"[resourceId('Microsoft.Network/virtualNetworks', variables('networkSettings').vNetName)]" ,
"[resourceId('Microsoft.Network/networkSecurityGroups', format('{0}-nsg', parameters('stackName')))]"
]
} ,
{
"type" : "Microsoft.Network/networkSecurityGroups" ,
"apiVersion" : "2023-11-01" ,
"name" : "[format('{0}-nsg', parameters('stackName'))]" ,
"location" : "[variables('location')]" ,
"properties" : {
"securityRules" : [
{
"name" : "SSH" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "22" ,
"access" : "Allow" ,
"priority" : 100 ,
"direction" : "Inbound"
}
} ,
{
"name" : "HTTP" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "80" ,
"access" : "Allow" ,
"priority" : 110 ,
"direction" : "Inbound"
}
} ,
{
"name" : "HTTPS" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "443" ,
"access" : "Allow" ,
"priority" : 120 ,
"direction" : "Inbound"
}
} ,
{
"name" : "TURN" ,
"properties" : {
"protocol" : "Udp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "443" ,
"access" : "Allow" ,
"priority" : 130 ,
"direction" : "Inbound"
}
} ,
{
"name" : "RTMP" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "1935" ,
"access" : "Allow" ,
"priority" : 140 ,
"direction" : "Inbound"
}
} ,
{
"name" : "WebRTC_over_TCP" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "7881" ,
"access" : "Allow" ,
"priority" : 150 ,
"direction" : "Inbound"
}
} ,
{
"name" : "WebRTC_using_WHIP" ,
"properties" : {
"protocol" : "Udp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "7885" ,
"access" : "Allow" ,
"priority" : 160 ,
"direction" : "Inbound"
}
} ,
{
"name" : "MinIO" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRange" : "9000" ,
"access" : "Allow" ,
"priority" : 170 ,
"direction" : "Inbound"
}
} ,
{
"name" : "WebRTC_traffic_UDP" ,
"properties" : {
"protocol" : "Udp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRanges" : [
"50000" ,
"60000"
] ,
"access" : "Allow" ,
"priority" : 180 ,
"direction" : "Inbound"
}
} ,
{
"name" : "WebRTC_traffic_TCP" ,
"properties" : {
"protocol" : "Tcp" ,
"sourceAddressPrefix" : "*" ,
"sourcePortRange" : "*" ,
"destinationAddressPrefix" : "*" ,
"destinationPortRanges" : [
"50000" ,
"60000"
] ,
"access" : "Allow" ,
"priority" : 190 ,
"direction" : "Inbound"
}
}
]
}
} ,
{
"type" : "Microsoft.Storage/storageAccounts" ,
"apiVersion" : "2023-01-01" ,
"name" : "[uniqueString(resourceGroup().id)]" ,
"location" : "[resourceGroup().location]" ,
"sku" : {
"name" : "Standard_LRS"
} ,
"kind" : "StorageV2" ,
"properties" : {
"accessTier" : "Cool" ,
"supportsHttpsTrafficOnly" : true
}
} ,
{
"type" : "Microsoft.Storage/storageAccounts/blobServices/containers" ,
"apiVersion" : "2023-01-01" ,
"name" : "[if(variables('isEmptyContainerName'), format('{0}/default/openvidu-appdata', uniqueString(resourceGroup().id)), format('{0}/default/{1}', uniqueString(resourceGroup().id), parameters('containerName')))]" ,
"properties" : {
"publicAccess" : "None"
} ,
"dependsOn" : [
"[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]"
]
}
]
}