AWS CloudFormation allows to deploy cloud instances stacks by a certain template. Thus, a simple WCS CDN can be deployed for example. In this case, WCS update to the latest build and instance setup can be made with UserData scripts.
Below, there is the CloudFormation template example to deploy a simplest CDN of two WCS instances: Origin and Edge. The template alllows:
AWSTemplateFormatVersion: "2010-09-09" Description: "Create WCS CDN stack" Parameters: KeyName: Description: "Name of an existing EC2 KeyPair to enable SSH access to the instance" Type: AWS::EC2::KeyPair::KeyName ConstraintDescription: "must be the name of an existing EC2 KeyPair" InstanceName: Description: "Name of EC2 instance" Type: String ConstraintDescription: "must be a valid EC2 instance string name" InstanceType: Description: "Basic EC2 instance type" Type: String Default: m5.xlarge AllowedValues: [t1.micro, t2.nano, t2.micro, t2.small, t2.medium, t2.large, m1.small, m1.medium, m1.large, m1.xlarge, m2.xlarge, m2.2xlarge, m2.4xlarge, m3.medium, m3.large, m3.xlarge, m3.2xlarge, m4.large, m4.xlarge, m4.2xlarge, m4.4xlarge, m4.10xlarge, m5.xlarge, c1.medium, c1.xlarge, c3.large, c3.xlarge, c3.2xlarge, c3.4xlarge, c3.8xlarge, c4.large, c4.xlarge, c4.2xlarge, c4.4xlarge, c4.8xlarge, g2.2xlarge, g2.8xlarge, r3.large, r3.xlarge, r3.2xlarge, r3.4xlarge, r3.8xlarge, i2.xlarge, i2.2xlarge, i2.4xlarge, i2.8xlarge, d2.xlarge, d2.2xlarge, d2.4xlarge, d2.8xlarge, hi1.4xlarge, hs1.8xlarge, cr1.8xlarge, cc2.8xlarge, cg1.4xlarge] ConstraintDescription: "must be a valid EC2 instance type" ImageId: Description: "Basic instance ami (WebCallServer 5.2.944 AMI by default, mapped by region)" Type: String Default: WCSAMI ConstraintDescription: "must be a valid AMI ID" VpcId: Type: String Description: "VpcId of your existing Virtual Private Cloud (VPC)" SubnetId: Type: String Description: "SubnetId of an existing subnet in your Virtual Private Cloud (VPC)" SSHLocation: Description: "The IP address range that can be used to SSH to the EC2 instances" Type: String MinLength: 9 MaxLength: 18 Default: 0.0.0.0/0 AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) ConstraintDescription: "must be a valid IP CIDR range of the form x.x.x.x/x" JavaHeapSize: Description: "Maximum Java heap size in megabytes (2048m) or gigabytes (2g), 1024m by default" Type: String Default: 1024m UpdateWCS: Description: "Update WCS to the latest build" Type: String Default: true ConstraintDescription: "must be true or false" WCSLicense: Description: "WCS License key to activate (optional, if you do not use Marketplace AMI)" Type: String Default: "" InstallJava: Description: "Java installation helper script. Do not change in wizard!" Type: String Default: | JAVA_CMD=`command -v java 2>/dev/null` if [[ -z $JAVA_CMD ]]; then rm -rf jdk* curl -s https://download.java.net/java/GA/jdk14.0.1/664493ef4a6946b186ff29eb326336a2/7/GPL/openjdk-14.0.1_linux-x64_bin.tar.gz | tar -zx if [ -d jdk-14.0.1/bin ]; then mkdir -p /usr/java [ -d /usr/java/jdk-14.0.1 ] && rm -rf /usr/java/jdk-14.0.1 mv -f jdk-14.0.1 /usr/java if [ -d /usr/java/jdk-14.0.1/bin ]; then rm -f /usr/java/default ln -sf /usr/java/jdk-14.0.1 /usr/java/default update-alternatives --install /usr/bin/java java /usr/java/jdk-14.0.1/bin/java 1 update-alternatives --install /usr/bin/jstack jstack /usr/java/jdk-14.0.1/bin/jstack 1 update-alternatives --install /usr/bin/jcmd jcmd /usr/java/jdk-14.0.1/bin/jcmd 1 update-alternatives --install /usr/bin/jmap jmap /usr/java/jdk-14.0.1/bin/jmap 1 update-alternatives --set java /usr/java/jdk-14.0.1/bin/java update-alternatives --set jstack /usr/java/jdk-14.0.1/bin/jstack update-alternatives --set jcmd /usr/java/jdk-14.0.1/bin/jcmd update-alternatives --set jmap /usr/java/jdk-14.0.1/bin/jmap echo "JDK 14 installed" >> $DELPOY_LOG fi fi fi StopPreviousWCS: Description: "Stop previosly running WCS helper script. Do not change in wizard!" Type: String Default: | PID=`pgrep -f 'com.flashphoner.server.Server' | grep -v bash` if [ -n "$PID" ]; then systemctl stop webcallserver fi UpdateToLatestWCS: Description: "WCS update to latest build helper script. Do not change in wizard!" Type: String Default: | # Check if WCS is installed, and install latest build if not if [ ! -f /usr/local/FlashphonerWebCallServer/bin/webcallserver ]; then echo "No WCS installed, will install latest build" >> $DEPLOY_LOG UPDATE=true fi echo "Update WCS: $UPDATE" >> $DEPLOY_LOG if $UPDATE; then cd /tmp wget --timeout=10 --no-check-certificate https://flashphoner.com/download-wcs5.2-server.tar.gz -O wcs5-server.tar.gz if [ $? -eq 0 ]; then mkdir -p FlashphonerWebCallServer-5.2-latest && tar xzf wcs5-server.tar.gz -C FlashphonerWebCallServer-5.2-latest --strip-components 1 cd FlashphonerWebCallServer-5.2-latest chmod +x install.sh ./install.sh -silent cd .. rm -rf FlashphonerWebCallServer-5.2-latest wcs5-server.tar.gz echo "WCS updated to build $(cat /usr/local/FlashphonerWebCallServer/conf/WCS.version)" >> $DEPLOY_LOG fi fi ConfigureWCS: Description: "WCS configuration helper script. Do not change in wizard!" Type: String Default: | # Request keyframes from WebRTC publishers every 5 seconds echo -e "\n" >> $WCS_CONFIG echo -e "periodic_fir_request=true" >> $WCS_CONFIG # Disable RTMP keepalives to publish from OBS echo -e "keep_alive.enabled=websocket,rtmfp" >> $WCS_CONFIG # Configure heap settings sed -i -e "s/^\(-Xmx\).*\$/\1$HEAP_SIZE/" $JVM_CONFIG sed -i -e "s/^\(-Xms\).*\$/\1$HEAP_SIZE/" $JVM_CONFIG ActivateWCS: Description: "WCS activation helper script. Do not change in wizard!" Type: String Default: | if [[ ! -z $LICENSE ]]; then /usr/local/FlashphonerWebCallServer/bin/activation.sh $LICENSE fi StartWCS: Description: "WCS startup helper script. Do not change in wizard!" Type: String Default: | systemctl restart webcallserver # Disable internal firewall, ports are allowed/blocked on security group level iptables -F chown ec2-user $DEPLOY_LOG OriginCDNSetup: Description: "WCS Origin intsance setup helper script. Do not change in wizard!" Type: String Default: | echo -e "\n" >> $WCS_CONFIG echo -e "cdn_enabled=true" >> $WCS_CONFIG echo -e "cdn_ip=0.0.0.0" >> $WCS_CONFIG echo -e "cdn_point_of_entry=" >> $WCS_CONFIG echo -e "cdn_role=origin" >> $WCS_CONFIG echo -e "cdn_nodes_resolve_ip=false" >> $WCS_CONFIG EdgeCDNSetup: Description: "WCS Edge intsance setup helper script. Do not change in wizard!" Type: String Default: | echo -e "\n" >> $WCS_CONFIG echo -e "cdn_enabled=true" >> $WCS_CONFIG echo -e "cdn_ip=0.0.0.0" >> $WCS_CONFIG echo -e "cdn_point_of_entry=$ORIGIN_IP" >> $WCS_CONFIG echo -e "cdn_role=edge" >> $WCS_CONFIG echo -e "cdn_nodes_resolve_ip=false" >> $WCS_CONFIG Mappings: WCSAMI: eu-north-1: AMI: ami-0cd89cf8212fd90b4 ap-south-1: AMI: ami-0861cf9f8d387a5cf eu-west-3: AMI: ami-0f5d7f6dcaf0910e0 eu-west-2: AMI: ami-0d61a966487038aeb eu-west-1: AMI: ami-01c249ebee9077dbc ap-northeast-2: AMI: ami-023e68299437cbf78 ap-northeast-1: AMI: ami-0f01e9f19c3733d99 sa-east-1: AMI: ami-01d3d7a07e6e5beda ca-central-1: AMI: ami-0aa76aec8c64e3d52 ap-southeast-1: AMI: ami-044fd54e788e44ddc ap-southeast-2: AMI: ami-0a4f9a18ad123d2ad eu-central-1: AMI: ami-0f785dd5a9571d373 us-east-1: AMI: ami-038f9ebb3c87f88ac us-east-2: AMI: ami-0636213ac22f6ef45 us-west-1: AMI: ami-0de64b6cac0f8d81c us-west-2: AMI: ami-0c8543b7418393ad5 Conditions: GetMarketplaceImage: Fn::Equals: - Ref: 'ImageId' - WCSAMI Resources: WCSOriginInstance: Type: AWS::EC2::Instance Properties: Tags: - Key: "Name" Value: Fn::Join: - '-' - - !Ref 'InstanceName' - "edge" ImageId: !If [ GetMarketplaceImage, !FindInMap [ WCSAMI, !Ref 'AWS::Region', AMI ], !Ref 'ImageId' ] InstanceType: Ref: 'InstanceType' SubnetId: Ref: 'SubnetId' SecurityGroupIds: - Ref: 'WCSSecurityGroup' KeyName: Ref: 'KeyName' Monitoring: false UserData: Fn::Base64: Fn::Sub: | #!/bin/bash # Declare variables UPDATE=${UpdateWCS} HEAP_SIZE=${JavaHeapSize} LICENSE=${WCSLicense} # Declare config files to change WCS_CONFIG=/usr/local/FlashphonerWebCallServer/conf/flashphoner.properties JVM_CONFIG=/usr/local/FlashphonerWebCallServer/conf/wcs-core.properties # Declare deployment log DEPLOY_LOG=/home/ec2-user/deploy.log # Install Java 14 if needed ${InstallJava} # Stop WCS before reconfiguring ${StopPreviousWCS} # Update WCS to the latest build ${UpdateToLatestWCS} # Configuration setup ${ConfigureWCS} # CDN setup ${OriginCDNSetup} # Activate WCS license if provided ${ActivateWCS} # Start WCS after reconfiguring ${StartWCS} WCSEdgeInstance: Type: AWS::EC2::Instance DependsOn: - WCSOriginInstance Properties: Tags: - Key: "Name" Value: Fn::Join: - '-' - - !Ref 'InstanceName' - "edge" ImageId: !If [ GetMarketplaceImage, !FindInMap [ WCSAMI, !Ref 'AWS::Region', AMI ], !Ref 'ImageId' ] InstanceType: Ref: 'InstanceType' SubnetId: Ref: 'SubnetId' SecurityGroupIds: - Ref: 'WCSSecurityGroup' KeyName: Ref: 'KeyName' Monitoring: false UserData: Fn::Base64: Fn::Sub: | #!/bin/bash # Declare variables UPDATE=${UpdateWCS} HEAP_SIZE=${JavaHeapSize} LICENSE=${WCSLicense} ORIGIN_IP=${WCSOriginInstance.PrivateIp} # Declare config files to change WCS_CONFIG=/usr/local/FlashphonerWebCallServer/conf/flashphoner.properties JVM_CONFIG=/usr/local/FlashphonerWebCallServer/conf/wcs-core.properties # Declare deployment log DEPLOY_LOG=/home/ec2-user/deploy.log # Install Java 14 if needed ${InstallJava} # Stop WCS before reconfiguring ${StopPreviousWCS} # Update WCS to the latest build ${UpdateToLatestWCS} # Configuration setup ${ConfigureWCS} # CDN setup ${EdgeCDNSetup} # Activate WCS license if provided ${ActivateWCS} # Start WCS after reconfiguring ${StartWCS} WCSSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: VpcId: Ref: 'VpcId' GroupDescription: "Enable SSH, websocket, web interface ports and media ports" SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: Ref: 'SSHLocation' - IpProtocol: tcp FromPort: 554 ToPort: 554 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 1935 ToPort: 1935 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 3478 ToPort: 3478 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 8080 ToPort: 8084 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 8443 ToPort: 8445 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 8888 ToPort: 8888 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 9091 ToPort: 9091 CidrIp: 0.0.0.0/0 - IpProtocol: udp FromPort: 30000 ToPort: 33000 CidrIp: 0.0.0.0/0 - IpProtocol: tcp FromPort: 30000 ToPort: 33000 CidrIp: 0.0.0.0/0 Outputs: OriginWebsiteURL: Description: "URL for newly created WCS Origin instance web interface. Use instance id as admin password" Value: Fn::Join: - '' - - "https://" - !GetAtt WCSOriginInstance.PublicDnsName - ":8444/admin/" OriginInstanceId: Value: Ref: 'WCSOriginInstance' Description: "Instance Id of newly created WCS Origin instance" OriginPrivateIp: Value: !GetAtt WCSOriginInstance.PrivateIp Description: "Private IP address of the Origin instance" OriginPublicIp: Value: !GetAtt WCSOriginInstance.PublicIp Description: "Public IP address of the Origin instance" EdgeWebsiteURL: Description: "URL for newly created WCS Edge instance web interface. Use instance id as admin password" Value: Fn::Join: - '' - - "https://" - !GetAtt WCSEdgeInstance.PublicDnsName - ":8444/admin/" EdgeInstanceId: Value: Ref: 'WCSEdgeInstance' Description: "Instance Id of newly created WCS Edge instance" EdgePrivateIp: Value: !GetAtt WCSEdgeInstance.PrivateIp Description: "Private IP address of the Edge instance" EdgePublicIp: Value: !GetAtt WCSEdgeInstance.PublicIp Description: "Public IP address of the Edge instance" |
1. Sing in to your AWS account, go to desired region and open CloudFormation in Services menu. Click "Create Stack"
2. Choose "Upload a template file", click "Choose file" and upload the example template
3. When template is uploaded, click Next
4. Enter stack name
5. Enter Amazon Linux 2 AMI ID for region chosen, or leave WCSAMI (in this case, AWS Marketplace WCS AMI will be used with hourly billing)
6. Enter basic part of instance name (-origin and -edge will be added respectively), choose instance type, enter Java heap size and choose SSH key to access stack instances
7. Set subnet Id
8. Enter "true" to automatically update WCS to the latest build
9. Set VPC Id
10. If Marketplace WCS AMI is not used, enter the license key to activate on instances and click Next
11. Add tags and set permissions if necessary
12. Set advanced stack options if necessary, then click Next
13. Review stack parameters
14. Click "Create stack"
15. Wait for stack creation completion
16. Go to Outputs tab
17. Open Origin and Edge web interfaces, publish the stream test to Origin using Two Way Streaming example, then play the stream on Edge