4 minutes
Pulumi Azure Bot Service
Pulumi IaaC => IaaC# (Infrastructure as CSharp) - Deploying Azure bots with Pulumi
I’ll admit that, until a week ago, I had never heard of Pulumi, but when they recently announced support for .NET - they got my attention. I’ve worked alot with JSON based Azure Resource Manager (ARM) templates in the past - but these quickly become complicated to author when you have many different Azure resources.
Whilst Terraform offers it’s own HashiCorp Configuration Language (HCL), that or working with YAML makes a bit of me want to die - the syntax seems we’ve gone back an era in computing. So, after Pulumi’s C# announcement I wanted to take a further look and see what the noise was all about. What better way to kick the tyres than to deploy a brand new Azure Bot Service instance directly into Azure.
You can read about the Pulumi architecture and high level concepts, to understand some of the basics and terminology. Under the covers Pulumi uses the Azure GO SDK which calls the Azure Management API. Once you’ve configured your IaaC, you can then integrate it into Azure DevOps Pipelines or GitHub Actions.
Deploying Azure Bot Service with Pulumi C# SDK
Essentially to deploy a Web App Bot within Azure Bot Services (ABS) requires several things:
Azure resource | Description | Optional |
---|---|---|
Resource Group | Container for the Azure resources | |
AAD Application ID and secret | AAD App registration and Authentication for the bot | |
App Service Plan | Defined set of compute resources for web app | |
AppService | Web API of the bot application | |
Bot Service | ABS bot registration | |
Application Insights | Telemetry/logging for bot application | * |
Cognitive Services | Universal key for LUIS/QnA Maker etc | * |
Declaring this in Pulumi CSharp
Let’s take a look at the individual code segments that can be used to provision the above Azure services. A link to a complete sample is provided at the bottom of this post:
Azure Resource Group
var resourceGroup = new ResourceGroup("botservice-rg");
Azure AD Application Registration
This requires the additional Pulumi.Azuread provider nuget package (this took me a while to figure out).
var msa = new Application("msapp", new ApplicationArgs
{
Oauth2AllowImplicitFlow = false,
AvailableToOtherTenants = true,
PublicClient = true
});
Azure AD Application Secret
Here we can use the additional Pulumi.Random provider nuget package to generate a strong password for the secret value and use that for the application password.
var pwd = new Random.RandomPassword("password", new Random.RandomPasswordArgs
{
Length = 16,
MinNumeric = 1,
MinSpecial = 1,
MinUpper = 1,
MinLower = 1
});
var msaSecret = new ApplicationPassword("msasecret", new ApplicationPasswordArgs
{
ApplicationObjectId = msa.ObjectId,
EndDateRelative = "8640h", // set whatever expiry you want
Value = pwd.Result
});
Azure App Service Plan
var appServicePlan = new Plan("asp", new PlanArgs
{
ResourceGroupName = resourceGroup.Name,
Kind = "App",
Sku = new PlanSkuArgs
{
Tier = "Basic",
Size = "B1"
},
});
Azure Application Insights
var appInsights = new AppInsights.Insights("ai", new AppInsights.InsightsArgs
{
ApplicationType = "web",
ResourceGroupName = resourceGroup.Name
});
Azure Application Insights API Key
var appInsightApiKey = new AppInsights.ApiKey("ai", new AppInsights.ApiKeyArgs
{
ApplicationInsightsId = appInsights.Id,
ReadPermissions = "api",
});
Azure Cognitive Service Key
Universal key for any Azure Cognitive Services used by your bot.
var luis = new Cognitive.Account("cs", new Cognitive.AccountArgs
{
Kind = "CognitiveServices", // includes LUIS
ResourceGroupName = resourceGroup.Name,
Sku = new Cognitive.Inputs.AccountSkuArgs() { Name = "S0", Tier = "Standard" }
});
Azure App Service
The web (API) application uses the Azure AD details and any Cognitive Service keys declared earlier.
var app = new AppService("app", new AppServiceArgs
{
ResourceGroupName = resourceGroup.Name,
AppServicePlanId = appServicePlan.Id,
AppSettings =
{
{ "WEBSITE_RUN_FROM_PACKAGE", codeBlobUrl },
{ "MicrosoftAppId", msa.ApplicationId },
{ "MicrosoftAppPassword", msaSecret.Value },
{ "LuisApiKey", luis.PrimaryAccessKey },
},
HttpsOnly = true
});
Azure Bot Service
Then finally the Azure Bot Service pieces it all together.
var bot = new Bot.WebApp(botName, new Bot.WebAppArgs
{
DisplayName = botName,
MicrosoftAppId = msa.ApplicationId,
ResourceGroupName = resourceGroup.Name,
Sku = "F0",
Location = "global",
Endpoint = Output.Format($"https://{app.DefaultSiteHostname}/api/messages"),
DeveloperAppInsightsApiKey = appInsightApiKey.Key,
DeveloperAppInsightsApplicationId = appInsights.AppId,
DeveloperAppInsightsKey = appInsights.InstrumentationKey
});
Then we can output the results
Take the below outputs and put them straight into the Bot Framework Emulator and you’ll be able to test the newly deployed bot. Alternatively, use the Azure Portal Azure Bot Service - Test in Webchat feature.
return new Dictionary<string, object>
{
{ "Bot Endpoint", bot.Endpoint },
{ "MicrosoftAppId", msa.ApplicationId },
{ "MicrosoftAppPassword", msaSecret.Value }
};
Execute the Pulumi CLI
$ pulumi stack init dev
$ az login
$ pulumi config set azure:location "North Europe"
$ pulumi config set botName PulumiBot1
$ pulumi up
Full source code sample
At the time of writing I’ve submitted a PR for a full sample here: https://github.com/pulumi/examples/pull/464
Full sample published here: https://github.com/pulumi/examples/tree/master/azure-cs-botservice
azure bot servicebot frameworkdevopspulumiterraformautomationIaaCazure resource managerarmc#csharp
773 Words
2019-11-17 20:08 +0000