--- AWSTemplateFormatVersion: 2010-09-09 Description: 360-Degree Live streaming Workshop Mappings: CidrMappings: public-subnet-1: CIDR: 10.0.1.0/24 public-subnet-2: CIDR: 10.0.2.0/24 vpc: CIDR: 10.0.0.0/16 amazonLinuxAmi: ap-northeast-1: AMI: ami-dac312b4 ap-southeast-1: AMI: ami-dc9339bf ap-southeast-2: AMI: ami-1c47407f ca-central-1: AMI: ami-ebed508f eu-central-1: AMI: ami-af0fc0c0 eu-west-1: AMI: ami-70edb016 eu-west-2: AMI: ami-f1949e95 us-east-1: AMI: ami-0b33d91d us-east-2: AMI: ami-c55673a0 us-west-1: AMI: ami-165a0876 us-west-2: AMI: ami-f173cc91 Metadata: Authors: Description: Konstantin Wilms , Shawn Przybilla , Chad Schmutzer License: Description: 'Copyright 2017 Amazon.com, Inc. and its affiliates. All Rights Reserved. Licensed under the Amazon Software License (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/asl/ or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.' Outputs: clientTestPatternUrl: Description: URL for the test pattern (requires manual start of ffmpeg) Value: Fn::Join: - '' - - Fn::GetAtt: - transcodingEgressBucket - WebsiteURL - /?url=http:// - Ref: primaryOriginElasticIp - /hls/test.m3u8 applicationLoadBalancerId: Description: The Application Load Balancer ID Value: Ref: applicationLoadBalancer applicationLoadBalancerDns: Description: The Application Load Balancer Domain Name Value: Fn::GetAtt: - applicationLoadBalancer - DNSName awsRegionId: Description: The AWS Region ID your template was launched in Value: Ref: AWS::Region clientWebsiteUrl: Description: URL for the website hosted on S3 Value: Fn::Join: - '' - - Fn::GetAtt: - transcodingEgressBucket - WebsiteURL - /?url= cloudWatchLogsGroupId: Description: The CloudWatch Logs group ID Value: Ref: cloudWatchLogsGroup edgeCacheSpotFleetId: Description: The edge cache Spot fleet request ID Value: Ref: edgeCacheSpotFleet primaryOriginElasticIp: Description: The primary origin Elastic IP Value: Ref: primaryOriginElasticIp primaryOriginElasticNetworkInterfacePrivateIpAddress: Description: The primary private IP address of the primary origin Elastic Network Interface Value: Fn::GetAtt: - primaryOriginElasticNetworkInterface - PrimaryPrivateIpAddress primaryOriginSpotFleetId: Description: The primary origin Spot fleet request ID Value: Ref: primaryOriginSpotFleet transcodingEgressBucketId: Description: The transcoding egress S3 bucket ID Value: Ref: transcodingEgressBucket transcodingIngressBucketId: Description: The transcoding ingress S3 bucket ID Value: Ref: transcodingIngressBucket transcodingQueueArn: Description: The transcoding SQS queue ARN Value: Fn::GetAtt: - transcodingQueue - Arn transcodingQueueUrl: Description: The transcoding SQS queue URL Value: Ref: transcodingQueue transcodingSpotFleetId: Description: The transcoding Spot fleet request ID Value: Ref: transcodingSpotFleet Parameters: edgeCacheSpotFleetMaximumCapacity: Default: 1 Description: Maximum number of EC2 Spot Instances to scale the edge cache Spot fleet Type: Number edgeCacheSpotFleetTargetCapacity: Default: 1 Description: Number of EC2 Spot Instances to initially launch in the edge cache Spot fleet Type: Number keyName: Description: Name of an existing EC2 KeyPair to enable SSH access to the EC2 Instances Type: AWS::EC2::KeyPair::KeyName sourceCidr: Default: 0.0.0.0/0 Description: Optional - CIDR/IP range for instance ssh access and encoder source - defaults to 0.0.0.0/0 Type: String spotInstancePrice: Default: 0.226 Description: Maximum Spot Instance price per hour per instance Type: Number transcodingSpotFleetMaximumCapacity: Default: 1 Description: Maximum number of EC2 Spot Instances to scale the transcoding Spot fleet Type: Number transcodingSpotFleetTargetCapacity: Default: 1 Description: Number of EC2 Spot Instances to initially launch in the transcoding Spot fleet Type: Number Resources: applicationLoadBalancer: DependsOn: - applicationLoadBalancerSecurityGroup Properties: LoadBalancerAttributes: - Key: idle_timeout.timeout_seconds Value: 30 Scheme: internet-facing SecurityGroups: - Ref: applicationLoadBalancerSecurityGroup Subnets: - Ref: publicSubnet1 - Ref: publicSubnet2 Tags: - Key: Name Value: Application Load Balancer Type: AWS::ElasticLoadBalancingV2::LoadBalancer applicationLoadBalancerListener: DependsOn: - applicationLoadBalancer - applicationLoadBalancerTargetGroup Properties: DefaultActions: - TargetGroupArn: Ref: applicationLoadBalancerTargetGroup Type: forward LoadBalancerArn: Ref: applicationLoadBalancer Port: 80 Protocol: HTTP Type: AWS::ElasticLoadBalancingV2::Listener applicationLoadBalancerSecurityGroup: DependsOn: - vpc Properties: GroupDescription: Application Load Balancer Security Group SecurityGroupIngress: - CidrIp: 0.0.0.0/0 FromPort: 80 IpProtocol: tcp ToPort: 80 VpcId: Ref: vpc Type: AWS::EC2::SecurityGroup applicationLoadBalancerTargetGroup: DependsOn: - vpc Properties: HealthCheckIntervalSeconds: 5 HealthCheckPath: / HealthCheckTimeoutSeconds: 2 HealthyThresholdCount: 2 Port: 80 Protocol: HTTP Tags: - Key: Name Value: Application Load Balancer Target Group TargetGroupAttributes: - Key: stickiness.enabled Value: true UnhealthyThresholdCount: 10 VpcId: Ref: vpc Type: AWS::ElasticLoadBalancingV2::TargetGroup attachGateway: DependsOn: - vpc - internetGateway Properties: InternetGatewayId: Ref: internetGateway VpcId: Ref: vpc Type: AWS::EC2::VPCGatewayAttachment cloudWatchLogsGroup: Properties: RetentionInDays: 7 Type: AWS::Logs::LogGroup edgeCacheSecurityGroup: DependsOn: - vpc Properties: GroupDescription: Edge cache Spot fleet instance security group SecurityGroupIngress: - CidrIp: Ref: sourceCidr FromPort: 22 IpProtocol: tcp ToPort: 22 VpcId: Ref: vpc Type: AWS::EC2::SecurityGroup edgeCacheSecurityGroupIngress: DependsOn: - edgeCacheSecurityGroup - applicationLoadBalancerSecurityGroup Properties: FromPort: 80 GroupId: Fn::GetAtt: - edgeCacheSecurityGroup - GroupId IpProtocol: tcp SourceSecurityGroupId: Fn::GetAtt: - applicationLoadBalancerSecurityGroup - GroupId ToPort: 80 Type: AWS::EC2::SecurityGroupIngress edgeCacheSpotFleet: DependsOn: - spotFleetRole - spotFleetInstanceProfile - edgeCacheSecurityGroup - icmpSecurityGroup - primaryOriginSpotFleet - applicationLoadBalancerTargetGroup - transcodingEgressBucket Properties: SpotFleetRequestConfigData: AllocationStrategy: diversified IamFleetRole: Fn::GetAtt: - spotFleetRole - Arn LaunchSpecifications: - IamInstanceProfile: Arn: Fn::GetAtt: - spotFleetInstanceProfile - Arn ImageId: Fn::FindInMap: - amazonLinuxAmi - Ref: AWS::Region - AMI InstanceType: m4.large KeyName: Ref: keyName Monitoring: Enabled: true SecurityGroups: - GroupId: Ref: edgeCacheSecurityGroup - GroupId: Ref: icmpSecurityGroup SubnetId: Fn::Join: - ',' - - Ref: publicSubnet1 - Ref: publicSubnet2 UserData: Fn::Base64: Fn::Sub: '#!/bin/bash -xe yum -y install git cd /root && git clone https://github.com/awslabs/immersive-media-refarch.git REGION=${AWS::Region} APPLICATIONLOADBALANCERTARGETGROUP=${applicationLoadBalancerTargetGroup} CLOUDWATCHLOGSGROUP=${cloudWatchLogsGroup} EGRESSBUCKETWEBSITEURL=${transcodingEgressBucket.WebsiteURL} PRIMARYORIGINPRIVATEIP=${primaryOriginElasticNetworkInterface.PrimaryPrivateIpAddress} WAITCONDITIONHANDLE="${edgeCacheSpotFleetWaitConditionHandle}" bash /root/immersive-media-refarch/workshop/start/user-data-edge.sh ' ReplaceUnhealthyInstances: true SpotPrice: Ref: spotInstancePrice TargetCapacity: Ref: edgeCacheSpotFleetTargetCapacity TerminateInstancesWithExpiration: true Type: AWS::EC2::SpotFleet edgeCacheSpotFleetScalableTarget: DependsOn: - edgeCacheSpotFleet - spotFleetAutoscaleRole Properties: MaxCapacity: Ref: edgeCacheSpotFleetMaximumCapacity MinCapacity: Ref: edgeCacheSpotFleetTargetCapacity ResourceId: Fn::Join: - / - - spot-fleet-request - Ref: edgeCacheSpotFleet RoleARN: Fn::GetAtt: - spotFleetAutoscaleRole - Arn ScalableDimension: ec2:spot-fleet-request:TargetCapacity ServiceNamespace: ec2 Type: AWS::ApplicationAutoScaling::ScalableTarget edgeCacheSpotFleetWaitCondition: DependsOn: edgeCacheSpotFleetWaitConditionHandle Properties: Count: Ref: edgeCacheSpotFleetTargetCapacity Handle: Ref: edgeCacheSpotFleetWaitConditionHandle Timeout: 900 Type: AWS::CloudFormation::WaitCondition edgeCacheSpotFleetWaitConditionHandle: Type: AWS::CloudFormation::WaitConditionHandle icmpSecurityGroup: DependsOn: - vpc Properties: GroupDescription: Security group to allow ICMP SecurityGroupIngress: - CidrIp: 0.0.0.0/0 FromPort: -1 IpProtocol: icmp ToPort: -1 VpcId: Ref: vpc Type: AWS::EC2::SecurityGroup internetGateway: DependsOn: - vpc Type: AWS::EC2::InternetGateway originSecurityGroup: DependsOn: - vpc Properties: GroupDescription: Origin Spot fleet instance security group SecurityGroupIngress: - CidrIp: Ref: sourceCidr FromPort: 22 IpProtocol: tcp ToPort: 22 - CidrIp: Ref: sourceCidr FromPort: 1935 IpProtocol: tcp ToPort: 1935 - CidrIp: Ref: sourceCidr FromPort: 80 IpProtocol: tcp ToPort: 80 VpcId: Ref: vpc Type: AWS::EC2::SecurityGroup originSecurityGroupIngress: DependsOn: - originSecurityGroup - edgeCacheSecurityGroup Properties: FromPort: 80 GroupId: Fn::GetAtt: - originSecurityGroup - GroupId IpProtocol: tcp SourceSecurityGroupId: Fn::GetAtt: - edgeCacheSecurityGroup - GroupId ToPort: 80 Type: AWS::EC2::SecurityGroupIngress primaryOriginElasticIp: Properties: Domain: vpc Type: AWS::EC2::EIP primaryOriginElasticNetworkInterface: DependsOn: - publicSubnet1 Properties: GroupSet: - Ref: originSecurityGroup - Ref: icmpSecurityGroup SubnetId: Ref: publicSubnet1 Type: AWS::EC2::NetworkInterface primaryOriginSpotFleet: DependsOn: - spotFleetRole - spotFleetInstanceProfile - originSecurityGroup - icmpSecurityGroup - transcodingIngressBucket - transcodingEgressBucket - primaryOriginElasticNetworkInterface Properties: SpotFleetRequestConfigData: AllocationStrategy: diversified IamFleetRole: Fn::GetAtt: - spotFleetRole - Arn LaunchSpecifications: - IamInstanceProfile: Arn: Fn::GetAtt: - spotFleetInstanceProfile - Arn ImageId: Fn::FindInMap: - amazonLinuxAmi - Ref: AWS::Region - AMI InstanceType: c4.large KeyName: Ref: keyName Monitoring: Enabled: true SecurityGroups: - GroupId: Ref: originSecurityGroup - GroupId: Ref: icmpSecurityGroup SubnetId: Ref: publicSubnet1 UserData: Fn::Base64: Fn::Sub: '#!/bin/bash -xe yum -y install git cd /root && git clone https://github.com/awslabs/immersive-media-refarch.git REGION=${AWS::Region} INGRESSBUCKET=${transcodingIngressBucket} CLOUDWATCHLOGSGROUP=${cloudWatchLogsGroup} ENI_ID=${primaryOriginElasticNetworkInterface} ALLOCATION_ID=${primaryOriginElasticIp.AllocationId} WAITCONDITIONHANDLE="${primaryOriginSpotFleetWaitConditionHandle}" bash /root/immersive-media-refarch/workshop/start/user-data-origin.sh ' ReplaceUnhealthyInstances: true SpotPrice: Ref: spotInstancePrice TargetCapacity: 1 TerminateInstancesWithExpiration: true Type: AWS::EC2::SpotFleet primaryOriginSpotFleetWaitCondition: DependsOn: primaryOriginSpotFleetWaitConditionHandle Properties: Count: 1 Handle: Ref: primaryOriginSpotFleetWaitConditionHandle Timeout: 900 Type: AWS::CloudFormation::WaitCondition primaryOriginSpotFleetWaitConditionHandle: Type: AWS::CloudFormation::WaitConditionHandle publicRoute: DependsOn: - publicRouteTable - internetGateway - attachGateway Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: Ref: internetGateway RouteTableId: Ref: publicRouteTable Type: AWS::EC2::Route publicRouteTable: DependsOn: - vpc - attachGateway Properties: Tags: - Key: Name Value: Public Route Table VpcId: Ref: vpc Type: AWS::EC2::RouteTable publicSubnet1: DependsOn: attachGateway Properties: AvailabilityZone: Fn::Select: - 0 - Fn::GetAZs: Ref: AWS::Region CidrBlock: Fn::FindInMap: - CidrMappings - public-subnet-1 - CIDR MapPublicIpOnLaunch: true Tags: - Key: Name Value: Public Subnet 1 VpcId: Ref: vpc Type: AWS::EC2::Subnet publicSubnet2: DependsOn: attachGateway Properties: AvailabilityZone: Fn::Select: - 1 - Fn::GetAZs: Ref: AWS::Region CidrBlock: Fn::FindInMap: - CidrMappings - public-subnet-2 - CIDR MapPublicIpOnLaunch: true Tags: - Key: Name Value: Public Subnet 2 VpcId: Ref: vpc Type: AWS::EC2::Subnet publicSubnet2RouteTableAssociation: DependsOn: - publicRouteTable - publicSubnet2 - attachGateway Properties: RouteTableId: Ref: publicRouteTable SubnetId: Ref: publicSubnet2 Type: AWS::EC2::SubnetRouteTableAssociation publicSubnet1RouteTableAssociation: DependsOn: - publicRouteTable - publicSubnet1 - attachGateway Properties: RouteTableId: Ref: publicRouteTable SubnetId: Ref: publicSubnet1 Type: AWS::EC2::SubnetRouteTableAssociation spotFleetAutoscaleRole: Properties: AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - application-autoscaling.amazonaws.com Version: 2012-10-17 ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetAutoscaleRole Path: / Type: AWS::IAM::Role spotFleetInstanceProfile: DependsOn: - spotFleetInstanceRole Properties: Path: / Roles: - Ref: spotFleetInstanceRole Type: AWS::IAM::InstanceProfile spotFleetInstanceRole: Properties: AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - ec2.amazonaws.com Version: 2012-10-17 ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role Path: / Policies: - PolicyDocument: Statement: - Action: sqs:* Effect: Allow Resource: Fn::GetAtt: - transcodingQueue - Arn Version: 2012-10-17 PolicyName: Fn::Join: - '-' - - Ref: AWS::StackName - transcodingQueuePolicy - PolicyDocument: Statement: - Action: - ec2:AttachNetworkInterface - ec2:DetachNetworkInterface - ec2:AssociateAddress - ec2:DisassociateAddress Effect: Allow Resource: '*' Version: 2012-10-17 PolicyName: Fn::Join: - '-' - - Ref: AWS::StackName - networkInterfacePolicy - PolicyDocument: Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents - logs:DescribeLogStreams Effect: Allow Resource: arn:aws:logs:*:*:* Version: 2012-10-17 PolicyName: Fn::Join: - '-' - - Ref: AWS::StackName - cloudWatchLogsPolicy - PolicyDocument: Statement: - Action: - elasticloadbalancing:DeregisterTargets - elasticloadbalancing:RegisterTargets Effect: Allow Resource: '*' Version: '2012-10-17' PolicyName: Fn::Join: - '-' - - Ref: AWS::StackName - applicationLoadBalancerPolicy - PolicyDocument: Statement: - Action: s3:ListBucket Effect: Allow Resource: - Fn::Join: - '' - - 'arn:aws:s3:::' - Ref: transcodingIngressBucket - Fn::Join: - '' - - 'arn:aws:s3:::' - Ref: transcodingEgressBucket Version: '2012-10-17' PolicyName: Fn::Join: - '-' - - Ref: AWS::StackName - transcodingBucketsListPolicy - PolicyDocument: Statement: - Action: - s3:PutObject* - s3:GetObject - s3:DeleteObject Effect: Allow Resource: - Fn::Join: - '' - - 'arn:aws:s3:::' - Ref: transcodingIngressBucket - /* - Fn::Join: - '' - - 'arn:aws:s3:::' - Ref: transcodingEgressBucket - /* Version: '2012-10-17' PolicyName: Fn::Join: - '-' - - Ref: AWS::StackName - transcodingBucketsReadWritePolicy Type: AWS::IAM::Role spotFleetRole: Properties: AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - spotfleet.amazonaws.com Version: 2012-10-17 ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonEC2SpotFleetTaggingRole Path: / Type: AWS::IAM::Role transcodingEgressBucket: Properties: AccessControl: PublicRead CorsConfiguration: CorsRules: - AllowedHeaders: - '*' AllowedMethods: - GET AllowedOrigins: - '*' MaxAge: '3600' WebsiteConfiguration: IndexDocument: index.html Type: AWS::S3::Bucket transcodingIngressBucket: DependsOn: - transcodingQueue - transcodingQueuePolicy Properties: NotificationConfiguration: QueueConfigurations: - Event: s3:ObjectCreated:* Queue: Fn::GetAtt: - transcodingQueue - Arn Type: AWS::S3::Bucket transcodingQueue: Properties: VisibilityTimeout: 7200 Type: AWS::SQS::Queue transcodingQueueDepthAlarmScaleDown: DependsOn: - transcodingQueue - transcodingSpotFleetScalingPolicyScaleDown Properties: AlarmActions: - Ref: transcodingSpotFleetScalingPolicyScaleDown AlarmDescription: Alarm if queue depth falls below 8 messages ComparisonOperator: LessThanThreshold Dimensions: - Name: QueueName Value: Fn::GetAtt: - transcodingQueue - QueueName EvaluationPeriods: 2 MetricName: ApproximateNumberOfMessagesVisible Namespace: AWS/SQS Period: 300 Statistic: Sum Threshold: 8 Type: AWS::CloudWatch::Alarm transcodingQueueDepthAlarmScaleUp: DependsOn: - transcodingQueue - transcodingSpotFleetScalingPolicyScaleUp Properties: AlarmActions: - Ref: transcodingSpotFleetScalingPolicyScaleUp AlarmDescription: Alarm if queue depth grows beyond 16 messages ComparisonOperator: GreaterThanThreshold Dimensions: - Name: QueueName Value: Fn::GetAtt: - transcodingQueue - QueueName EvaluationPeriods: 2 MetricName: ApproximateNumberOfMessagesVisible Namespace: AWS/SQS Period: 300 Statistic: Sum Threshold: 16 Type: AWS::CloudWatch::Alarm transcodingQueuePolicy: DependsOn: - transcodingQueue Properties: PolicyDocument: Statement: - Action: - sqs:SendMessage Effect: Allow Principal: Service: s3.amazonaws.com Resource: '*' Version: 2012-10-17 Queues: - Ref: transcodingQueue Type: AWS::SQS::QueuePolicy transcodingSecurityGroup: DependsOn: - vpc Properties: GroupDescription: Transcoding Spot fleet instance security group SecurityGroupIngress: - CidrIp: Ref: sourceCidr FromPort: 22 IpProtocol: tcp ToPort: 22 VpcId: Ref: vpc Type: AWS::EC2::SecurityGroup transcodingSpotFleet: DependsOn: - spotFleetRole - spotFleetInstanceProfile - transcodingSecurityGroup - icmpSecurityGroup Properties: SpotFleetRequestConfigData: AllocationStrategy: diversified IamFleetRole: Fn::GetAtt: - spotFleetRole - Arn LaunchSpecifications: - IamInstanceProfile: Arn: Fn::GetAtt: - spotFleetInstanceProfile - Arn ImageId: Fn::FindInMap: - amazonLinuxAmi - Ref: AWS::Region - AMI InstanceType: c4.xlarge KeyName: Ref: keyName Monitoring: Enabled: true SecurityGroups: - GroupId: Ref: transcodingSecurityGroup - GroupId: Ref: icmpSecurityGroup SubnetId: Fn::Join: - ',' - - Ref: publicSubnet1 - Ref: publicSubnet2 UserData: Fn::Base64: Fn::Sub: '#!/bin/bash -xe yum -y install git cd /root && git clone https://github.com/awslabs/immersive-media-refarch.git REGION=${AWS::Region} TRANSCODINGINGRESSBUCKET=${transcodingIngressBucket} TRANSCODINGEGRESSBUCKET=${transcodingEgressBucket} TRANSCODINGQUEUE=${transcodingQueue} CLOUDWATCHLOGSGROUP=${cloudWatchLogsGroup} WAITCONDITIONHANDLE="${transcodingSpotFleetWaitConditionHandle}" bash /root/immersive-media-refarch/workshop/start/user-data-transcoding.sh ' ReplaceUnhealthyInstances: true SpotPrice: Ref: spotInstancePrice TargetCapacity: Ref: transcodingSpotFleetTargetCapacity TerminateInstancesWithExpiration: true Type: AWS::EC2::SpotFleet transcodingSpotFleetScalableTarget: DependsOn: - transcodingSpotFleet - spotFleetAutoscaleRole Properties: MaxCapacity: Ref: transcodingSpotFleetMaximumCapacity MinCapacity: Ref: transcodingSpotFleetTargetCapacity ResourceId: Fn::Join: - / - - spot-fleet-request - Ref: transcodingSpotFleet RoleARN: Fn::GetAtt: - spotFleetAutoscaleRole - Arn ScalableDimension: ec2:spot-fleet-request:TargetCapacity ServiceNamespace: ec2 Type: AWS::ApplicationAutoScaling::ScalableTarget transcodingSpotFleetScalingPolicyScaleDown: Properties: PolicyName: transcodingSpotFleetScalingPolicyScaleDown PolicyType: StepScaling ScalingTargetId: Ref: transcodingSpotFleetScalableTarget StepScalingPolicyConfiguration: AdjustmentType: ChangeInCapacity Cooldown: 300 MetricAggregationType: Average StepAdjustments: - MetricIntervalUpperBound: 0 ScalingAdjustment: -1 Type: AWS::ApplicationAutoScaling::ScalingPolicy transcodingSpotFleetScalingPolicyScaleUp: Properties: PolicyName: transcodingSpotFleetScalingPolicyScaleUp PolicyType: StepScaling ScalingTargetId: Ref: transcodingSpotFleetScalableTarget StepScalingPolicyConfiguration: AdjustmentType: ChangeInCapacity Cooldown: 300 MetricAggregationType: Average StepAdjustments: - MetricIntervalLowerBound: 0 ScalingAdjustment: 1 Type: AWS::ApplicationAutoScaling::ScalingPolicy transcodingSpotFleetWaitCondition: DependsOn: transcodingSpotFleetWaitConditionHandle Properties: Count: Ref: transcodingSpotFleetTargetCapacity Handle: Ref: transcodingSpotFleetWaitConditionHandle Timeout: 900 Type: AWS::CloudFormation::WaitCondition transcodingSpotFleetWaitConditionHandle: Type: AWS::CloudFormation::WaitConditionHandle vpc: Properties: CidrBlock: Fn::FindInMap: - CidrMappings - vpc - CIDR EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: VPC for Running a Highly Scalable Immersive Media Solution on EC2 Spot Instances Type: AWS::EC2::VPC ...