mirror of https://github.com/OpenVidu/openvidu.git
582 lines
19 KiB
Plaintext
582 lines
19 KiB
Plaintext
AWSTemplateFormatVersion: 2010-09-09
|
|
Description: OpenVidu Platform
|
|
|
|
Parameters:
|
|
|
|
# Domain and SSL certificate configuration
|
|
|
|
WhichCert:
|
|
Description: >
|
|
[selfsigned] Self signed certificate. Not recommended for production use.
|
|
[owncert] Valid certificate purchased in a Internet services company.
|
|
[letsencrypt] Generate a new certificate using Let's Encrypt.
|
|
Type: String
|
|
AllowedValues:
|
|
- selfsigned
|
|
- owncert
|
|
- letsencrypt
|
|
Default: selfsigned
|
|
|
|
PublicElasticIP:
|
|
Description: "Previously created AWS Elastic IP to associate it to the OpenVidu EC2 instance. If certificate type is 'selfsigned' this value is optional. If certificate type is 'owncert' or 'letsencrypt' this value is mandatory. Example 13.33.145.23."
|
|
Type: String
|
|
AllowedPattern: ^$|^([01]?\d{1,2}|2[0-4]\d|25[0-5])\.([01]?\d{1,2}|2[0-4]\d|25[0-5])\.([01]?\d{1,2}|2[0-4]\d|25[0-5])\.([01]?\d{1,2}|2[0-4]\d|25[0-5])$
|
|
ConstraintDescription: The public Elastic IP does not have a valid IPv4 format
|
|
|
|
MyDomainName:
|
|
Description: "Valid domain name pointing to previous IP. If certificate type is 'selfsigned' this value is optional. If certificate type is 'owncert' or 'letsencrypt' this value is mandatory. Example: openvidu.company.com"
|
|
Type: String
|
|
AllowedPattern: ^$|^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]$
|
|
ConstraintDescription: The domain name does not have a valid domain name format
|
|
|
|
OwnCertCRT:
|
|
Description: "If certificate type is 'owncert' this is the URL where CRT file will be downloaded"
|
|
Type: String
|
|
|
|
OwnCertKEY:
|
|
Description: "If certificate type is 'owncert' this is the URL where KEY file will be downloaded"
|
|
Type: String
|
|
|
|
LetsEncryptEmail:
|
|
Description: "If certificate type is 'letsencrypt', this email will be used for Let's Encrypt notifications"
|
|
Type: String
|
|
|
|
# OpenVidu configuration
|
|
|
|
OpenViduSecret:
|
|
Description: "Secret to connect to this OpenVidu Platform. Cannot be empty and must contain only alphanumeric characters [a-zA-Z0-9], hypens ('-') and underscores ('_')"
|
|
Type: String
|
|
AllowedPattern: ^[a-zA-Z0-9_-]+$
|
|
NoEcho: true
|
|
ConstraintDescription: "Cannot be empty and must contain only alphanumeric characters [a-zA-Z0-9], hypens ('-') and underscores ('_')"
|
|
|
|
# EC2 Instance configuration
|
|
|
|
InstanceType:
|
|
Description: "Specifies the EC2 instance type for your OpenVidu instance"
|
|
Type: String
|
|
Default: c5.xlarge
|
|
AllowedValues:
|
|
- t2.large
|
|
- t2.xlarge
|
|
- t2.2xlarge
|
|
- t3.large
|
|
- t3.xlarge
|
|
- t3.2xlarge
|
|
- m4.large
|
|
- m4.xlarge
|
|
- m4.2xlarge
|
|
- m4.4xlarge
|
|
- m4.10xlarge
|
|
- m4.16xlarge
|
|
- m5.large
|
|
- m5.xlarge
|
|
- m5.2xlarge
|
|
- m5.4xlarge
|
|
- m5.8xlarge
|
|
- m5.12xlarge
|
|
- m5.16xlarge
|
|
- m5.24xlarge
|
|
- c4.large
|
|
- c4.xlarge
|
|
- c4.2xlarge
|
|
- c4.4xlarge
|
|
- c4.8xlarge
|
|
- c5.large
|
|
- c5.xlarge
|
|
- c5.2xlarge
|
|
- c5.4xlarge
|
|
- c5.9xlarge
|
|
- c5.12xlarge
|
|
- c5.18xlarge
|
|
- c5.24xlarge
|
|
- c6a.large
|
|
- c6a.xlarge
|
|
- c6a.2xlarge
|
|
- c6a.4xlarge
|
|
- c6a.8xlarge
|
|
- c6a.12xlarge
|
|
- c6a.16xlarge
|
|
- c6a.24xlarge
|
|
- c6a.32xlarge
|
|
- c6a.48xlarge
|
|
- c6a.metal
|
|
ConstraintDescription: "Must be a valid EC2 instance type"
|
|
|
|
KeyName:
|
|
Description: "Name of an existing EC2 KeyPair to enable SSH access to the instance. It is mandatory to perform some administrative tasks of OpenVidu."
|
|
Type: 'AWS::EC2::KeyPair::KeyName'
|
|
ConstraintDescription: "must be the name of an existing EC2 KeyPair"
|
|
|
|
# Other configuration
|
|
|
|
WantToDeployDemos:
|
|
Description: "Choose if you want to deploy OpenVidu Call application alongside OpenVidu platform."
|
|
Type: String
|
|
AllowedValues:
|
|
- true
|
|
- false
|
|
Default: true
|
|
|
|
WantToSendInfo:
|
|
Description: "Choose if you want to send to OpenVidu team the version deployed and AWS region."
|
|
Type: String
|
|
AllowedValues:
|
|
- true
|
|
- false
|
|
Default: true
|
|
|
|
#start_mappings
|
|
Mappings:
|
|
OVAMIMAP:
|
|
eu-west-1:
|
|
AMI: OV_AMI_ID
|
|
#end_mappings
|
|
|
|
Metadata:
|
|
'AWS::CloudFormation::Interface':
|
|
ParameterGroups:
|
|
- Label:
|
|
default: Domain and SSL certificate configuration
|
|
Parameters:
|
|
- WhichCert
|
|
- PublicElasticIP
|
|
- MyDomainName
|
|
- OwnCertCRT
|
|
- OwnCertKEY
|
|
- LetsEncryptEmail
|
|
- Label:
|
|
default: OpenVidu configuration
|
|
Parameters:
|
|
- OpenViduSecret
|
|
- Label:
|
|
default: EC2 Instance configuration
|
|
Parameters:
|
|
- InstanceType
|
|
- KeyName
|
|
- Label:
|
|
default: Other configuration
|
|
Parameters:
|
|
- WantToDeployDemos
|
|
- WantToSendInfo
|
|
|
|
ParameterLabels:
|
|
# SSL certificate configuration
|
|
WhichCert:
|
|
default: "Certificate Type"
|
|
PublicElasticIP:
|
|
default: "AWS Elastic IP (EIP)"
|
|
MyDomainName:
|
|
default: "Domain Name pointing to Elastic IP"
|
|
OwnCertCRT:
|
|
default: "URL to the CRT file (owncert)"
|
|
OwnCertKEY:
|
|
default: "URL to the key file (owncert)"
|
|
LetsEncryptEmail:
|
|
default: "Email for Let's Encrypt (letsencrypt)"
|
|
# OpenVidu configuration
|
|
OpenViduSecret:
|
|
default: "Openvidu Secret"
|
|
# EC2 Instance configuration
|
|
InstanceType:
|
|
default: "Instance type"
|
|
KeyName:
|
|
default: "SSH Key"
|
|
# Other configuration
|
|
WantToDeployDemos:
|
|
default: "Deploy OpenVidu Call application"
|
|
WantToSendInfo:
|
|
default: "Send deployment info to OpenVidu team"
|
|
|
|
Conditions:
|
|
WhichCertPresent: !Not [ !Equals [!Ref WhichCert, ""] ]
|
|
PublicElasticIPPresent: !Not [ !Equals [!Ref PublicElasticIP, ""] ]
|
|
|
|
Resources:
|
|
|
|
LaunchTemplate:
|
|
Type: AWS::EC2::LaunchTemplate
|
|
Properties:
|
|
LaunchTemplateName: IMDSV2
|
|
LaunchTemplateData:
|
|
MetadataOptions:
|
|
HttpEndpoint: enabled
|
|
HttpPutResponseHopLimit: 1
|
|
HttpTokens: required
|
|
|
|
OpenviduServer:
|
|
Type: 'AWS::EC2::Instance'
|
|
Metadata:
|
|
Comment: 'Install and configure OpenVidu Server and Demos'
|
|
AWS::CloudFormation::Init:
|
|
config:
|
|
files:
|
|
'/usr/local/bin/ping.sh':
|
|
content: |
|
|
#!/bin/bash
|
|
|
|
INXDB_URL=193.147.51.51
|
|
INXDB_DB=ov_server
|
|
INXDB_MEASUREMENT=server
|
|
|
|
OV_VERSION=OPENVIDU_VERSION
|
|
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
|
|
EC2_AVAIL_ZONE=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/availability-zone)
|
|
EC2_REGION=$(echo "$EC2_AVAIL_ZONE" | sed 's/[a-z]$//')
|
|
|
|
curl -i -XPOST "http://$INXDB_URL:8086/write?db=$INXDB_DB" \
|
|
--data-binary "$INXDB_MEASUREMENT,region=$EC2_REGION ov_version=\"$OV_VERSION\" "
|
|
mode: "000755"
|
|
owner: "root"
|
|
group: "root"
|
|
'/usr/local/bin/check_app_ready.sh':
|
|
content: |
|
|
#!/bin/bash
|
|
while true; do
|
|
HTTP_STATUS=$(curl -Ik http://localhost:5443 | head -n1 | awk '{print $2}')
|
|
if [ $HTTP_STATUS == 200 ]; then
|
|
break
|
|
fi
|
|
sleep 5
|
|
done
|
|
mode: "000755"
|
|
owner: "root"
|
|
group: "root"
|
|
'/usr/local/bin/feedGroupVars.sh':
|
|
content: !Sub |
|
|
#!/bin/bash -x
|
|
WORKINGDIR=/opt/openvidu
|
|
|
|
# Replace secret
|
|
sed -i "s/OPENVIDU_SECRET=/OPENVIDU_SECRET=${OpenViduSecret}/" $WORKINGDIR/.env
|
|
|
|
# Replace domain name
|
|
if [[ "${MyDomainName}" != '' && "${PublicElasticIP}" != '' ]]; then
|
|
sed -i "s/DOMAIN_OR_PUBLIC_IP=/DOMAIN_OR_PUBLIC_IP=${MyDomainName}/" $WORKINGDIR/.env
|
|
elif [[ "${MyDomainName}" == '' && "${PublicElasticIP}" != '' ]]; then
|
|
sed -i "s/DOMAIN_OR_PUBLIC_IP=/DOMAIN_OR_PUBLIC_IP=${PublicElasticIP}/" $WORKINGDIR/.env
|
|
else
|
|
[ ! -d "/usr/share/openvidu" ] && mkdir -p /usr/share/openvidu
|
|
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
|
|
PublicHostname=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-hostname)
|
|
sed -i "s/DOMAIN_OR_PUBLIC_IP=/DOMAIN_OR_PUBLIC_IP=$PublicHostname/" $WORKINGDIR/.env
|
|
echo $PublicHostname > /usr/share/openvidu/old-host-name
|
|
fi
|
|
|
|
# Replace certificated type
|
|
sed -i "s/CERTIFICATE_TYPE=selfsigned/CERTIFICATE_TYPE=${WhichCert}/" $WORKINGDIR/.env
|
|
sed -i "s/LETSENCRYPT_EMAIL=user@example.com/LETSENCRYPT_EMAIL=${LetsEncryptEmail}/" $WORKINGDIR/.env
|
|
|
|
# Without Application
|
|
if [ "${WantToDeployDemos}" == "false" ]; then
|
|
sed -i "s/WITH_APP=true/WITH_APP=false/" $WORKINGDIR/docker-compose.yml
|
|
rm $WORKINGDIR/docker-compose.override.yml
|
|
fi
|
|
mode: "000755"
|
|
owner: "root"
|
|
group: "root"
|
|
'/usr/local/bin/buildCerts.sh':
|
|
content: !Sub |
|
|
#!/bin/bash -x
|
|
WORKINGDIR=/opt/openvidu
|
|
wget --no-check-certificate -O $WORKINGDIR/owncert/certificate.cert ${OwnCertCRT}
|
|
wget --no-check-certificate -O $WORKINGDIR/owncert/certificate.key ${OwnCertKEY}
|
|
mode: "000755"
|
|
owner: "root"
|
|
group: "root"
|
|
'/usr/local/bin/restartCE.sh':
|
|
content: !Sub |
|
|
#!/bin/bash -x
|
|
WORKINGDIR=/opt/openvidu
|
|
|
|
# Get new amazon URL
|
|
OldPublicHostname=$(cat /usr/share/openvidu/old-host-name)
|
|
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
|
|
PublicHostname=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-hostname)
|
|
sed -i "s/$OldPublicHostname/$PublicHostname/" $WORKINGDIR/.env
|
|
echo $PublicHostname > /usr/share/openvidu/old-host-name
|
|
|
|
# Restart all services
|
|
pushd "$WORKINGDIR"
|
|
./openvidu restart >/dev/null 2>&1 &
|
|
popd
|
|
mode: "000755"
|
|
owner: "root"
|
|
group: "root"
|
|
Properties:
|
|
ImageId: !GetAtt CloudformationLambdaInvoke.ImageId
|
|
LaunchTemplate:
|
|
LaunchTemplateName: IMDSV2
|
|
Version: 1
|
|
InstanceType: !Ref InstanceType
|
|
SecurityGroups:
|
|
- !Ref WebServerSecurityGroup
|
|
KeyName: !Ref KeyName
|
|
Tags:
|
|
- Key: Name
|
|
Value: !Ref 'AWS::StackName'
|
|
UserData:
|
|
Fn::Base64: !Sub |
|
|
#!/bin/bash -x
|
|
set -eu -o pipefail
|
|
|
|
cfn-init --region ${AWS::Region} --stack ${AWS::StackId} --resource OpenviduServer
|
|
|
|
export HOME="/root"
|
|
|
|
# Replace .env variables
|
|
/usr/local/bin/feedGroupVars.sh || { echo "[OpenVidu] Parameters incorrect/insufficient"; exit 1; }
|
|
|
|
# Launch on reboot
|
|
echo "@reboot /usr/local/bin/restartCE.sh" | crontab
|
|
|
|
# Download certs if "WichCert" mode
|
|
if [ "${WhichCert}" == "owncert" ]; then
|
|
/usr/local/bin/buildCerts.sh || { echo "[OpenVidu] error with the certificate files"; exit 1; }
|
|
fi
|
|
|
|
# Start openvidu application
|
|
pushd /opt/openvidu
|
|
./openvidu start >/dev/null 2>&1 &
|
|
popd
|
|
|
|
# Send info to openvidu
|
|
if [ "${WantToSendInfo}" == "true" ]; then
|
|
/usr/local/bin/ping.sh || true
|
|
fi
|
|
rm /usr/local/bin/ping.sh
|
|
|
|
# Wait for the app
|
|
/usr/local/bin/check_app_ready.sh
|
|
|
|
# sending the finish call
|
|
/usr/local/bin/cfn-signal -e $? --stack ${AWS::StackId} --resource WaitCondition --region ${AWS::Region}
|
|
|
|
BlockDeviceMappings:
|
|
- DeviceName: /dev/sda1
|
|
Ebs:
|
|
VolumeType: gp3
|
|
DeleteOnTermination: true
|
|
VolumeSize: 200
|
|
|
|
MyEIP:
|
|
Type: 'AWS::EC2::EIPAssociation'
|
|
Condition: PublicElasticIPPresent
|
|
Properties:
|
|
InstanceId: !Ref OpenviduServer
|
|
EIP: !Ref PublicElasticIP
|
|
|
|
WaitCondition:
|
|
Type: 'AWS::CloudFormation::WaitCondition'
|
|
CreationPolicy:
|
|
ResourceSignal:
|
|
Timeout: PT30M
|
|
Count: '1'
|
|
|
|
WebServerSecurityGroup:
|
|
Type: 'AWS::EC2::SecurityGroup'
|
|
Properties:
|
|
GroupDescription: SSH, Proxy and OpenVidu WebRTC Ports
|
|
SecurityGroupIngress:
|
|
- IpProtocol: tcp
|
|
FromPort: 22
|
|
ToPort: 22
|
|
CidrIp: 0.0.0.0/0
|
|
- IpProtocol: tcp
|
|
FromPort: 22
|
|
ToPort: 22
|
|
CidrIpv6: ::/0
|
|
- IpProtocol: tcp
|
|
FromPort: 80
|
|
ToPort: 80
|
|
CidrIp: 0.0.0.0/0
|
|
- IpProtocol: tcp
|
|
FromPort: 80
|
|
ToPort: 80
|
|
CidrIpv6: ::/0
|
|
- IpProtocol: tcp
|
|
FromPort: 443
|
|
ToPort: 443
|
|
CidrIp: 0.0.0.0/0
|
|
- IpProtocol: tcp
|
|
FromPort: 443
|
|
ToPort: 443
|
|
CidrIpv6: ::/0
|
|
- IpProtocol: tcp
|
|
FromPort: 3478
|
|
ToPort: 3478
|
|
CidrIp: 0.0.0.0/0
|
|
- IpProtocol: tcp
|
|
FromPort: 3478
|
|
ToPort: 3478
|
|
CidrIpv6: ::/0
|
|
- IpProtocol: udp
|
|
FromPort: 3478
|
|
ToPort: 3478
|
|
CidrIp: 0.0.0.0/0
|
|
- IpProtocol: udp
|
|
FromPort: 3478
|
|
ToPort: 3478
|
|
CidrIpv6: ::/0
|
|
- IpProtocol: udp
|
|
FromPort: 40000
|
|
ToPort: 57000
|
|
CidrIp: 0.0.0.0/0
|
|
- IpProtocol: udp
|
|
FromPort: 40000
|
|
ToPort: 57000
|
|
CidrIpv6: ::/0
|
|
- IpProtocol: tcp
|
|
FromPort: 40000
|
|
ToPort: 57000
|
|
CidrIp: 0.0.0.0/0
|
|
- IpProtocol: tcp
|
|
FromPort: 40000
|
|
ToPort: 57000
|
|
CidrIpv6: ::/0
|
|
|
|
##########
|
|
# Lambda to Copy original AMI to the deployment region
|
|
##########
|
|
CloudformationLambdaRole:
|
|
Type: 'AWS::IAM::Role'
|
|
DeletionPolicy: Delete
|
|
Properties:
|
|
AssumeRolePolicyDocument:
|
|
Version: 2012-10-17
|
|
Statement:
|
|
- Effect: Allow
|
|
Principal:
|
|
Service:
|
|
- lambda.amazonaws.com
|
|
Action:
|
|
- 'sts:AssumeRole'
|
|
Path: /
|
|
Policies:
|
|
- PolicyName: !Join ['', [ !Ref AWS::StackName, '-cf-lambda-policy'] ]
|
|
PolicyDocument:
|
|
Version: 2012-10-17
|
|
Statement:
|
|
- Effect: Allow
|
|
Action:
|
|
- 'ec2:DescribeImages'
|
|
- 'ec2:CopyImage'
|
|
Resource: '*'
|
|
RoleName: !Join ['', [ !Ref AWS::StackName, '-cf-lambda-role'] ]
|
|
|
|
CloudformationLambda:
|
|
Type: AWS::Lambda::Function
|
|
DeletionPolicy: Delete
|
|
Properties:
|
|
FunctionName: !Join ['', [ !Ref AWS::StackName, '-cf-lambda'] ]
|
|
Code:
|
|
ZipFile: |
|
|
import boto3
|
|
import cfnresponse
|
|
from botocore.config import Config
|
|
|
|
def handler(event, context):
|
|
try:
|
|
if (event['RequestType'] == 'Create'):
|
|
copy_ami(event, context)
|
|
return
|
|
else:
|
|
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
|
|
except Exception:
|
|
cfnresponse.send(event, context, cfnresponse.FAILED, {})
|
|
|
|
def copy_ami(event, context):
|
|
new_images=[]
|
|
cfn_output = {}
|
|
source_image_id = event['ResourceProperties']['AmiSourceId']
|
|
source_region = event['ResourceProperties']['AmiSourceRegion']
|
|
deployment_region = event['ResourceProperties']['DeploymentRegion']
|
|
|
|
# Clients init
|
|
ec2_client = boto3.client('ec2', config = Config(region_name=deployment_region))
|
|
ec2_client_ov = boto3.client('ec2', config = Config(region_name=source_region))
|
|
img_exists_waiter= ec2_client.get_waiter('image_exists')
|
|
img_avail_waiter = ec2_client.get_waiter('image_available')
|
|
|
|
# Get original ami name
|
|
public_ami_filter = [{ 'Name': 'image-id', 'Values': [ source_image_id ] }]
|
|
|
|
response = ec2_client_ov.describe_images(Filters=public_ami_filter)
|
|
new_ami_name= "[ OpenVidu CE AMI Copy ] - " + response['Images'][0]['Name']
|
|
|
|
own_ami_filter = [{ 'Name': 'name', 'Values': [new_ami_name] }]
|
|
response = ec2_client.describe_images(Filters=own_ami_filter)
|
|
if (len(response['Images']) == 1):
|
|
# If AMI exists, don't copy
|
|
new_images.append(response['Images'][0]['ImageId'])
|
|
cfn_output['ImageId'] = response['Images'][0]['ImageId']
|
|
else:
|
|
# If AMI does not exist, copy
|
|
response = ec2_client.copy_image(
|
|
SourceImageId=source_image_id,
|
|
SourceRegion=source_region,
|
|
Name=new_ami_name
|
|
)
|
|
new_images.append(response['ImageId'])
|
|
cfn_output['ImageId'] = response['ImageId']
|
|
|
|
# Wait images to be available
|
|
waiter_config = {'Delay': 15, 'MaxAttempts': 59
|
|
}
|
|
# Wait image to exist
|
|
response = img_exists_waiter.wait(ImageIds=new_images, WaiterConfig=waiter_config
|
|
)
|
|
# Wait image to be available
|
|
response = img_avail_waiter.wait(ImageIds=new_images, WaiterConfig=waiter_config)
|
|
|
|
# Return AMI
|
|
cfnresponse.send(event, context, cfnresponse.SUCCESS, cfn_output)
|
|
|
|
Handler: index.handler
|
|
Role:
|
|
!GetAtt CloudformationLambdaRole.Arn
|
|
Runtime: python3.11
|
|
Timeout: 900
|
|
|
|
CloudformationLambdaInvoke:
|
|
Type: AWS::CloudFormation::CustomResource
|
|
DeletionPolicy: Delete
|
|
Version: "1.0"
|
|
Properties:
|
|
ServiceToken: !GetAtt CloudformationLambda.Arn
|
|
AmiSourceRegion: 'eu-west-1'
|
|
AmiSourceId: !FindInMap [OVAMIMAP, 'eu-west-1', AMI]
|
|
DeploymentRegion: !Ref AWS::Region
|
|
|
|
Outputs:
|
|
OpenViduServerURL:
|
|
Description: Use this URL to connect OpenVidu Server
|
|
Value: !Join
|
|
- ''
|
|
- - 'https://'
|
|
- !GetAtt
|
|
- OpenviduServer
|
|
- PublicDnsName
|
|
OpenViduServerURLLE:
|
|
Description: Use this URL to connect OpenVidu Server
|
|
Value: !Join
|
|
- ''
|
|
- - 'https://'
|
|
- !Ref MyDomainName
|
|
Condition: WhichCertPresent
|
|
OpenViduCallURL:
|
|
Description: If you choose to deploy OpenVidu Call application, use this URL
|
|
Value: !Join
|
|
- ''
|
|
- - 'https://'
|
|
- !GetAtt
|
|
- OpenviduServer
|
|
- PublicDnsName
|
|
OpenViduCallURLLE:
|
|
Description: If you choose to deploy OpenVidu Call application, use this URL
|
|
Value: !Join
|
|
- ''
|
|
- - 'https://'
|
|
- !Ref MyDomainName
|
|
Condition: WhichCertPresent
|