2025-04-22 11:46:24 +02:00
AWSTemplateFormatVersion : 2010-09-09
Description : OpenVidu Community - Single Node
Parameters :
CertificateType :
Description : |
2025-09-07 01:19:37 +02:00
[ 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).
2025-04-22 11:46:24 +02:00
Type : String
AllowedValues :
- selfsigned
- letsencrypt
2025-09-02 01:11:37 +02:00
- owncert
Default : letsencrypt
2025-04-22 11:46:24 +02:00
PublicElasticIP :
Type : String
Description : Previously created Elastic IP for the OpenVidu Deployment.
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
DomainName :
Type : String
Description : Domain name for the OpenVidu Deployment.
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
OwnPublicCertificate :
2025-12-23 19:35:00 +01:00
Description : "If certificate type is 'owncert', this parameter will be used to specify the public certificate in base64 format"
2025-04-22 11:46:24 +02:00
Type : String
OwnPrivateCertificate :
2025-12-23 19:35:00 +01:00
Description : "If certificate type is 'owncert', this parameter will be used to specify the private certificate in base64 format"
2025-04-22 11:46:24 +02:00
Type : String
2025-09-15 12:30:04 +02:00
InitialMeetAdminPassword :
Description : 'Initial password for the "admin" user in OpenVidu Meet. If not provided, a random password will be generated.'
Type : String
2025-09-15 22:51:57 +02:00
NoEcho : true
2025-09-15 12:30:04 +02:00
Default : ''
# Only allow alphanumeric characters
2025-09-15 22:51:57 +02:00
AllowedPattern : '^[A-Za-z0-9_-]*$'
2025-09-15 12:30:04 +02:00
ConstraintDescription : 'Must contain only alphanumeric characters (A-Z, a-z, 0-9). Leave empty to generate a random password.'
InitialMeetApiKey :
Description : 'Initial API key for OpenVidu Meet. If not provided, no API key will be set and the user can set it later from Meet Console.'
Type : String
2025-09-15 22:51:57 +02:00
NoEcho : true
2025-09-15 12:30:04 +02:00
Default : ''
# Only allow alphanumeric characters
2025-09-15 22:51:57 +02:00
AllowedPattern : '^[A-Za-z0-9_-]*$'
2025-09-15 12:30:04 +02:00
ConstraintDescription : 'Must contain only alphanumeric characters (A-Z, a-z, 0-9). Leave empty to not set an initial API key.'
2025-06-13 19:19:53 +02:00
AdditionalInstallFlags :
Description : Additional optional flags to pass to the OpenVidu installer (comma-separated, e.g., "--flag1=value, --flag2").
Type : String
Default : ""
AllowedPattern : '^[A-Za-z0-9, =_.\-]*$' # Allows letters, numbers, comma, space, underscore, dot, equals, and hyphen
ConstraintDescription : Must be a comma-separated list of flags (for example, --flag=value, --bool-flag).
2025-04-22 11:46:24 +02:00
TurnDomainName :
Description : '(Optional) Domain name for the TURN server with TLS. Only needed if your users are behind restrictive firewalls'
Type : String
Default : ''
TurnOwnPublicCertificate :
2025-12-23 19:35:00 +01:00
Description : "(Optional) This setting is applicable if the certificate type is set to 'owncert' and the TurnDomainName is specified. Provide in base64 format."
2025-04-22 11:46:24 +02:00
Type : String
Default : ''
TurnOwnPrivateCertificate :
2025-12-23 19:35:00 +01:00
Description : "(Optional) This setting is applicable if the certificate type is set to 'owncert' and the TurnDomainName is specified. Provide in base64 format."
2025-04-22 11:46:24 +02:00
Type : String
Default : ''
# EC2 Instance configuration
InstanceType :
Description : "Specifies the EC2 instance type for your OpenVidu instance"
Type : String
Default : c6a.xlarge
AllowedValues :
2025-12-01 20:36:57 +01:00
- t3.nano
- t3.micro
- t3.small
2025-04-22 11:46:24 +02:00
- t3.medium
- t3.large
- t3.xlarge
- t3.2xlarge
2025-12-01 20:36:57 +01:00
- t3a.nano
- t3a.micro
- t3a.small
- t3a.medium
- t3a.large
- t3a.xlarge
- t3a.2xlarge
- t4g.nano
- t4g.micro
- t4g.small
- t4g.medium
- t4g.large
- t4g.xlarge
- t4g.2xlarge
2025-04-22 11:46:24 +02:00
- c5.large
- c5.xlarge
- c5.2xlarge
- c5.4xlarge
- c5.9xlarge
- c5.12xlarge
- c5.18xlarge
- c5.24xlarge
2025-12-01 20:36:57 +01:00
- c5.metal
- c5a.large
- c5a.xlarge
- c5a.2xlarge
- c5a.4xlarge
- c5a.8xlarge
- c5a.12xlarge
- c5a.16xlarge
- c5a.24xlarge
- c5ad.large
- c5ad.xlarge
- c5ad.2xlarge
- c5ad.4xlarge
- c5ad.8xlarge
- c5ad.12xlarge
- c5ad.16xlarge
- c5ad.24xlarge
- c5d.large
- c5d.xlarge
- c5d.2xlarge
- c5d.4xlarge
- c5d.9xlarge
- c5d.12xlarge
- c5d.18xlarge
- c5d.24xlarge
- c5d.metal
- c5n.large
- c5n.xlarge
- c5n.2xlarge
- c5n.4xlarge
- c5n.9xlarge
- c5n.18xlarge
- c5n.metal
2025-04-22 11:46:24 +02:00
- c6a.large
- c6a.xlarge
- c6a.2xlarge
- c6a.4xlarge
- c6a.8xlarge
- c6a.12xlarge
- c6a.16xlarge
- c6a.24xlarge
- c6a.32xlarge
- c6a.48xlarge
- c6a.metal
2025-12-01 20:36:57 +01:00
- c6g.medium
- c6g.large
- c6g.xlarge
- c6g.2xlarge
- c6g.4xlarge
- c6g.8xlarge
- c6g.12xlarge
- c6g.16xlarge
- c6g.metal
- c6gd.medium
- c6gd.large
- c6gd.xlarge
- c6gd.2xlarge
- c6gd.4xlarge
- c6gd.8xlarge
- c6gd.12xlarge
- c6gd.16xlarge
- c6gd.metal
- c6gn.medium
- c6gn.large
- c6gn.xlarge
- c6gn.2xlarge
- c6gn.4xlarge
- c6gn.8xlarge
- c6gn.12xlarge
- c6gn.16xlarge
2025-04-22 11:46:24 +02:00
- c6i.large
- c6i.xlarge
- c6i.2xlarge
- c6i.4xlarge
- c6i.8xlarge
- c6i.12xlarge
- c6i.16xlarge
- c6i.24xlarge
- c6i.32xlarge
- c6i.metal
2025-12-01 20:36:57 +01:00
- c6id.large
- c6id.xlarge
- c6id.2xlarge
- c6id.4xlarge
- c6id.8xlarge
- c6id.12xlarge
- c6id.16xlarge
- c6id.24xlarge
- c6id.32xlarge
- c6id.metal
- c6in.large
- c6in.xlarge
- c6in.2xlarge
- c6in.4xlarge
- c6in.8xlarge
- c6in.12xlarge
- c6in.16xlarge
- c6in.24xlarge
- c6in.32xlarge
- c6in.metal
2025-04-22 11:46:24 +02:00
- c7a.medium
- c7a.large
- c7a.xlarge
- c7a.2xlarge
- c7a.4xlarge
- c7a.8xlarge
- c7a.12xlarge
- c7a.16xlarge
- c7a.24xlarge
- c7a.32xlarge
- c7a.48xlarge
- c7a.metal-48xl
2025-12-01 20:36:57 +01:00
- c7g.medium
- c7g.large
- c7g.xlarge
- c7g.2xlarge
- c7g.4xlarge
- c7g.8xlarge
- c7g.12xlarge
- c7g.16xlarge
- c7g.metal
- c7gd.medium
- c7gd.large
- c7gd.xlarge
- c7gd.2xlarge
- c7gd.4xlarge
- c7gd.8xlarge
- c7gd.12xlarge
- c7gd.16xlarge
- c7gd.metal
- c7gn.medium
- c7gn.large
- c7gn.xlarge
- c7gn.2xlarge
- c7gn.4xlarge
- c7gn.8xlarge
- c7gn.12xlarge
- c7gn.16xlarge
- c7gn.metal
- c7i-flex.large
- c7i-flex.xlarge
- c7i-flex.2xlarge
- c7i-flex.4xlarge
- c7i-flex.8xlarge
- c7i-flex.12xlarge
- c7i-flex.16xlarge
2025-04-22 11:46:24 +02:00
- c7i.large
- c7i.xlarge
- c7i.2xlarge
- c7i.4xlarge
- c7i.8xlarge
- c7i.12xlarge
- c7i.16xlarge
- c7i.24xlarge
- c7i.48xlarge
- c7i.metal-24xl
- c7i.metal-48xl
2025-12-01 20:36:57 +01:00
- c8g.medium
- c8g.large
- c8g.xlarge
- c8g.2xlarge
- c8g.4xlarge
- c8g.8xlarge
- c8g.12xlarge
- c8g.16xlarge
- c8g.24xlarge
- c8g.48xlarge
- c8g.metal-24xl
- c8g.metal-48xl
- m6a.large
- m6a.xlarge
- m6a.2xlarge
- m6a.4xlarge
- m6a.8xlarge
- m6a.12xlarge
- m6a.16xlarge
- m6a.24xlarge
- m6a.32xlarge
- m6a.48xlarge
- m6a.metal
- m6g.medium
- m6g.large
- m6g.xlarge
- m6g.2xlarge
- m6g.4xlarge
- m6g.8xlarge
- m6g.12xlarge
- m6g.16xlarge
- m6g.metal
- m6gd.medium
- m6gd.large
- m6gd.xlarge
- m6gd.2xlarge
- m6gd.4xlarge
- m6gd.8xlarge
- m6gd.12xlarge
- m6gd.16xlarge
- m6gd.metal
- m6i.large
- m6i.xlarge
- m6i.2xlarge
- m6i.4xlarge
- m6i.8xlarge
- m6i.12xlarge
- m6i.16xlarge
- m6i.24xlarge
- m6i.32xlarge
- m6i.metal
- m6id.large
- m6id.xlarge
- m6id.2xlarge
- m6id.4xlarge
- m6id.8xlarge
- m6id.12xlarge
- m6id.16xlarge
- m6id.24xlarge
- m6id.32xlarge
- m6id.metal
- m6idn.large
- m6idn.xlarge
- m6idn.2xlarge
- m6idn.4xlarge
- m6idn.8xlarge
- m6idn.12xlarge
- m6idn.16xlarge
- m6idn.24xlarge
- m6idn.32xlarge
- m6idn.metal
2025-04-22 11:46:24 +02:00
- m6in.large
- m6in.xlarge
- m6in.2xlarge
- m6in.4xlarge
- m6in.8xlarge
- m6in.12xlarge
- m6in.16xlarge
- m6in.24xlarge
- m6in.32xlarge
2025-12-01 20:36:57 +01:00
- m6in.metal
- m7a.medium
- m7a.large
- m7a.xlarge
- m7a.2xlarge
- m7a.4xlarge
- m7a.8xlarge
- m7a.12xlarge
- m7a.16xlarge
- m7a.24xlarge
- m7a.32xlarge
- m7a.48xlarge
- m7a.metal-48xl
- m7g.medium
- m7g.large
- m7g.xlarge
- m7g.2xlarge
- m7g.4xlarge
- m7g.8xlarge
- m7g.12xlarge
- m7g.16xlarge
- m7g.metal
- m7gd.medium
- m7gd.large
- m7gd.xlarge
- m7gd.2xlarge
- m7gd.4xlarge
- m7gd.8xlarge
- m7gd.12xlarge
- m7gd.16xlarge
- m7gd.metal
- m7i-flex.large
- m7i-flex.xlarge
- m7i-flex.2xlarge
- m7i-flex.4xlarge
- m7i-flex.8xlarge
- m7i-flex.12xlarge
- m7i-flex.16xlarge
- m7i.large
- m7i.xlarge
- m7i.2xlarge
- m7i.4xlarge
- m7i.8xlarge
- m7i.12xlarge
- m7i.16xlarge
- m7i.24xlarge
- m7i.48xlarge
- m7i.metal-24xl
- m7i.metal-48xl
- m8g.medium
- m8g.large
- m8g.xlarge
- m8g.2xlarge
- m8g.4xlarge
- m8g.8xlarge
- m8g.12xlarge
- m8g.16xlarge
- m8g.24xlarge
- m8g.48xlarge
- m8g.metal-24xl
- m8g.metal-48xl
2025-04-22 11:46:24 +02:00
ConstraintDescription : "Must be a valid EC2 instance type"
KeyName :
Type : AWS::EC2::KeyPair::KeyName
Description : Name of an existing EC2 KeyPair to enable SSH access to the Deployment.
AllowedPattern : ^.+$
ConstraintDescription : must be the name of an existing EC2 KeyPair.
2025-12-01 20:36:57 +01:00
OperatingSystem :
Description : VSCode Server EC2 operating system
Type : String
Default : "Ubuntu-24"
AllowedValues : [ 'Ubuntu-22' , 'Ubuntu-24' ]
2025-04-22 11:46:24 +02:00
S3AppDataBucketName :
Type : String
Description : Name of the S3 bucket to store data and recordings. If empty, a bucket will be created
Metadata :
'AWS::CloudFormation::Interface' :
ParameterGroups :
- Label :
default : Domain and SSL certificate configuration
Parameters :
- CertificateType
- PublicElasticIP
- DomainName
- OwnPublicCertificate
- OwnPrivateCertificate
2025-09-15 12:30:04 +02:00
- Label :
default : OpenVidu Meet configuration
Parameters :
- InitialMeetAdminPassword
- InitialMeetApiKey
2025-04-22 11:46:24 +02:00
- Label :
default : EC2 Instance configuration
Parameters :
- InstanceType
2025-09-06 21:44:34 +02:00
- KeyName
2025-12-01 20:36:57 +01:00
- OperatingSystem
2025-04-22 11:46:24 +02:00
- Label :
default : S3 bucket for application data and recordings
Parameters :
- S3AppDataBucketName
2025-06-13 19:19:53 +02:00
- Label :
default : "(Optional) Additional Installer Flags"
Parameters :
- AdditionalInstallFlags
2025-04-22 11:46:24 +02:00
- Label :
default : (Optional) TURN server configuration with TLS
Parameters :
- TurnDomainName
- TurnOwnPublicCertificate
- TurnOwnPrivateCertificate
Conditions :
PublicElasticIPPresent : !Not [ !Equals [!Ref PublicElasticIP, ""] ]
2025-09-02 12:01:54 +02:00
PublicElasticIPAbsent : !Equals [!Ref PublicElasticIP, ""]
2025-04-22 11:46:24 +02:00
CreateRecordingsBucket : !Equals [!Ref S3AppDataBucketName, ""]
2025-12-01 20:36:57 +01:00
IsGraviton : !Or
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 't4g']
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 'c6g']
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 'c7g']
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 'c7gd']
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 'c8g']
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 'm6g']
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 'm6gd']
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 'm7g']
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 'm7gd']
- !Equals [ !Select [ 0, !Split ['.', !Ref InstanceType ]], 'm8g']
Mappings :
ArmImage :
# aws ssm get-parameters-by-path --path "/aws/service/canonical/ubuntu/" --recursive --query "Parameters[*].Name" > canonical-ami.txt
Ubuntu-22 :
ImageId : '{{resolve:ssm:/aws/service/canonical/ubuntu/server/jammy/stable/current/arm64/hvm/ebs-gp2/ami-id}}'
Ubuntu-24 :
ImageId : '{{resolve:ssm:/aws/service/canonical/ubuntu/server/noble/stable/current/arm64/hvm/ebs-gp3/ami-id}}'
AmdImage :
Ubuntu-22 :
ImageId : '{{resolve:ssm:/aws/service/canonical/ubuntu/server/jammy/stable/current/amd64/hvm/ebs-gp2/ami-id}}'
Ubuntu-24 :
ImageId : '{{resolve:ssm:/aws/service/canonical/ubuntu/server/noble/stable/current/amd64/hvm/ebs-gp3/ami-id}}'
2025-04-22 11:46:24 +02:00
Resources :
OpenViduSharedInfo :
Type : AWS::SecretsManager::Secret
UpdateReplacePolicy : Retain
DeletionPolicy : Delete
Properties :
Name : !Sub openvidu-${AWS::Region}-${AWS::StackName}
Description : Secret for OpenVidu to store deployment info and seed secrets
SecretString : |
{
2025-09-02 12:01:54 +02:00
"OPENVIDU_URL": "none" ,
"MEET_INITIAL_ADMIN_USER": "none" ,
"MEET_INITIAL_ADMIN_PASSWORD": "none" ,
"MEET_INITIAL_API_KEY": "none" ,
"LIVEKIT_URL": "none" ,
"LIVEKIT_API_KEY": "none" ,
"LIVEKIT_API_SECRET": "none" ,
"DASHBOARD_URL": "none" ,
"GRAFANA_URL": "none" ,
"MINIO_URL": "none" ,
2025-04-22 11:46:24 +02:00
"DOMAIN_NAME": "none" ,
"LIVEKIT_TURN_DOMAIN_NAME": "none" ,
"REDIS_PASSWORD": "none" ,
"MONGO_ADMIN_USERNAME": "none" ,
"MONGO_ADMIN_PASSWORD": "none" ,
"MONGO_REPLICA_SET_KEY": "none" ,
"MINIO_ACCESS_KEY": "none" ,
"MINIO_SECRET_KEY": "none" ,
"DASHBOARD_ADMIN_USERNAME": "none" ,
"DASHBOARD_ADMIN_PASSWORD": "none" ,
"GRAFANA_ADMIN_USERNAME": "none" ,
"GRAFANA_ADMIN_PASSWORD": "none" ,
"ENABLED_MODULES": "none"
}
S3AppDataBucketResource :
Type : 'AWS::S3::Bucket'
Properties :
### Unique bucket name using Stack ID
BucketName : !Join ["-" , [ 'openvidu-appdata', !Select [0, !Split ["-", !Select [2, !Split [/, !Ref AWS::StackId ]]]]]]
AccessControl : Private
PublicAccessBlockConfiguration :
BlockPublicAcls : true
BlockPublicPolicy : true
IgnorePublicAcls : true
RestrictPublicBuckets : true
DeletionPolicy : Retain
UpdateReplacePolicy : Retain
Condition : CreateRecordingsBucket
OpenViduServerRole :
Type : 'AWS::IAM::Role'
Properties :
AssumeRolePolicyDocument :
Version : 2012-10-17
Statement :
- Effect : Allow
Principal :
Service :
- ec2.amazonaws.com
Action :
- 'sts:AssumeRole'
Path : /
Policies :
- PolicyName : !Sub openvidu-policy-${AWS::Region}-${AWS::StackName}
PolicyDocument :
Version : 2012-10-17
Statement :
- Effect : Allow
Action :
- secretsmanager:GetSecretValue
- secretsmanager:UpdateSecret
Resource : !Ref OpenViduSharedInfo
- Fn::If :
- CreateRecordingsBucket
- Effect : Allow
Action :
- s3:DeleteObject
- s3:GetObject
- s3:PutObject
Resource : !Sub ${S3AppDataBucketResource.Arn}/*
- Effect : Allow
Action :
- s3:DeleteObject
- s3:GetObject
- s3:PutObject
Resource : !Sub arn:${AWS::Partition}:s3:::${S3AppDataBucketName}/*
- Fn::If :
- CreateRecordingsBucket
- Effect : Allow
Action :
- s3:ListBucket
- s3:GetBucketLocation
Resource : !GetAtt S3AppDataBucketResource.Arn
- Effect : Allow
Action :
- s3:ListBucket
- s3:GetBucketLocation
Resource : !Sub arn:${AWS::Partition}:s3:::${S3AppDataBucketName}
RoleName :
Fn::Join :
# Generate a not too long and unique role name
# Getting a unique identifier from the stack id
- ''
- - openvidu-role-
- !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]
OpenViduServerInstanceProfile :
Type : 'AWS::IAM::InstanceProfile'
Properties :
Roles :
- !Ref OpenViduServerRole
InstanceProfileName : !Sub openvidu-instance-profile-${AWS::Region}-${AWS::StackName}
OpenviduServer :
Type : 'AWS::EC2::Instance'
Metadata :
Comment : 'Install and configure OpenVidu Community - Single Node'
AWS::CloudFormation::Init :
config :
files :
'/usr/local/bin/install.sh' :
content : !Sub |
#!/bin/bash -x
2025-10-13 18:57:47 +02:00
OPENVIDU_VERSION=main
2025-04-22 11:46:24 +02:00
DOMAIN=
YQ_VERSION=v4.44.5
apt-get update && apt-get install -y \
curl \
unzip \
jq \
wget
2025-09-02 01:11:37 +02:00
wget https://github.com/mikefarah/yq/releases/download/${!YQ_VERSION}/yq_linux_$(dpkg --print-architecture).tar.gz -O - |\
tar xz && mv yq_linux_$(dpkg --print-architecture) /usr/bin/yq
2025-04-22 11:46:24 +02:00
# Install aws-cli
2025-09-02 01:11:37 +02:00
curl "https://awscli.amazonaws.com/awscli-exe-linux-$(uname -m).zip" -o "awscliv2.zip"
2025-04-22 11:46:24 +02:00
unzip -qq awscliv2.zip
./aws/install
rm -rf awscliv2.zip aws
# Token for IMDSv2
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# Configure Domain
if [[ "${DomainName}" == '' ]]; then
PublicHostname=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/public-hostname)
2025-09-02 12:01:54 +02:00
RANDOM_DOMAIN_STRING=$(tr -dc 'a-z' < /dev/urandom | head -c 8)
DOMAIN=openvidu-$RANDOM_DOMAIN_STRING-$(echo "$PublicHostname" | cut -d'.' -f1 | sed 's/^ec2-//').sslip.io
TURN_DOMAIN_NAME_SSLIP_IO="turn-$RANDOM_DOMAIN_STRING-$(echo "$PublicHostname" | cut -d'.' -f1 | sed 's/^ec2-//').sslip.io"
2025-04-22 11:46:24 +02:00
else
DOMAIN=${DomainName}
fi
DOMAIN="$(/usr/local/bin/store_secret.sh save DOMAIN_NAME "$DOMAIN")"
2025-09-15 12:30:04 +02:00
# Meet initial admin user and password
MEET_INITIAL_ADMIN_USER="$(/usr/local/bin/store_secret.sh save MEET_INITIAL_ADMIN_USER "admin")"
if [[ "${InitialMeetAdminPassword}" != '' ]]; then
MEET_INITIAL_ADMIN_PASSWORD="$(/usr/local/bin/store_secret.sh save MEET_INITIAL_ADMIN_PASSWORD "${InitialMeetAdminPassword}")"
else
MEET_INITIAL_ADMIN_PASSWORD="$(/usr/local/bin/store_secret.sh generate MEET_INITIAL_ADMIN_PASSWORD)"
fi
if [[ "${InitialMeetApiKey}" != '' ]]; then
MEET_INITIAL_API_KEY="$(/usr/local/bin/store_secret.sh save MEET_INITIAL_API_KEY "${InitialMeetApiKey}")"
else
MEET_INITIAL_API_KEY="$(/usr/local/bin/store_secret.sh save MEET_INITIAL_API_KEY "")"
fi
2025-04-22 11:46:24 +02:00
# Store usernames and generate random passwords
REDIS_PASSWORD="$(/usr/local/bin/store_secret.sh generate REDIS_PASSWORD)"
MONGO_ADMIN_USERNAME="$(/usr/local/bin/store_secret.sh save MONGO_ADMIN_USERNAME "mongoadmin")"
MONGO_ADMIN_PASSWORD="$(/usr/local/bin/store_secret.sh generate MONGO_ADMIN_PASSWORD)"
MONGO_REPLICA_SET_KEY="$(/usr/local/bin/store_secret.sh generate MONGO_REPLICA_SET_KEY)"
MINIO_ACCESS_KEY="$(/usr/local/bin/store_secret.sh save MINIO_ACCESS_KEY "minioadmin")"
MINIO_SECRET_KEY="$(/usr/local/bin/store_secret.sh generate MINIO_SECRET_KEY)"
DASHBOARD_ADMIN_USERNAME="$(/usr/local/bin/store_secret.sh save DASHBOARD_ADMIN_USERNAME "dashboardadmin")"
DASHBOARD_ADMIN_PASSWORD="$(/usr/local/bin/store_secret.sh generate DASHBOARD_ADMIN_PASSWORD)"
GRAFANA_ADMIN_USERNAME="$(/usr/local/bin/store_secret.sh save GRAFANA_ADMIN_USERNAME "grafanaadmin")"
GRAFANA_ADMIN_PASSWORD="$(/usr/local/bin/store_secret.sh generate GRAFANA_ADMIN_PASSWORD)"
2025-07-18 21:53:13 +02:00
ENABLED_MODULES="$(/usr/local/bin/store_secret.sh save ENABLED_MODULES "observability,openviduMeet")"
2025-04-22 11:46:24 +02:00
LIVEKIT_API_KEY="$(/usr/local/bin/store_secret.sh generate LIVEKIT_API_KEY "API" 12)"
LIVEKIT_API_SECRET="$(/usr/local/bin/store_secret.sh generate LIVEKIT_API_SECRET)"
# Base command
INSTALL_COMMAND="sh <(curl -fsSL http://get.openvidu.io/community/singlenode/$OPENVIDU_VERSION/install.sh)"
# Common arguments
COMMON_ARGS=(
"--no-tty"
"--install"
"--environment=aws"
"--deployment-type=single_node"
"--domain-name=$DOMAIN"
"--enabled-modules='$ENABLED_MODULES'"
"--redis-password=$REDIS_PASSWORD"
"--mongo-admin-user=$MONGO_ADMIN_USERNAME"
"--mongo-admin-password=$MONGO_ADMIN_PASSWORD"
"--mongo-replica-set-key=$MONGO_REPLICA_SET_KEY"
"--minio-access-key=$MINIO_ACCESS_KEY"
"--minio-secret-key=$MINIO_SECRET_KEY"
"--dashboard-admin-user=$DASHBOARD_ADMIN_USERNAME"
"--dashboard-admin-password=$DASHBOARD_ADMIN_PASSWORD"
"--grafana-admin-user=$GRAFANA_ADMIN_USERNAME"
"--grafana-admin-password=$GRAFANA_ADMIN_PASSWORD"
2025-08-28 13:58:03 +02:00
"--meet-initial-admin-password=$MEET_INITIAL_ADMIN_PASSWORD"
"--meet-initial-api-key=$MEET_INITIAL_API_KEY"
2025-04-22 11:46:24 +02:00
"--livekit-api-key=$LIVEKIT_API_KEY"
"--livekit-api-secret=$LIVEKIT_API_SECRET"
)
2025-06-13 19:19:53 +02:00
# Include additional installer flags provided by the user
if [[ "${AdditionalInstallFlags}" != "" ]]; then
IFS=',' read -ra EXTRA_FLAGS <<< "${AdditionalInstallFlags}"
for extra_flag in "${!EXTRA_FLAGS[@]}"; do
# Trim whitespace around each flag
extra_flag="$(echo -e "${!extra_flag}" | sed -e 's/^[ \t]*//' -e 's/[ \t]*$//')"
if [[ "$extra_flag" != "" ]]; then
COMMON_ARGS+=("$extra_flag")
fi
done
fi
2025-09-02 01:11:37 +02:00
if [[ "${!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"
)
elif [[ "${TurnDomainName}" != '' ]]; then
2025-04-22 11:46:24 +02:00
LIVEKIT_TURN_DOMAIN_NAME=$(/usr/local/bin/store_secret.sh save LIVEKIT_TURN_DOMAIN_NAME "${TurnDomainName}")
COMMON_ARGS+=(
"--turn-domain-name=$LIVEKIT_TURN_DOMAIN_NAME"
)
fi
# Certificate arguments
if [[ "${CertificateType}" == "selfsigned" ]]; then
CERT_ARGS=(
"--certificate-type=selfsigned"
)
elif [[ "${CertificateType}" == "letsencrypt" ]]; then
CERT_ARGS=(
"--certificate-type=letsencrypt"
)
else
2025-12-23 19:35:00 +01:00
# Use base64 encoded certificates directly
OWN_CERT_CRT=${OwnPublicCertificate}
OWN_CERT_KEY=${OwnPrivateCertificate}
2025-04-22 11:46:24 +02:00
CERT_ARGS=(
"--certificate-type=owncert"
"--owncert-public-key=$OWN_CERT_CRT"
"--owncert-private-key=$OWN_CERT_KEY"
)
# Turn with TLS and own certificate
if [[ "${TurnDomainName}" != '' ]]; then
2025-12-23 19:35:00 +01:00
# Use base64 encoded certificates directly
OWN_CERT_CRT_TURN=${TurnOwnPublicCertificate}
OWN_CERT_KEY_TURN=${TurnOwnPrivateCertificate}
2025-04-22 11:46:24 +02:00
CERT_ARGS+=(
"--turn-owncert-private-key=$OWN_CERT_KEY_TURN"
"--turn-owncert-public-key=$OWN_CERT_CRT_TURN"
)
fi
fi
# Construct the final command with all arguments
FINAL_COMMAND="$INSTALL_COMMAND $(printf "%s " "${!COMMON_ARGS[@]}") $(printf "%s " "${!CERT_ARGS[@]}")"
# Install OpenVidu
exec bash -c "$FINAL_COMMAND"
mode : "000755"
owner : "root"
group : "root"
'/usr/local/bin/config_s3.sh' :
content : !Sub
- |
#!/bin/bash
set -e
# Install dir and config dir
INSTALL_DIR="/opt/openvidu"
CONFIG_DIR="${!INSTALL_DIR}/config"
# Config S3 bucket
EXTERNAL_S3_ENDPOINT="https://s3.${AWS::Region}.amazonaws.com"
EXTERNAL_S3_REGION="${AWS::Region}"
EXTERNAL_S3_PATH_STYLE_ACCESS="false"
EXTERNAL_S3_BUCKET_APP_DATA=${S3RecordingsBucketResourceName}
sed -i "s|EXTERNAL_S3_ENDPOINT=.*|EXTERNAL_S3_ENDPOINT=$EXTERNAL_S3_ENDPOINT|" "${!CONFIG_DIR}/openvidu.env"
sed -i "s|EXTERNAL_S3_REGION=.*|EXTERNAL_S3_REGION=$EXTERNAL_S3_REGION|" "${!CONFIG_DIR}/openvidu.env"
sed -i "s|EXTERNAL_S3_PATH_STYLE_ACCESS=.*|EXTERNAL_S3_PATH_STYLE_ACCESS=$EXTERNAL_S3_PATH_STYLE_ACCESS|" "${!CONFIG_DIR}/openvidu.env"
sed -i "s|EXTERNAL_S3_BUCKET_APP_DATA=.*|EXTERNAL_S3_BUCKET_APP_DATA=$EXTERNAL_S3_BUCKET_APP_DATA|" "${!CONFIG_DIR}/openvidu.env"
- S3RecordingsBucketResourceName : !If
- CreateRecordingsBucket
- !Ref S3AppDataBucketResource
- !Ref S3AppDataBucketName
mode : "000755"
owner : "root"
group : "root"
'/usr/local/bin/after_install.sh' :
content : !Sub |
#!/bin/bash
set -e
# Get current shared secret
SHARED_SECRET=$(aws secretsmanager get-secret-value \
--region ${AWS::Region} \
--secret-id openvidu-${AWS::Region}-${AWS::StackName} \
--query SecretString --output text)
2025-09-09 22:26:41 +02:00
DOMAIN=$(echo $SHARED_SECRET | jq -r .DOMAIN_NAME)
2025-04-22 11:46:24 +02:00
# Generate URLs
2025-09-02 12:01:54 +02:00
OPENVIDU_URL="https://${!DOMAIN}/"
LIVEKIT_URL="wss://${!DOMAIN}/"
2025-04-22 11:46:24 +02:00
DASHBOARD_URL="https://${!DOMAIN}/dashboard/"
GRAFANA_URL="https://${!DOMAIN}/grafana/"
MINIO_URL="https://${!DOMAIN}/minio-console/"
# Update shared secret
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DOMAIN_NAME": "'"$DOMAIN"'"}')"
2025-09-02 12:01:54 +02:00
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"OPENVIDU_URL": "'"$OPENVIDU_URL"'" }')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"LIVEKIT_URL": "'"$LIVEKIT_URL"'" }')"
2025-04-22 11:46:24 +02:00
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DASHBOARD_URL": "'"$DASHBOARD_URL"'" }')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"GRAFANA_URL": "'"$GRAFANA_URL"'" }')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MINIO_URL": "'"$MINIO_URL"'" }')"
# Update shared secret
aws secretsmanager update-secret \
--region ${AWS::Region} \
--secret-id openvidu-${AWS::Region}-${AWS::StackName} \
--secret-string "$SHARED_SECRET"
mode : "000755"
owner : "root"
group : "root"
'/usr/local/bin/update_config_from_secret.sh' :
content : !Sub |
#!/bin/bash
set -e
# Token for IMDSv2
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# Get current shared secret
SHARED_SECRET=$(aws secretsmanager get-secret-value \
--region ${AWS::Region} \
--secret-id openvidu-${AWS::Region}-${AWS::StackName} \
--query SecretString --output text)
# Installation directory
INSTALL_DIR="/opt/openvidu"
CONFIG_DIR="${!INSTALL_DIR}/config"
# Replace DOMAIN_NAME
export DOMAIN=$(echo $SHARED_SECRET | jq -r .DOMAIN_NAME)
if [[ -n "$DOMAIN" ]]; then
sed -i "s/DOMAIN_NAME=.*/DOMAIN_NAME=$DOMAIN/" "${!CONFIG_DIR}/openvidu.env"
else
exit 1
fi
# Replace LIVEKIT_TURN_DOMAIN_NAME
export LIVEKIT_TURN_DOMAIN_NAME=$(echo $SHARED_SECRET | jq -r .LIVEKIT_TURN_DOMAIN_NAME)
if [[ -n "$LIVEKIT_TURN_DOMAIN_NAME" ]]; then
sed -i "s/LIVEKIT_TURN_DOMAIN_NAME=.*/LIVEKIT_TURN_DOMAIN_NAME=$LIVEKIT_TURN_DOMAIN_NAME/" "${!CONFIG_DIR}/openvidu.env"
fi
# Replace rest of the values
sed -i "s/REDIS_PASSWORD=.*/REDIS_PASSWORD=$(echo $SHARED_SECRET | jq -r .REDIS_PASSWORD)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/MONGO_ADMIN_USERNAME=.*/MONGO_ADMIN_USERNAME=$(echo $SHARED_SECRET | jq -r .MONGO_ADMIN_USERNAME)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/MONGO_ADMIN_PASSWORD=.*/MONGO_ADMIN_PASSWORD=$(echo $SHARED_SECRET | jq -r .MONGO_ADMIN_PASSWORD)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/MONGO_REPLICA_SET_KEY=.*/MONGO_REPLICA_SET_KEY=$(echo $SHARED_SECRET | jq -r .MONGO_REPLICA_SET_KEY)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/DASHBOARD_ADMIN_USERNAME=.*/DASHBOARD_ADMIN_USERNAME=$(echo $SHARED_SECRET | jq -r .DASHBOARD_ADMIN_USERNAME)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/DASHBOARD_ADMIN_PASSWORD=.*/DASHBOARD_ADMIN_PASSWORD=$(echo $SHARED_SECRET | jq -r .DASHBOARD_ADMIN_PASSWORD)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/MINIO_ACCESS_KEY=.*/MINIO_ACCESS_KEY=$(echo $SHARED_SECRET | jq -r .MINIO_ACCESS_KEY)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/MINIO_SECRET_KEY=.*/MINIO_SECRET_KEY=$(echo $SHARED_SECRET | jq -r .MINIO_SECRET_KEY)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/GRAFANA_ADMIN_USERNAME=.*/GRAFANA_ADMIN_USERNAME=$(echo $SHARED_SECRET | jq -r .GRAFANA_ADMIN_USERNAME)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/GRAFANA_ADMIN_PASSWORD=.*/GRAFANA_ADMIN_PASSWORD=$(echo $SHARED_SECRET | jq -r .GRAFANA_ADMIN_PASSWORD)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/LIVEKIT_API_KEY=.*/LIVEKIT_API_KEY=$(echo $SHARED_SECRET | jq -r .LIVEKIT_API_KEY)/" "${!CONFIG_DIR}/openvidu.env"
sed -i "s/LIVEKIT_API_SECRET=.*/LIVEKIT_API_SECRET=$(echo $SHARED_SECRET | jq -r .LIVEKIT_API_SECRET)/" "${!CONFIG_DIR}/openvidu.env"
2025-08-28 13:58:03 +02:00
sed -i "s/MEET_INITIAL_ADMIN_USER=.*/MEET_INITIAL_ADMIN_USER=$(echo $SHARED_SECRET | jq -r .MEET_INITIAL_ADMIN_USER)/" "${!CONFIG_DIR}/meet.env"
sed -i "s/MEET_INITIAL_ADMIN_PASSWORD=.*/MEET_INITIAL_ADMIN_PASSWORD=$(echo $SHARED_SECRET | jq -r .MEET_INITIAL_ADMIN_PASSWORD)/" "${!CONFIG_DIR}/meet.env"
2025-09-15 22:51:57 +02:00
if [[ "${InitialMeetApiKey}" != '' ]]; then
sed -i "s/MEET_INITIAL_API_KEY=.*/MEET_INITIAL_API_KEY=$(echo $SHARED_SECRET | jq -r .MEET_INITIAL_API_KEY)/" "${!CONFIG_DIR}/meet.env"
fi
2025-04-22 11:46:24 +02:00
sed -i "s/ENABLED_MODULES=.*/ENABLED_MODULES=$(echo $SHARED_SECRET | jq -r .ENABLED_MODULES)/" "${!CONFIG_DIR}/openvidu.env"
# Update URLs in secret
2025-09-02 12:01:54 +02:00
OPENVIDU_URL="https://${!DOMAIN}/"
2025-09-02 17:30:50 +02:00
LIVEKIT_URL="wss://${!DOMAIN}/"
2025-04-22 11:46:24 +02:00
DASHBOARD_URL="https://${!DOMAIN}/dashboard/"
GRAFANA_URL="https://${!DOMAIN}/grafana/"
MINIO_URL="https://${!DOMAIN}/minio-console/"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DOMAIN_NAME": "'"$DOMAIN"'" }')"
2025-09-02 12:01:54 +02:00
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"OPENVIDU_URL": "'"$OPENVIDU_URL"'" }')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"LIVEKIT_URL": "'"$LIVEKIT_URL"'" }')"
2025-04-22 11:46:24 +02:00
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DASHBOARD_URL": "'"$DASHBOARD_URL"'" }')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"GRAFANA_URL": "'"$GRAFANA_URL"'" }')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MINIO_URL": "'"$MINIO_URL"'" }')"
aws secretsmanager update-secret \
--region ${AWS::Region} \
--secret-id openvidu-${AWS::Region}-${AWS::StackName} \
--secret-string "$SHARED_SECRET"
mode : "000755"
owner : "root"
group : "root"
'/usr/local/bin/update_secret_from_config.sh' :
content : !Sub |
#!/bin/bash
set -e
# Get current shared secret
SHARED_SECRET=$(aws secretsmanager get-secret-value \
--region ${AWS::Region} \
--secret-id openvidu-${AWS::Region}-${AWS::StackName} \
--query SecretString --output text)
# Installation directory
INSTALL_DIR="/opt/openvidu"
CONFIG_DIR="${!INSTALL_DIR}/config"
# Update shared secret
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"REDIS_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh REDIS_PASSWORD "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DOMAIN_NAME": "'"$(/usr/local/bin/get_value_from_config.sh DOMAIN_NAME "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"LIVEKIT_TURN_DOMAIN_NAME": "'"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_TURN_DOMAIN_NAME "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MONGO_ADMIN_USERNAME": "'"$(/usr/local/bin/get_value_from_config.sh MONGO_ADMIN_USERNAME "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MONGO_ADMIN_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh MONGO_ADMIN_PASSWORD "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MONGO_REPLICA_SET_KEY": "'"$(/usr/local/bin/get_value_from_config.sh MONGO_REPLICA_SET_KEY "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MINIO_ACCESS_KEY": "'"$(/usr/local/bin/get_value_from_config.sh MINIO_ACCESS_KEY "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MINIO_SECRET_KEY": "'"$(/usr/local/bin/get_value_from_config.sh MINIO_SECRET_KEY "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DASHBOARD_ADMIN_USERNAME": "'"$(/usr/local/bin/get_value_from_config.sh DASHBOARD_ADMIN_USERNAME "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DASHBOARD_ADMIN_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh DASHBOARD_ADMIN_PASSWORD "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"GRAFANA_ADMIN_USERNAME": "'"$(/usr/local/bin/get_value_from_config.sh GRAFANA_ADMIN_USERNAME "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"GRAFANA_ADMIN_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh GRAFANA_ADMIN_PASSWORD "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"LIVEKIT_API_KEY": "'"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_API_KEY "${!CONFIG_DIR}/openvidu.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"LIVEKIT_API_SECRET": "'"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_API_SECRET "${!CONFIG_DIR}/openvidu.env")"'"}')"
2025-08-28 13:58:03 +02:00
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MEET_INITIAL_ADMIN_USER": "'"$(/usr/local/bin/get_value_from_config.sh MEET_INITIAL_ADMIN_USER "${!CONFIG_DIR}/meet.env")"'"}')"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MEET_INITIAL_ADMIN_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh MEET_INITIAL_ADMIN_PASSWORD "${!CONFIG_DIR}/meet.env")"'"}')"
2025-09-15 22:51:57 +02:00
if [[ "${InitialMeetApiKey}" != '' ]]; then
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MEET_INITIAL_API_KEY": "'"$(/usr/local/bin/get_value_from_config.sh MEET_INITIAL_API_KEY "${!CONFIG_DIR}/meet.env")"'"}')"
fi
2025-04-22 11:46:24 +02:00
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"ENABLED_MODULES": "'"$(/usr/local/bin/get_value_from_config.sh ENABLED_MODULES "${!CONFIG_DIR}/openvidu.env")"'"}')"
# Update shared secret
aws secretsmanager update-secret \
--region ${AWS::Region} \
--secret-id openvidu-${AWS::Region}-${AWS::StackName} \
--secret-string "$SHARED_SECRET"
mode : "000755"
owner : "root"
group : "root"
'/usr/local/bin/get_value_from_config.sh' :
content : |
#!/bin/bash
set -e
# Function to get the value of a given key from the environment file
get_value() {
local key="$1"
local file_path="$2"
# Use grep to find the line with the key, ignoring lines starting with #
# Use awk to split on '=' and print the second field, which is the value
local value=$(grep -E "^\s*$key\s*=" "$file_path" | awk -F= '{print $2}' | sed 's/#.*//; s/^\s*//; s/\s*$//')
# If the value is empty, return "none"
if [ -z "$value" ]; then
echo "none"
else
echo "$value"
fi
}
# Check if the correct number of arguments are supplied
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <key> <file_path>"
exit 1
fi
# Get the key and file path from the arguments
key="$1"
file_path="$2"
# Get and print the value
get_value "$key" "$file_path"
mode : "000755"
owner : "root"
group : "root"
'/usr/local/bin/store_secret.sh' :
content : !Sub |
#!/bin/bash
set -e
# Modes: save, generate
# save mode: save the secret in the secret manager
# generate mode: generate a random password and save it in the secret manager
MODE="$1"
SHARED_SECRET="$(aws secretsmanager get-secret-value \
--region ${AWS::Region} \
--secret-id ${OpenViduSharedInfo} \
--query SecretString --output text)"
if [[ "$MODE" == "generate" ]]; then
SECRET_KEY_NAME="$2"
PREFIX="${!3:-}"
LENGTH="${!4:-44}"
RANDOM_PASSWORD="$(openssl rand -base64 64 | tr -d '+/=\n' | cut -c -${!LENGTH})"
RANDOM_PASSWORD="${!PREFIX}${!RANDOM_PASSWORD}"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"'"$SECRET_KEY_NAME"'": "'"$RANDOM_PASSWORD"'"}')"
aws secretsmanager update-secret \
--region ${AWS::Region} \
--secret-id ${OpenViduSharedInfo} \
--secret-string "$SHARED_SECRET" > /dev/null 2>&1
echo "$RANDOM_PASSWORD"
elif [[ "$MODE" == "save" ]]; then
SECRET_KEY_NAME="$2"
SECRET_VALUE="$3"
SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"'"$SECRET_KEY_NAME"'": "'"$SECRET_VALUE"'"}')"
aws secretsmanager update-secret \
--region ${AWS::Region} \
--secret-id ${OpenViduSharedInfo} \
--secret-string "$SHARED_SECRET" > /dev/null 2>&1
echo "$SECRET_VALUE"
else
exit 1
fi
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:7880 | head -n1 | awk '{print $2}')
if [ $HTTP_STATUS == 200 ]; then
break
fi
sleep 5
done
mode : "000755"
owner : "root"
group : "root"
'/usr/local/bin/restart.sh' :
content : |
#!/bin/bash
set -e
# Stop all services
systemctl stop openvidu
# Update config from secret
/usr/local/bin/update_config_from_secret.sh
# Start all services
systemctl start openvidu
mode : "000755"
owner : "root"
group : "root"
Properties :
2025-12-01 20:36:57 +01:00
ImageId : !If
- IsGraviton
- !FindInMap [ArmImage, !Ref OperatingSystem, ImageId]
- !FindInMap [AmdImage, !Ref OperatingSystem, ImageId]
2025-04-22 11:46:24 +02:00
LaunchTemplate :
# Enable IMDSv2 by default
2025-09-25 15:39:41 +02:00
LaunchTemplateId : !Ref IMDSv2LaunchTemplate
2025-04-22 11:46:24 +02:00
Version : !GetAtt IMDSv2LaunchTemplate.DefaultVersionNumber
InstanceType : !Ref InstanceType
IamInstanceProfile : !Ref OpenViduServerInstanceProfile
SecurityGroups :
- !Ref WebServerSecurityGroup
KeyName : !Ref KeyName
Tags :
- Key : Name
Value : !Ref 'AWS::StackName'
UserData :
Fn::Base64 : !Sub |
#!/bin/bash -x
set -eu -o pipefail
2025-12-16 12:49:34 +01:00
echo "DPkg::Lock::Timeout \"-1\";" > /etc/apt/apt.conf.d/99timeout
2025-04-22 11:46:24 +02:00
apt-get update && apt-get install -y \
python3-pip \
2025-09-06 20:41:39 +02:00
ec2-instance-connect
# Detect Ubuntu version and install cfn-bootstrap accordingly
UBUNTU_VERSION=$(lsb_release -rs | cut -d. -f1)
if [ "$UBUNTU_VERSION" -ge 24 ]; then
python3 -m pip install --break-system-packages https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-py3-latest.tar.gz
else
python3 -m pip install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-py3-latest.tar.gz
fi
2025-04-22 11:46:24 +02:00
cfn-init --region ${AWS::Region} --stack ${AWS::StackId} --resource OpenviduServer
export HOME="/root"
# Install OpenVidu
/usr/local/bin/install.sh || { echo "[OpenVidu] error installing OpenVidu"; exit 1; }
# Config S3 bucket
/usr/local/bin/config_s3.sh || { echo "[OpenVidu] error configuring S3 bucket"; exit 1; }
# Start OpenVidu
systemctl start openvidu || { echo "[OpenVidu] error starting OpenVidu"; exit 1; }
# Update shared secret
/usr/local/bin/after_install.sh || { echo "[OpenVidu] error updating shared secret"; exit 1; }
# Launch on reboot
echo "@reboot /usr/local/bin/restart.sh" | crontab
# Wait for the app
/usr/local/bin/check_app_ready.sh
# sending the finish call
2025-09-02 01:11:37 +02:00
cfn-signal -e $? --stack ${AWS::StackId} --resource WaitCondition --region ${AWS::Region}
2025-04-22 11:46:24 +02:00
BlockDeviceMappings :
- DeviceName : /dev/sda1
Ebs :
VolumeType : gp2
DeleteOnTermination : true
VolumeSize : 200
MyEIP :
Type : 'AWS::EC2::EIPAssociation'
Condition : PublicElasticIPPresent
Properties :
InstanceId : !Ref OpenviduServer
EIP : !Ref PublicElasticIP
2025-09-02 12:01:54 +02:00
NewEIP :
Type : 'AWS::EC2::EIP'
Condition : PublicElasticIPAbsent
Properties :
InstanceId : !Ref OpenviduServer
2025-04-22 11:46:24 +02:00
IMDSv2LaunchTemplate :
Type : AWS::EC2::LaunchTemplate
Properties :
2025-09-25 15:13:11 +02:00
LaunchTemplateName : !Sub openvidu-singlenode-${AWS::Region}-${AWS::StackName}
2025-04-22 11:46:24 +02:00
LaunchTemplateData :
MetadataOptions :
HttpEndpoint : enabled
HttpPutResponseHopLimit : 1
HttpTokens : required
WaitCondition :
Type : 'AWS::CloudFormation::WaitCondition'
CreationPolicy :
ResourceSignal :
Timeout : PT10M
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 : udp
FromPort : 443
ToPort : 443
CidrIp : 0.0 .0 .0 /0
- IpProtocol : udp
FromPort : 443
ToPort : 443
CidrIpv6 : : : /0
- IpProtocol : tcp
FromPort : 1935
ToPort : 1935
CidrIp : 0.0 .0 .0 /0
- IpProtocol : tcp
FromPort : 1935
ToPort : 1935
CidrIpv6 : : : /0
2025-07-11 21:33:05 +02:00
- IpProtocol : tcp
FromPort : 7881
ToPort : 7881
CidrIp : 0.0 .0 .0 /0
- IpProtocol : tcp
FromPort : 7881
ToPort : 7881
CidrIpv6 : : : /0
2025-04-22 11:46:24 +02:00
- IpProtocol : udp
FromPort : 7885
ToPort : 7885
CidrIp : 0.0 .0 .0 /0
- IpProtocol : udp
FromPort : 7885
ToPort : 7885
CidrIpv6 : : : /0
- IpProtocol : udp
FromPort : 50000
ToPort : 60000
CidrIp : 0.0 .0 .0 /0
- IpProtocol : udp
FromPort : 50000
ToPort : 60000
CidrIpv6 : : : /0
Outputs :
ServicesAndCredentials :
Description : Services and credentials
Value : !Sub https://${AWS::Region}.console.aws.amazon.com/secretsmanager/home?region=${AWS::Region}#!/secret?name=openvidu-${AWS::Region}-${AWS::StackName}