• Using S3 with Kentico CMS




    In order to improve the performance of a Kentico CMS install we decided to setup a content delivery network (CDN) using Amazon S3 and CloudFront. While Kentico is .NET and more easily deployed on Azure than AWS via their documents, making a resilient Kentico install on Amazon is achievable after working your way carefully through the setup process.

    Setting up S3 in Kentico CMS was a less than pleasant experience thanks in part due to a small inconsistency in their documentation. After a call to their support, the recommendation was to use the Azure setup instructions for setting up a custom file system provider. Upon reading these instructions it became apparent WHY the instructions for the S3 setup was failing.

    When you read the documents, the Azure document states IN BOLD:

    Do NOT set the CMSExternalStorageName key in your web.config (remove the key if it is present). Setting the key’s value to azure maps the project’s entire file system to the Azure storage, which is not recommended. See the Configuring Kentico to map its file system to Azure storage section for more information about this scenario.

    These exact same directions apply to AWS, yet it is not mentioned anywhere under the AWS documents and it is the ONLY thing that is stopping their directions from working for S3.

    So now that this is clear, you can follow the directions as writeen except SKIP STEP 2!

    2. Add the following key into the appSettings section of your project’s web.config.
    <add key=”CMSExternalStorageName” value=”amazon” />

    If you don’t do that, the rest of the steps will work.

    This is what we did. First we added the following to our web.config. You can substitute the CloudFront URL for an S3 URL if you don’t need to to use it.

    
    <add key="CMSAmazonEndPoint" value="http://asdf1234xyz.cloudfront.net" />
    <add key="CMSAmazonBucketName"  value="BUCKETNAME" />
    <add key="CMSAmazonAccessKeyID" value="AWSACCESSKEYID" />    
    <add key="CMSAmazonAccessKey" value="AWSSECRETACCESSKEY" />
    

    Next we switched the Kentico settings to use the file system instead of the database for storage as per the directions in Settings -> System -> Files.

    Now we just added a file called s3.cs into our App_Code folder, but we intend to add it into the solution. This file is exactly the same as the one posted in their documentation so I am not going to repost it here.

    Everything is now setup and you have a working CloudFront distribution serving your media library assets from S3 if you configured your AWS environment correctly, so we will touch upon that next.

    The somewhat more important part in the setup is making sure you add a user with limited permissions. Ideally, we wanted to setup an IAM role for our EC2 instance, but undoing some of the Kentico settings to allow an EC2 IAM role is slightly beyond my skills as a non-programmer type so this is something that will wait until there is time. In the meantime, we had to unfortunately copy the keys to the server to make things work thus the need to limit any possible ‘trouble’.

    To restrict our IAM user to S3 we decided to make a bucket policy to allow everyone to read and only our created IAM user is allowed to write and delete items. This is what our bucket policy looks like to accomplish this:




    
    {
        "Version": "2012-10-17",
        "Id": "Policy1493904280010",
        "Statement": [
            {
                "Sid": "statement0",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::OURBUCKET/*"
            },
            {
                "Sid": "statement1",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::111111111111:user/IAM-USER"
                },
                "Action": "s3:*",
                "Resource": "arn:aws:s3:::OURBUCKET/*"
            },
            {
                "Sid": "statement2",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::111111111111:user/IAM-USER"
                },
                "Action": [
                "s3:GetBucketLocation",
                "s3:ListBucket"
             ],
                "Resource": "arn:aws:s3:::OURBUCKET"
            }
        ]
    }
    

    Statement0 is what allows anonymous users to read the bucket. We could have setup restricted access to just CloudFront but it wasn’t necessary in this case. This is also technically set by the mediaProvider.PublicExternalFolderObject = true setting in the .cs file I believe but no harm in doing it twice IMO.

    Statement1 is what allows the IAM-USER to read/write/delete within the bucket. To help prevent accidents, we are using S3 versioning so any accidental deletes and overwrites can be recovered.

    Statement2 is what allows us to access the bucket and list contents. If you used s3:* here you would give permission for the IAM-USER to potentially delete the bucket, not good…

    Next up will be setting up a Redis cluster for the session handling. Stay tuned.




    Share
     

    1 responses to “Using S3 with Kentico CMS” RSS icon


    Leave a reply