diff --git a/openvidu-deployment/pro/ha/aws/cf-openvidu-ha-internal-tls.yaml b/openvidu-deployment/pro/ha/aws/cf-openvidu-ha-internal-tls.yaml deleted file mode 100644 index 3d0db46a..00000000 --- a/openvidu-deployment/pro/ha/aws/cf-openvidu-ha-internal-tls.yaml +++ /dev/null @@ -1,2394 +0,0 @@ -AWSTemplateFormatVersion: 2010-09-09 -Description: OpenVidu Pro - High Availability - -Parameters: - DomainName: - Type: String - Description: Domain name for the OpenVidu High Availability cluster - 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 - - TurnDomainName: - Description: '(Optional) Domain name for the TURN server with TLS.' - Type: String - Default: '' - - OpenViduLicense: - Description: "Visit https://openvidu.io/account" - Type: String - AllowedPattern: ^(?!\s*$).+$ - NoEcho: true - ConstraintDescription: OpenVidu Pro License is mandatory - - RTCEngine: - Description: "RTCEngine media engine to use" - Type: String - AllowedValues: - - pion - - mediasoup - Default: pion - - MasterNodeInstanceType: - Description: "Specifies the EC2 instance type for your OpenVidu Master Node" - Type: String - Default: c6a.xlarge - AllowedValues: - - t2.large - - t2.xlarge - - t2.2xlarge - - t3.medium - - 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 - - m6i.large - - m6i.xlarge - - m6i.2xlarge - - m6i.4xlarge - - m6i.8xlarge - - m6i.12xlarge - - m6i.16xlarge - - m6i.24xlarge - - m6i.32xlarge - - m6i.metal - - 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 - - c6i.large - - c6i.xlarge - - c6i.2xlarge - - c6i.4xlarge - - c6i.8xlarge - - c6i.12xlarge - - c6i.16xlarge - - c6i.24xlarge - - c6i.32xlarge - - c6i.metal - - 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 - - c7i.large - - c7i.xlarge - - c7i.2xlarge - - c7i.4xlarge - - c7i.8xlarge - - c7i.12xlarge - - c7i.16xlarge - - c7i.24xlarge - - c7i.48xlarge - - c7i.metal-24xl - - c7i.metal-48xl - - c5n.large - - c5n.xlarge - - c5n.2xlarge - - c5n.4xlarge - - c5n.9xlarge - - c5n.18xlarge - - m5n.large - - m5n.xlarge - - m5n.2xlarge - - m5n.4xlarge - - m5n.8xlarge - - m5n.12xlarge - - m5n.16xlarge - - m5n.24xlarge - - m6in.large - - m6in.xlarge - - m6in.2xlarge - - m6in.4xlarge - - m6in.8xlarge - - m6in.12xlarge - - m6in.16xlarge - - m6in.24xlarge - - m6in.32xlarge - - r5n.large - - r5n.xlarge - - r5n.2xlarge - - r5n.4xlarge - - r5n.8xlarge - - r5n.12xlarge - - r5n.16xlarge - - r5n.24xlarge - ConstraintDescription: "Must be a valid EC2 instance type" - - MediaNodeInstanceType: - Description: "Specifies the EC2 instance type for your OpenVidu Media Nodes" - Type: String - Default: c6a.xlarge - AllowedValues: - - t2.large - - t2.xlarge - - t2.2xlarge - - t3.medium - - 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 - - m6i.large - - m6i.xlarge - - m6i.2xlarge - - m6i.4xlarge - - m6i.8xlarge - - m6i.12xlarge - - m6i.16xlarge - - m6i.24xlarge - - m6i.32xlarge - - m6i.metal - - 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 - - c6i.large - - c6i.xlarge - - c6i.2xlarge - - c6i.4xlarge - - c6i.8xlarge - - c6i.12xlarge - - c6i.16xlarge - - c6i.24xlarge - - c6i.32xlarge - - c6i.metal - - 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 - - c7i.large - - c7i.xlarge - - c7i.2xlarge - - c7i.4xlarge - - c7i.8xlarge - - c7i.12xlarge - - c7i.16xlarge - - c7i.24xlarge - - c7i.48xlarge - - c7i.metal-24xl - - c7i.metal-48xl - - c5n.large - - c5n.xlarge - - c5n.2xlarge - - c5n.4xlarge - - c5n.9xlarge - - c5n.18xlarge - - m5n.large - - m5n.xlarge - - m5n.2xlarge - - m5n.4xlarge - - m5n.8xlarge - - m5n.12xlarge - - m5n.16xlarge - - m5n.24xlarge - - m6in.large - - m6in.xlarge - - m6in.2xlarge - - m6in.4xlarge - - m6in.8xlarge - - m6in.12xlarge - - m6in.16xlarge - - m6in.24xlarge - - m6in.32xlarge - - r5n.large - - r5n.xlarge - - r5n.2xlarge - - r5n.4xlarge - - r5n.8xlarge - - r5n.12xlarge - - r5n.16xlarge - - r5n.24xlarge - 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 instances - AllowedPattern: ^.+$ - ConstraintDescription: must be the name of an existing EC2 KeyPair. - - AmiId: - Type: AWS::SSM::Parameter::Value - Default: /aws/service/canonical/ubuntu/server/jammy/stable/current/amd64/hvm/ebs-gp2/ami-id - Description: AMI ID for the EC2 instances - - InitialNumberOfMediaNodes: - Type: Number - Default: 1 - Description: Number of initial media nodes to deploy - - MinNumberOfMediaNodes: - Type: Number - Default: 1 - Description: Minimum number of media nodes to deploy - - MaxNumberOfMediaNodes: - Type: Number - Default: 5 - Description: Maximum number of media nodes to deploy - - ScaleTargetCPU: - Type: Number - Default: 50 - Description: Target CPU percentage to scale up or down - - S3AppDataBucketName: - Type: String - Description: Name of the S3 bucket to store data and recordings. If empty, a bucket will be created - - S3ClusterDataBucketName: - Type: String - Description: Name of the S3 bucket to store cluster data. If empty, a bucket will be created - - OpenViduVPC: - Description: "Dedicated VPC for OpenVidu cluster" - Type: AWS::EC2::VPC::Id - AllowedPattern: ^.+$ - ConstraintDescription: You must specify a VPC ID - - OpenViduMasterNodeSubnets: - Description: "Subnets for OpenVidu Master Node" - Type: List - AllowedPattern: ^.+$ - ConstraintDescription: You must specify a list of subnet IDs - - OpenViduMediaNodeSubnets: - Description: "Subnets for OpenVidu Media Nodes" - Type: List - AllowedPattern: ^.+$ - ConstraintDescription: You must specify a list of subnet IDs - - MasterNodesDiskSize: - Description: Size of the disk in GB - Type: Number - Default: 100 - MinValue: 50 - ConstraintDescription: The disk size must be at least 50 GB - -Metadata: - 'AWS::CloudFormation::Interface': - ParameterGroups: - - Label: - default: Domain and Load Blancer configuration - Parameters: - - DomainName - - Label: - default: OpenVidu High Availability configuration - Parameters: - - OpenViduLicense - - RTCEngine - - Label: - default: EC2 Instance configuration - Parameters: - - MasterNodeInstanceType - - MediaNodeInstanceType - - KeyName - - AmiId - - Label: - default: Media Nodes Autoscaling Group configuration - Parameters: - - InitialNumberOfMediaNodes - - MinNumberOfMediaNodes - - MaxNumberOfMediaNodes - - ScaleTargetCPU - - Label: - default: S3 bucket for application data, cluster data and recordings - Parameters: - - S3AppDataBucketName - - S3ClusterDataBucketName - - Label: - default: VPC configuration - Parameters: - - OpenViduVPC - - OpenViduMasterNodeSubnets - - OpenViduMediaNodeSubnets - - Label: - default: Volumes configuration - Parameters: - - MasterNodesDiskSize - - Label: - default: (Optional) TURN server configuration with TLS - Parameters: - - TurnDomainName - -Conditions: - TurnTLSIsEnabled: !Not [!Equals [!Ref TurnDomainName, ""]] - CreateRecordingsBucket: !Equals [!Ref S3AppDataBucketName, ""] - CreateClusterDataBucket: !Equals [!Ref S3ClusterDataBucketName, ""] - -Resources: - - OpenViduSharedInfo: - Type: AWS::SecretsManager::Secret - UpdateReplacePolicy: Retain - DeletionPolicy: Delete - Properties: - Name: !Sub openvidu-ha-${AWS::Region}-${AWS::StackName} - Description: Secret for OpenVidu High Availability to store deployment info and seed secret - # All the values are initialized by one master node and shared with the rest of the nodes - SecretString: | - { - "ALL_SECRETS_GENERATED": "false", - "DOMAIN_NAME": "none", - "LIVEKIT_TURN_DOMAIN_NAME": "none", - "OPENVIDU_PRO_LICENSE": "none", - "OPENVIDU_RTC_ENGINE": "none", - "REDIS_PASSWORD": "none", - "MONGO_ADMIN_USERNAME": "none", - "MONGO_ADMIN_PASSWORD": "none", - "MONGO_REPLICA_SET_KEY": "none", - "MINIO_URL": "none", - "MINIO_ACCESS_KEY": "none", - "MINIO_SECRET_KEY": "none", - "DASHBOARD_URL": "none", - "DASHBOARD_ADMIN_USERNAME": "none", - "DASHBOARD_ADMIN_PASSWORD": "none", - "GRAFANA_URL": "none", - "GRAFANA_ADMIN_USERNAME": "none", - "GRAFANA_ADMIN_PASSWORD": "none", - "DEFAULT_APP_USERNAME": "none", - "DEFAULT_APP_PASSWORD": "none", - "DEFAULT_APP_ADMIN_USERNAME": "none", - "DEFAULT_APP_ADMIN_PASSWORD": "none", - "LIVEKIT_API_KEY": "none", - "LIVEKIT_API_SECRET": "none", - "ENABLED_MODULES": "none", - "MASTER_NODE_1_PRIVATE_IP": "none", - "MASTER_NODE_2_PRIVATE_IP": "none", - "MASTER_NODE_3_PRIVATE_IP": "none", - "MASTER_NODE_4_PRIVATE_IP": "none", - "OPENVIDU_VERSION": "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 - - S3ClusterDataBucketResource: - Type: 'AWS::S3::Bucket' - Properties: - ### Unique bucket name using Stack ID - BucketName: !Join ["-" , [ 'openvidu-clusterdata', !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: CreateClusterDataBucket - - # ------------------------- - # Preprocess subnets to allocate Volumes and ENIs across Availability Zones - # For OpenVidu Master Nodes - # ------------------------- - SubnetProcessorFunction: - Type: AWS::Lambda::Function - Properties: - FunctionName: !Sub 'SubnetProcessor-${AWS::Region}-${AWS::StackName}' - Handler: index.lambda_handler - Role: !GetAtt LambdaExecutionRole.Arn - Code: - ZipFile: | - import cfnresponse - import boto3 - - def lambda_handler(event, context): - try: - # Process event data - subnets = event['ResourceProperties']['Subnets'] - ec2 = boto3.client('ec2') - - # Ensure we have at least four subnets by cycling through the available subnets - subnets = (subnets * 4)[:4] # Repeat the list to have at least 4 elements and then take the first 4 - - # Prepare the response - responseData = { - 'Subnet1': subnets[0], - 'Subnet2': subnets[1], - 'Subnet3': subnets[2], - 'Subnet4': subnets[3], - } - cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData) - - except Exception as e: - cfnresponse.send(event, context, cfnresponse.FAILED, {'Message': str(e)}) - - - Runtime: python3.12 - Timeout: 120 - - SubnetProcessor: - Type: Custom::SubnetProcessor - Properties: - ServiceToken: !GetAtt SubnetProcessorFunction.Arn - Subnets: !Ref OpenViduMasterNodeSubnets - - LambdaLogGroup: - UpdateReplacePolicy: Retain - DeletionPolicy: Delete - Type: AWS::Logs::LogGroup - Properties: - LogGroupName: !Sub '/aws/lambda/SubnetProcessor-${AWS::Region}-${AWS::StackName}' - RetentionInDays: 7 - - LambdaExecutionRole: - Type: AWS::IAM::Role - Properties: - AssumeRolePolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Principal: - Service: - - lambda.amazonaws.com - Action: 'sts:AssumeRole' - Policies: - - PolicyName: LambdaLogsPolicy - PolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Action: - - logs:CreateLogStream - - logs:PutLogEvents - Resource: !Sub 'arn:${AWS::Partition}:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/SubnetProcessor-${AWS::Region}-${AWS::StackName}:*' - - Effect: Allow - Action: - - ec2:DescribeSubnets - Resource: '*' - - OpenViduMasterNodeRole: - 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-master-policy-${AWS::Region}-${AWS::StackName} - PolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Action: - - autoscaling:SetInstanceHealth - Resource: '*' - Condition: - StringEquals: - 'aws:ResourceTag/aws:cloudformation:stack-id': !Ref 'AWS::StackId' - - 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} - - Fn::If: - - CreateClusterDataBucket - - Effect: Allow - Action: - - s3:DeleteObject - - s3:GetObject - - s3:PutObject - Resource: !Sub ${S3ClusterDataBucketResource.Arn}/* - - Effect: Allow - Action: - - s3:DeleteObject - - s3:GetObject - - s3:PutObject - Resource: !Sub arn:${AWS::Partition}:s3:::${S3ClusterDataBucketName}/* - - Fn::If: - - CreateClusterDataBucket - - Effect: Allow - Action: - - s3:ListBucket - - s3:GetBucketLocation - Resource: !GetAtt S3ClusterDataBucketResource.Arn - - Effect: Allow - Action: - - s3:ListBucket - - s3:GetBucketLocation - Resource: !Sub arn:${AWS::Partition}:s3:::${S3ClusterDataBucketName} - RoleName: - Fn::Join: - # Generate a not too long and unique role name - # Getting a unique identifier from the stack id - - '' - - - openvidu-master-role- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - - OpenViduMediaNodeRole: - Type: 'AWS::IAM::Role' - Properties: - AssumeRolePolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Principal: - Service: - - ec2.amazonaws.com - Action: - - 'sts:AssumeRole' - Path: / - ManagedPolicyArns: - - !Sub arn:${AWS::Partition}:iam::aws:policy/AmazonSSMManagedInstanceCore - Policies: - - PolicyName: !Sub openvidu-media-policy-${AWS::Region}-${AWS::StackName} - PolicyDocument: - Version: 2012-10-17 - Statement: - - Effect: Allow - Action: - - secretsmanager:GetSecretValue - Resource: !Ref OpenViduSharedInfo - - Effect: Allow - Action: - - autoscaling:SetInstanceHealth - - autoscaling:CompleteLifecycleAction - - autoscaling:RecordLifecycleActionHeartbeat - Resource: '*' - Condition: - StringEquals: - 'aws:ResourceTag/aws:cloudformation:stack-name': !Ref 'AWS::StackName' - - 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-media-role- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - - OpenViduMasterInstanceProfile: - Type: AWS::IAM::InstanceProfile - Properties: - InstanceProfileName: !Sub OpenViduMasterInstanceProfile-${AWS::Region}-${AWS::StackName} - Roles: - - !Ref OpenViduMasterNodeRole - - OpenViduMediaInstanceProfile: - Type: AWS::IAM::InstanceProfile - DependsOn: - - MasterNodesWaitCondition4 - Properties: - InstanceProfileName: !Sub OpenViduMediaInstanceProfile-${AWS::Region}-${AWS::StackName} - Roles: - - !Ref OpenViduMediaNodeRole - - OpenViduMasterLaunchTemplate: - Type: AWS::EC2::LaunchTemplate - Metadata: - Comment: Launch template for OpenVidu Master Node - AWS::CloudFormation::Init: - config: - files: - '/usr/local/bin/install.sh': - content: !Sub | - #!/bin/bash -x - set -e - OPENVIDU_VERSION=main - DOMAIN= - YQ_VERSION=v4.44.5 - - # Install dependencies - apt-get update && apt-get install -y \ - curl \ - unzip \ - jq \ - wget - wget https://github.com/mikefarah/yq/releases/download/${!YQ_VERSION}/yq_linux_amd64.tar.gz -O - |\ - tar xz && mv yq_linux_amd64 /usr/bin/yq - - # Install aws-cli - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - unzip -qq awscliv2.zip - ./aws/install - rm -rf awscliv2.zip aws - - # Singal to notify instance is waiting - SIGNAL_NAME="$1" - - # Token for IMDSv2 - TOKEN="$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")" - - # Subnets IDs - SUBNETS=( - "${SubnetProcessor.Subnet1}" - "${SubnetProcessor.Subnet2}" - "${SubnetProcessor.Subnet3}" - "${SubnetProcessor.Subnet4}" - ) - - MAC_ADDRESS="$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254//latest/meta-data/mac)" - SUBNET_ID="$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s "http://169.254.169.254/latest/meta-data/network/interfaces/macs/$MAC_ADDRESS/subnet-id")" - - # Check master node number - MASTER_NODE_NUM=1 - for subnet in "${!SUBNETS[@]}"; do - if [[ "$subnet" == "$SUBNET_ID" ]]; then - - SHARED_SECRET=$(aws secretsmanager get-secret-value \ - --region ${AWS::Region} \ - --secret-id openvidu-ha-${AWS::Region}-${AWS::StackName} \ - --query SecretString --output text || echo 'none') - - # Check if current master node is reacheable with ping - ACUTAL_MASTER_NODE_IP=$(echo "$SHARED_SECRET" | jq -r ".MASTER_NODE_${!MASTER_NODE_NUM}_PRIVATE_IP") - if [[ "$ACUTAL_MASTER_NODE_IP" == "none" ]]; then - break - fi - fi - MASTER_NODE_NUM=$((MASTER_NODE_NUM + 1)) - done - - # Get own private IP - PRIVATE_IP="$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/local-ipv4)" - - if [[ "$PRIVATE_IP" == "" ]]; then - echo "Error: Private IP not found" - exit 1 - fi - - # Store current private IP - /usr/local/bin/store_secret.sh save MASTER_NODE_${!MASTER_NODE_NUM}_PRIVATE_IP "${!PRIVATE_IP}" - - SHARED_SECRET=$(aws secretsmanager get-secret-value \ - --region ${AWS::Region} \ - --secret-id openvidu-ha-${AWS::Region}-${AWS::StackName} \ - --query SecretString --output text) - ALL_SECRETS_GENERATED=$(echo "$SHARED_SECRET" | jq -r '.ALL_SECRETS_GENERATED') - - # If the private IP is the same as the first master node, generate the secrets - if [[ $MASTER_NODE_NUM -eq 1 ]] && [[ "$ALL_SECRETS_GENERATED" == "false" ]]; then - DOMAIN="$(/usr/local/bin/store_secret.sh save DOMAIN_NAME "${DomainName}")" - if [[ -n "${TurnDomainName}" ]]; then - LIVEKIT_TURN_DOMAIN_NAME="$(/usr/local/bin/store_secret.sh save LIVEKIT_TURN_DOMAIN_NAME "${TurnDomainName}")" - fi - OPENVIDU_PRO_LICENSE="$(/usr/local/bin/store_secret.sh save OPENVIDU_PRO_LICENSE "${OpenViduLicense}")" - OPENVIDU_RTC_ENGINE="$(/usr/local/bin/store_secret.sh save OPENVIDU_RTC_ENGINE "${RTCEngine}")" - # Store version so media nodes can use it to install the same version - /usr/local/bin/store_secret.sh save OPENVIDU_VERSION "${!OPENVIDU_VERSION}" - - # 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)" - DEFAULT_APP_USERNAME="$(/usr/local/bin/store_secret.sh save DEFAULT_APP_USERNAME "calluser")" - DEFAULT_APP_PASSWORD="$(/usr/local/bin/store_secret.sh generate DEFAULT_APP_PASSWORD)" - DEFAULT_APP_ADMIN_USERNAME="$(/usr/local/bin/store_secret.sh save DEFAULT_APP_ADMIN_USERNAME "calladmin")" - DEFAULT_APP_ADMIN_PASSWORD="$(/usr/local/bin/store_secret.sh generate DEFAULT_APP_ADMIN_PASSWORD)" - 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)" - ENABLED_MODULES="$(/usr/local/bin/store_secret.sh save ENABLED_MODULES "observability,v2compatibility,app")" - ALL_SECRETS_GENERATED="$(/usr/local/bin/store_secret.sh save ALL_SECRETS_GENERATED "true")" - fi - - # Fetch the shared secret again - SHARED_SECRET=$(aws secretsmanager get-secret-value \ - --region ${AWS::Region} \ - --secret-id openvidu-ha-${AWS::Region}-${AWS::StackName} \ - --query SecretString --output text) - - ALL_SECRETS_GENERATED=$(echo "$SHARED_SECRET" | jq -r '.ALL_SECRETS_GENERATED') - if [[ "${!ALL_SECRETS_GENERATED}" == "false" ]]; then - echo "Error: Secrets not generated" - exit 1 - fi - - # sending the signal call - cfn-signal -e $? --stack ${AWS::StackId} --resource "$SIGNAL_NAME" --region ${AWS::Region} - - # Wait for all master nodes to store their private IPs - while true; do - SHARED_SECRET=$(aws secretsmanager get-secret-value \ - --region ${AWS::Region} \ - --secret-id openvidu-ha-${AWS::Region}-${AWS::StackName} \ - --query SecretString --output text || echo 'none') - - MASTER_NODE_1_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_1_PRIVATE_IP') - MASTER_NODE_2_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_2_PRIVATE_IP') - MASTER_NODE_3_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_3_PRIVATE_IP') - MASTER_NODE_4_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_4_PRIVATE_IP') - - # Check if all master nodes have stored their private IPs - if [[ "$MASTER_NODE_1_PRIVATE_IP" != "none" ]] && - [[ "$MASTER_NODE_2_PRIVATE_IP" != "none" ]] && - [[ "$MASTER_NODE_3_PRIVATE_IP" != "none" ]] && - [[ "$MASTER_NODE_4_PRIVATE_IP" != "none" ]]; then - break - fi - sleep 5 - done - - SHARED_SECRET=$(aws secretsmanager get-secret-value \ - --region ${AWS::Region} \ - --secret-id openvidu-ha-${AWS::Region}-${AWS::StackName} \ - --query SecretString --output text) - - MASTER_NODE_1_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_1_PRIVATE_IP') - MASTER_NODE_2_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_2_PRIVATE_IP') - MASTER_NODE_3_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_3_PRIVATE_IP') - MASTER_NODE_4_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_4_PRIVATE_IP') - MASTER_NODE_PRIVATE_IP_LIST="$MASTER_NODE_1_PRIVATE_IP,$MASTER_NODE_2_PRIVATE_IP,$MASTER_NODE_3_PRIVATE_IP,$MASTER_NODE_4_PRIVATE_IP" - - DOMAIN=$(echo "$SHARED_SECRET" | jq -r '.DOMAIN_NAME') - LIVEKIT_TURN_DOMAIN_NAME=$(echo "$SHARED_SECRET" | jq -r '.LIVEKIT_TURN_DOMAIN_NAME') - OPENVIDU_PRO_LICENSE=$(echo "$SHARED_SECRET" | jq -r '.OPENVIDU_PRO_LICENSE') - OPENVIDU_RTC_ENGINE=$(echo "$SHARED_SECRET" | jq -r '.OPENVIDU_RTC_ENGINE') - REDIS_PASSWORD=$(echo "$SHARED_SECRET" | jq -r '.REDIS_PASSWORD') - MONGO_ADMIN_USERNAME=$(echo "$SHARED_SECRET" | jq -r '.MONGO_ADMIN_USERNAME') - MONGO_ADMIN_PASSWORD=$(echo "$SHARED_SECRET" | jq -r '.MONGO_ADMIN_PASSWORD') - MONGO_REPLICA_SET_KEY=$(echo "$SHARED_SECRET" | jq -r '.MONGO_REPLICA_SET_KEY') - MINIO_ACCESS_KEY=$(echo "$SHARED_SECRET" | jq -r '.MINIO_ACCESS_KEY') - MINIO_SECRET_KEY=$(echo "$SHARED_SECRET" | jq -r '.MINIO_SECRET_KEY') - DASHBOARD_ADMIN_USERNAME=$(echo "$SHARED_SECRET" | jq -r '.DASHBOARD_ADMIN_USERNAME') - DASHBOARD_ADMIN_PASSWORD=$(echo "$SHARED_SECRET" | jq -r '.DASHBOARD_ADMIN_PASSWORD') - GRAFANA_ADMIN_USERNAME=$(echo "$SHARED_SECRET" | jq -r '.GRAFANA_ADMIN_USERNAME') - GRAFANA_ADMIN_PASSWORD=$(echo "$SHARED_SECRET" | jq -r '.GRAFANA_ADMIN_PASSWORD') - DEFAULT_APP_USERNAME=$(echo "$SHARED_SECRET" | jq -r '.DEFAULT_APP_USERNAME') - DEFAULT_APP_PASSWORD=$(echo "$SHARED_SECRET" | jq -r '.DEFAULT_APP_PASSWORD') - DEFAULT_APP_ADMIN_USERNAME=$(echo "$SHARED_SECRET" | jq -r '.DEFAULT_APP_ADMIN_USERNAME') - DEFAULT_APP_ADMIN_PASSWORD=$(echo "$SHARED_SECRET" | jq -r '.DEFAULT_APP_ADMIN_PASSWORD') - LIVEKIT_API_KEY=$(echo "$SHARED_SECRET" | jq -r '.LIVEKIT_API_KEY') - LIVEKIT_API_SECRET=$(echo "$SHARED_SECRET" | jq -r '.LIVEKIT_API_SECRET') - ENABLED_MODULES=$(echo "$SHARED_SECRET" | jq -r '.ENABLED_MODULES') - - # Base command - INSTALL_COMMAND="sh <(curl -fsSL http://get.openvidu.io/pro/ha/$OPENVIDU_VERSION/install_ov_master_node.sh)" - - # Common arguments - COMMON_ARGS=( - "--no-tty" - "--install" - "--environment=aws" - "--deployment-type='ha'" - "--node-role='master-node'" - "--external-load-balancer" - "--internal-tls-termination" - "--master-node-private-ip-list='$MASTER_NODE_PRIVATE_IP_LIST'" - "--openvidu-pro-license='$OPENVIDU_PRO_LICENSE'" - "--domain-name='$DOMAIN'" - "--enabled-modules='$ENABLED_MODULES'" - "--rtc-engine=$OPENVIDU_RTC_ENGINE" - "--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" - "--default-app-user=$DEFAULT_APP_USERNAME" - "--default-app-password=$DEFAULT_APP_PASSWORD" - "--default-app-admin-user=$DEFAULT_APP_ADMIN_USERNAME" - "--default-app-admin-password=$DEFAULT_APP_ADMIN_PASSWORD" - "--livekit-api-key=$LIVEKIT_API_KEY" - "--livekit-api-secret=$LIVEKIT_API_SECRET" - "--certificate-type='letsencrypt'" - "--letsencrypt-email='openvidu@gmail.com'" - ) - - if [[ "${!LIVEKIT_TURN_DOMAIN_NAME}" != "none" ]]; then - COMMON_ARGS+=("--turn-domain-name='${!LIVEKIT_TURN_DOMAIN_NAME}'") - fi - - # Construct the final command - FINAL_COMMAND="$INSTALL_COMMAND $(printf "%s " "${!COMMON_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" - CLUSTER_CONFIG_DIR="${!INSTALL_DIR}/config/cluster" - - # 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=${S3AppDataBucketResourceName} - EXTERNAL_S3_BUCKET_CLUSTER_DATA=${S3ClusterDataBucketResourceName} - sed -i "s|EXTERNAL_S3_ENDPOINT=.*|EXTERNAL_S3_ENDPOINT=$EXTERNAL_S3_ENDPOINT|" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s|EXTERNAL_S3_REGION=.*|EXTERNAL_S3_REGION=$EXTERNAL_S3_REGION|" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s|EXTERNAL_S3_PATH_STYLE_ACCESS=.*|EXTERNAL_S3_PATH_STYLE_ACCESS=$EXTERNAL_S3_PATH_STYLE_ACCESS|" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s|EXTERNAL_S3_BUCKET_APP_DATA=.*|EXTERNAL_S3_BUCKET_APP_DATA=$EXTERNAL_S3_BUCKET_APP_DATA|" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s|EXTERNAL_S3_BUCKET_CLUSTER_DATA=.*|EXTERNAL_S3_BUCKET_CLUSTER_DATA=$EXTERNAL_S3_BUCKET_CLUSTER_DATA|" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - - S3AppDataBucketResourceName: !If - - CreateRecordingsBucket - - !Ref S3AppDataBucketResource - - !Ref S3AppDataBucketName - S3ClusterDataBucketResourceName: !If - - CreateClusterDataBucket - - !Ref S3ClusterDataBucketResource - - !Ref S3ClusterDataBucketName - 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-ha-${AWS::Region}-${AWS::StackName} \ - --query SecretString --output text) - - # Save access URLs - DOMAIN=$(echo "$SHARED_SECRET" | jq -r '.DOMAIN_NAME') - 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"'"}')" - 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-ha-${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-ha-${AWS::Region}-${AWS::StackName} \ - --query SecretString --output text) - - # Installation directory - INSTALL_DIR="/opt/openvidu" - CLUSTER_CONFIG_DIR="${!INSTALL_DIR}/config/cluster" - MASTER_NODE_CONFIG_DIR="${!INSTALL_DIR}/config/node" - - # Replace DOMAIN_NAME - export DOMAIN=$(echo $SHARED_SECRET | jq -r .DOMAIN_NAME) - if [[ -n "$DOMAIN" ]]; then - sed -i "s/DOMAIN_NAME=.*/DOMAIN_NAME=$DOMAIN/" "${!CLUSTER_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/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - fi - - # Replace rest of the values - sed -i "s/REDIS_PASSWORD=.*/REDIS_PASSWORD=$(echo $SHARED_SECRET | jq -r .REDIS_PASSWORD)/" "${!MASTER_NODE_CONFIG_DIR}/master_node.env" - sed -i "s/OPENVIDU_RTC_ENGINE=.*/OPENVIDU_RTC_ENGINE=$(echo $SHARED_SECRET | jq -r .OPENVIDU_RTC_ENGINE)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/OPENVIDU_PRO_LICENSE=.*/OPENVIDU_PRO_LICENSE=$(echo $SHARED_SECRET | jq -r .OPENVIDU_PRO_LICENSE)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/MONGO_ADMIN_USERNAME=.*/MONGO_ADMIN_USERNAME=$(echo $SHARED_SECRET | jq -r .MONGO_ADMIN_USERNAME)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/MONGO_ADMIN_PASSWORD=.*/MONGO_ADMIN_PASSWORD=$(echo $SHARED_SECRET | jq -r .MONGO_ADMIN_PASSWORD)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/DASHBOARD_ADMIN_USERNAME=.*/DASHBOARD_ADMIN_USERNAME=$(echo $SHARED_SECRET | jq -r .DASHBOARD_ADMIN_USERNAME)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/DASHBOARD_ADMIN_PASSWORD=.*/DASHBOARD_ADMIN_PASSWORD=$(echo $SHARED_SECRET | jq -r .DASHBOARD_ADMIN_PASSWORD)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/MINIO_ACCESS_KEY=.*/MINIO_ACCESS_KEY=$(echo $SHARED_SECRET | jq -r .MINIO_ACCESS_KEY)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/MINIO_SECRET_KEY=.*/MINIO_SECRET_KEY=$(echo $SHARED_SECRET | jq -r .MINIO_SECRET_KEY)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/GRAFANA_ADMIN_USERNAME=.*/GRAFANA_ADMIN_USERNAME=$(echo $SHARED_SECRET | jq -r .GRAFANA_ADMIN_USERNAME)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/GRAFANA_ADMIN_PASSWORD=.*/GRAFANA_ADMIN_PASSWORD=$(echo $SHARED_SECRET | jq -r .GRAFANA_ADMIN_PASSWORD)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/LIVEKIT_API_KEY=.*/LIVEKIT_API_KEY=$(echo $SHARED_SECRET | jq -r .LIVEKIT_API_KEY)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/LIVEKIT_API_SECRET=.*/LIVEKIT_API_SECRET=$(echo $SHARED_SECRET | jq -r .LIVEKIT_API_SECRET)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - sed -i "s/CALL_USER=.*/CALL_USER=$(echo $SHARED_SECRET | jq -r .DEFAULT_APP_USERNAME)/" "${!CLUSTER_CONFIG_DIR}/master_node/app.env" - sed -i "s/CALL_SECRET=.*/CALL_SECRET=$(echo $SHARED_SECRET | jq -r .DEFAULT_APP_PASSWORD)/" "${!CLUSTER_CONFIG_DIR}/master_node/app.env" - sed -i "s/CALL_ADMIN_USER=.*/CALL_ADMIN_USER=$(echo $SHARED_SECRET | jq -r .DEFAULT_APP_ADMIN_USERNAME)/" "${!CLUSTER_CONFIG_DIR}/master_node/app.env" - sed -i "s/CALL_ADMIN_SECRET=.*/CALL_ADMIN_SECRET=$(echo $SHARED_SECRET | jq -r .DEFAULT_APP_ADMIN_PASSWORD)/" "${!CLUSTER_CONFIG_DIR}/master_node/app.env" - sed -i "s/ENABLED_MODULES=.*/ENABLED_MODULES=$(echo $SHARED_SECRET | jq -r .ENABLED_MODULES)/" "${!CLUSTER_CONFIG_DIR}/openvidu.env" - - # Update URLs in secret - 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"'" }')" - 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-ha-${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-ha-${AWS::Region}-${AWS::StackName} \ - --query SecretString --output text) - - # Installation directory - INSTALL_DIR="/opt/openvidu" - CLUSTER_CONFIG_DIR="${!INSTALL_DIR}/config/cluster" - MASTER_NODE_CONFIG_DIR="${!INSTALL_DIR}/config/node" - - - # Update shared secret - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"REDIS_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh REDIS_PASSWORD "${!MASTER_NODE_CONFIG_DIR}/master_node.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DOMAIN_NAME": "'"$(/usr/local/bin/get_value_from_config.sh DOMAIN_NAME "${!CLUSTER_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 "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"OPENVIDU_RTC_ENGINE": "'"$(/usr/local/bin/get_value_from_config.sh OPENVIDU_RTC_ENGINE "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"OPENVIDU_PRO_LICENSE": "'"$(/usr/local/bin/get_value_from_config.sh OPENVIDU_PRO_LICENSE "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MONGO_ADMIN_USERNAME": "'"$(/usr/local/bin/get_value_from_config.sh MONGO_ADMIN_USERNAME "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MONGO_ADMIN_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh MONGO_ADMIN_PASSWORD "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MINIO_ACCESS_KEY": "'"$(/usr/local/bin/get_value_from_config.sh MINIO_ACCESS_KEY "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"MINIO_SECRET_KEY": "'"$(/usr/local/bin/get_value_from_config.sh MINIO_SECRET_KEY "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DASHBOARD_ADMIN_USERNAME": "'"$(/usr/local/bin/get_value_from_config.sh DASHBOARD_ADMIN_USERNAME "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DASHBOARD_ADMIN_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh DASHBOARD_ADMIN_PASSWORD "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"GRAFANA_ADMIN_USERNAME": "'"$(/usr/local/bin/get_value_from_config.sh GRAFANA_ADMIN_USERNAME "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"GRAFANA_ADMIN_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh GRAFANA_ADMIN_PASSWORD "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"LIVEKIT_API_KEY": "'"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_API_KEY "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"LIVEKIT_API_SECRET": "'"$(/usr/local/bin/get_value_from_config.sh LIVEKIT_API_SECRET "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DEFAULT_APP_USERNAME": "'"$(/usr/local/bin/get_value_from_config.sh CALL_USER "${!CLUSTER_CONFIG_DIR}/master_node/app.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DEFAULT_APP_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh CALL_SECRET "${!CLUSTER_CONFIG_DIR}/master_node/app.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DEFAULT_APP_ADMIN_USERNAME": "'"$(/usr/local/bin/get_value_from_config.sh CALL_ADMIN_USER "${!CLUSTER_CONFIG_DIR}/master_node/app.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"DEFAULT_APP_ADMIN_PASSWORD": "'"$(/usr/local/bin/get_value_from_config.sh CALL_ADMIN_SECRET "${!CLUSTER_CONFIG_DIR}/master_node/app.env")"'"}')" - SHARED_SECRET="$(echo "$SHARED_SECRET" | jq '. + {"ENABLED_MODULES": "'"$(/usr/local/bin/get_value_from_config.sh ENABLED_MODULES "${!CLUSTER_CONFIG_DIR}/openvidu.env")"'"}')" - - # Update shared secret - aws secretsmanager update-secret \ - --region ${AWS::Region} \ - --secret-id openvidu-ha-${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 " - 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/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: - LaunchTemplateName: !Sub 'openvidu-ha-master-${AWS::Region}-${AWS::StackName}' - LaunchTemplateData: - # Enable IMDSv2 - MetadataOptions: - HttpEndpoint: enabled - HttpPutResponseHopLimit: 1 - HttpTokens: required - IamInstanceProfile: - Name: !Ref OpenViduMasterInstanceProfile - ImageId: !Ref AmiId - InstanceType: !Ref MasterNodeInstanceType - KeyName: !Ref KeyName - SecurityGroupIds: - - !Ref OpenViduMasterNodeSG - BlockDeviceMappings: - - DeviceName: /dev/sda1 - Ebs: - VolumeSize: !Ref MasterNodesDiskSize - VolumeType: gp3 - DeleteOnTermination: true - - OpenViduMasterNode1: - Type: AWS::EC2::Instance - Properties: - LaunchTemplate: - LaunchTemplateId: !Ref OpenViduMasterLaunchTemplate - Version: !GetAtt OpenViduMasterLaunchTemplate.LatestVersionNumber - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - Master Node 1 - SubnetId: !GetAtt SubnetProcessor.Subnet1 - UserData: - Fn::Base64: !Sub | - #!/bin/bash - 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 -v --region ${AWS::Region} --stack ${AWS::StackName} --resource OpenViduMasterLaunchTemplate - - # Install OpenVidu - /usr/local/bin/install.sh "MasterNodesWaitCondition1" || { 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 &> /var/log/openvidu-restart.log" | crontab - - - MasterNodesWaitCondition1: - Type: 'AWS::CloudFormation::WaitCondition' - CreationPolicy: - ResourceSignal: - Timeout: PT10M - Count: '1' - - OpenViduMasterNode2: - Type: AWS::EC2::Instance - DependsOn: MasterNodesWaitCondition1 - Properties: - LaunchTemplate: - LaunchTemplateId: !Ref OpenViduMasterLaunchTemplate - Version: !GetAtt OpenViduMasterLaunchTemplate.LatestVersionNumber - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - Master Node 2 - SubnetId: !GetAtt SubnetProcessor.Subnet2 - UserData: - Fn::Base64: !Sub | - #!/bin/bash - 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 -v --region ${AWS::Region} --stack ${AWS::StackName} --resource OpenViduMasterLaunchTemplate - - # Install OpenVidu - /usr/local/bin/install.sh "MasterNodesWaitCondition2" || { 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 &> /var/log/openvidu-restart.log" | crontab - - - MasterNodesWaitCondition2: - Type: 'AWS::CloudFormation::WaitCondition' - CreationPolicy: - ResourceSignal: - Timeout: PT10M - Count: '1' - - OpenViduMasterNode3: - Type: AWS::EC2::Instance - DependsOn: MasterNodesWaitCondition2 - Properties: - LaunchTemplate: - LaunchTemplateId: !Ref OpenViduMasterLaunchTemplate - Version: !GetAtt OpenViduMasterLaunchTemplate.LatestVersionNumber - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - Master Node 3 - SubnetId: !GetAtt SubnetProcessor.Subnet3 - UserData: - Fn::Base64: !Sub | - #!/bin/bash - 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 -v --region ${AWS::Region} --stack ${AWS::StackName} --resource OpenViduMasterLaunchTemplate - - # Install OpenVidu - /usr/local/bin/install.sh "MasterNodesWaitCondition3" || { 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 - systemctl enable crond.service - systemctl start crond.service - echo "@reboot /usr/local/bin/restart.sh &> /var/log/openvidu-restart.log" | crontab - - - MasterNodesWaitCondition3: - Type: 'AWS::CloudFormation::WaitCondition' - CreationPolicy: - ResourceSignal: - Timeout: PT10M - Count: '1' - - OpenViduMasterNode4: - Type: AWS::EC2::Instance - DependsOn: MasterNodesWaitCondition3 - Properties: - LaunchTemplate: - LaunchTemplateId: !Ref OpenViduMasterLaunchTemplate - Version: !GetAtt OpenViduMasterLaunchTemplate.LatestVersionNumber - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - Master Node 4 - SubnetId: !GetAtt SubnetProcessor.Subnet4 - UserData: - Fn::Base64: !Sub | - #!/bin/bash - 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 -v --region ${AWS::Region} --stack ${AWS::StackName} --resource OpenViduMasterLaunchTemplate - - # Install OpenVidu - /usr/local/bin/install.sh "MasterNodesWaitCondition4" || { 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 - systemctl enable crond.service - systemctl start crond.service - echo "@reboot /usr/local/bin/restart.sh &> /var/log/openvidu-restart.log" | crontab - - MasterNodesWaitCondition4: - Type: 'AWS::CloudFormation::WaitCondition' - CreationPolicy: - ResourceSignal: - Timeout: PT10M - Count: '1' - - OpenViduMediaNodeLaunchTemplate: - Type: AWS::EC2::LaunchTemplate - Metadata: - Comment: Launch template for OpenVidu Media Node - AWS::CloudFormation::Init: - config: - files: - '/usr/local/bin/install.sh': - content: !Sub | - #!/bin/bash - set -e - YQ_VERSION=v4.44.5 - - # Install dependencies - apt-get update && apt-get install -y \ - curl \ - unzip \ - jq \ - wget - wget https://github.com/mikefarah/yq/releases/download/${!YQ_VERSION}/yq_linux_amd64.tar.gz -O - |\ - tar xz && mv yq_linux_amd64 /usr/bin/yq - - # Install aws-cli - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - 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")" - - # Get own private IP - PRIVATE_IP="$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/local-ipv4)" - - SHARED_SECRET="$(aws secretsmanager get-secret-value \ - --region ${AWS::Region} \ - --secret-id openvidu-ha-${AWS::Region}-${AWS::StackName} \ - --query SecretString --output text || echo 'none')" - if [[ "$SHARED_SECRET" == "none" ]]; then - echo "Error: Shared secret not found" - exit 1 - fi - - # Get OpenVidu Media Nodes version to deploy - OPENVIDU_VERSION=$(echo "$SHARED_SECRET" | jq -r '.OPENVIDU_VERSION') - if [[ "$OPENVIDU_VERSION" == "none" ]]; then - echo "OpenVidu version not found" - exit 1 - fi - - ALL_SECRETS_GENERATED=$(echo "$SHARED_SECRET" | jq -r '.ALL_SECRETS_GENERATED') - if [[ "$ALL_SECRETS_GENERATED" == "none" ]]; then - echo "Error: Secrets not generated" - exit 1 - fi - MASTER_NODE_1_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_1_PRIVATE_IP') - MASTER_NODE_2_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_2_PRIVATE_IP') - MASTER_NODE_3_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_3_PRIVATE_IP') - MASTER_NODE_4_PRIVATE_IP=$(echo "$SHARED_SECRET" | jq -r '.MASTER_NODE_4_PRIVATE_IP') - MASTER_NODE_PRIVATE_IP_LIST="$MASTER_NODE_1_PRIVATE_IP,$MASTER_NODE_2_PRIVATE_IP,$MASTER_NODE_3_PRIVATE_IP,$MASTER_NODE_4_PRIVATE_IP" - REDIS_PASSWORD=$(echo "$SHARED_SECRET" | jq -r '.REDIS_PASSWORD') - - # Base command - INSTALL_COMMAND="sh <(curl -fsSL http://get.openvidu.io/pro/ha/$OPENVIDU_VERSION/install_ov_media_node.sh)" - - # Common arguments - COMMON_ARGS=( - "--no-tty" - "--install" - "--environment=aws" - "--deployment-type='ha'" - "--node-role='media-node'" - "--master-node-private-ip-list=$MASTER_NODE_PRIVATE_IP_LIST" - "--private-ip=$PRIVATE_IP" - "--redis-password=$REDIS_PASSWORD" - ) - - # Construct the final command with all arguments - FINAL_COMMAND="$INSTALL_COMMAND $(printf "%s " "${!COMMON_ARGS[@]}")" - - # Install OpenVidu - exec bash -c "$FINAL_COMMAND" - mode: '000755' - owner: root - group: root - '/usr/local/bin/set_as_unhealthy.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 own instance ID - INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id) - - # Set instance as unhealthy - aws autoscaling set-instance-health \ - --region ${AWS::Region} \ - --instance-id "$INSTANCE_ID" \ - --health-status Unhealthy - mode: "000755" - owner: "root" - group: "root" - '/usr/local/bin/stop_media_node.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 own instance ID - INSTANCE_ID=$(curl -s -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id) - ASG_NAME=openvidu-ha-media-asg-${AWS::Region}-${AWS::StackName} - - # Execute if docker is installed - if [ -x "$(command -v docker)" ]; then - echo "Stopping media node services and waiting for termination..." - docker container kill --signal=SIGQUIT openvidu || true - docker container kill --signal=SIGQUIT ingress || true - docker container kill --signal=SIGQUIT egress || true - TIME_PASSED=0 - HEARTBEAT_MAX=1800 - # Wait for running containers to not be openvidu, ingress or egress - while [ $(docker inspect -f '{{.State.Running}}' openvidu 2>/dev/null) == "true" ] || \ - [ $(docker inspect -f '{{.State.Running}}' ingress 2>/dev/null) == "true" ] || \ - [ $(docker inspect -f '{{.State.Running}}' egress 2>/dev/null) == "true" ]; do - echo "Waiting for containers to stop..." - sleep 5 - TIME_PASSED=$((TIME_PASSED+5)) - if [ $TIME_PASSED -ge $HEARTBEAT_MAX ]; then - echo "Increase lifecycle hook timeout to continue waiting for termination" - # Increase lifecycle hook timeout - aws autoscaling record-lifecycle-action-heartbeat \ - --region ${AWS::Region} \ - --lifecycle-hook-name StopMediaNodeLifecycleHook-${AWS::Region}-${AWS::StackName} \ - --auto-scaling-group-name "$ASG_NAME" \ - --instance-id "$INSTANCE_ID" - TIME_PASSED=0 - fi - done - fi - - aws autoscaling complete-lifecycle-action \ - --region ${AWS::Region} \ - --lifecycle-hook-name StopMediaNodeLifecycleHook-${AWS::Region}-${AWS::StackName} \ - --auto-scaling-group-name "$ASG_NAME" \ - --lifecycle-action-result CONTINUE \ - --instance-id "$INSTANCE_ID" - mode: "000755" - owner: "root" - group: "root" - Properties: - LaunchTemplateName: !Sub 'openvidu-ha-media-${AWS::Region}-${AWS::StackName}' - LaunchTemplateData: - # Enable IMDSv2 by default - MetadataOptions: - HttpEndpoint: enabled - HttpPutResponseHopLimit: 1 - HttpTokens: required - IamInstanceProfile: - Arn: !GetAtt OpenViduMediaInstanceProfile.Arn - SecurityGroupIds: - - !GetAtt OpenViduMediaNodeSG.GroupId - ImageId: !Ref AmiId - KeyName: !Ref KeyName - InstanceType: !Ref MediaNodeInstanceType - UserData: - Fn::Base64: !Sub | - #!/bin/bash - 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 OpenViduMediaNodeLaunchTemplate - - export HOME="/root" - - # Install OpenVidu - /usr/local/bin/install.sh || { echo "[OpenVidu] error installing OpenVidu"; /usr/local/bin/set_as_unhealthy.sh; exit 1; } - - # Start OpenVidu - systemctl start openvidu || { echo "[OpenVidu] error starting OpenVidu"; /usr/local/bin/set_as_unhealthy.sh; exit 1; } - - # Wait for the app - # /usr/local/bin/check_app_ready.sh - BlockDeviceMappings: - - DeviceName: /dev/sda1 - Ebs: - VolumeType: gp3 - DeleteOnTermination: true - VolumeSize: 50 - - OpenViduMediaNodeASG: - DependsOn: - - OpenViduMediaInstanceProfile - - OpenViduMasterInstanceProfile - - StopMediaNodeCloudWatchEventRule - Type: AWS::AutoScaling::AutoScalingGroup - Properties: - AutoScalingGroupName: !Sub openvidu-ha-media-asg-${AWS::Region}-${AWS::StackName} - LaunchTemplate: - LaunchTemplateId: !Ref OpenViduMediaNodeLaunchTemplate - Version: !GetAtt OpenViduMediaNodeLaunchTemplate.DefaultVersionNumber - MinSize: !Ref MinNumberOfMediaNodes - MaxSize: !Ref MaxNumberOfMediaNodes - DesiredCapacity: !Ref InitialNumberOfMediaNodes - VPCZoneIdentifier: !Ref OpenViduMediaNodeSubnets - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - Media Node - PropagateAtLaunch: true - - StopMediaNodeLifecycleHook: - Type: 'AWS::AutoScaling::LifecycleHook' - Properties: - LifecycleHookName: !Sub StopMediaNodeLifecycleHook-${AWS::Region}-${AWS::StackName} - AutoScalingGroupName: !Ref OpenViduMediaNodeASG - LifecycleTransition: 'autoscaling:EC2_INSTANCE_TERMINATING' - DefaultResult: 'CONTINUE' - HeartbeatTimeout: 3600 - - StopMediaNodeDocumentRole: - Type: AWS::IAM::Role - Properties: - AssumeRolePolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Principal: - Service: - - ssm.amazonaws.com - Action: - - sts:AssumeRole - Policies: - - PolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Action: - - ssm:DescribeInstanceInformation - - ssm:ListCommands - - ssm:ListCommandInvocations - Resource: "*" - - Effect: Allow - Action: - - ssm:SendCommand - Resource: !Sub arn:${AWS::Partition}:ssm:${AWS::Region}::document/AWS-RunShellScript - - Action: - - ssm:SendCommand - Resource: !Sub arn:${AWS::Partition}:ec2:*:*:instance/* - Condition: - StringEquals: - 'aws:ResourceTag/aws:cloudformation:stack-name': !Ref 'AWS::StackName' - Effect: Allow - PolicyName: SSM-Automation-Policy - - StopMediaNodeAutomationDocument: - Type: AWS::SSM::Document - Properties: - Name: - Fn::Join: - # Generate a not too long and unique document name - # Getting a unique identifier from the stack id - - '' - - - 'StopMediaNodeAutomationDocument-' - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - DocumentType: Automation - Content: - schemaVersion: '0.3' - assumeRole: "{{automationAssumeRole}}" - description: This document stops the OpenVidu services in a Media Node and - terminates the instance. It stop the OpenVidu services without interrupting - the running sessions, ingress and egress running in the Media Node. - Also it sends a CONTINUE signal to the Auto Scaling Group to continue the - instance termination when the services are stopped. - parameters: - InstanceId: - type: String - automationAssumeRole: - type: String - default: !GetAtt StopMediaNodeDocumentRole.Arn - description: "(Required) The ARN of the role that allows Automation to - perform the actions." - mainSteps: - - name: RunCommand - action: aws:runCommand - inputs: - DocumentName: AWS-RunShellScript - InstanceIds: - - "{{ InstanceId }}" - Parameters: - # 24 hours as a timeout to wait for the instance to stop all services - executionTimeout: "60" - commands: - - nohup /usr/local/bin/stop_media_node.sh > /var/log/stop_media_node.log 2>&1 & - - - StopMediaNodeCloudWatchEventRole: - Type: AWS::IAM::Role - Properties: - AssumeRolePolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Principal: - Service: - - events.amazonaws.com - Action: - - sts:AssumeRole - Policies: - - PolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Action: - - ssm:StartAutomationExecution - Resource: !Sub arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${StopMediaNodeAutomationDocument}:$DEFAULT - PolicyName: !Sub StopMediaNodeCloudWatchEventPolicy-${AWS::Region}-${AWS::StackName} - - PolicyDocument: - Version: '2012-10-17' - Statement: - - Effect: Allow - Action: - - iam:PassRole - Resource: !GetAtt StopMediaNodeDocumentRole.Arn - PolicyName: Pass-Role-SSM-Automation-Policy - - StopMediaNodeCloudWatchEventRule: - Type: AWS::Events::Rule - Properties: - Description: Rule to trigger the StopMediaNodeAutomationDocument when an instance is terminated - EventPattern: - source: - - aws.autoscaling - detail-type: - - EC2 Instance-terminate Lifecycle Action - detail: - AutoScalingGroupName: - - !Sub openvidu-ha-media-asg-${AWS::Region}-${AWS::StackName} - Name: - Fn::Join: - # Generate a not too long and unique rule name - # Getting a unique identifier from the stack id - - '' - - - StopMediaNodeCloudWatchEventRule- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - Targets: - - Arn: !Sub arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${StopMediaNodeAutomationDocument}:$DEFAULT - RoleArn: !GetAtt StopMediaNodeCloudWatchEventRole.Arn - Id: - Fn::Join: - # Generate a not too long and unique target id - # Getting a unique identifier from the stack id - - '' - - - StopMediaNodeCloudWatchEventRule- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - InputTransformer: - InputPathsMap: - instanceid: "$.detail.EC2InstanceId" - InputTemplate: | - { - "InstanceId": [ ] - } - - OpenViduMediaNodeASGScalingPolicy: - Type: AWS::AutoScaling::ScalingPolicy - Properties: - AutoScalingGroupName: !Ref OpenViduMediaNodeASG - PolicyType: TargetTrackingScaling - EstimatedInstanceWarmup: 120 - TargetTrackingConfiguration: - PredefinedMetricSpecification: - PredefinedMetricType: ASGAverageCPUUtilization - TargetValue: !Ref ScaleTargetCPU - - OpenViduMasterNodeSG: - Type: AWS::EC2::SecurityGroup - Properties: - GroupDescription: Security group for OpenVidu Master Node - GroupName: !Sub openvidu-ha-master-sg-${AWS::Region}-${AWS::StackName} - VpcId: !Ref OpenViduVPC - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - CidrIpv6: ::/0 - - OpenViduLoadBalancerToMasterHTTPIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 80 - ToPort: 80 - SourceSecurityGroupId: !Ref OpenViduLoadBalancerSG - - OpenViduLoadBalancerToMasterIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 443 - ToPort: 443 - SourceSecurityGroupId: !Ref OpenViduLoadBalancerSG - - OpenViduLoadBalancerToMasterHealthCheckIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 7880 - ToPort: 7880 - SourceSecurityGroupId: !Ref OpenViduLoadBalancerSG - - - OpenViduMasterToMasterRedisIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 7000 - ToPort: 7001 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMediaNodeToMasterRedisIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 7000 - ToPort: 7001 - SourceSecurityGroupId: !Ref OpenViduMediaNodeSG - - OpenViduMasterToMasterMinioIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 9100 - ToPort: 9100 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMasterToMasterMinioConsoleSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 9101 - ToPort: 9101 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMediaNodeToMasterMinioIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 9100 - ToPort: 9100 - SourceSecurityGroupId: !Ref OpenViduMediaNodeSG - - OpenViduMasterToMasterMongoIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 20000 - ToPort: 20000 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMediaNodeToMasterMongoIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 20000 - ToPort: 20000 - SourceSecurityGroupId: !Ref OpenViduMediaNodeSG - - OpenViduMasterToMasterMimirGrpcIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 9095 - ToPort: 9095 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMasterToMasterMimirGossipIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 7946 - ToPort: 7946 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMediaNodeToMasterHTTPMimirSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 9009 - ToPort: 9009 - SourceSecurityGroupId: !Ref OpenViduMediaNodeSG - - OpenViduMasterToMasterLokiGrpcIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 9096 - ToPort: 9096 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMasterToMasterLokiGossipIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 7947 - ToPort: 7947 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMasterToMasterDashboardsIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 5000 - ToPort: 5000 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMasterToMasterGrafanaIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 3000 - ToPort: 3000 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMediaNodeToMasterHTTPLokiSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 3100 - ToPort: 3100 - SourceSecurityGroupId: !Ref OpenViduMediaNodeSG - - OpenViduMasterToMasterV2CompatibilityIngress: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 4443 - ToPort: 4443 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMediaNodeToMasterV2CompatibilityWebhookIngress: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !GetAtt OpenViduMasterNodeSG.GroupId - IpProtocol: tcp - FromPort: 4443 - ToPort: 4443 - SourceSecurityGroupId: !GetAtt OpenViduMediaNodeSG.GroupId - - OpenViduMasterToMasterDefaultAppIngress: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 6080 - ToPort: 6080 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMediaNodeToMasterDefaultAppWebhookIngress: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !GetAtt OpenViduMasterNodeSG.GroupId - IpProtocol: tcp - FromPort: 6080 - ToPort: 6080 - SourceSecurityGroupId: !GetAtt OpenViduMediaNodeSG.GroupId - - OpenViduMediaNodeSG: - Type: AWS::EC2::SecurityGroup - Properties: - GroupDescription: Security group for OpenVidu Media Node - GroupName: !Sub openvidu-ha-media-sg-${AWS::Region}-${AWS::StackName} - VpcId: !Ref OpenViduVPC - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 22 - ToPort: 22 - CidrIpv6: ::/0 - - IpProtocol: udp - FromPort: 443 - ToPort: 443 - CidrIp: 0.0.0.0/0 - - IpProtocol: udp - FromPort: 443 - ToPort: 443 - CidrIpv6: ::/0 - - 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 - - OpenViduLoadBalancerToMasterNodeRTMPIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMasterNodeSG - IpProtocol: tcp - FromPort: 1945 - ToPort: 1945 - SourceSecurityGroupId: !Ref OpenViduLoadBalancerSG - - OpenViduMasterNodeToMediaNodeRTMPIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMediaNodeSG - IpProtocol: tcp - FromPort: 1935 - ToPort: 1935 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduLoadBalancerToMediaNodeIngressHealthCheckSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMediaNodeSG - IpProtocol: tcp - FromPort: 9092 - ToPort: 9092 - SourceSecurityGroupId: !Ref OpenViduLoadBalancerSG - - OpenViduMasterNodeTurnTLSToMediaNodeIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Condition: TurnTLSIsEnabled - Properties: - GroupId: !Ref OpenViduMediaNodeSG - IpProtocol: tcp - FromPort: 5349 - ToPort: 5349 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - - OpenViduMasterToMediaNodeServerIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMediaNodeSG - IpProtocol: tcp - FromPort: 7880 - ToPort: 7880 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduMasterToMediaNodeClientIngressSG: - Type: AWS::EC2::SecurityGroupIngress - Properties: - GroupId: !Ref OpenViduMediaNodeSG - IpProtocol: tcp - FromPort: 8080 - ToPort: 8080 - SourceSecurityGroupId: !Ref OpenViduMasterNodeSG - - OpenViduLoadBalancerSG: - Type: AWS::EC2::SecurityGroup - Properties: - GroupDescription: Security group for the Load Balancer - GroupName: !Sub openvidu-ha-lb-sg-${AWS::Region}-${AWS::StackName} - VpcId: !Ref OpenViduVPC - SecurityGroupIngress: - - 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: 1935 - ToPort: 1935 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 1935 - ToPort: 1935 - CidrIpv6: ::/0 - - OpenViduTurnTLSLoadBalancerSG: - Type: AWS::EC2::SecurityGroup - Condition: TurnTLSIsEnabled - Properties: - GroupDescription: Security group for the Load Balancer for TURN with TLS - GroupName: !Sub openvidu-ha-turn-tls-lb-sg-${AWS::Region}-${AWS::StackName} - VpcId: !Ref OpenViduVPC - SecurityGroupIngress: - - IpProtocol: tcp - FromPort: 443 - ToPort: 443 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 443 - ToPort: 443 - CidrIpv6: ::/0 - - LoadBalancer: - Type: AWS::ElasticLoadBalancingV2::LoadBalancer - DependsOn: - - MasterNodesWaitCondition4 - Properties: - Name: - Fn::Join: - # Generate a not too long and unique load balancer name - # Getting a unique identifier from the stack id - - '' - - - OpenViduHA- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - Subnets: !Ref OpenViduMasterNodeSubnets - SecurityGroups: - - !Ref OpenViduLoadBalancerSG - Type: network - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - Load Balancer - - TurnTLSLoadBalancer: - Type: AWS::ElasticLoadBalancingV2::LoadBalancer - Condition: TurnTLSIsEnabled - Properties: - Name: - Fn::Join: - # Generate a not too long and unique load balancer name - # Getting a unique identifier from the stack id - - '' - - - OpenViduHA-TurnTLS- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - Subnets: !Ref OpenViduMasterNodeSubnets - SecurityGroups: - - !Ref OpenViduLoadBalancerSG - Type: network - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - TURN with TLS Load Balancer - - OpenViduMasterNodeHTTPListener: - Type: 'AWS::ElasticLoadBalancingV2::Listener' - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref OpenViduMasterNodeTGHTTP - LoadBalancerArn: !Ref LoadBalancer - Port: 80 - Protocol: TCP - - OpenViduMasterNodeListener: - Type: 'AWS::ElasticLoadBalancingV2::Listener' - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref OpenViduMasterNodeTG - LoadBalancerArn: !Ref LoadBalancer - Port: 443 - Protocol: TCP - - OpenViduRTMPMasterNodeListener: - Type: 'AWS::ElasticLoadBalancingV2::Listener' - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref OpenViduMasterNodeRTMPTG - LoadBalancerArn: !Ref LoadBalancer - Port: 1935 - Protocol: TCP - - OpenViduTurnTLSMasterNodeListener: - Type: 'AWS::ElasticLoadBalancingV2::Listener' - Condition: TurnTLSIsEnabled - Properties: - DefaultActions: - - Type: forward - TargetGroupArn: !Ref OpenViduMasterNodeTurnTLSTG - LoadBalancerArn: !Ref TurnTLSLoadBalancer - Port: 443 - Protocol: TCP - - OpenViduMasterNodeTGHTTP: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - Name: - Fn::Join: - # Generate a not too long and unique target id - # Getting a unique identifier from the stack id - - '' - - - OpenVidu-HTTP- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - TargetType: instance - Targets: - - Id: !Ref OpenViduMasterNode1 - - Id: !Ref OpenViduMasterNode2 - - Id: !Ref OpenViduMasterNode3 - - Id: !Ref OpenViduMasterNode4 - VpcId: !Ref OpenViduVPC - Port: 80 - Protocol: TCP - Matcher: - HttpCode: '200' - HealthCheckIntervalSeconds: 10 - HealthCheckPath: /health/caddy - HealthCheckProtocol: HTTP - HealthCheckPort: '7880' - HealthCheckTimeoutSeconds: 5 - HealthyThresholdCount: 3 - UnhealthyThresholdCount: 4 - TargetGroupAttributes: - - Key: deregistration_delay.timeout_seconds - Value: 60 - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - Master Target Group - - OpenViduMasterNodeTG: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - Name: - Fn::Join: - # Generate a not too long and unique target id - # Getting a unique identifier from the stack id - - '' - - - OpenVidu- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - TargetType: instance - Targets: - - Id: !Ref OpenViduMasterNode1 - - Id: !Ref OpenViduMasterNode2 - - Id: !Ref OpenViduMasterNode3 - - Id: !Ref OpenViduMasterNode4 - VpcId: !Ref OpenViduVPC - Port: 443 - Protocol: TCP - Matcher: - HttpCode: '200' - HealthCheckIntervalSeconds: 10 - HealthCheckPath: /health/caddy - HealthCheckProtocol: HTTP - HealthCheckPort: '7880' - HealthCheckTimeoutSeconds: 5 - HealthyThresholdCount: 3 - UnhealthyThresholdCount: 4 - TargetGroupAttributes: - - Key: deregistration_delay.timeout_seconds - Value: 60 - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - Master Target Group - - OpenViduMasterNodeRTMPTG: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Properties: - Name: - Fn::Join: - # Generate a not too long and unique target id - # Getting a unique identifier from the stack id - - '' - - - OVRTMP- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - VpcId: !Ref OpenViduVPC - TargetType: instance - Targets: - - Id: !Ref OpenViduMasterNode1 - - Id: !Ref OpenViduMasterNode2 - - Id: !Ref OpenViduMasterNode3 - - Id: !Ref OpenViduMasterNode4 - Port: 1945 - Protocol: TCP - Matcher: - HttpCode: '200' - HealthCheckIntervalSeconds: 10 - HealthCheckPath: /health/caddy - HealthCheckProtocol: HTTP - # Ingress health check port - HealthCheckPort: '7880' - HealthCheckTimeoutSeconds: 5 - HealthyThresholdCount: 3 - UnhealthyThresholdCount: 4 - TargetGroupAttributes: - - Key: deregistration_delay.timeout_seconds - Value: 60 - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - RTMP Target Group - - OpenViduMasterNodeTurnTLSTG: - Type: AWS::ElasticLoadBalancingV2::TargetGroup - Condition: TurnTLSIsEnabled - Properties: - Name: - Fn::Join: - # Generate a not too long and unique target id - # Getting a unique identifier from the stack id - - '' - - - OVTurnTLS- - - !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]] - TargetType: instance - Targets: - - Id: !Ref OpenViduMasterNode1 - - Id: !Ref OpenViduMasterNode2 - - Id: !Ref OpenViduMasterNode3 - - Id: !Ref OpenViduMasterNode4 - VpcId: !Ref OpenViduVPC - Port: 443 - Protocol: TCP - Matcher: - HttpCode: '200' - HealthCheckIntervalSeconds: 10 - HealthCheckPath: /health/caddy - HealthCheckProtocol: HTTP - HealthCheckPort: '7880' - HealthCheckTimeoutSeconds: 5 - HealthyThresholdCount: 3 - UnhealthyThresholdCount: 4 - Tags: - - Key: Name - Value: !Sub ${AWS::StackName} - OpenVidu HA - TURN TLS Target Group - -Outputs: - ServicesAndCredentials: - Description: Services and credentials - Value: !Sub https://${AWS::Region}.console.aws.amazon.com/secretsmanager/home?region=${AWS::Region}#!/secret?name=openvidu-ha-${AWS::Region}-${AWS::StackName}