Continuing on from Part 2 where we created the required IAM group, user, and policies we get to the exciting part…building! The first step is to create the storage backend. In this case we’re utilizing Amazon Simple Storage Service (S3). As usual, I will refer you to AWS’s docs for the official S3 guide for creating the bucket. The process itself is very simple, but there are a few details to pay attention to specifically regarding this application.


  • Must be a globally unique name as bucket names are public per AWS policy
  • S3 buckets are managed and named globally, but it does need to reside in the same region as the EC2 instance to eliminate data transfer costs.
  • Block all public access. Use a bucket policy to allow access to your EC2 user role as outlined below.
  • A programmatic user to use in the bucket policy as created in the previous post.


  • Encryption - Enable default encryption as this will contain your video feeds
  • Storage class - I am using Infrequently Accessed to keep costs to a minimum. I don’t need long duration or reliable storage. I just need a couple days of footage that can then be deleted.
  • Lifecycle - Depending on the use case, you may want to retain your video while managing costs
  • Tags - Add whatever tagging applies to your AWS management strategy

S3 Bucket Policy

Here is an example of a simple bucket policy that we will need utilizing the user role previously created. I blanked out anything that could be a bit more specific to my account.

    "Version": "2012-10-17",
    "Id": "Policy########",
    "Statement": [
            "Sid": "Stmt########",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::<<ACCOUNT#>>:user/<<USER>>"
            "Action": "s3:*",
            "Resource": [


Deploying to the console is quick and simple; however, I prefer to code my infrastructure whenever possible. Here is a simple example of a YAML CloudFormation template to provision a bucket. For more information, refer to AWS S3 CloudFormation page

AWSTemplateFormatVersion: 2010-09-09
Description: S3 bucket for Unifi Video
    Type: AWS::S3::Bucket
      BucketName: !Sub '<<UniqueUnifiVideo>>-${AWS::Region}-${AWS::AccountId}'
          - ServerSideEncryptionByDefault:
              SSEAlgorithm: AES256
    DeletionPolicy: Delete

Once the S3 bucket is provisioned it is time to create the server; more aptly referred to in this case as an Elastic Compute Container (EC2). See the details here in the next post in this series.