{ "AWSTemplateFormatVersion" : "2010-09-09", "Description" : "This template uses Amazon CloudFront, Flash Media Server on Amazon EC2, an aiCache EC2 Instance and Amazon Route 53, to create a CloudFormation stack for HTTP streaming of your live event.", "Parameters" : { "InstanceType" : { "Type" : "String", "Description" : "Type of EC2 instance to launch for FMS - options include m1.large, m1.xlarge, m2.xlarge, m2.2xlarge, m2.4xlarge, and c1.xlarge", "Default" : "m1.large" }, "aiCacheInstanceType" : { "Type" : "String", "Description" : "Type of EC2 instance to launch for aiCache - options include m1.large, m1.xlarge, m2.xlarge, m2.2xlarge, m2.4xlarge, and c1.xlarge", "Default" : "m1.large" }, "DNSDomain" : { "Type" : "String", "Description" : "Name of an existing Route 53 DNS domain (e.g., mydomain.com)" }, "EventName" : { "Type" : "String", "Description" : "Name of your live event. Note the final CNAME of the live stream publish endpoint is .. E.g., my-live-event.mydomain.com", "Default" : "my-live-event" }, "BitRate" : { "Type" : "String", "Description" : "The bit rate for your live stream", "Default" : "350" }, "KeyPair" : { "Type" : "String", "Description" : "The key pair name for your FMS EC2 instance" }, "aiCacheKeyPair" : { "Type" : "String", "Description" : "The key pair name for your aiCache EC2 instance" } }, "Mappings" : { "RegionMap" : { "us-east-1" : { "AMI" : "ami-2f945346" }, "ap-southeast-1" : { "AMI" : "ami-fafe86a8" }, "ap-northeast-1" : { "AMI" : "ami-bcd366bd" }, "us-west-1" : { "AMI" : "ami-a7c391e2" }, "eu-west-1" : { "AMI" : "ami-885b6bfc" } }, "aiCacheRegionMap" : { "us-east-1" : { "AMI" : "ami-9b35e0f2" }, "ap-southeast-1" : { "AMI" : "ami-ccfdb89e" }, "ap-northeast-1" : { "AMI" : "ami-ecb204ed" }, "us-west-1" : { "AMI" : "ami-dfd08e9a" }, "eu-west-1" : { "AMI" : "ami-1d88b769" } } }, "Resources" : { "LiveStreamingDistribution" : { "Type" : "AWS::CloudFront::Distribution", "Properties" : { "DistributionConfig" : { "CustomOrigin" : { "DNSName": { "Ref" : "LiveStreamingIndirection" }, "HTTPPort" : "80", "HTTPSPort" : "443", "OriginProtocolPolicy" : "http-only" }, "Enabled" : "true" } } }, "Ec2Instance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "SecurityGroups" : [ { "Ref" : "InstanceSecurityGroup" } ], "KeyName" : { "Ref" : "KeyPair" }, "ImageId" : { "Fn::FindInMap" : [ "RegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}, "InstanceType" : {"Ref" : "InstanceType"}, "UserData" : { "Fn::Base64" : { "Fn::Join" : [ "", [ "#!/bin/bash", "\n", "cat > /mnt/applications/livepkgr/events/_definst_/liveevent/Manifest.xml <", "\n", "", "\n", "", "\n", "EOF", "\n", "sed -i \"s/^ADAPTOR.HOSTPORT.*=.*:1935,80/ADAPTOR.HOSTPORT = :1935/\" /opt/adobe/fms/conf/fms.ini", "\n", "sed -i \"s/^HTTPPROXY.HOST.*=.*:8134/HTTPPROXY.HOST = /\" /opt/adobe/fms/conf/fms.ini", "\n", "chown fmsuser:fmsgroup /opt/adobe/fms/conf/fms.ini", "\n", "sed -i \"s/^Listen 8134/Listen 80/\" /opt/adobe/fms/Apache2.2/conf/httpd.conf", "\n", "chown fmsuser:fmsgroup /opt/adobe/fms/Apache2.2/conf/httpd.conf", "\n", "cat > /mnt/webroot/crossdomain.xml <", "\n", " ", "\n", " ", "\n", " ", "\n", " ", "\n", " ", "\n", " ", "\n", " ", "\n", "", "\n", "EOFF", "\n", "chown fmsuser:fmsgroup /mnt/webroot/crossdomain.xml", "\n", "/opt/adobe/fms/fmsmgr server fms restart" ] ] }} } }, "aiCacheEc2Instance" : { "Type" : "AWS::EC2::Instance", "Properties" : { "SecurityGroups" : [ { "Ref" : "aiCacheInstanceSecurityGroup" } ], "KeyName" : { "Ref" : "aiCacheKeyPair" }, "ImageId" : { "Fn::FindInMap" : [ "aiCacheRegionMap", { "Ref" : "AWS::Region" }, "AMI" ]}, "InstanceType" : {"Ref" : "aiCacheInstanceType"}, "UserData" : { "Fn::Base64" : { "Fn::Join" : [ "", [ "#!/bin/bash", "\n", "cp /root/aicache.cfg.tpl /root/aicache.cfg", "\n", "sed -i \"s/example.com/", { "Fn::Join" : [ "", [{"Ref" : "EventName"}, ".", {"Ref" : "DNSDomain"}]]}, "/\" /root/aicache.cfg", "\n", "sed -i \"s/^healthcheck/#healthcheck/\" /root/aicache.cfg", "\n", "sed -i \"s/^pattern/#pattern/\" /root/aicache.cfg", "\n", "sed -i \"s/#pattern .png simple 7d no_log/pattern .bootstrap simple 2/\" /root/aicache.cfg", "\n", "sed -i \"s/origin 74.125.67.100/origin ", { "Fn::GetAtt" : [ "Ec2Instance", "PublicIp" ] }, "/\" /root/aicache.cfg" ] ] }} } }, "InstanceSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Security group for live streaming using Amazon CloudFront", "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0" }, { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : "0.0.0.0/0" }, { "IpProtocol" : "tcp", "FromPort" : "1935", "ToPort" : "1935", "CidrIp" : "0.0.0.0/0" }, { "IpProtocol" : "udp", "FromPort" : "1935", "ToPort" : "1935", "CidrIp" : "0.0.0.0/0" } ] } }, "aiCacheInstanceSecurityGroup" : { "Type" : "AWS::EC2::SecurityGroup", "Properties" : { "GroupDescription" : "Security group for aiCache used for live streaming using Amazon CloudFront", "SecurityGroupIngress" : [ { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0" }, { "IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : "0.0.0.0/0" } ] } }, "InstanceARecord" : { "Type" : "AWS::Route53::RecordSet", "Properties" : { "HostedZoneName" : { "Fn::Join" : [ "", [ {"Ref" : "DNSDomain"}, "." ]]}, "Comment" : "DNS name live streaming instance.", "Name" : { "Fn::Join" : [ "", [{"Ref" : "EventName"}, "-instance.", {"Ref" : "DNSDomain"}]]}, "Type" : "A", "TTL" : "900", "ResourceRecords" : [ { "Fn::GetAtt" : [ "aiCacheEc2Instance", "PublicIp" ] } ] } }, "LiveStreamingIndirection" : { "Type" : "AWS::Route53::RecordSet", "Properties" : { "HostedZoneName" : { "Fn::Join" : [ "", [ {"Ref" : "DNSDomain"}, "." ]]}, "Comment" : "CNAME redirect to live streaming instance to break cyclic dependency", "Name" : { "Fn::Join" : [ "", [{"Ref" : "EventName"}, ".", {"Ref" : "DNSDomain"}]]}, "Type" : "CNAME", "TTL" : "900", "ResourceRecords" : [ {"Fn::Join" : [ "", [{"Ref" : "EventName"}, "-instance.", {"Ref" : "DNSDomain"}]]} ] } } }, "Outputs" : { "aiCacheServer" : { "Value" : { "Fn::Join" : [ "", [ { "Fn::GetAtt" : [ "aiCacheEc2Instance", "PublicIp" ] } ]]} }, "FMSServer" : { "Value" : { "Fn::Join" : [ "", [ { "Ref" : "LiveStreamingIndirection" } ]]} }, "FMSServerIP" : { "Value" : { "Fn::Join" : [ "", [ { "Fn::GetAtt" : [ "Ec2Instance", "PublicIp" ] } ]]} }, "FMSURL" : { "Value" : { "Fn::Join" : [ "", [ "rtmp://", { "Ref" : "LiveStreamingIndirection" }, "/livepkgr" ]]} }, "Stream" : { "Value" : { "Fn::Join" : [ "", [ "livestream?adbe-live-event=liveevent" ]]} }, "VideoSource" : { "Value" : { "Fn::Join" : [ "", [ "http://", { "Ref" : "LiveStreamingIndirection" }, "/live/events/livepkgr/events/_definst_/liveevent.f4m" ]]} } } }