How to deploy an Episerver site to AWS Elastic Beanstalk

How to deploy an Episerver site to AWS Elastic Beanstalk

Niteco Solution Architect Tien Man Quach explains how you can deploy your Episerver site in an AWS Elastic Beanstalk environment in a few easy steps.

Recently, I had a chance to create a Proof of Concept for moving an existing Episerver Commerce site from an AWS On-Premise environment to an AWS Elastic Beanstalk environment. It’s actually not that complicated, but a bit tricky if you’re new to it. So hopefully, this guideline will give everyone a good look at what we need to do.

Episerver has provided very good documentation on how to create an Alloy sample site by using the Episerver Visual Studio plug-in here. While this already contains a lot of steps, in this post I'll be going through some additional notes that have helped me along the way to get the website up and running. 

Below is the AWS Cloud architecture we're aiming to achieve:

 AWS Cloud setup

Prerequisites

Looking at the above diagram, we will need the following resources in terms of infrastructure:

  1. One Authoring CMS Beanstalk environment 
  2. One Commerce Manager environment (which I will not focus on in this topic)
  3. One front-end PoC Beanstalk application environment 
  4. One Load Balancer which already comes with Elastic Beanstalk
  5. RDS for databases
  6. S3 for blob storage
  7. SNS for event publish/subscribe
  8. Cloudwatch for application logging (optional)

Tip: All above prerequisites can be easily ticked off your list if you can get support from an AWS Partner.

Data Migration

Once we have got the infrastructure up and running, we can start migrating data from our development environment or previous On-Premise infrastructure to the AWS environment, such as databases or blobs:

  1. Existing databases need to be completely migrated to RDS (using AWS Database Migration Service)
  2. Blobs need to be migrated to an existing S3 bucket (using AWS Command Line Interface)

 

Nuget Package

In order to get Episerver to work with AWS, we need to make sure the following nuget package is installed into our Episerver application project:

 AWS Nuget Package

Configuration Transformation for Beanstalk

Essentially, we will need to complete the following transformation to make sure our Episerver application can be hosted on AWS Beanstalk:

  • SQL Server connection string to RDS
  • Blob provider should be set to "s3blobs" and filled with S3 bucket access information.

<blob defaultProvider="s3blobs" xdt:Transform="Replace">
  <providers>
    <add name="s3blobs"
         type="EPiServer.Amazon.Blobs.AmazonBlobProvider,EPiServer.Amazon"
         accessKey=""
         secretKey=""
         region=""
         bucket="" />
  </providers>
</blob>
  • Event provider should be set to "amazonevents" and filled with SNS Topic access information.

<event defaultProvider="amazonevents" xdt:Transform="Insert">
      <providers>
        <add name="amazonevents"
             type="EPiServer.Amazon.Events.AmazonEventProvider,EPiServer.Amazon"
             accessKey=""
             secretKey=""
             region=""
             topic="" />
      </providers>
    </event>

 

Deployment

We can quickly deploy our application to Beanstalk using the AWS Toolkit for Visual Studio. All we need to do is:

  1. Install AWS ToolKit for Visual Studio extension
  2. Add your AWS Credentials, which is actually your AWS Access Key ID and secret access key as described here.

Once you have correctly set up your development environment, you can quickly deploy your code to the Beanstalk environment with a couple of clicks.

Beanstalk Environment Configuration

As you know, there is a special folder in the Episerver application which requires the "write" permission to be granted so that the application can run. Without that, we will get an error.

Here is where it gets tricky. Elastic Beanstalk uses a special configuration model called ".ebextensions" and we cannot simply RDP into a webserver and grant permissions to a particular folder. Instead, we have to use a different approach to achieve this: by adding the AWS Elastic Beanstalk configuration files to your web application's source code in order to configure your environment as well as customize the AWS resources that it contains.

Technically, what we need to do is:

  1. Create a folder called ".ebextensions" and include it in our application source code
  2. For every single environment or resource configuration, we need to create the corresponding configuration files, which are YAML- or JSON-formatted documents with a .config file extension that we can place in the ".ebextensions" folder and deploy in our application source bundle.

Below is a sample config file for granting the write permission to the "~/modules" folder of Episerver, the minimum configuration to get the Episerver application up.

AWS sample config file

files:
  "C:\\scripts\\permissions-for-modules.ps1":
    content: |
      Import-Module WebAdministration
      $appPoolName='DefaultAppPool'
      # Update your custom IIS folder path here
      $folderDirectory='C:\inetpub\wwwroot\modules'
      $appPoolSid = (Get-ItemProperty IIS:\AppPools\$appPoolName).applicationPoolSid
      $identifier = New-Object System.Security.Principal.SecurityIdentifier $appPoolSid
      $user = $identifier.Translate([System.Security.Principal.NTAccount])
      If(!(test-path $folderDirectory))
      {
         New-Item -ItemType Directory -Force -Path $folderDirectory
      }
      $acl = Get-Acl $folderDirectory
      # SetAccessRuleProtection (bool isProtected, bool preserveInheritance);
      # isProtected - true to protect the access rules associated with this ObjectSecurity object from inheritance; false to allow inheritance.
      # preserveInheritance - true to preserve inherited access rules; false to remove inherited access rules. This parameter is ignored if isProtected is false.
      $acl.SetAccessRuleProtection($False, $True)
      $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($user,"FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")
      $acl.AddAccessRule($rule)
      Set-Acl $folderDirectory $acl
      # Print the final ACL in log
      # Get-Acl $folderDirectory  | Format-List
container_commands :
  set_permission:
    command: powershell.exe -ExecutionPolicy Bypass -Command "C:\\scripts\\permissions-for-modules.ps1"
    ignoreErrors: false
    waitAfterCompletion: 5

 

Launch

Last but not least, we need to make sure the Episerver license is included in the Visual Studio solution to ensure it is deployed along with the source code in one go.

Finally, once everything is ready, we can launch our Episerver application on AWS Beanstalk in Visual Studio with just a few clicks.

About The Author

Tien Quach

Tien Quach

Solution Architect

Tien is Niteco's Solution Architect and works closely with global brands to improve their commerce sites. He has more than 15 years of web development experience and is Episerver CMS and Commerce certified. You can contact him at: [email protected]