{"id":31107,"date":"2016-01-11T09:21:38","date_gmt":"2016-01-11T03:51:38","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=31107"},"modified":"2016-01-11T20:19:00","modified_gmt":"2016-01-11T14:49:00","slug":"streaming-videos-on-demand-using-amazon-cloudfront-and-s3","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/streaming-videos-on-demand-using-amazon-cloudfront-and-s3\/","title":{"rendered":"Streaming Videos On Demand using  Amazon Cloudfront and S3"},"content":{"rendered":"<p>I came across a scenario where we have to stream Videos On Demand (VOD) using \u00a0Amazon CloudFront and Amazon Simple Storage Service (S3). The on-demand streaming is done using Cloudfront Content Delivery Network (CDN). The videos to be served are stored on Amazon S3. I have designed a secure\u00a0architecture for the same setup.<\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone  wp-image-31173\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/01\/Untitled-Diagram.png\" alt=\"Untitled Diagram\" width=\"624\" height=\"336\" \/><\/p>\n<p>&nbsp;<\/p>\n<ul>\n<li>The user sends the request to AWS CloudFront CDN for the video to be streamed.<\/li>\n<li>The request is preferred to be sent on the HTTPS protocol. For more secure streaming, all requests being made through HTTP protocol are denied by the CloudFront.<\/li>\n<li>The videos to be served are stored on AWS S3. The CORS configuration is set so as to allow access from the desired domains only.<\/li>\n<li>The access to S3 bucket is made through HTTPS protocol for more secure architecture. The HTTP requests are denied by AWS S3 policy which will be described later in the blog.<\/li>\n<li>The\u00a0<strong>CloudFront Origin Access Identity<\/strong>, which is a special Cloudfront user is used to restrict access to the content in S3 buckets. The access is given only through the CloudFront so that the users cannot access the content directly by using S3 url.<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h3><span style=\"text-decoration: underline\">Creating Amazon S3 bucket to store video content<\/span><\/h3>\n<p>The following steps are performed to create Amazon S3 bucket and modify its permissions:<\/p>\n<p>1. Go to S3 console by logging into AWS console. Click on S3 option as shown below:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-31174\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/01\/EC2-Management-Console.png\" alt=\"EC2 Management Console\" width=\"1351\" height=\"647\" \/><\/p>\n<p>2. Create a new S3 bucket by clicking on\u00a0<strong>Create Bucket\u00a0<\/strong>button. Specify the name and region of the bucket.<\/p>\n<p>3. Upload the video files to be served on the bucket by using AWS console or AWS CLI.<\/p>\n<p>4. Create a file named <strong>crossdomain.xml\u00a0<\/strong>and upload it. The file should contain the following content:<\/p>\n<p>[js]<br \/>\n&lt;cross-domain-policy&gt;<br \/>\n&lt;allow-access-from domain=&quot;*&quot; secure=&quot;false&quot;\/&gt;<br \/>\n&lt;site-control permitted-cross-domain-policies=&quot;all&quot;\/&gt;<br \/>\n&lt;\/cross-domain-policy&gt;<br \/>\n[\/js]<\/p>\n<p>5.\u00a0Update CORS information by clicking on <strong>Edit CORS configuration<\/strong> as shown:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-31287\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/01\/CORS.png\" alt=\"CORS\" width=\"692\" height=\"437\" \/><\/p>\n<p>6. \u00a0Put the following content in the CORS configuration file:<\/p>\n<p>[js]<br \/>\n&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;<br \/>\n&lt;CORSConfiguration xmlns=&quot;http:\/\/s3.amazonaws.com\/doc\/2006-03-01\/&quot;&gt;<br \/>\n&lt;CORSRule&gt;<br \/>\n&lt;AllowedOrigin&gt;*&lt;\/AllowedOrigin&gt;<br \/>\n&lt;AllowedMethod&gt;PUT&lt;\/AllowedMethod&gt;<br \/>\n&lt;AllowedMethod&gt;POST&lt;\/AllowedMethod&gt;<br \/>\n&lt;AllowedMethod&gt;DELETE&lt;\/AllowedMethod&gt;<br \/>\n&lt;AllowedMethod&gt;GET&lt;\/AllowedMethod&gt;<br \/>\n&lt;ExposeHeader&gt;ETag&lt;\/ExposeHeader&gt;<br \/>\n&lt;AllowedHeader&gt;*&lt;\/AllowedHeader&gt;<br \/>\n&lt;\/CORSRule&gt;<br \/>\n&lt;\/CORSConfiguration&gt;<br \/>\n[\/js]<\/p>\n<p>Here <strong>AllowedOrigin<\/strong> tag ensures the host from which the access to the content is allowed. You can set it to your desired host. <strong>AllowedMethod<\/strong> tag ensures methods allowed on the bucket.<\/p>\n<p>7. Now update the S3 bucket policy by clicking on\u00a0<strong>Add Bucket Policy\u00a0<\/strong>near <b>Edit CORS configuration\u00a0<\/b>option. The policy must contain the following content:<\/p>\n<p>[js]<br \/>\n{<br \/>\n&quot;Version&quot;: &quot;2008-10-17&quot;,<br \/>\n&quot;Id&quot;: &quot;some_policy&quot;,<br \/>\n&quot;Statement&quot;: [<br \/>\n{<br \/>\n&quot;Sid&quot;: &quot;AddPerm&quot;,<br \/>\n&quot;Effect&quot;: &quot;Deny&quot;,<br \/>\n&quot;Principal&quot;: &quot;*&quot;,<br \/>\n&quot;Action&quot;: &quot;s3:*&quot;,<br \/>\n&quot;Resource&quot;: &quot;arn:aws:s3:::&lt;strong&gt;bucket_name&lt;\/strong&gt;\/*&quot;,<br \/>\n&quot;Condition&quot;: {<br \/>\n&quot;Bool&quot;: {<br \/>\n&quot;aws:SecureTransport&quot;: false<br \/>\n}<br \/>\n}<br \/>\n},<br \/>\n{<br \/>\n&quot;Sid&quot;: &quot;2&quot;,<br \/>\n&quot;Effect&quot;: &quot;Allow&quot;,<br \/>\n&quot;Principal&quot;: {<br \/>\n&quot;AWS&quot;: &quot;arn:aws:iam::cloudfront:user\/CloudFront Origin Access Identity &lt;strong&gt;&lt;strong&gt;OriginAccessIdentityID&lt;\/strong&gt;&lt;\/strong&gt;&quot;<br \/>\n},<br \/>\n&quot;Action&quot;: &quot;s3:GetObject&quot;,<br \/>\n&quot;Resource&quot;: &quot;arn:aws:s3:::&lt;strong&gt;&lt;strong&gt;bucket_name&lt;\/strong&gt;&lt;\/strong&gt;\/*&quot;<br \/>\n}<br \/>\n]<br \/>\n}<br \/>\n[\/js]<\/p>\n<p>The\u00a0<strong>bucket_name\u00a0<\/strong>should be replaced by the name of the bucket and\u00a0<strong>OriginAccessIdentityID\u00a0<\/strong>should be replaced by CloudFront Origin Access Identity. It will be obtained when we create the CloudFront distribution below.<\/p>\n<p>Here &#8220;<strong>Effect&#8221;:&#8221;Deny&#8221; \u00a0<\/strong><strong>aws:SecureTransport&#8221;: false\u00a0<\/strong>is used to prevent HTTP access to S3 bucket. The GetObject permission is given of the content in S3 only to the cloud front user.<\/p>\n<p>&nbsp;<\/p>\n<h3><span style=\"text-decoration: underline\">Creating Amazon CloudFront distribution to stream video content<\/span><\/h3>\n<p>1. \u00a0Go to CloudFront console by logging into AWS console. Click on CloudFront option as shown below:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-31178\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/01\/Cloudfront.png\" alt=\"Cloudfront\" width=\"694\" height=\"596\" \/><\/p>\n<p>2.\u00a0Click then on <strong>Create Distribution<\/strong> to create a new cloud front distribution. The new distribution will be used to stream videos.<\/p>\n<p>3. Click on\u00a0<strong>Create Web Distribution.<\/strong><\/p>\n<p>4. Now enter the required details in the boxes as shown in the image below:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\" wp-image-31119\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/01\/Selection_100.png\" alt=\"CLoudfront\" width=\"624\" height=\"315\" \/><\/p>\n<p>Origin is where you store your content to be served.<\/p>\n<ul>\n<li><strong>Origin Domain Name: \u00a0<\/strong>Choose\u00a0Amazon S3 bucket<b>\u00a0<\/b>you created above.<\/li>\n<li><strong>Origin Path:\u00a0<\/strong>Leave it blank.<\/li>\n<li><strong>Origin ID: \u00a0<\/strong>It will be automatically set on choosing bucket in Origin Domain Name above.<\/li>\n<li><strong>Restrict Bucket Access:\u00a0<\/strong>Choose Yes.<\/li>\n<li><strong>Origin Access Identity:\u00a0<\/strong>Choose to create a new Identity.<\/li>\n<li><strong>Viewer Protocol Policy:\u00a0<\/strong>Choose HTTPS only.<\/li>\n<li><strong>Allowed HTTP methods:\u00a0<\/strong>Choose the methods you want to allow.<\/li>\n<\/ul>\n<p>5. <strong>SSL Certificate: <\/strong>You can\u00a0use default CloudFront certificate or can create your own certificate. To create your own certificate, follow the below steps:<\/p>\n<ul>\n<li>We need a <strong>server certificate<\/strong>, a <strong>private key<\/strong> and a <strong>certificate chain\u00a0<\/strong>to create our own SSL certificate.<\/li>\n<li>Then using AWS CLI create certificate by:<\/li>\n<\/ul>\n<p>[js]<br \/>\naws iam upload-server-certificate &#8211;server-certificate-name YOURNAME &#8211;certificate-body file:\/\/YOURSIGNEDCERT.pem &#8211;private-key file:\/\/YOURPRIVATEKEY.pem &#8211;certificate-chain file:\/\/INTERMEDIATECERT.pem &#8211;path \/cloudfront\/path\/<br \/>\n[\/js]<\/p>\n<p>&nbsp;<\/p>\n<p><strong>YOURNAME<\/strong> \u2013 Identifying the certificate once it is uploaded to AWS console.<br \/>\n<strong>YOURSIGNEDCERT<\/strong> \u2013 The certificate received from Certificate Authority(CA).<br \/>\n<strong>YOURPRIVATEKEY<\/strong> \u2013 The private key, which is generated as a part of certificate process.<br \/>\n<strong>INTERMEDIATECERT<\/strong> \u2013 The intermediate key provided by CA.<\/p>\n<p>The certificate will then be available on your AWS console. The certificate generated above can be verified by:<\/p>\n<p>[js]<br \/>\naws iam get-server-certificate &#8211;server-certificate-name YOURNAME<br \/>\n[\/js]<\/p>\n<p>Leave other options as default and click on\u00a0<strong>Create Distribution.<\/strong><\/p>\n<p>6. On Web distribution page, you will get DNS of your CloudFront as\u00a0**************<strong>.net.\u00a0<\/strong>Copy this and create a Cname\u00a0in Route 53 as shown:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-31181\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/01\/Route-53-Management-Console.png\" alt=\"Route 53 Management Console\" width=\"411\" height=\"498\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>7.\u00a0Now update this DNS in CloudFront distribution. Go to your web distribution. Click on\u00a0General and then click on Edit. Then update DNS as shown:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone  wp-image-31184\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/01\/AWS-CloudFront-Management-Console.png\" alt=\"AWS CloudFront Management Console\" width=\"630\" height=\"363\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>8.\u00a0The origin access identity will be obtained after you create the cloud front\u00a0distribution. After creating the distribution, edit the distribution and origin access identity will be seen as below:<br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-31186\" src=\"\/blog\/wp-ttn-blog\/uploads\/2016\/01\/cfr.png\" alt=\"cfr\" width=\"1132\" height=\"249\" \/><\/p>\n<p>The CloudFront distribution will take some time to create. You can check the status at main distribution page. After the distribution is created, you can check out the complete secure architecture. The few testing steps are as follows:<\/p>\n<ul>\n<li>The content present on S3 will not directly be accessible by using the S3 url.<\/li>\n<li>Access the content by https:\/\/&lt;cloudfront_dns&gt;\/&lt;folder_name&gt;\/&lt;file_name&gt;.<\/li>\n<li>The content should not be accessible by http:\/\/&lt;cloudfront_dns&gt;\/&lt;folder_name&gt;\/&lt;file_name&gt;.<\/li>\n<\/ul>\n<p>The secure architecture has been implemented. The architecture can be modified at ease by modifying the parameters or policies.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I came across a scenario where we have to stream Videos On Demand (VOD) using \u00a0Amazon CloudFront and Amazon Simple Storage Service (S3). The on-demand streaming is done using Cloudfront Content Delivery Network (CDN). The videos to be served are stored on Amazon S3. I have designed a secure\u00a0architecture for the same setup. &nbsp; The [&hellip;]<\/p>\n","protected":false},"author":163,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":36},"categories":[1174,2348,1],"tags":[2937,1332,2947,2939,2936,2940,2938],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/31107"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/163"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=31107"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/31107\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=31107"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=31107"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=31107"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}