-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start using Bicep and Az CLI for deployment
- Loading branch information
1 parent
45a4567
commit bbf572a
Showing
24 changed files
with
989 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<Project> | ||
<Target Name="ZipPublishDir" AfterTargets="Publish"> | ||
<ZipDirectory | ||
SourceDirectory="$(PublishDir)" | ||
DestinationFile="$(DeployDirectory)\$(MSBuildProjectName).zip" | ||
Overwrite="true" /> | ||
</Target> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"Deployment": { | ||
"ExistingWebsitePlanId": "/subscriptions/87b3a2cf-ab4e-487b-a7af-59192cd21caf/resourceGroups/Shared-WestUS2/providers/Microsoft.Web/serverfarms/Shared-WestUS2", | ||
"WorkerCount": 3, | ||
"WorkerLogLevel": "Information" | ||
}, | ||
"AppSettings": { | ||
"Shared": { | ||
"Knapcode.ExplorePackages": { | ||
"DisabledDrivers": [ | ||
"NuGetPackageExplorerToCsv" | ||
], | ||
"RestrictUsers": false | ||
} | ||
}, | ||
"Worker": { | ||
"Knapcode.ExplorePackages": { | ||
"MoveTempToHome": true | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
[CmdletBinding()] | ||
param ( | ||
[Parameter(Mandatory = $true)] | ||
[string]$ConfigName, | ||
|
||
[Parameter(Mandatory)] | ||
[string]$StackName | ||
) | ||
|
||
$ErrorActionPreference = "Stop" | ||
. (Join-Path $PSScriptRoot "scripts/common.ps1") | ||
|
||
$configPath = Join-Path $PSScriptRoot "config/$ConfigName.json" | ||
function Get-Config() { Get-Content $configPath | ConvertFrom-Json | ConvertTo-Hashtable } | ||
|
||
# Prepare the website config | ||
$websiteConfig = Get-Config | ||
$websiteConfig = Merge-Hashtable $websiteConfig.AppSettings.Shared $websiteConfig.AppSettings.Website | ||
|
||
# Prepare the worker config | ||
$workerConfig = Get-Config | ||
$workerConfig = Merge-Hashtable $workerConfig.AppSettings.Shared $workerConfig.AppSettings.Worker | ||
|
||
# Prepare the deployment parameters | ||
$parameters = Get-Config | ||
$parameters = $parameters.Deployment | ||
$parameters.StackName = if ($StackName) { $StackName } else {$ConfigName } | ||
$parameters.WebsiteConfig = $websiteConfig | ||
$parameters.WorkerConfig = $workerConfig | ||
|
||
. (Join-Path $PSScriptRoot "scripts/Invoke-Deploy") @parameters |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
// Parameters | ||
param stackName string | ||
|
||
param storageAccountName string | ||
param storageKeySecretName string | ||
param sasDefinitionName string | ||
|
||
param keyVaultName string | ||
|
||
param websitePlanId string | ||
param websiteAadClientId string | ||
param websiteConfig array | ||
|
||
param workerConfig array | ||
@allowed([ | ||
'Warning' | ||
'Information' | ||
]) | ||
param workerLogLevel string = 'Warning' | ||
@minValue(1) | ||
param workerCount int | ||
param existingWorkerCount int | ||
|
||
// Shared resources | ||
resource insights 'Microsoft.Insights/components@2015-05-01' = { | ||
name: 'ExplorePackages-${stackName}' | ||
location: resourceGroup().location | ||
kind: 'web' | ||
properties: { | ||
Application_Type: 'web' | ||
} | ||
} | ||
|
||
resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' existing = { | ||
name: storageAccountName | ||
} | ||
|
||
// Cannot use a KeyVault reference for initial deployment. | ||
// https://github.com/Azure/azure-functions-host/issues/7094 | ||
var storageSecretValue = 'DefaultEndpointsProtocol=https;AccountName=${storageAccountName};AccountKey=${listkeys(storageAccount.id, storageAccount.apiVersion).keys[0].value};EndpointSuffix=core.windows.net' | ||
var storageSecretReference = '@Microsoft.KeyVault(VaultName=${keyVaultName};SecretName=${storageKeySecretName})' | ||
var workerSecret = existingWorkerCount >= workerCount ? storageSecretReference : storageSecretValue | ||
|
||
output needsAnotherDeploy bool = workerSecret != storageSecretReference | ||
output websiteDefaultHostName string = website.properties.defaultHostName | ||
output websiteHostNames array = website.properties.hostNames | ||
output websiteId string = website.id | ||
output workerIds array = [for i in range(0, workerCount): workers[i].id] | ||
|
||
var sharedConfig = [ | ||
{ | ||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY' | ||
value: insights.properties.InstrumentationKey | ||
} | ||
{ | ||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING' | ||
value: insights.properties.ConnectionString | ||
} | ||
{ | ||
name: 'ApplicationInsightsAgent_EXTENSION_VERSION' | ||
value: '~2' | ||
} | ||
{ | ||
name: 'Knapcode.ExplorePackages:StorageAccountName' | ||
value: storageAccountName | ||
} | ||
{ | ||
name: 'Knapcode.ExplorePackages:StorageSharedAccessSignature' | ||
value: '@Microsoft.KeyVault(VaultName=${keyVaultName};SecretName=${storageAccountName}-${sasDefinitionName})' | ||
} | ||
{ | ||
name: 'WEBSITE_RUN_FROM_PACKAGE' | ||
value: '1' | ||
} | ||
] | ||
|
||
resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' = { | ||
name: keyVaultName | ||
location: resourceGroup().location | ||
properties: { | ||
tenantId: subscription().tenantId | ||
sku: { | ||
family: 'A' | ||
name: 'standard' | ||
} | ||
accessPolicies: [for i in range(0, workerCount + 1): { | ||
tenantId: i == 0 ? website.identity.tenantId : workers[i - 1].identity.tenantId | ||
objectId: i == 0 ? website.identity.principalId : workers[i - 1].identity.principalId | ||
permissions: { | ||
secrets: [ | ||
'get' | ||
] | ||
} | ||
}] | ||
} | ||
} | ||
|
||
resource keyVaultDiagnostics 'microsoft.insights/diagnosticSettings@2017-05-01-preview' = { | ||
scope: keyVault | ||
name: '${keyVaultName}-diagnostics' | ||
properties: { | ||
storageAccountId: storageAccount.id | ||
logs: [ | ||
{ | ||
category: 'AuditEvent' | ||
enabled: true | ||
retentionPolicy: { | ||
enabled: true | ||
days: 30 | ||
} | ||
} | ||
] | ||
} | ||
} | ||
|
||
// Website | ||
resource website 'Microsoft.Web/sites@2020-09-01' = { | ||
name: 'ExplorePackages-${stackName}' | ||
location: resourceGroup().location | ||
identity: { | ||
type: 'SystemAssigned' | ||
} | ||
properties: { | ||
serverFarmId: websitePlanId | ||
clientAffinityEnabled: false | ||
httpsOnly: true | ||
siteConfig: { | ||
webSocketsEnabled: true | ||
minTlsVersion: '1.2' | ||
netFrameworkVersion: 'v5.0' | ||
appSettings: concat([ | ||
{ | ||
name: 'AzureAd:Instance' | ||
value: 'https://login.microsoftonline.com/' | ||
} | ||
{ | ||
name: 'AzureAd:ClientId' | ||
value: websiteAadClientId | ||
} | ||
{ | ||
name: 'AzureAd:TenantId' | ||
value: 'common' | ||
} | ||
], sharedConfig, websiteConfig) | ||
} | ||
} | ||
} | ||
|
||
// Workers | ||
resource workerPlan 'Microsoft.Web/serverfarms@2020-09-01' = { | ||
name: 'ExplorePackages-${stackName}-WorkerPlan' | ||
location: resourceGroup().location | ||
sku: { | ||
name: 'Y1' | ||
} | ||
} | ||
|
||
resource workers 'Microsoft.Web/sites@2020-09-01' = [for i in range(0, workerCount): { | ||
name: 'ExplorePackages-${stackName}-Worker-${i}' | ||
location: resourceGroup().location | ||
kind: 'FunctionApp' | ||
identity: { | ||
type: 'SystemAssigned' | ||
} | ||
properties: { | ||
serverFarmId: workerPlan.id | ||
clientAffinityEnabled: false | ||
httpsOnly: true | ||
siteConfig: { | ||
minTlsVersion: '1.2' | ||
appSettings: concat([ | ||
{ | ||
name: 'AzureFunctionsJobHost__logging__LogLevel__Default' | ||
value: workerLogLevel | ||
} | ||
{ | ||
name: 'AzureWebJobsFeatureFlags' | ||
value: 'EnableEnhancedScopes' | ||
} | ||
{ | ||
name: 'AzureWebJobsStorage' | ||
value: workerSecret | ||
} | ||
{ | ||
name: 'FUNCTIONS_EXTENSION_VERSION' | ||
value: '~3' | ||
} | ||
{ | ||
name: 'FUNCTIONS_WORKER_RUNTIME' | ||
value: 'dotnet' | ||
} | ||
{ | ||
name: 'SCM_DO_BUILD_DURING_DEPLOYMENT' | ||
value: 'false' | ||
} | ||
{ | ||
name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING' | ||
value: workerSecret | ||
} | ||
], sharedConfig, workerConfig) | ||
} | ||
} | ||
}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
[CmdletBinding()] | ||
param ( | ||
[Parameter(Mandatory = $true)] | ||
[string]$AadAppName | ||
) | ||
|
||
$ErrorActionPreference = "Stop" | ||
. (Join-Path $PSScriptRoot "common.ps1") | ||
|
||
Write-Status "Looking for AAD app with name '$AadAppName'..." | ||
Invoke-Call { az ad app list ` | ||
--display-name $AadAppName ` | ||
--query "[].{displayName: displayName, appId: appId, objectId: objectId}" } | Tee-Object -Variable 'existingApps' | Out-Host | ||
$existingApps = $existingApps | ConvertFrom-Json | ||
|
||
if ($existingApps.Count -eq 0) { | ||
Write-Status "Creating a new AAD app..." | ||
Invoke-Call { az ad app create ` | ||
--display-name $AadAppName ` | ||
--query "{displayName: displayName, appId: appId, objectId: objectId}" } | Tee-Object -Variable 'app' | Out-Host | ||
$app = $app | ConvertFrom-Json | ||
Write-Status "Created new app with object ID '$($app.objectId)'." | ||
} elseif ($existingApps.Count -eq 1) { | ||
$app = $existingApps[0] | ||
Write-Status "Using existing app with object ID '$($app.objectId)'." | ||
} else { | ||
Write-Warning "There are $($existingApps.Count) apps with the name '$AadAppName'. Using the first with object ID '$($app.objectId)'." | ||
$app = $existingApps[0] | ||
} | ||
|
||
New-Object PSObject -Property ([ordered]@{ | ||
appId = $app.appId; | ||
objectId = $app.objectId | ||
}) |
Oops, something went wrong.