mirror of https://github.com/OpenVidu/openvidu.git
376 lines
12 KiB
YAML
376 lines
12 KiB
YAML
AWSTemplateFormatVersion: 2010-09-09
|
|
Description: External TURN server for OpenVidu Server.
|
|
|
|
Parameters:
|
|
|
|
PublicElasticIP:
|
|
Description: "Previously created AWS Elastic IP to associate it to the EC2 instance. 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 and it is mandatory
|
|
|
|
MyDomainName:
|
|
Description: "Valid domain name pointing to previous IP. 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
|
|
|
|
LetsEncryptEmail:
|
|
Description: "This email will be used for Let's Encrypt notifications"
|
|
AllowedPattern: ^(.+)@(.+)$
|
|
Type: String
|
|
|
|
TurnStaticAuthSecret:
|
|
Description: "Shared secret for the TURN server to generate credentials for clients"
|
|
Type: String
|
|
NoEcho: true
|
|
AllowedPattern: .+$
|
|
ConstraintDescription: Turn secret is mandatory.
|
|
|
|
InstanceType:
|
|
Description: "Specifies the EC2 instance type for your TURN 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 to the TURN server."
|
|
Type: 'AWS::EC2::KeyPair::KeyName'
|
|
ConstraintDescription: "must be the name of an existing EC2 KeyPair"
|
|
|
|
Metadata:
|
|
'AWS::CloudFormation::Interface':
|
|
ParameterGroups:
|
|
- Label:
|
|
default: Domain and SSL certificate configuration
|
|
Parameters:
|
|
- PublicElasticIP
|
|
- MyDomainName
|
|
- LetsEncryptEmail
|
|
- Label:
|
|
default: Turn server configuration
|
|
Parameters:
|
|
- TurnStaticAuthSecret
|
|
- Label:
|
|
default: EC2 Instance configuration
|
|
Parameters:
|
|
- InstanceType
|
|
- KeyName
|
|
|
|
ParameterLabels:
|
|
# SSL certificate configuration
|
|
PublicElasticIP:
|
|
default: "AWS Elastic IP (EIP)"
|
|
MyDomainName:
|
|
default: "Domain Name pointing to Elastic IP"
|
|
LetsEncryptEmail:
|
|
default: "Email for Let's Encrypt (letsencrypt)"
|
|
# OpenVidu configuration
|
|
TurnStaticAuthSecret:
|
|
default: >
|
|
Turn shared secret. This is used to generate credentials and should be in OpenVidu Server configuration.
|
|
# EC2 Instance configuration
|
|
InstanceType:
|
|
default: "Instance type"
|
|
KeyName:
|
|
default: "SSH Key"
|
|
# Other configuration
|
|
|
|
Resources:
|
|
|
|
DescribeImagesRole:
|
|
Type: AWS::IAM::Role
|
|
Properties:
|
|
AssumeRolePolicyDocument:
|
|
Version: '2012-10-17'
|
|
Statement:
|
|
- Action: sts:AssumeRole
|
|
Effect: Allow
|
|
Principal:
|
|
Service: lambda.amazonaws.com
|
|
ManagedPolicyArns:
|
|
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
|
|
Policies:
|
|
- PolicyName: DescribeImages
|
|
PolicyDocument:
|
|
Version: '2012-10-17'
|
|
Statement:
|
|
- Action: ec2:DescribeImages
|
|
Effect: Allow
|
|
Resource: "*"
|
|
|
|
GetLatestUbuntuAmi:
|
|
Type: AWS::Lambda::Function
|
|
Properties:
|
|
Handler: index.handler
|
|
Role: !Sub ${DescribeImagesRole.Arn}
|
|
Timeout: 60
|
|
Runtime: python3.11
|
|
Code:
|
|
ZipFile: |
|
|
import boto3
|
|
import cfnresponse
|
|
import json
|
|
import traceback
|
|
|
|
def handler(event, context):
|
|
try:
|
|
response = boto3.client('ec2').describe_images(Filters=[
|
|
{'Name': 'name', 'Values': [event['ResourceProperties']['Name']]},
|
|
{'Name': 'owner-alias', 'Values': ['amazon']}
|
|
])
|
|
amis = sorted(response['Images'], key=lambda x: x['CreationDate'], reverse=True)
|
|
id = amis[0]['ImageId']
|
|
cfnresponse.send(event, context, cfnresponse.SUCCESS, {}, id)
|
|
except:
|
|
traceback.print_last()
|
|
cfnresponse.send(event, context, cfnresponse.FAIL, {}, "ok")
|
|
UbuntuAmi:
|
|
Type: Custom::FindAMI
|
|
Properties:
|
|
ServiceToken: !Sub ${GetLatestUbuntuAmi.Arn}
|
|
Name: "*ubuntu/images/hvm-ssd/ubuntu-noble-24.04-amd64-server-*"
|
|
|
|
TurnServerInstance:
|
|
Type: 'AWS::EC2::Instance'
|
|
Metadata:
|
|
Comment: 'Install External TURN server for OpenVidu Server'
|
|
AWS::CloudFormation::Init:
|
|
config:
|
|
files:
|
|
'/usr/local/bin/install_docker.sh':
|
|
content: |
|
|
#!/bin/bash
|
|
|
|
# Check if docker is already installed
|
|
if ! command -v docker &> /dev/null; then
|
|
# Install docker
|
|
apt-get -y update
|
|
apt-get -y install \
|
|
ca-certificates \
|
|
curl \
|
|
gnupg
|
|
|
|
mkdir -m 0755 -p /etc/apt/keyrings
|
|
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
|
echo \
|
|
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
|
|
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
|
|
tee /etc/apt/sources.list.d/docker.list > /dev/null
|
|
apt-get -y update
|
|
|
|
apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
|
fi
|
|
mode: "000755"
|
|
owner: "root"
|
|
group: "root"
|
|
'/usr/local/bin/coturn.sh':
|
|
content: !Sub |
|
|
#!/bin/bash -x
|
|
WORKIND_DIR=/opt/coturn
|
|
cd /opt
|
|
|
|
# Check if directory /opt/coturn exists
|
|
# If it does not exist, it means it is the first time we run this script
|
|
# and we need to install coturn and fill the .env file
|
|
if [ ! -d "$WORKIND_DIR" ]; then
|
|
# This means it is the first time we run this script
|
|
curl https://s3.eu-west-1.amazonaws.com/aws.openvidu.io/external-turn/4.6.2/install_openvidu_external_coturn.sh | bash
|
|
cd "$WORKIND_DIR"
|
|
# Replace environment variables
|
|
sed -i "s|TURN_DOMAIN_NAME=.*|TURN_DOMAIN_NAME=${MyDomainName}|" .env
|
|
sed -i "s|LETSENCRYPT_EMAIL=.*|LETSENCRYPT_EMAIL=${LetsEncryptEmail}|" .env
|
|
sed -i "s|TURN_STATIC_AUTH_SECRET=.*|TURN_STATIC_AUTH_SECRET=${TurnStaticAuthSecret}|" .env
|
|
fi
|
|
|
|
cd "$WORKIND_DIR"
|
|
docker compose down
|
|
docker compose up -d
|
|
mode: "000755"
|
|
owner: "root"
|
|
group: "root"
|
|
'/usr/local/bin/wait_for_coturn.sh':
|
|
content: !Sub |
|
|
#!/bin/bash -x
|
|
|
|
# Configuration
|
|
SERVER="${MyDomainName}"
|
|
PORT="443"
|
|
TIMEOUT=600 # 10 minutes in seconds
|
|
INTERVAL=10 # Time interval between attempts in seconds
|
|
TARGET_EXIT_CODE=0
|
|
|
|
start_time=$(date +%s)
|
|
|
|
while true; do
|
|
current_time=$(date +%s)
|
|
elapsed_time=$((current_time - start_time))
|
|
|
|
if [ $elapsed_time -ge $TIMEOUT ]; then
|
|
echo "Time limit reached: $TIMEOUT seconds"
|
|
exit 1
|
|
fi
|
|
|
|
# Run the command and get the exit code
|
|
docker exec coturn turnutils_stunclient -p $PORT $SERVER
|
|
exit_code=$?
|
|
|
|
if [ $exit_code -eq $TARGET_EXIT_CODE ]; then
|
|
echo "Coturn is ready"
|
|
exit 0
|
|
else
|
|
echo "Coturn is not ready yet. Waiting $INTERVAL seconds before the next attempt..."
|
|
sleep $INTERVAL
|
|
fi
|
|
done
|
|
mode: "000755"
|
|
owner: "root"
|
|
group: "root"
|
|
Properties:
|
|
ImageId: !Ref UbuntuAmi
|
|
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
|
|
|
|
apt-get update && apt-get install -y \
|
|
python3-pip \
|
|
ec2-instance-connect
|
|
pip3 install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-py3-latest.tar.gz
|
|
|
|
cfn-init --region ${AWS::Region} --stack ${AWS::StackId} --resource TurnServerInstance
|
|
|
|
/usr/local/bin/install_docker.sh
|
|
|
|
export HOME="/root"
|
|
|
|
# Check if crontab has already been configured
|
|
if ! crontab -l | grep -q "coturn.sh"; then
|
|
# Configure crontab
|
|
echo "@reboot /usr/local/bin/coturn.sh" | crontab
|
|
fi
|
|
|
|
# Run coturn
|
|
/usr/local/bin/coturn.sh
|
|
|
|
# Wait for coturn to be ready
|
|
/usr/local/bin/wait_for_coturn.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: 25
|
|
|
|
MyEIP:
|
|
Type: 'AWS::EC2::EIPAssociation'
|
|
Properties:
|
|
InstanceId: !Ref TurnServerInstance
|
|
EIP: !Ref PublicElasticIP
|
|
|
|
WaitCondition:
|
|
Type: 'AWS::CloudFormation::WaitCondition'
|
|
CreationPolicy:
|
|
ResourceSignal:
|
|
Timeout: PT30M
|
|
Count: '1'
|
|
|
|
WebServerSecurityGroup:
|
|
Type: 'AWS::EC2::SecurityGroup'
|
|
Properties:
|
|
GroupDescription: SSH, Proxy and Turn necessaty 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
|
|
|
|
Outputs:
|
|
TurnServerURI:
|
|
Description: Use this URL to connect the TURN Server
|
|
Value: !Sub 'turns://${MyDomainName}:443?transport=tcp'
|