Article How Do I Deploy my Site to Microsoft Azure?

Community can be run as an Azure Web App using an Azure SQL database, Azure Service Bus, Azure Storage account and Azure Web Jobs. This guide will assist in helping you understand the technologies being used and where they need to be deployed in Azure, however there is an expectation that your organization has an understanding of how Azure works, its components and infrastructure, and utilization of the Azure portal.  

Limitations

Currently, Azure is only a supported solution for a new community running version 10.1 or later.  There is currently no supported migration path from an on-premise installation of Community to an Azure based installation unless you are currently running version 10.3 or higher and only if you currently use the default local filesystem for file storage.

You will still need to have at least a single windows virtual machine(VM) to install and run search (Solr). This machine should only be accessible by the website and job service, not publicly.

Planning

It is important to plan out your architecture before building it as it requires a functional knowledge of Azure and how to configure all aspects of Azure topology. This guide will go through the components needed for Community to run in Azure, but to ensure a secure, stable and efficient infrastructure you will need to understand parts of Azure that are beyond the scope of this article.

The biggest consideration is that Community requires a mix of App Services and at least 1 virtual machine. The App Services need to be able to communicate with the VM while still being available over the internet publicly, however the VM itself must not be accessible. 

Required Components

Azure Web Application (Web App)

This is where the actual Community web components will be deployed. Create a new Web App in Azure App Services and in its application settings ensure the following:

  • .NET Framework is set to version 4.7 (or higher)
  • Web Sockets are ON
  • Always On is set to ON
  • ARR Affinity is set to OFF

Other options can be left in their default state. Once set up be sure to STOP the Web App itself.

Job Server

The job server runs as a continuous Azure Web Job that you configure as part of the Web App itself or it can run as its own Web App (recommended). To set up the job server as a web job, access the Web App responsible for running the jobs, select WebJobs and add a new one. Or you can do this on its own separate Web App but the steps are the same.

  • It should be configured as continuous.
  • The required command file is Telligent.Jobs.AzureWebJobs.cmd  and it can be found in your '[Community Install Package]\JobServer' folder.

Be sure the Web Job remains in a stopped state.

SQL Database

The database portion of the community utilizes an Azure SQL database.  Your community requires a dedicated SQL database(it should not be shared with any other applications) but can share a SQL Server.   Never make alterations to the database schema even if a third party tool or Azure itself makes recommendations.  When configuring a SQL database be sure to:

  • Automatic Tuning options for FORCE PLAN, CREATE INDEX, and DROP INDEX are set to OFF for their desired state. Do not use INHERIT to ensure these settings are not accidentally applied to the server.

Service Bus

There are two service bus options when running Community in Azure: Azure Cache for Redis (recommended) or Azure Service Bus. Azure Cache for Redis is recommended for performance reasons along with the benefit of being a distributed cache.

Azure Cache for Redis (recommended)

We recommend Azure Cache for Redis due to being a performant, managed service but you can use other Redis services within Azure if you are comfortable managing those instances. Azure Cache for Redis configuration recommendations:

Azure Service Bus

You can create a new service bus on in Azure or utilize an existing one, however whichever you choose that service bus must support topics. This means as of the publication of this document you must use a standard pricing tier or higher. Basic does not support topics.

You should create a community specific shared access key on the bus. Avoid using the default. This way, especially in a shared bus, an access key can be revoked without impacting other services.  When creating a new shared access policy/key it needs the following permissions:

  • Manage
  • Listen
  • Send

Storage Account

The Centralized File Storage (CFS) portion of of your community is housed in a Azure storage account you will need to create. This storage account needs to be dedicated to your community and not utilized for any other application or other storage purpose. Community manages the contents of the storage account and therefore unless directed by support you should never manually manipulate the contents of the storage account or configure it outside of the recommended settings outlined below:

  • Configure the storage account as "Blob Storage", not general purpose
  • Production storage accounts should always be on a "Hot" tier.

Migrating Your Files to Azure

If you are currently running version 10.3 or higher and you already have an existing community that uses the default local file system for file storage you can migrate files to Azure.

CDN

It is highly recommend you place your storage account behind a CDN. CDNs offer expanded capabilities and features such as compression that blob storage directly does not. You can create a new CDN end point directly from the storage account itself.  Be sure to note the endpoint URL for later use.

Search

As noted previously, search currently does not utilize any Azure specific services or features.  It must be installed on a windows virtual machine powerful enough to handle the search traffic and enough disk space to store the search index. This  server should never be accessible over the internet publicly. It does however have to be accessible to the Web App and Jobs.

Because search is run on a virtual machine, its installation is no different than installing it on a windows machine on-premise and those instructions should be consulted.

Deployment

Preparation

It is assumed at this point you have you created the infrastructure as defined above and have all the components in place. If not please review the required components again and setup as necessary.

Configure Connection Strings

