Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

title slide
What is this presentation about?

This presentation will describe an approach to using Sitecore Azure within a Continuous Delivery pipeline.


This is not about Continuous Delivery/Deployment, but about how Sitecore Azure fits into those methodologies.


Continuous Delivery 101

1) ARCHITECTURE
2) CODE
3) TIPS + TRICKS


Example Architecture with Sitecore Azure

Where does this topic fit?

Deployment continues as normal, up to the Content Management server that has the Sitecore Azure module installed.

Once code and content is deployed to the Content Management server, then the Sitecore Azure module is invoked via HTTP Requests to start the deployment process, and later the role swap process. The code provides the HTTP Request interface.

What the Code Will Do?


Sitecore Azure Deployment and Swap

1) ARCHITECTURE
2) CODE
3) TIPS + TRICKS

Sitecore Azure Terminology


  • Deployment - A Web Role instance
  • Upgrade Files - Copy and deploy content from Content Management to Web Role(s)
  • Swap - Swap Web Role instance(s) from Staging to Production
But first, some terminology...
Adding a Service for Sitecore Azure

We require a Sitecore context to run the Sitecore Azure commands, therefore we need to intercept HTTP requests via the HttpRequestBegin pipeline. When invoked, the service will find deployments for given subscription, and call 'Upgrade Files' command.

            
public AzureDeployments GetDeployments()
{

	var azureDeployments = new AzureDeployments {
		SubscriptionId = _configurationProvider.Settings.SubscriptionId
	};

	//Get list of environments
	IEnumerable environments =
		Environments.Environment.GetEnvironments(azureDeployments.SubscriptionId);

	if (environments != null)
	{
		foreach (var environment in environments)
		{
			//Create new environment
			var azureEnvironment = new AzureEnvironment { 
			EnvironmentId = environment.EnvironmentId, 
			Environment = environment.DisplayName };

			foreach (var deployment in environment.GetDeployments())
			{
				//Add deployment to collection
				azureEnvironment.Deployment.Add(
					new AzureDeployment
						{
							DeploymentId = deployment.ID.ToString(),
							Location = deployment.WebRole.Farm.Location.Name,
							DeploymentName = deployment.DisplayName,
							DeploymentType = deployment.DeploymentType.ToString(),
							DeploymentSlot = deployment.DeploymentSlot.ToString(),
							HostedServiceName = deployment.HostedServiceName,
							Databases = deployment.DatabaseReferences.DisplayName
						});
			}

			//Add environment to collection
			azureDeployments.Deployments.Add(azureEnvironment);

		}

	}
	else
	{
		//Log action
		Log.Info(string.Format("No deployments found for Subscription ID : {0}", 
		_configurationProvider.Settings.SubscriptionId), this);
	}

	return azureDeployments;
}
            
            
            
public AzureDeployments GetDeployments()
{

	var azureDeployments = new AzureDeployments {
		SubscriptionId = _configurationProvider.Settings.SubscriptionId
	};

	//Get list of environments
	IEnumerable environments =
		Sitecore.Azure.Deployments.Environments.Environment.GetEnvironments(azureDeployments.SubscriptionId);

	if (environments != null)
	{
		foreach (var environment in environments)
		{
			//Create new environment
			var azureEnvironment = new AzureEnvironment { 
			EnvironmentId = environment.EnvironmentId, 
			Environment = environment.DisplayName };

			foreach (var deployment in environment.GetDeployments())
			{
				//Add deployment to collection
				azureEnvironment.Deployment.Add(
					new AzureDeployment
						{
							DeploymentId = deployment.ID.ToString(),
							Location = deployment.WebRole.Farm.Location.Name,
							DeploymentName = deployment.DisplayName,
							DeploymentType = deployment.DeploymentType.ToString(),
							DeploymentSlot = deployment.DeploymentSlot.ToString(),
							HostedServiceName = deployment.HostedServiceName,
							Databases = deployment.DatabaseReferences.DisplayName
						});
			}

			//Add environment to collection
			azureDeployments.Deployments.Add(azureEnvironment);

		}

	}
	else
	{
		//Log action
		Log.Info(string.Format("No deployments found for Subscription ID : {0}", 
		_configurationProvider.Settings.SubscriptionId), this);
	}

	return azureDeployments;
}
            
            
            
