From 259585929b1f3dad3dc4c5c5068b7b2ce5a3c66c Mon Sep 17 00:00:00 2001 From: cruizba Date: Tue, 9 Sep 2025 22:06:36 +0200 Subject: [PATCH] openvidu-deployment: ha - azure - support sslip if no domain is defined --- .../pro/ha/azure/cf-openvidu-ha.bicep | 118 ++++++++++++------ .../pro/ha/azure/cf-openvidu-ha.json | 59 +++++---- .../pro/ha/azure/createUiDefinition.json | 16 +-- 3 files changed, 123 insertions(+), 70 deletions(-) diff --git a/openvidu-deployment/pro/ha/azure/cf-openvidu-ha.bicep b/openvidu-deployment/pro/ha/azure/cf-openvidu-ha.bicep index 697bf7fb..741ab13a 100644 --- a/openvidu-deployment/pro/ha/azure/cf-openvidu-ha.bicep +++ b/openvidu-deployment/pro/ha/azure/cf-openvidu-ha.bicep @@ -2,21 +2,19 @@ param stackName string @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. -[owncert] Valid for productions environments. If you have a FQDN, (DomainName parameter) -and an Elastic IP, you can use this option to use your own certificate. -[letsencrypt] Valid for production environments. If you have a FQDN, (DomainName parameter) -and an Elastic IP, you can use this option to generate a Let's Encrypt certificate. +[selfsigned] Not recommended for production use. Just for testing purposes or development environments. You don't need a FQDN to use this option. +[owncert] Valid for production environments. Use your own certificate. You need a FQDN to use this option. +[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). ''') @allowed([ 'selfsigned' 'owncert' 'letsencrypt' ]) -param certificateType string = 'selfsigned' +param certificateType string = 'letsencrypt' @description('Domain name for the OpenVidu Deployment.') -param domainName string +param domainName string = '' @description('If certificate type is \'owncert\', this parameter will be used to specify the public certificate') param ownPublicCertificate string = '' @@ -299,6 +297,10 @@ param additionalInstallFlags string = '' /*------------------------------------------- VARIABLES AND VALIDATIONS -------------------------------------------*/ +var isEmptyIp = publicIpAddressObject.newOrExistingOrNone == 'none' + +var isEmptyDomain = domainName == '' + var masterNodeVMSettings = { osDiskType: 'StandardSSD_LRS' osDiskSize: masterNodesDiskSize @@ -345,8 +347,6 @@ var mediaNodeVMSettings = { var turnTLSIsEnabled = turnDomainName != '' -var fqdn = domainName - var keyVaultName = '${stackName}-keyvault' var location = resourceGroup().location @@ -424,6 +424,7 @@ resource openviduSharedInfo 'Microsoft.KeyVault/vaults@2023-07-01' = { /*------------------------------------------- MASTER NODE -------------------------------------------*/ var stringInterpolationParamsMaster1 = { + publicIPId: publicIPId domainName: domainName turnDomainName: turnDomainName certificateType: certificateType @@ -431,7 +432,6 @@ var stringInterpolationParamsMaster1 = { ownPrivateCertificate: ownPrivateCertificate turnOwnPublicCertificate: turnOwnPublicCertificate turnOwnPrivateCertificate: turnOwnPrivateCertificate - fqdn: fqdn openviduLicense: openviduLicense rtcEngine: rtcEngine keyVaultName: keyVaultName @@ -440,6 +440,7 @@ var stringInterpolationParamsMaster1 = { } var stringInterpolationParamsMaster2 = { + publicIPId: publicIPId domainName: domainName turnDomainName: turnDomainName certificateType: certificateType @@ -447,7 +448,6 @@ var stringInterpolationParamsMaster2 = { ownPrivateCertificate: ownPrivateCertificate turnOwnPublicCertificate: turnOwnPublicCertificate turnOwnPrivateCertificate: turnOwnPrivateCertificate - fqdn: fqdn openviduLicense: openviduLicense rtcEngine: rtcEngine keyVaultName: keyVaultName @@ -456,6 +456,7 @@ var stringInterpolationParamsMaster2 = { } var stringInterpolationParamsMaster3 = { + publicIPId: publicIPId domainName: domainName turnDomainName: turnDomainName certificateType: certificateType @@ -463,7 +464,6 @@ var stringInterpolationParamsMaster3 = { ownPrivateCertificate: ownPrivateCertificate turnOwnPublicCertificate: turnOwnPublicCertificate turnOwnPrivateCertificate: turnOwnPrivateCertificate - fqdn: fqdn openviduLicense: openviduLicense rtcEngine: rtcEngine keyVaultName: keyVaultName @@ -472,6 +472,7 @@ var stringInterpolationParamsMaster3 = { } var stringInterpolationParamsMaster4 = { + publicIPId: publicIPId domainName: domainName turnDomainName: turnDomainName certificateType: certificateType @@ -479,7 +480,6 @@ var stringInterpolationParamsMaster4 = { ownPrivateCertificate: ownPrivateCertificate turnOwnPublicCertificate: turnOwnPublicCertificate turnOwnPrivateCertificate: turnOwnPrivateCertificate - fqdn: fqdn openviduLicense: openviduLicense rtcEngine: rtcEngine keyVaultName: keyVaultName @@ -501,12 +501,6 @@ apt-get update && apt-get install -y \ jq \ wget -# Configure Domain -if [[ "${domainName}" == '' ]]; then - DOMAIN=${fqdn} -else - DOMAIN=${domainName} -fi # Wait for the keyvault availability MAX_WAIT=100 @@ -545,9 +539,34 @@ PRIVATE_IP="$(/usr/local/bin/store_secret.sh save MASTER-NODE-${masterNodeNum}-P if [[ $MASTER_NODE_NUM -eq 1 ]] && [[ "$ALL_SECRETS_GENERATED" == "" || "$ALL_SECRETS_GENERATED" == "false" ]]; then + + # Configure Domain name + if [[ "${domainName}" == '' ]]; then + # Get public IP using the get_public_ip.sh script + PUBLIC_IP=$(/usr/local/bin/get_public_ip.sh 2>/dev/null) + if [[ $? -ne 0 || -z "${PUBLIC_IP}" ]]; then + echo "Could not determine public IP." + exit 1 + fi + + RANDOM_DOMAIN_STRING=$(tr -dc 'a-z' < /dev/urandom | head -c 8) + DOMAIN="openvidu-$RANDOM_DOMAIN_STRING-$(echo "$PUBLIC_IP" | tr '.' '-').sslip.io" + TURN_DOMAIN_NAME_SSLIP_IO="turn-$RANDOM_DOMAIN_STRING-$(echo "$PUBLIC_IP" | tr '.' '-').sslip.io" + echo $RANDOM_DOMAIN_STRING > /usr/share/openvidu/random-domain-string + echo $PUBLIC_IP > /usr/share/openvidu/public-ip + else + DOMAIN=${domainName} + fi DOMAIN="$(/usr/local/bin/store_secret.sh save DOMAIN-NAME "${domainName}")" + + # Configure TURN server domain name if [[ -n "${turnDomainName}" ]]; then LIVEKIT_TURN_DOMAIN_NAME="$(/usr/local/bin/store_secret.sh save LIVEKIT-TURN-DOMAIN-NAME "${turnDomainName}")" + elif [[ "${TURN_DOMAIN_NAME_SSLIP_IO}" != '' ]]; then + LIVEKIT_TURN_DOMAIN_NAME=$(/usr/local/bin/store_secret.sh save LIVEKIT-TURN-DOMAIN-NAME "${TURN_DOMAIN_NAME_SSLIP_IO}") + COMMON_ARGS+=( + "--turn-domain-name=$LIVEKIT_TURN_DOMAIN_NAME" + ) fi # Store usernames and generate random passwords @@ -947,6 +966,15 @@ else fi ''' +var get_public_ip = ''' +#!/bin/bash +az login --identity --allow-no-subscriptions > /dev/null + +az network public-ip show \ + --id ${publicIPId} \ + --query "ipAddress" -o tsv +''' + var check_app_readyScriptMaster = ''' #!/bin/bash set -e @@ -1028,6 +1056,12 @@ var update_config_from_secretScriptMaster = reduce( (curr, next) => { value: replace(curr.value, '\${${next.key}}', next.value) } ).value +var get_public_ip_script = reduce( + items(stringInterpolationParamsMaster1), + { value: get_public_ip}, + (curr, next) => { value: replace(curr.value, '\${${next.key}}', next.value) } +).value + var update_secret_from_configScriptMaster = reduce( items(stringInterpolationParamsMaster1), { value: update_secret_from_configScriptTemplateMaster }, @@ -1060,6 +1094,7 @@ var base64installMaster2 = base64(installScriptMaster2) var base64installMaster3 = base64(installScriptMaster3) var base64installMaster4 = base64(installScriptMaster4) var base64after_installMaster = base64(after_installScriptMaster) +var base64get_public_ip = base64(get_public_ip_script) var base64update_config_from_secretMaster = base64(update_config_from_secretScriptMaster) var base64update_secret_from_configMaster = base64(update_secret_from_configScriptMaster) var base64get_value_from_configMaster = base64(get_value_from_configScriptMaster) @@ -1071,6 +1106,7 @@ var base64config_blobStorage = base64(config_blobStorageScript) var userDataParamsMasterNode1 = { base64install: base64installMaster1 base64after_install: base64after_installMaster + base64get_public_ip: base64get_public_ip base64update_config_from_secret: base64update_config_from_secretMaster base64update_secret_from_config: base64update_secret_from_configMaster base64get_value_from_config: base64get_value_from_configMaster @@ -1085,6 +1121,7 @@ var userDataParamsMasterNode1 = { var userDataParamsMasterNode2 = { base64install: base64installMaster2 base64after_install: base64after_installMaster + base64get_public_ip: base64get_public_ip base64update_config_from_secret: base64update_config_from_secretMaster base64update_secret_from_config: base64update_secret_from_configMaster base64get_value_from_config: base64get_value_from_configMaster @@ -1099,6 +1136,7 @@ var userDataParamsMasterNode2 = { var userDataParamsMasterNode3 = { base64install: base64installMaster3 base64after_install: base64after_installMaster + base64get_public_ip: base64get_public_ip base64update_config_from_secret: base64update_config_from_secretMaster base64update_secret_from_config: base64update_secret_from_configMaster base64get_value_from_config: base64get_value_from_configMaster @@ -1113,6 +1151,7 @@ var userDataParamsMasterNode3 = { var userDataParamsMasterNode4 = { base64install: base64installMaster4 base64after_install: base64after_installMaster + base64get_public_ip: base64get_public_ip base64update_config_from_secret: base64update_config_from_secretMaster base64update_secret_from_config: base64update_secret_from_configMaster base64get_value_from_config: base64get_value_from_configMaster @@ -1138,6 +1177,10 @@ chmod +x /usr/local/bin/install.sh echo ${base64after_install} | base64 -d > /usr/local/bin/after_install.sh chmod +x /usr/local/bin/after_install.sh +# get_public_ip.sh +echo ${base64get_public_ip} | base64 -d > /usr/local/bin/get_public_ip.sh +chmod +x /usr/local/bin/get_public_ip.sh + # update_config_from_secret.sh echo ${base64update_config_from_secret} | base64 -d > /usr/local/bin/update_config_from_secret.sh chmod +x /usr/local/bin/update_config_from_secret.sh @@ -1877,35 +1920,36 @@ resource scaleInActivityLogRule 'Microsoft.Insights/activityLogAlerts@2020-10-01 /*------------------------------------------- NETWORK -------------------------------------------*/ -var isEmptyIp = publicIpAddressObject.newOrExistingOrNone == 'none' var lbName = '${stackName}-loadBalancer' var lbFrontEndName = 'LoadBalancerFrontEnd' var lbBackendPoolNameMasterNode = 'LoadBalancerBackEndMasterNode' -resource publicIPAddressLoadBalancer 'Microsoft.Network/publicIPAddresses@2024-05-01' = if (isEmptyIp == true) { - name: '${stackName}-publicIPAddressLoadBalancer' - location: location - sku: { - name: 'Standard' - } - properties: { - publicIPAddressVersion: 'IPv4' - publicIPAllocationMethod: 'Static' - } -} - var ipExists = publicIpAddressObject.newOrExistingOrNone == 'existing' -resource publicIP_LoadBalancer_ifExisting 'Microsoft.Network/publicIPAddresses@2023-11-01' existing = if (ipExists == true) { +resource publicIP_OV_ifExisting'Microsoft.Network/publicIPAddresses@2023-11-01' existing = if (ipExists == true) { name: publicIpAddressObject.name } var ipNew = publicIpAddressObject.newOrExistingOrNone == 'new' -resource publicIP_LoadBalancer_ifNew 'Microsoft.Network/publicIPAddresses@2023-11-01' existing = if (ipNew == true) { +resource publicIP_OV_ifNew 'Microsoft.Network/publicIPAddresses@2023-11-01' = if (ipNew == true) { name: publicIpAddressObject.name + location: location + sku: { + name: 'Standard' + tier: 'Regional' + } + properties: { + publicIPAddressVersion: 'IPv4' + publicIPAllocationMethod: 'Static' + dnsSettings: { + domainNameLabel: isEmptyDomain ? toLower('${stackName}') : null + } + } } +var publicIPId = ipNew ? publicIP_OV_ifNew.id : ipExists ? publicIP_OV_ifExisting.id : '' + resource LoadBalancer 'Microsoft.Network/loadBalancers@2024-05-01' = { name: lbName location: location @@ -1917,10 +1961,8 @@ resource LoadBalancer 'Microsoft.Network/loadBalancers@2024-05-01' = { { name: lbFrontEndName properties: { - publicIPAddress: { - id: isEmptyIp - ? publicIPAddressLoadBalancer.id - : ipNew ? publicIP_LoadBalancer_ifNew.id : publicIP_LoadBalancer_ifExisting.id + publicIPAddress: isEmptyIp ? null : { + id: ipNew ? publicIP_OV_ifNew.id : publicIP_OV_ifExisting.id } } } diff --git a/openvidu-deployment/pro/ha/azure/cf-openvidu-ha.json b/openvidu-deployment/pro/ha/azure/cf-openvidu-ha.json index e885cec7..4d48283d 100644 --- a/openvidu-deployment/pro/ha/azure/cf-openvidu-ha.json +++ b/openvidu-deployment/pro/ha/azure/cf-openvidu-ha.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.37.4.10188", - "templateHash": "7702876701274448546" + "templateHash": "14526614081270314025" } }, "parameters": { @@ -17,18 +17,19 @@ }, "certificateType": { "type": "string", - "defaultValue": "selfsigned", + "defaultValue": "letsencrypt", "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" + "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" } }, "domainName": { "type": "string", + "defaultValue": "", "metadata": { "description": "Domain name for the OpenVidu Deployment." } @@ -408,6 +409,8 @@ } }, "variables": { + "isEmptyIp": "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'none')]", + "isEmptyDomain": "[equals(parameters('domainName'), '')]", "masterNodeVMSettings": { "osDiskType": "StandardSSD_LRS", "osDiskSize": "[parameters('masterNodesDiskSize')]", @@ -451,12 +454,12 @@ } }, "turnTLSIsEnabled": "[not(equals(parameters('turnDomainName'), ''))]", - "fqdn": "[parameters('domainName')]", "keyVaultName": "[format('{0}-keyvault', parameters('stackName'))]", "location": "[resourceGroup().location]", "tenantId": "[subscription().tenantId]", "deploymentUser": "[deployer().objectId]", "stringInterpolationParamsMaster1": { + "publicIPId": "[variables('publicIPId')]", "domainName": "[parameters('domainName')]", "turnDomainName": "[parameters('turnDomainName')]", "certificateType": "[parameters('certificateType')]", @@ -464,7 +467,6 @@ "ownPrivateCertificate": "[parameters('ownPrivateCertificate')]", "turnOwnPublicCertificate": "[parameters('turnOwnPublicCertificate')]", "turnOwnPrivateCertificate": "[parameters('turnOwnPrivateCertificate')]", - "fqdn": "[variables('fqdn')]", "openviduLicense": "[parameters('openviduLicense')]", "rtcEngine": "[parameters('rtcEngine')]", "keyVaultName": "[variables('keyVaultName')]", @@ -472,6 +474,7 @@ "additionalInstallFlags": "[parameters('additionalInstallFlags')]" }, "stringInterpolationParamsMaster2": { + "publicIPId": "[variables('publicIPId')]", "domainName": "[parameters('domainName')]", "turnDomainName": "[parameters('turnDomainName')]", "certificateType": "[parameters('certificateType')]", @@ -479,7 +482,6 @@ "ownPrivateCertificate": "[parameters('ownPrivateCertificate')]", "turnOwnPublicCertificate": "[parameters('turnOwnPublicCertificate')]", "turnOwnPrivateCertificate": "[parameters('turnOwnPrivateCertificate')]", - "fqdn": "[variables('fqdn')]", "openviduLicense": "[parameters('openviduLicense')]", "rtcEngine": "[parameters('rtcEngine')]", "keyVaultName": "[variables('keyVaultName')]", @@ -487,6 +489,7 @@ "additionalInstallFlags": "[parameters('additionalInstallFlags')]" }, "stringInterpolationParamsMaster3": { + "publicIPId": "[variables('publicIPId')]", "domainName": "[parameters('domainName')]", "turnDomainName": "[parameters('turnDomainName')]", "certificateType": "[parameters('certificateType')]", @@ -494,7 +497,6 @@ "ownPrivateCertificate": "[parameters('ownPrivateCertificate')]", "turnOwnPublicCertificate": "[parameters('turnOwnPublicCertificate')]", "turnOwnPrivateCertificate": "[parameters('turnOwnPrivateCertificate')]", - "fqdn": "[variables('fqdn')]", "openviduLicense": "[parameters('openviduLicense')]", "rtcEngine": "[parameters('rtcEngine')]", "keyVaultName": "[variables('keyVaultName')]", @@ -502,6 +504,7 @@ "additionalInstallFlags": "[parameters('additionalInstallFlags')]" }, "stringInterpolationParamsMaster4": { + "publicIPId": "[variables('publicIPId')]", "domainName": "[parameters('domainName')]", "turnDomainName": "[parameters('turnDomainName')]", "certificateType": "[parameters('certificateType')]", @@ -509,19 +512,19 @@ "ownPrivateCertificate": "[parameters('ownPrivateCertificate')]", "turnOwnPublicCertificate": "[parameters('turnOwnPublicCertificate')]", "turnOwnPrivateCertificate": "[parameters('turnOwnPrivateCertificate')]", - "fqdn": "[variables('fqdn')]", "openviduLicense": "[parameters('openviduLicense')]", "rtcEngine": "[parameters('rtcEngine')]", "keyVaultName": "[variables('keyVaultName')]", "masterNodeNum": "4", "additionalInstallFlags": "[parameters('additionalInstallFlags')]" }, - "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\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 MEET_INITIAL_ADMIN_USER=\"$(/usr/local/bin/store_secret.sh save MEET-INITIAL-ADMIN-USER \"meetadmin\")\"\n MEET_INITIAL_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate MEET-INITIAL-ADMIN-PASSWORD)\"\n MEET_INITIAL_API_KEY=\"$(/usr/local/bin/store_secret.sh generate MEET-INITIAL-API-KEY)\"\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,openviduMeet,v2compatibility\")\"\n ALL_SECRETS_GENERATED=\"$(/usr/local/bin/store_secret.sh save ALL-SECRETS-GENERATED \"true\")\"\nfi\n\nwhile true; do\n MASTER_NODE_1_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-1-PRIVATE-IP --query value -o tsv) || true\n MASTER_NODE_2_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-2-PRIVATE-IP --query value -o tsv) || true\n MASTER_NODE_3_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-3-PRIVATE-IP --query value -o tsv) || true\n MASTER_NODE_4_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-4-PRIVATE-IP --query value -o tsv) || true\n # Check if all master nodes have stored their private IPs\n if [[ \"$MASTER_NODE_1_PRIVATE_IP\" != \"\" ]] &&\n [[ \"$MASTER_NODE_2_PRIVATE_IP\" != \"\" ]] &&\n [[ \"$MASTER_NODE_3_PRIVATE_IP\" != \"\" ]] &&\n [[ \"$MASTER_NODE_4_PRIVATE_IP\" != \"\" ]]; then\n break\n fi\n sleep 5\ndone\n\n\n# Fetch the values in the keyvault\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\"\n\nDOMAIN=$(az keyvault secret show --vault-name ${keyVaultName} --name DOMAIN-NAME --query value -o tsv)\nif [[ -n \"${turnDomainName}\" ]]; then\n LIVEKIT_TURN_DOMAIN_NAME=$(az keyvault secret show --vault-name ${keyVaultName} --name LIVEKIT-TURN-DOMAIN-NAME --query value -o tsv)\nfi\nOPENVIDU_RTC_ENGINE=$(az keyvault secret show --vault-name ${keyVaultName} --name OPENVIDU-RTC-ENGINE --query value -o tsv)\nOPENVIDU_PRO_LICENSE=$(az keyvault secret show --vault-name ${keyVaultName} --name OPENVIDU-PRO-LICENSE --query value -o tsv)\nREDIS_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name REDIS-PASSWORD --query value -o tsv)\nMONGO_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name MONGO-ADMIN-USERNAME --query value -o tsv)\nMONGO_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name MONGO-ADMIN-PASSWORD --query value -o tsv)\nMONGO_REPLICA_SET_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MONGO-REPLICA-SET-KEY --query value -o tsv)\nDASHBOARD_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name DASHBOARD-ADMIN-USERNAME --query value -o tsv)\nDASHBOARD_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name DASHBOARD-ADMIN-PASSWORD --query value -o tsv)\nMINIO_ACCESS_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MINIO-ACCESS-KEY --query value -o tsv)\nMINIO_SECRET_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MINIO-SECRET-KEY --query value -o tsv)\nGRAFANA_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name GRAFANA-ADMIN-USERNAME --query value -o tsv)\nGRAFANA_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name GRAFANA-ADMIN-PASSWORD --query value -o tsv)\nLIVEKIT_API_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name LIVEKIT-API-KEY --query value -o tsv)\nLIVEKIT_API_SECRET=$(az keyvault secret show --vault-name ${keyVaultName} --name LIVEKIT-API-SECRET --query value -o tsv)\nMEET_INITIAL_ADMIN_USER=$(az keyvault secret show --vault-name ${keyVaultName} --name MEET-INITIAL-ADMIN-USER --query value -o tsv)\nMEET_INITIAL_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name MEET-INITIAL-ADMIN-PASSWORD --query value -o tsv)\nMEET_INITIAL_API_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MEET-INITIAL-API-KEY --query value -o tsv)\nENABLED_MODULES=$(az keyvault secret show --vault-name ${keyVaultName} --name ENABLED-MODULES --query value -o tsv)\n\n\n# Base command\nINSTALL_COMMAND=\"sh <(curl -fsSL http://get.openvidu.io/pro/ha/$OPENVIDU_VERSION/install_ov_master_node.sh)\"\n\n# Common arguments\nCOMMON_ARGS=(\n \"--no-tty\"\n \"--install\"\n \"--environment=azure\"\n \"--deployment-type='ha'\"\n \"--node-role='master-node'\"\n \"--external-load-balancer\"\n \"--internal-tls-termination\"\n \"--master-node-private-ip-list='$MASTER_NODE_PRIVATE_IP_LIST'\"\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}\" != \"\" ]]; then\n IFS=',' read -ra EXTRA_FLAGS <<< \"${additionalInstallFlags}\"\n for extra_flag in \"${EXTRA_FLAGS[@]}\"; do\n # Trim whitespace around each flag\n extra_flag=\"$(echo -e \"${extra_flag}\" | sed -e 's/^[ \\t]*//' -e 's/[ \\t]*$//')\"\n if [[ \"$extra_flag\" != \"\" ]]; then\n COMMON_ARGS+=(\"$extra_flag\")\n fi\n done\nfi\n\nif [[ $LIVEKIT_TURN_DOMAIN_NAME != \"\" ]]; then\n COMMON_ARGS+=(\"--turn-domain-name=$LIVEKIT_TURN_DOMAIN_NAME\")\nfi\n\n# Certificate arguments\nif [[ \"${certificateType}\" == \"selfsigned\" ]]; then\n CERT_ARGS=(\n \"--certificate-type=selfsigned\"\n )\nelif [[ \"${certificateType}\" == \"letsencrypt\" ]]; then\n CERT_ARGS=(\n \"--certificate-type=letsencrypt\"\n )\nelse\n # Download owncert files\n mkdir -p /tmp/owncert\n wget -O /tmp/owncert/fullchain.pem ${ownPublicCertificate}\n wget -O /tmp/owncert/privkey.pem ${ownPrivateCertificate}\n\n # Convert to base64\n OWN_CERT_CRT=$(base64 -w 0 /tmp/owncert/fullchain.pem)\n OWN_CERT_KEY=$(base64 -w 0 /tmp/owncert/privkey.pem)\n\n CERT_ARGS=(\n \"--certificate-type=owncert\"\n \"--owncert-public-key=$OWN_CERT_CRT\"\n \"--owncert-private-key=$OWN_CERT_KEY\"\n )\n\n # Turn with TLS and own certificate\n if [[ \"${turnDomainName}\" != '' ]]; then\n # Download owncert files\n mkdir -p /tmp/owncert-turn\n wget -O /tmp/owncert-turn/fullchain.pem ${turnOwnPublicCertificate}\n wget -O /tmp/owncert-turn/privkey.pem ${turnOwnPrivateCertificate}\n\n # Convert to base64\n OWN_CERT_CRT_TURN=$(base64 -w 0 /tmp/owncert-turn/fullchain.pem)\n OWN_CERT_KEY_TURN=$(base64 -w 0 /tmp/owncert-turn/privkey.pem)\n\n CERT_ARGS+=(\n \"--turn-owncert-private-key=$OWN_CERT_KEY_TURN\"\n \"--turn-owncert-public-key=$OWN_CERT_CRT_TURN\"\n )\n fi\nfi\n\n# Construct the final command\nFINAL_COMMAND=\"$INSTALL_COMMAND $(printf \"%s \" \"${COMMON_ARGS[@]}\") $(printf \"%s \" \"${CERT_ARGS[@]}\")\"\n\n# Install OpenVidu\nexec bash -c \"$FINAL_COMMAND\" \n", + "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\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\n # Configure Domain name\n if [[ \"${domainName}\" == '' ]]; then\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\n else\n DOMAIN=${domainName}\n fi\n DOMAIN=\"$(/usr/local/bin/store_secret.sh save DOMAIN-NAME \"${domainName}\")\"\n\n # Configure TURN server domain name\n if [[ -n \"${turnDomainName}\" ]]; then\n LIVEKIT_TURN_DOMAIN_NAME=\"$(/usr/local/bin/store_secret.sh save LIVEKIT-TURN-DOMAIN-NAME \"${turnDomainName}\")\"\n elif [[ \"${TURN_DOMAIN_NAME_SSLIP_IO}\" != '' ]]; then\n LIVEKIT_TURN_DOMAIN_NAME=$(/usr/local/bin/store_secret.sh save LIVEKIT-TURN-DOMAIN-NAME \"${TURN_DOMAIN_NAME_SSLIP_IO}\")\n COMMON_ARGS+=(\n \"--turn-domain-name=$LIVEKIT_TURN_DOMAIN_NAME\"\n )\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 MEET_INITIAL_ADMIN_USER=\"$(/usr/local/bin/store_secret.sh save MEET-INITIAL-ADMIN-USER \"meetadmin\")\"\n MEET_INITIAL_ADMIN_PASSWORD=\"$(/usr/local/bin/store_secret.sh generate MEET-INITIAL-ADMIN-PASSWORD)\"\n MEET_INITIAL_API_KEY=\"$(/usr/local/bin/store_secret.sh generate MEET-INITIAL-API-KEY)\"\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,openviduMeet,v2compatibility\")\"\n ALL_SECRETS_GENERATED=\"$(/usr/local/bin/store_secret.sh save ALL-SECRETS-GENERATED \"true\")\"\nfi\n\nwhile true; do\n MASTER_NODE_1_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-1-PRIVATE-IP --query value -o tsv) || true\n MASTER_NODE_2_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-2-PRIVATE-IP --query value -o tsv) || true\n MASTER_NODE_3_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-3-PRIVATE-IP --query value -o tsv) || true\n MASTER_NODE_4_PRIVATE_IP=$(az keyvault secret show --vault-name ${keyVaultName} --name MASTER-NODE-4-PRIVATE-IP --query value -o tsv) || true\n # Check if all master nodes have stored their private IPs\n if [[ \"$MASTER_NODE_1_PRIVATE_IP\" != \"\" ]] &&\n [[ \"$MASTER_NODE_2_PRIVATE_IP\" != \"\" ]] &&\n [[ \"$MASTER_NODE_3_PRIVATE_IP\" != \"\" ]] &&\n [[ \"$MASTER_NODE_4_PRIVATE_IP\" != \"\" ]]; then\n break\n fi\n sleep 5\ndone\n\n\n# Fetch the values in the keyvault\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\"\n\nDOMAIN=$(az keyvault secret show --vault-name ${keyVaultName} --name DOMAIN-NAME --query value -o tsv)\nif [[ -n \"${turnDomainName}\" ]]; then\n LIVEKIT_TURN_DOMAIN_NAME=$(az keyvault secret show --vault-name ${keyVaultName} --name LIVEKIT-TURN-DOMAIN-NAME --query value -o tsv)\nfi\nOPENVIDU_RTC_ENGINE=$(az keyvault secret show --vault-name ${keyVaultName} --name OPENVIDU-RTC-ENGINE --query value -o tsv)\nOPENVIDU_PRO_LICENSE=$(az keyvault secret show --vault-name ${keyVaultName} --name OPENVIDU-PRO-LICENSE --query value -o tsv)\nREDIS_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name REDIS-PASSWORD --query value -o tsv)\nMONGO_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name MONGO-ADMIN-USERNAME --query value -o tsv)\nMONGO_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name MONGO-ADMIN-PASSWORD --query value -o tsv)\nMONGO_REPLICA_SET_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MONGO-REPLICA-SET-KEY --query value -o tsv)\nDASHBOARD_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name DASHBOARD-ADMIN-USERNAME --query value -o tsv)\nDASHBOARD_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name DASHBOARD-ADMIN-PASSWORD --query value -o tsv)\nMINIO_ACCESS_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MINIO-ACCESS-KEY --query value -o tsv)\nMINIO_SECRET_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MINIO-SECRET-KEY --query value -o tsv)\nGRAFANA_ADMIN_USERNAME=$(az keyvault secret show --vault-name ${keyVaultName} --name GRAFANA-ADMIN-USERNAME --query value -o tsv)\nGRAFANA_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name GRAFANA-ADMIN-PASSWORD --query value -o tsv)\nLIVEKIT_API_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name LIVEKIT-API-KEY --query value -o tsv)\nLIVEKIT_API_SECRET=$(az keyvault secret show --vault-name ${keyVaultName} --name LIVEKIT-API-SECRET --query value -o tsv)\nMEET_INITIAL_ADMIN_USER=$(az keyvault secret show --vault-name ${keyVaultName} --name MEET-INITIAL-ADMIN-USER --query value -o tsv)\nMEET_INITIAL_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name MEET-INITIAL-ADMIN-PASSWORD --query value -o tsv)\nMEET_INITIAL_API_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MEET-INITIAL-API-KEY --query value -o tsv)\nENABLED_MODULES=$(az keyvault secret show --vault-name ${keyVaultName} --name ENABLED-MODULES --query value -o tsv)\n\n\n# Base command\nINSTALL_COMMAND=\"sh <(curl -fsSL http://get.openvidu.io/pro/ha/$OPENVIDU_VERSION/install_ov_master_node.sh)\"\n\n# Common arguments\nCOMMON_ARGS=(\n \"--no-tty\"\n \"--install\"\n \"--environment=azure\"\n \"--deployment-type='ha'\"\n \"--node-role='master-node'\"\n \"--external-load-balancer\"\n \"--internal-tls-termination\"\n \"--master-node-private-ip-list='$MASTER_NODE_PRIVATE_IP_LIST'\"\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}\" != \"\" ]]; then\n IFS=',' read -ra EXTRA_FLAGS <<< \"${additionalInstallFlags}\"\n for extra_flag in \"${EXTRA_FLAGS[@]}\"; do\n # Trim whitespace around each flag\n extra_flag=\"$(echo -e \"${extra_flag}\" | sed -e 's/^[ \\t]*//' -e 's/[ \\t]*$//')\"\n if [[ \"$extra_flag\" != \"\" ]]; then\n COMMON_ARGS+=(\"$extra_flag\")\n fi\n done\nfi\n\nif [[ $LIVEKIT_TURN_DOMAIN_NAME != \"\" ]]; then\n COMMON_ARGS+=(\"--turn-domain-name=$LIVEKIT_TURN_DOMAIN_NAME\")\nfi\n\n# Certificate arguments\nif [[ \"${certificateType}\" == \"selfsigned\" ]]; then\n CERT_ARGS=(\n \"--certificate-type=selfsigned\"\n )\nelif [[ \"${certificateType}\" == \"letsencrypt\" ]]; then\n CERT_ARGS=(\n \"--certificate-type=letsencrypt\"\n )\nelse\n # Download owncert files\n mkdir -p /tmp/owncert\n wget -O /tmp/owncert/fullchain.pem ${ownPublicCertificate}\n wget -O /tmp/owncert/privkey.pem ${ownPrivateCertificate}\n\n # Convert to base64\n OWN_CERT_CRT=$(base64 -w 0 /tmp/owncert/fullchain.pem)\n OWN_CERT_KEY=$(base64 -w 0 /tmp/owncert/privkey.pem)\n\n CERT_ARGS=(\n \"--certificate-type=owncert\"\n \"--owncert-public-key=$OWN_CERT_CRT\"\n \"--owncert-private-key=$OWN_CERT_KEY\"\n )\n\n # Turn with TLS and own certificate\n if [[ \"${turnDomainName}\" != '' ]]; then\n # Download owncert files\n mkdir -p /tmp/owncert-turn\n wget -O /tmp/owncert-turn/fullchain.pem ${turnOwnPublicCertificate}\n wget -O /tmp/owncert-turn/privkey.pem ${turnOwnPrivateCertificate}\n\n # Convert to base64\n OWN_CERT_CRT_TURN=$(base64 -w 0 /tmp/owncert-turn/fullchain.pem)\n OWN_CERT_KEY_TURN=$(base64 -w 0 /tmp/owncert-turn/privkey.pem)\n\n CERT_ARGS+=(\n \"--turn-owncert-private-key=$OWN_CERT_KEY_TURN\"\n \"--turn-owncert-public-key=$OWN_CERT_CRT_TURN\"\n )\n fi\nfi\n\n# Construct the final command\nFINAL_COMMAND=\"$INSTALL_COMMAND $(printf \"%s \" \"${COMMON_ARGS[@]}\") $(printf \"%s \" \"${CERT_ARGS[@]}\")\"\n\n# Install OpenVidu\nexec bash -c \"$FINAL_COMMAND\" \n", "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\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 MEET_INITIAL_ADMIN_USER=$(az keyvault secret show --vault-name ${keyVaultName} --name MEET-INITIAL-ADMIN-USER --query value -o tsv)\nexport MEET_INITIAL_ADMIN_PASSWORD=$(az keyvault secret show --vault-name ${keyVaultName} --name MEET-INITIAL-ADMIN-PASSWORD --query value -o tsv)\nexport MEET_INITIAL_API_KEY=$(az keyvault secret show --vault-name ${keyVaultName} --name MEET-INITIAL-API-KEY --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\"\nsed -i \"s/OPENVIDU_PRO_LICENSE=.*/OPENVIDU_PRO_LICENSE=$OPENVIDU_PRO_LICENSE/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/MONGO_ADMIN_USERNAME=.*/MONGO_ADMIN_USERNAME=$MONGO_ADMIN_USERNAME/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/MONGO_ADMIN_PASSWORD=.*/MONGO_ADMIN_PASSWORD=$MONGO_ADMIN_PASSWORD/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/MONGO_REPLICA_SET_KEY=.*/MONGO_REPLICA_SET_KEY=$MONGO_REPLICA_SET_KEY/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/DASHBOARD_ADMIN_USERNAME=.*/DASHBOARD_ADMIN_USERNAME=$DASHBOARD_ADMIN_USERNAME/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/DASHBOARD_ADMIN_PASSWORD=.*/DASHBOARD_ADMIN_PASSWORD=$DASHBOARD_ADMIN_PASSWORD/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/MINIO_ACCESS_KEY=.*/MINIO_ACCESS_KEY=$MINIO_ACCESS_KEY/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/MINIO_SECRET_KEY=.*/MINIO_SECRET_KEY=$MINIO_SECRET_KEY/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/GRAFANA_ADMIN_USERNAME=.*/GRAFANA_ADMIN_USERNAME=$GRAFANA_ADMIN_USERNAME/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/GRAFANA_ADMIN_PASSWORD=.*/GRAFANA_ADMIN_PASSWORD=$GRAFANA_ADMIN_PASSWORD/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/LIVEKIT_API_KEY=.*/LIVEKIT_API_KEY=$LIVEKIT_API_KEY/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/LIVEKIT_API_SECRET=.*/LIVEKIT_API_SECRET=$LIVEKIT_API_SECRET/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\nsed -i \"s/MEET_INITIAL_ADMIN_USER=.*/MEET_INITIAL_ADMIN_USER=$MEET_INITIAL_ADMIN_USER/\" \"${CLUSTER_CONFIG_DIR}/master_node/meet.env\"\nsed -i \"s/MEET_INITIAL_ADMIN_PASSWORD=.*/MEET_INITIAL_ADMIN_PASSWORD=$MEET_INITIAL_ADMIN_PASSWORD/\" \"${CLUSTER_CONFIG_DIR}/master_node/meet.env\"\nsed -i \"s/MEET_INITIAL_API_KEY=.*/MEET_INITIAL_API_KEY=$MEET_INITIAL_API_KEY/\" \"${CLUSTER_CONFIG_DIR}/master_node/meet.env\"\nsed -i \"s/ENABLED_MODULES=.*/ENABLED_MODULES=$ENABLED_MODULES/\" \"${CLUSTER_CONFIG_DIR}/openvidu.env\"\n\n# Update URLs in secret\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", "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\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\")\"\nMEET_INITIAL_ADMIN_USER=\"$(/usr/local/bin/get_value_from_config.sh MEET_INITIAL_ADMIN_USER \"${CLUSTER_CONFIG_DIR}/master_node/meet.env\")\"\nMEET_INITIAL_ADMIN_PASSWORD=\"$(/usr/local/bin/get_value_from_config.sh MEET_INITIAL_ADMIN_PASSWORD \"${CLUSTER_CONFIG_DIR}/master_node/meet.env\")\"\nMEET_INITIAL_API_KEY=\"$(/usr/local/bin/get_value_from_config.sh MEET_INITIAL_API_KEY \"${CLUSTER_CONFIG_DIR}/master_node/meet.env\")\"\nENABLED_MODULES=\"$(/usr/local/bin/get_value_from_config.sh ENABLED_MODULES \"${CLUSTER_CONFIG_DIR}/openvidu.env\")\"\n\n# Update shared secret\naz keyvault secret set --vault-name ${keyVaultName} --name REDIS-PASSWORD --value $REDIS_PASSWORD\naz keyvault secret set --vault-name ${keyVaultName} --name DOMAIN-NAME --value $DOMAIN_NAME\naz keyvault secret set --vault-name ${keyVaultName} --name LIVEKIT-TURN-DOMAIN-NAME --value $LIVEKIT_TURN_DOMAIN_NAME\naz keyvault secret set --vault-name ${keyVaultName} --name OPENVIDU-RTC-ENGINE --value $OPENVIDU_RTC_ENGINE\naz keyvault secret set --vault-name ${keyVaultName} --name OPENVIDU-PRO-LICENSE --value $OPENVIDU_PRO_LICENSE\naz keyvault secret set --vault-name ${keyVaultName} --name MONGO-ADMIN-USERNAME --value $MONGO_ADMIN_USERNAME\naz keyvault secret set --vault-name ${keyVaultName} --name MONGO-ADMIN-PASSWORD --value $MONGO_ADMIN_PASSWORD\naz keyvault secret set --vault-name ${keyVaultName} --name MONGO-REPLICA-SET-KEY --value $MONGO_REPLICA_SET_KEY\naz keyvault secret set --vault-name ${keyVaultName} --name MINIO-ACCESS-KEY --value $MINIO_ACCESS_KEY\naz keyvault secret set --vault-name ${keyVaultName} --name MINIO-SECRET-KEY --value $MINIO_SECRET_KEY\naz keyvault secret set --vault-name ${keyVaultName} --name DASHBOARD-ADMIN-USERNAME --value $DASHBOARD_ADMIN_USERNAME\naz keyvault secret set --vault-name ${keyVaultName} --name DASHBOARD-ADMIN-PASSWORD --value $DASHBOARD_ADMIN_PASSWORD\naz keyvault secret set --vault-name ${keyVaultName} --name GRAFANA-ADMIN-USERNAME --value $GRAFANA_ADMIN_USERNAME\naz keyvault secret set --vault-name ${keyVaultName} --name GRAFANA-ADMIN-PASSWORD --value $GRAFANA_ADMIN_PASSWORD\naz keyvault secret set --vault-name ${keyVaultName} --name LIVEKIT-API-KEY --value $LIVEKIT_API_KEY\naz keyvault secret set --vault-name ${keyVaultName} --name LIVEKIT-API-SECRET --value $LIVEKIT_API_SECRET\naz keyvault secret set --vault-name ${keyVaultName} --name MEET-INITIAL-ADMIN-USER --value $MEET_INITIAL_ADMIN_USER\naz keyvault secret set --vault-name ${keyVaultName} --name MEET-INITIAL-ADMIN-PASSWORD --value $MEET_INITIAL_ADMIN_PASSWORD\naz keyvault secret set --vault-name ${keyVaultName} --name MEET-INITIAL-API-KEY --value $MEET_INITIAL_API_KEY\naz keyvault secret set --vault-name ${keyVaultName} --name ENABLED-MODULES --value $ENABLED_MODULES\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 \"\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", + "get_public_ip": "#!/bin/bash\naz login --identity --allow-no-subscriptions > /dev/null\n\naz network public-ip show \\\n --id ${publicIPId} \\\n --query \"ipAddress\" -o tsv\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", "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", @@ -531,6 +534,7 @@ "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]", + "get_public_ip_script": "[reduce(items(variables('stringInterpolationParamsMaster1')), createObject('value', variables('get_public_ip')), 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'))]", @@ -538,13 +542,14 @@ "base64installMaster3": "[base64(variables('installScriptMaster3'))]", "base64installMaster4": "[base64(variables('installScriptMaster4'))]", "base64after_installMaster": "[base64(variables('after_installScriptMaster'))]", + "base64get_public_ip": "[base64(variables('get_public_ip_script'))]", "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'))]", - "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", + "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# 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\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", "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]", @@ -560,12 +565,12 @@ "base64stopMediaNode": "[base64(variables('stop_media_nodesScriptMedia'))]", "base64delete_mediaNode_ScriptMedia": "[base64(variables('delete_mediaNode_ScriptMedia'))]", "isEmptyAutomationAccountName": "[equals(parameters('automationAccountName'), '')]", - "isEmptyIp": "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'none')]", "lbName": "[format('{0}-loadBalancer', parameters('stackName'))]", "lbFrontEndName": "LoadBalancerFrontEnd", "lbBackendPoolNameMasterNode": "LoadBalancerBackEndMasterNode", "ipExists": "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'existing')]", "ipNew": "[equals(parameters('publicIpAddressObject').newOrExistingOrNone, 'new')]", + "publicIPId": "[if(variables('ipNew'), resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name), if(variables('ipExists'), resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name), ''))]", "networkSettings": { "vNetAddressPrefix": "10.0.0.0/16", "subnetAddressPrefixMaster1": "10.0.1.0/24", @@ -710,10 +715,11 @@ "adminUsername": "[parameters('adminUsername')]", "linuxConfiguration": "[variables('masterNodeVMSettings').linuxConfiguration]" }, - "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)]" + "userData": "[base64(reduce(items(createObject('base64install', variables('base64installMaster1'), 'base64after_install', variables('base64after_installMaster'), 'base64get_public_ip', variables('base64get_public_ip'), '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)]" }, "dependsOn": [ "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface1', parameters('stackName')))]", + "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name)]", "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]" ] }, @@ -751,11 +757,12 @@ "adminUsername": "[parameters('adminUsername')]", "linuxConfiguration": "[variables('masterNodeVMSettings').linuxConfiguration]" }, - "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)]" + "userData": "[base64(reduce(items(createObject('base64install', variables('base64installMaster2'), 'base64after_install', variables('base64after_installMaster'), 'base64get_public_ip', variables('base64get_public_ip'), '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)]" }, "dependsOn": [ "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface2', parameters('stackName')))]", "[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode1', parameters('stackName')))]", + "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name)]", "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]" ] }, @@ -793,11 +800,12 @@ "adminUsername": "[parameters('adminUsername')]", "linuxConfiguration": "[variables('masterNodeVMSettings').linuxConfiguration]" }, - "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)]" + "userData": "[base64(reduce(items(createObject('base64install', variables('base64installMaster3'), 'base64after_install', variables('base64after_installMaster'), 'base64get_public_ip', variables('base64get_public_ip'), '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)]" }, "dependsOn": [ "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface3', parameters('stackName')))]", "[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode2', parameters('stackName')))]", + "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name)]", "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]" ] }, @@ -835,11 +843,12 @@ "adminUsername": "[parameters('adminUsername')]", "linuxConfiguration": "[variables('masterNodeVMSettings').linuxConfiguration]" }, - "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)]" + "userData": "[base64(reduce(items(createObject('base64install', variables('base64installMaster4'), 'base64after_install', variables('base64after_installMaster'), 'base64get_public_ip', variables('base64get_public_ip'), '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)]" }, "dependsOn": [ "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-masterNodeNetInterface4', parameters('stackName')))]", "[resourceId('Microsoft.Compute/virtualMachines', format('{0}-VM-MasterNode3', parameters('stackName')))]", + "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name)]", "[resourceId('Microsoft.Storage/storageAccounts', uniqueString(resourceGroup().id))]" ] }, @@ -1130,17 +1139,21 @@ ] }, { - "condition": "[equals(variables('isEmptyIp'), true())]", + "condition": "[equals(variables('ipNew'), true())]", "type": "Microsoft.Network/publicIPAddresses", - "apiVersion": "2024-05-01", - "name": "[format('{0}-publicIPAddressLoadBalancer', parameters('stackName'))]", + "apiVersion": "2023-11-01", + "name": "[parameters('publicIpAddressObject').name]", "location": "[variables('location')]", "sku": { - "name": "Standard" + "name": "Standard", + "tier": "Regional" }, "properties": { "publicIPAddressVersion": "IPv4", - "publicIPAllocationMethod": "Static" + "publicIPAllocationMethod": "Static", + "dnsSettings": { + "domainNameLabel": "[if(variables('isEmptyDomain'), toLower(format('{0}', parameters('stackName'))), null())]" + } } }, { @@ -1156,9 +1169,7 @@ { "name": "[variables('lbFrontEndName')]", "properties": { - "publicIPAddress": { - "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)))]" - } + "publicIPAddress": "[if(variables('isEmptyIp'), null(), createObject('id', if(variables('ipNew'), resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name), resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name))))]" } } ], @@ -1257,7 +1268,7 @@ "outboundRules": [] }, "dependsOn": [ - "[resourceId('Microsoft.Network/publicIPAddresses', format('{0}-publicIPAddressLoadBalancer', parameters('stackName')))]" + "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpAddressObject').name)]" ] }, { diff --git a/openvidu-deployment/pro/ha/azure/createUiDefinition.json b/openvidu-deployment/pro/ha/azure/createUiDefinition.json index 3ab8f96b..03b917a5 100644 --- a/openvidu-deployment/pro/ha/azure/createUiDefinition.json +++ b/openvidu-deployment/pro/ha/azure/createUiDefinition.json @@ -47,8 +47,8 @@ "type": "Microsoft.Common.DropDown", "label": "Certificate Type", "subLabel": "", - "defaultValue": "selfsigned", - "toolTip": "[[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", + "defaultValue": "letsencrypt", + "toolTip": "[[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", "constraints": { "required": false, "allowedValues": [ @@ -77,13 +77,13 @@ "publicIpAddress": "Public IP address" }, "toolTip": { - "publicIpAddress": "Name of the PublicIPAddress resource in Azure when using certificateType 'owncert' or 'letsencrypt'" + "publicIpAddress": "Previously created Public IP address for the OpenVidu Deployment. Blank will generate a public IP" }, "defaultValue": { "publicIpAddressName": "defaultName" }, "options": { - "hideNone": false, + "hideNone": true, "hideDomainNameLabel": true, "hideExisting": false }, @@ -97,13 +97,13 @@ "defaultValue": "", "toolTip": "", "constraints": { - "required": true, + "required": false, "regex": "^$|^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$", - "validationMessage": "", + "validationMessage": "Please enter a valid domain name or leave it blank to generate", "validations": [ { - "isValid": "[if(or(equals(steps('parameters SSL').certificateType, 'letsencrypt'), equals(steps('parameters SSL').certificateType, 'owncert')), not(empty(steps('parameters SSL').domainName)), true)]", - "message": "You need to fill this parameter because you've selected another certificate type that is not selfsigned." + "isValid": "[if(equals(steps('parameters SSL').certificateType, 'owncert'), not(empty(steps('parameters SSL').domainName)), true)]", + "message": "You need to fill this parameter because you've selected owncert certificate type." } ] },