If you are used to on-premise installations you are familiar with having to setup connection strings in the connectionstrings.config file. In an Azure deployment, all the connection strings are stored as part of the Web App and configured in the portal. Access the Web App's application settings and locate the "Connection Strings" section. You need to add and configure the keys below.

***DO NOT SET the Slot setting for any key. It should remain unchecked

Name Value Category
SiteSqlServer The connection string value of the SQL Database.  You can obtain this from the connection strings area of the SQL database itself.  Be sure to substitute the correct name and password. SQL Database
AzureServiceBus The connection string to the service bus you configured.  It can be copied from the access keys area of the service bus instance. (Note: This is not necessary if using Azure Cache for Redis) Custom
AzureServiceBusTopic A user defined string that will be used as the topic in the service bus.  A good value to use is the name of your community. Custom
AzureFilestorageContainer The connection string of the storage account created for CFS.  It can be copied from the access keys area of the storage account instance. Custom
SearchContentUrl The url that points to the search index.  It should be http://[solrvm]:8983/solr/telligent-content/  where [solrvm] should be replaced with the IP or DNS name or your search virtual machine Custom
SearchConversationsUrl The url that points to the search index for conversations.  It should be http://[solrvm]:8983/solr/telligent-conversations/  where [solrvm] should be replaced with the IP or DNS name or your search virtual machine

Custom

SiteUrl The url your community will use.

Custom

IMPORTANT:  If you are running the web job as part of of the main Web App, you do not need to configure separate connection strings. However if you chose to run the web jobs in their own dedicated Web App Service, you will need to configure the connection strings up on the dedicated Web App.

Prepare Web and Job Files For Deployment

  1. Locate your Community Installation Package and ensure the .zip file is unblocked. Extract the zip file. We will reference this folder as [Community Install Package] below.
  2. Download the the Azure deployment zip file. Note: For Community versions prior to 12.1, use this download.
    1. Ensure the file is unblocked (Right click on file -> Properties -> Unblock should be unchecked) and extract the contents.
    2. Copy the contents to the '[Community Install Package]\Web' folder. If prompted by Windows to merge the 'bin' folder, choose 'Yes'.
    3. Copy the contents to the '[Community Install Package]\JobServer' folder.
  3. If you will be using Azure Cache for Redis, download Redis for Community.
    1. Ensure the file is unblocked (Right click on file -> Properties -> Unblock should be unchecked) and extract the contents.
    2. Copy the contents to the '[Community Install Package]\Web' folder.
    3. Copy the contents to the '[Community Install Package]\JobServer' folder.
  4. Edit the communityserver_override.config file in the '[Community Install Package]\Web' folder and un-comment the two override nodes for the fileStoreGroup.
  5. Configure Azure blob storage options (optional)
    1. cdnUrl - If you are using Azure's CDN services, edit the fileStoreGroup node with the name of "Azure" and add an "cdnUrl" attribute with the value of your CDN.
    2. maximumSecureFileAccessDays - The number of days secured file links are valid.
    3. minimumSecureFileAccessHours - The number of hours (or time window) before link expiration when a new URL will be generated. For example, if the 'maximumSecureFileAccessDays' is set to 14 days and 'minimumSecureFileAccessHours' is set to 2, the same URL will be given in requests for 14 days until 2 hours before the expiration time is up at which point a new URL is generated for the next 14 days.

      <Override xpath="/CommunityServer/CentralizedFileStorage" mode="add" where="end">
        <fileStoreGroup name="Azure"
            default="true" 
            type="Telligent.Evolution.Azure.Filestorage.AzureBlobFilestorageProvider, Telligent.Evolution.Azure.Filestorage"
            cdnUrl="https://yourcdn.azureedge.net"
            maximumSecureFileAccessDays="7"
            minimumSecureFileAccessHours="2"
            />
       </Override>    
      
  6. Copy the just edited '[Community Install Package]\Web\communityserver_override.config' file to the '[Community Install Package]\JobServer'
  7. When using Community 12.1 (or newer), add the following three assembly bindings within the web.config and job server's Telligent.Jobs.Server.exe.config:

<configuration>
	<runtime>
		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
			<dependentAssembly>
				<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
				<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
			</dependentAssembly>
			<dependentAssembly>
				<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
				<bindingRedirect oldVersion="0.0.0.0-5.0.0.1" newVersion="5.0.0.1" />
			</dependentAssembly>
			<dependentAssembly>
				<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
				<bindingRedirect oldVersion="0.0.0.0-5.0.0.2" newVersion="5.0.0.2" />
			</dependentAssembly>
		</assemblyBinding>
	</runtime>
</configuration>

Installation

Database

Previously you had already created a new dedicated database, setting up your community database is no different than an on-premise installation. Connect to the database using the tool of your choice that will allow you to execute SQL scripts and do the following:

  1. In the Community Installation package execute Install.sql.
  2. Once the install script has finished with no errors, set up your community by executing the following:

    EXECUTE[dbo].[cs_system_CreateCommunity]
        @ApplicationName = N'telligent',
        @AdminEmail = N'notset@localhost.com',
        @AdminUserName = N'temporary-admin',
        @AdminPassword = N'[PUT A TEMPORARY PASSWORD HERE]',
        @PasswordFormat = 0,
        @CreateSamples = 0


    NOTE: As with an on-premise installation, the temporary-admin account should be removed after you have created an alternate administrative account via the community itself for security purposes.

