Monday, June 24, 2019

Using the Azure Node SDK to Create/Update an AppService Container

The Azure Node SDK allows developers to manipulate Azure resources via typescript and node. I was recently tasked with using this SDK to create and update an Azure AppService that was based on a container located in an Azure Container Registry. This means that instead of deploying the application code directly, the AppService runs a Docker image container. Doing things this way, you get all the benefits that containers have to offer.

The problem is that while the Node SDK for app services is very robust, the documentation is a bit lacking (for the moment, anyway?). The SDK is broken out into many separate components. The AppService module can be found here: https://www.npmjs.com/package/@azure/arm-appservice.

After much soul-searching, virgin sacrifices and rain dancing, I managed to find the combination of parameter options that allow me to achieve what I'm after. Using this object:

const newSite: Site = { 
   location: [MY LOCATION], 
   name: [MY SITE NAME], 
   kind: 'app,linux,container', 
   type: 'Microsoft.Web/sites', 
   serverFarmId: '[MY SERVER FARM ID]', 
   resourceGroup: [MY RESOURCE GROUP], 
   reserved: true, 
   isXenon: false, 
   hyperV: false, 
   isDefaultContainer: false, 
   siteConfig: { 
      linuxFxVersion: DOCKER|[REGISTRY URL]/[CONTAINER NAME]:[TAG], 
      appSettings: [ 
            {
                'name': 'WEBSITES_ENABLE_APP_SERVICE_STORAGE',
                'value': 'false'
            },
            {
                'name': 'WEBSITE_HTTPLOGGING_RETENTION_DAYS',
                'value': '14'
            },
            {
                'name': 'DOCKER_REGISTRY_SERVER_URL',
                'value': '[MY REGISTRY URL]'
            },
            {
                 'name': 'DOCKER_REGISTRY_SERVER_USERNAME',
                 'value': '[MY REGISTRY USER]'
            },
            {
                 'name': 'DOCKER_REGISTRY_SERVER_PASSWORD',
                 'value': '[MY REGISTRY PASSWORD]'
            } ]
        }
 }

I was able to call createOrUpdate() and successfully create, and then subsequently update a container-based app service.
import { WebSiteManagementClient } from '@azure/arm-appservice';
import { loginWithServicePrincipalSecret } from "@azure/ms-rest-nodeauth";

await loginWithServicePrincipalSecret(appId, secret, domain, 
    async (err, creds) => { 
        const client = new WebSiteManagementClient(creds, subscriptionId); 
        await client.webApps.createOrUpdate( 
             resourceGroupName, 
             siteName, 
             newSite 
        ); 
});
After running this, I was able to view my newly created AppService in the Azure portal (Note the Container settings item under Settings).




Hopefully this post will offer some guidance to those trying to use this really valuable SDK while the documentation gets some love from their developers.