Provisioning Cloudfront CDN using AWS CLI

Provisioning Cloudfront CDN using AWS CLI

Hi there! Today we are going to provision Content Delivery Network (CDN) using AWS CLI.

What is Cloudfront?

Amazon CloudFront is a fast content delivery network (CDN) service that securely delivers data, videos, applications, and APIs to customers globally with low latency, high transfer speeds, all within a developer-friendly environment. CloudFront is integrated with AWS – both physical locations that are directly connected to the AWS global infrastructure, as well as other AWS services. CloudFront works seamlessly with services including AWS Shield for DDoS mitigation, Amazon S3, Elastic Load Balancing or Amazon EC2 as origins for your applications, and Lambda@Edge to run custom code closer to customers’ users and to customize the user experience. Lastly, if you use AWS origins such as Amazon S3, Amazon EC2 or Elastic Load Balancing, you don’t pay for any data transferred between these services and CloudFront.

List of steps

  1. Create an S3 Bucket
  2. Put Object in Bucket
  3. Create Origin Access Identity
  4. Create Cloudfront Distribution
  5. Update Bucket Policy
  6. Create EBS Volume, partitions, format and mount
  7. Launch Webserver on Instance and copy CDN webpages

How to setup CDN

  • First, we create an S3 bucket like this
aws s3api create-bucket --bucket mytask6 --acl private --region ap-south-1 --create-bucket-configuration LocationConstraint=ap-south-1
  • Then time to put the object in S3 like in my case it's an image.
aws s3api put-object --bucket mytask6 --acl private --key test/Dussehra.png --body "F:\Downloads\Cool Images\Dussehra.png"
  • AS in above commands we have made the objects and bucket private so we need to create an Origin Access Identity (OAI) so that CloudFront distribution can access this bucket using OAI.
aws cloudfront create-cloud-front-origin-access-identity --cloud-front-origin-access-identity-config CallerReference="mytask6",Comment="Task 6 OAI"
  • Now time to create our CloudFront distribution
aws cloudfront create-distribution --distribution-config file://C:\Users\saura\Desktop\Task-6\conf.json

Here I used the config file to configure the CloudFront distribution. Our conf.json looks like this.

{
    "CallerReference": "mytask6",
    "Aliases": {
        "Quantity": 0
    },
    "DefaultRootObject": "/test/Dussehra.png",
    "Origins": {
        "Quantity": 1,
        "Items": [
            {
                "Id": "mytask6.s3.amazonaws.com-mytask6",
                "DomainName": "mytask6.s3.amazonaws.com",
                "OriginPath": "",
                "CustomHeaders": {
                    "Quantity": 0
                },
                "S3OriginConfig": {
                    "OriginAccessIdentity": "origin-access-identity/cloudfront/E1YPGOKOH5QY04"
                }
            }
        ]
    },
    "OriginGroups": {
        "Quantity": 0
    },
    "DefaultCacheBehavior": {
        "TargetOriginId": "mytask6.s3.amazonaws.com-mytask6",
        "ForwardedValues": {
            "QueryString": false,
            "Cookies": {
                "Forward": "none"
            },
            "Headers": {
                "Quantity": 0
            },
            "QueryStringCacheKeys": {
                "Quantity": 0
            }
        },
        "TrustedSigners": {
            "Enabled": false,
            "Quantity": 0
        },
        "ViewerProtocolPolicy": "allow-all",
        "MinTTL": 0,
        "AllowedMethods": {
            "Quantity": 2,
            "Items": [
                "HEAD",
                "GET"
            ],
            "CachedMethods": {
                "Quantity": 2,
                "Items": [
                    "HEAD",
                    "GET"
                ]
            }
        },
        "SmoothStreaming": false,
        "DefaultTTL": 86400,
        "MaxTTL": 31536000,
        "Compress": false,
        "LambdaFunctionAssociations": {
            "Quantity": 0
        },
        "FieldLevelEncryptionId": ""
    },
    "CacheBehaviors": {
        "Quantity": 0
    },
    "CustomErrorResponses": {
        "Quantity": 0
    },
    "Comment": "",
    "Logging": {
        "Enabled": false,
        "IncludeCookies": false,
        "Bucket": "",
        "Prefix": ""
    },
    "PriceClass": "PriceClass_All",
    "Enabled": true,
    "ViewerCertificate": {
        "CloudFrontDefaultCertificate": true,
        "MinimumProtocolVersion": "TLSv1",
        "CertificateSource": "cloudfront"
    },
    "Restrictions": {
        "GeoRestriction": {
            "RestrictionType": "none",
            "Quantity": 0
        }
    },
    "WebACLId": "",
    "HttpVersion": "http2",
    "IsIPV6Enabled": true
}
  • Now we have to update the bucket policy so that our CDN can access the content in the bucket.
aws s3api put-bucket-policy --bucket mytask6 --policy file://C:\Users\saura\Desktop\Task-6\bucket-policy.json

I created a file for policy and used that to update the policy in S3. Here is bucket-policy.json

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E1YPGOKOH5QY04"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mytask6/*"
        }
    ]
}
  • Now all that is left is to create an EBS volume, create partitions in it, format it and then mount it to ec2 instance. All this can be done using a single command.
aws ec2 run-instances --image-id ami-0e306788ff2473ccb --key-name myclikey --security-groups myclisg --count 1 --instance-type t2.micro --tag-specifications ResourceType=instance,Tags=[{Key=Name,Value=mytask6}] --block-device-mappings file://C:\Users\saura\Desktop\Task-6\mapping.json --user-data file://C:\Users\saura\Desktop\Task-6\script.txt

Here --block-device-mappings will create an EBS volume according to mapping.json file. Here is mapping.json

   [
       {
           "DeviceName": "/dev/sdh",
           "Ebs": {
               "VolumeSize": 1
           }
       }
   ]

Also, I used --user-data option which is a great feature of ec2 instance. With it, we can execute scripts or commands at launch time of instance.Here is my script.txt

#!/bin/bash
sudo yum install httpd git -y
sudo systemctl start httpd
sudo systemctl enable httpd

sudo printf 'o\nn\np\n1\n\n\nw\n' | sudo fdisk /dev/xvdh
sudo mkfs.ext4  /dev/xvdh
sudo mount  /dev/xvdh  /var/www/html

sudo rm -rf /var/www/html/*

sudo git clone https://github.com/sauravrana646/arth-task-6 /var/www/html/

What this will do is that it will install and setup webserver and git on ec2. Also it will create partition , format and mount the EBS volume to /var/www/html directory of the instance which is root document directory for our webserver and then clone our webpages to it which uses cloudfront to get data.

This will setup our basic CDN setup and now lets see if it worked.

Screenshot (908).png

It was just a simple demo on how to use and provision infrastructure on aws using AWS CLI.

Thanks for reading...!!!

Did you find this article valuable?

Support Saurav Rana by becoming a sponsor. Any amount is appreciated!