Job Server

Using a deployment method of your choice such as FTP, deploy the contents of the '[Community Install Package]\JobServer' folder [site/wwwroot/App_Data/jobs/continuous/[Web job Name]] to the Web App's job folder. You will be prompted to override the command file as you uploaded it to create the job, this okay or you can skip it. 

Note: Azure will ultimately deploy and run the job service in a temporary folder (ex. D:\local\Temp\JobsShutdown\continuous\jobs\[random.string]) which will change across restarts. For this reason, we recommend updating the logging location to a persistent location. This can be done by editing the <file> configuration elements for the <ErrorLogFileAppender> and <FullLoggingAppender> within the Telligent.Jobs.Server.exe.config file to sub-folder under the existing 'D:\home\LogFiles\' folder (e.g. D:\home\LogFiles\Community).

<log4net>
		<root>
			<level value="DEBUG"/>
			<appender-ref ref="ConsoleAppender"/>
			<appender-ref ref="ErrorLogFileAppender"/>
			<appender-ref ref="FullLoggingAppender"/>
		</root>
		<appender name="ErrorLogFileAppender" type="log4net.Appender.RollingFileAppender">
			<threshold value="WARN"/>
			<!-- <file value="Logs\errors.log"/> -->
			<file value="D:\home\LogFiles\Community\errors.log"/>
			<appendToFile value="true"/>
			<rollingStyle value="Size"/>
			<maxSizeRollBackups value="10"/>
			<maximumFileSize value="10MB"/>
			<staticLogFileName value="true"/>
			<layout type="log4net.Layout.PatternLayout">
				<conversionPattern value="%date %-5level [%thread] - %message%newline"/>
			</layout>
		</appender>
		<appender name="FullLoggingAppender" type="log4net.Appender.RollingFileAppender">
			<threshold value="INFO"/>
			<!-- <file value="Logs\log.log"/> -->
			<file value="D:\home\LogFiles\Community\log.log"/>
			<appendToFile value="true"/>
			<layout type="log4net.Layout.PatternLayout">
				<conversionPattern value="%date %-5level [%thread] - %message%newline"/>
			</layout>
		</appender>
[snip]

Web Site

Similar to job server, using a deployment method of your choice such as FTP, deploy the contents of the '[Community Install Package]\Web' folder [site/wwwroot] to the Web App's site folder. 

Search

As mentioned previously, because you are installing search on a windows VM, its installation is the same as on-premise installations. See the search installation section of How Do I Install Telligent Community?. Remember your VM will need to have a Java JRE installed.

IMPORTANT: Search cannot be publicly accessible. You will need to configure your environment in such a way as to allow communication from the Web App to the search VM on its virtual network while ensuring that any public traffic is being blocked to the VM itself.

Configuring Redis (*if using Redis)

Once your Redis instance is up and the Community site is running, its time to configure Redis for the service bus and distributed cache.

  1. Login to your site as an administrator and navigate to Administration (Click Pencil icon - > Administration).
  2. Navigate to Site -> Message Buses -> and disable (uncheck) the existing message bus and click 'Save'. This will disable the current message bus. 
  3. In the left-hand categories, click 'Extensions' and find the 'Redis' plugin. 
  4. Enter the host, port and credentials for your Redis instance. Once entered, select 'Enabled' (checked) and click 'Save'.
    1. Below is an example of this information from an Azure Cache for Redis instance



  5. Navigate back to Administration-> Site -> Message Bus and confirm a successful connection via the 'Diagnostics' tab.
  6. Note: The distributed cache will automatically be enabled.

Upgrading

You must bring your community down completely to upgrade.  You cannot rely on slot deployments or upgrading single nodes at a time. The database and ALL web files must be updated for your community to function. Failure to do this could result in instability, data corruption or failure of your installation.  Run backups of all components for safety.

  1. Repeat the section Prepare Web and Job Files for Deployment to get the new package ready. Instead of re-manipulating the community_server.config file, you can simply back up the existing one and use it instead.
  2. STOP the Web job for the job server. DO NOT Rely on shutting down the web app to shut it down.
  3. STOP the Web App
  4. Using FTP or another deployment option, clear the contents of the [site/wwwroot/App_Data/jobs/continuous/[Web job Name]]
  5. Using FTP or another deployment option, clear the contents of the [site/wwwroot] folder leaving the App_Data folder in tact.
  6. Connect to your database using a tool of your choice and execute the Upgrade.sql file.
  7. Re-Install the job the same was as you did in the Job Server section of the Installation.
  8. Re-Install the web files the same was as you did in the Web Files section of the Installation.
  9. Restart the Web App and Web Job