Automating slot swapping after successful testing
TypeScriptSlot swapping is a powerful feature in Azure App Services that allows you to switch the content and configuration between two deployment slots—usually between the production slot and a staging slot. Automating this process is highly beneficial for a DevOps workflow as it enables seamless, zero-downtime deployments.
In the context of Azure App Services, a slot is a separate environment for your web app, which can be used to host different instances of your application. Commonly, a secondary slot is used for staging, where you can deploy and test changes before swapping with the production slot.
To enable automated slot swapping after successful testing, you can use the Azure Pipelines in combination with Pulumi or integrate testing and swapping as part of your CI/CD process. However, here we will focus on how to automate this process with Pulumi using TypeScript.
First, let's initialize an Azure App Service with two slots:
production
andstaging
. We will then automate the swap fromstaging
toproduction
.Before you start, ensure you have Pulumi CLI installed and configured to interact with Azure. You should also have Node.js installed to run the TypeScript program.
Here is a Pulumi program that sets up two slots and provides a mechanism for swapping them after successful testing:
import * as azure from "@pulumi/azure"; import * as pulumi from "@pulumi/pulumi"; // Create an Azure Resource Group const resourceGroup = new azure.core.ResourceGroup("resourceGroup", { location: azure.Locations.WestEurope, // Choose the appropriate location }); // Create an App Service Plan const appServicePlan = new azure.appservice.Plan("appServicePlan", { resourceGroupName: resourceGroup.name, kind: "App", sku: { tier: "Standard", size: "S1", }, }); // Create a Function App const functionApp = new azure.appservice.FunctionApp("functionApp", { resourceGroupName: resourceGroup.name, appServicePlanId: appServicePlan.id, siteConfig: { dotnetFrameworkVersion: "~3", }, }); // Create a staging slot associated with the Function App const stagingSlot = new azure.appservice.Slot("stagingSlot", { appServiceName: functionApp.name, resourceGroupName: resourceGroup.name, siteConfig: { dotnetFrameworkVersion: "~3", }, }); // Function to perform the slot swap export function swapSlots(): Promise<void> { // Logic to determine whether the staging environment is ready for production can be done here. // This could be based on automated tests or other verification processes. // If the tests passed, perform the swap return pulumi.all([functionApp.name, resourceGroup.name, stagingSlot.name]).apply( ([functionAppName, resourceGroupName, stagingSlotName]) => { const liveSlot = new azure.appservice.Slot("productionSlot", { appServiceName: functionAppName, resourceGroupName: resourceGroupName, siteConfig: { dotnetFrameworkVersion: "~3", }, name: stagingSlotName, }, { deleteBeforeReplace: true, }); return liveSlot.id.apply(id => { if (!id) return Promise.resolve(); return azure.appservice.getSlot({ name: functionAppName, resourceGroupName: resourceGroupName, slot: stagingSlotName, }).then(slot => { return azure.appservice.listSlotConfigurationNames({ resourceGroupName: resourceGroupName, name: functionAppName, }).then(configNames => { return azure.appservice.updateSlot({ name: functionAppName, slot: "production", resourceGroupName: resourceGroupName, appServicePlanId: appServicePlan.id, // Any other configuration that should be updated can be specified here. }).then(() => { console.log(`Slot swap between 'production' and '${stagingSlotName}' complete!`); }); }); }); }); } ); } // Export the name and endpoint of the function app export const endpoint = pulumi.interpolate`https://${functionApp.defaultHostname}/api/MyFunction?code=${functionApp.defaultSiteHostname}`;
In this program:
- We import the necessary Pulumi and Azure packages.
- We create an Azure resource group as a container for our Azure resources.
- We create an App Service Plan, which dictates the underlying Virtual Machine that hosts our web apps.
- We then create a Function App. This could equally be a Web App depending on the specifics of the scenario.
- Then, we define a
stagingSlot
as a deployment slot associated with our Function App. - The
swapSlots
function is an example of how you might automate the process of swapping slots based on some tests. The actual implementation of your tests or conditions should be placed in this function.
Notes:
- This program assumes you have
.pulumi/config
set or environment variables configured to provide access to your Azure subscription, and Pulumi is configured to create resources in Azure. - In a real-world scenario, the logic to verify the testing conditions should be implemented in the
swapSlots
function. This can integrate with your testing framework or another verification system. - Ensure that you understand the costs associated with the resources deployed using this code and how to clean up resources to avoid unnecessary charges.
To execute the slot swap after successful testing, simply call the
swapSlots
function in your deployment process, which might be part of a CI/CD pipeline or an automated script.Remember to replace the import statements with the appropriate package versions and verify the regions and sizes are suitable for your needs.