public void UpdateFiles()
{
	//If no subscriptionId passed in parameters then use configuration provided id
	var subscriptionId = _configurationProvider.Settings.SubscriptionId;

	//Get list of environments
	IEnumerable environments =
		Sitecore.Azure.Deployments.Environments.Environment.GetEnvironments(subscriptionId);

	//Loop through environments and deployments
	foreach (var deployment in environments.SelectMany(
		environment => AzureDeploymentManager.Current.GetDeployments(environment)))
	{
		AzureDeploymentManager.Current.UpgradeDeploymentAsync(deployment);

		Log.Info(string.Format("Updated deployment : {0}", deployment.DisplayName), this);
	}
}
            
            
            
public void UpdateFiles()
{
	//If no subscriptionId passed in parameters then use configuration provided id
	var subscriptionId = _configurationProvider.Settings.SubscriptionId;

	//Get list of environments
	IEnumerable environments =
		Sitecore.Azure.Deployments.Environments.Environment.GetEnvironments(subscriptionId);

	//Loop through environments and deployments
	foreach (var deployment in environments.SelectMany(
		environment => AzureDeploymentManager.Current.GetDeployments(environment)))
	{
		AzureDeploymentManager.Current.UpgradeDeploymentAsync(deployment);

		Log.Info(string.Format("Updated deployment : {0}", deployment.DisplayName), this);
	}
}
            
            
            
	public void SwapDeployments()
	{
		//If no subscriptionId passed in parameters then use configuration provided id
		var subscriptionId = _configurationProvider.Settings.SubscriptionId;

		//Get list of environments
		IEnumerable environments =
			Sitecore.Azure.Deployments.Environments.Environment.GetEnvironments(subscriptionId);

		//Loop through environments and deployments
		foreach (var deployment in environments.SelectMany(environment => AzureDeploymentManager.Current.GetDeployments(environment)))
		{
			AzureDeploymentManager.Current.SwapAsync(deployment);

			Log.Info(string.Format("Swapped deployment : {0}", deployment.DisplayName), this);
		}
	}
            
            
            
	public void SwapDeployments()
	{
		//If no subscriptionId passed in parameters then use configuration provided id
		var subscriptionId = _configurationProvider.Settings.SubscriptionId;

		//Get list of environments
		IEnumerable environments =
			Sitecore.Azure.Deployments.Environments.Environment.GetEnvironments(subscriptionId);

		//Loop through environments and deployments
		foreach (var deployment in environments.SelectMany(environment => AzureDeploymentManager.Current.GetDeployments(environment)))
		{
			AzureDeploymentManager.Current.SwapAsync(deployment);

			Log.Info(string.Format("Swapped deployment : {0}", deployment.DisplayName), this);
		}
	}
            
            


Deployment Success!

1) ARCHITECTURE
2) CODE
3) TIPS + TRICKS

Alerting and Monitoring Deployments

Sitecore Azure does not provide any alerting out of the box. When used in a CD pipeline, this means that the final deployment could fail (or succeed) without alerting anyone.

To get around this, add a pipeline processor into the 'UpgradeDeployment' pipeline.

            
				<UpgradeDeployment patch:source="Sitecore.Azure.config">
					<processor type="Sitecore.Azure.Pipelines.DeployAndRun.Azure.ResolveSources, Sitecore.Azure"/>
					<processor type="Sitecore.Azure.Pipelines.DeployAndRun.Azure.CreatePackage, Sitecore.Azure"/>
					<processor type="Sitecore.Azure.Pipelines.DeployAndRun.Azure.Upload, Sitecore.Azure"/>
					<processor type="Sitecore.Azure.Pipelines.UpgradeDeployment.Upgrade, Sitecore.Azure"/>
					<processor type="Sitecore.Azure.Pipelines.UpgradeDeployment.WaitForInitialization, Sitecore.Azure"/>
					<processor type="Sitecore.Azure.Pipelines.DeployAndRun.Azure.Finalize, Sitecore.Azure"/>
					Add processor for monitoring here
				</UpgradeDeployment>
            
            
            
				<SwapAzureDeployment patch:source="Sitecore.Azure.config">
					<processor type="Sitecore.Azure.Pipelines.SwapAzureDeployment.SwapAzureDeployment, Sitecore.Azure"/>
					Add processor for monitoring here
				</SwapAzureDeployment>
            
            

Thanks for listening!

@brooksyd2dbs

dbs@sitecore.net