Added Blueprint automation content

This commit is contained in:
Ben Houghton 2018-07-20 14:01:21 +01:00
Родитель 098fe04b00
Коммит 4310abbc28
13 изменённых файлов: 1988 добавлений и 26 удалений

34
LICENSE
Просмотреть файл

@ -1,21 +1,21 @@
MIT License
MIT License
Copyright (c) Microsoft Corporation. All rights reserved.
Copyright (c) 2018 Ian Alderman
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Просмотреть файл

@ -0,0 +1,4 @@
# Key Vault Template
This template deploys an Azure Key Vault instance. This KeyVault instance has uses Soft Delete and Purge Protection in order to support Bring Your Own Key (BYOK) in Azure SQL and Storage.

Просмотреть файл

@ -0,0 +1,121 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"baseResourceName": {
"type": "string",
"metadata": {
"description": "Name of the resource"
},
"maxLength": 15,
"defaultValue": "[uniqueString(resourceGroup().id)]"
},
"storageAccountId": {
"type": "string",
"metadata": {
"description": "Resource Id for the storage account to store diagnostics"
},
"defaultValue": "[json('null')]"
},
"workspaceId": {
"type": "string",
"metadata": {
"description": "Resource Id for the Log Analytics workspace to store diagnostics"
},
"defaultValue": "[json('null')]"
},
"LogsRetentionInDays": {
"type": "int",
"metadata": {
"description": "Number of days to retain logs"
},
"defaultValue": 7
},
"accessPolicies": {
"type": "array",
"metadata": {
"description": "Array of Access Policies to apply to the vault"
},
"defaultValue": []
},
"secretsAndKeys": {
"type": "array",
"metadata": {
"description": "Array of Secrets & Keys to apply to the vault"
},
"defaultValue": []
},
"vaultNameSuffix": {
"type": "string",
"metadata": {
"description": "Suffix to apply to the name of the Key Vault"
},
"defaultValue": "vault"
}
},
"variables": {
"tenantId": "[subscription().tenantId]",
"vaultName": "[concat('kv',parameters('baseResourceName'), parameters('vaultNameSuffix'))]"
},
"resources": [
{
"type": "Microsoft.KeyVault/vaults",
"name": "[variables('vaultName')]",
"apiVersion": "2015-06-01",
"location": "[resourceGroup().location]",
"properties": {
"tenantId": "[variables('tenantId')]",
"sku": {
"family": "A",
"name": "Standard"
},
"accessPolicies": "[parameters('accessPolicies')]",
"resources": [
{
"copy": [
{
"name": "deployKeyVaultChildResources",
"count": "[length(parameters('secretsAndKeys'))]",
"input": {
"type": "[parameters('secretsAndKeys')[copyIndex('deployKeyVaultChildResources')].type]",
"name": "[parameters('secretsAndKeys')[copyIndex('deployKeyVaultChildResources')].name]",
"apiVersion": "[parameters('secretsAndKeys')[copyIndex('deployKeyVaultChildResources')].apiVersion]",
"properties": "[parameters('secretsAndKeys')[copyIndex('deployKeyVaultChildResources')].properties]"
}
}
]
},
{
"type":"Microsoft.KeyVault/vaults/providers/diagnosticsettings",
"name":"[concat(variables('vaultName'), '/Microsoft.Insights/service')]",
"apiVersion":"2016-09-01",
"location":"[resourceGroup().location]",
"dependsOn":[
"[concat('Microsoft.KeyVault/vaults/', variables('vaultName'))]"
],
"properties":{
"storageAccountId":"[parameters('storageAccountId')]",
"workspaceId":"[parameters('workspaceId')]",
"logs":[
{
"category":"AuditEvent",
"enabled":true,
"retentionPolicy":{
"enabled":true,
"days":"[parameters('LogsRetentionInDays')]"
}
}
]
}
}
]
}
}
],
"outputs": {
"keyVaultId": {
"type": "string",
"value": "[resourceId('Microsoft.KeyVault/vaults',variables('vaultName'))]"
}
}
}

Просмотреть файл

@ -0,0 +1,233 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"workspaceName": {
"type": "string",
"metadata": {
"description": "Name of the resource"
},
"maxLength": 15,
"defaultValue": "[uniqueString(resourceGroup().id)]"
},
"LogsRetentionInDays": {
"type": "int",
"defaultValue": 7,
"metadata": {
"description": "Number of days to retain logs"
}
},
"LogsWorkspaceLocation": {
"type": "string",
"allowedValues": [
"eastus",
"westeurope",
"southeastasia",
"australiasoutheast",
"westcentralus",
"japaneast",
"uksouth",
"centralindia",
"canadacentral"
],
"defaultValue": "westeurope",
"metadata": {
"description": "The Azure region the Logs Workspace will be deployed to"
}
},
"logAnalyticsSKU": {
"type": "string",
"defaultValue": "Free",
"allowedValues": [
"Free",
"pergb2018"
],
"metadata": {
"description": "The pricing tier of the Log Analytics workspace. New workspaces should be ok 'pergb2018', some subscritpions may require 'Free' please see http://aka.ms/PricingTierWarning"
}
},
"AuditRetentionPeriodInDays": {
"type": "int",
"defaultValue": 7
}
},
"variables": {
"SQLAssessment": {
"Name": "[Concat('SQLAssessment', '(', parameters('workspaceName'), ')')]",
"GalleryName": "SQLAssessment"
},
"ApplicationInsights": {
"Name": "[Concat('ApplicationInsights', '(', parameters('workspaceName'), ')')]",
"GalleryName": "ApplicationInsights"
},
"KeyVaultAnalytics": {
"Name": "[Concat('KeyVaultAnalytics', '(', parameters('workspaceName'), ')')]",
"GalleryName": "KeyVaultAnalytics"
},
"AzureSQLAnalytics": {
"Name": "[Concat('AzureSQLAnalytics', '(', parameters('workspaceName'), ')')]",
"GalleryName": "AzureSQLAnalytics"
},
"AzureActivity": {
"Name": "[Concat('AzureActivity', '(', parameters('workspaceName'), ')')]",
"GalleryName": "AzureActivity"
},
"AzureWebAppsAnalytics": {
"Name": "[Concat('AzureWebAppsAnalytics', '(', parameters('workspaceName'), ')')]",
"GalleryName": "AzureWebAppsAnalytics"
}
},
"resources": [
{
"name": "[parameters('workspaceName')]",
"type": "Microsoft.OperationalInsights/workspaces",
"apiVersion": "2017-04-26-preview",
"location": "[parameters('LogsWorkspaceLocation')]",
"dependsOn": [],
"properties": {
"retention": "[parameters('LogsRetentionInDays')]",
"sku": {
"name": "[parameters('LogAnalyticsSKU')]"
}
},
"resources": [
{
"name": "AzureActivityLog",
"type": "datasources",
"apiVersion": "2015-11-01-preview",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
],
"kind": "AzureActivityLog",
"properties": {
"linkedResourceId": "[concat(subscription().id, '/providers/Microsoft.Insights/eventTypes/management')]"
}
}
]
},
{
"apiVersion": "2015-11-01-preview",
"location": "[parameters('LogsWorkspaceLocation')]",
"name": "[variables('SQLAssessment').Name]",
"type": "Microsoft.OperationsManagement/solutions",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.OperationsManagement/solutions/', variables('SQLAssessment').Name)]",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
],
"properties": {
"workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
},
"plan": {
"name": "[variables('SQLAssessment').Name]",
"publisher": "Microsoft",
"product": "[Concat('OMSGallery/', variables('SQLAssessment').GalleryName)]",
"promotionCode": ""
}
},
{
"apiVersion": "2015-11-01-preview",
"location": "[parameters('LogsWorkspaceLocation')]",
"name": "[variables('ApplicationInsights').Name]",
"type": "Microsoft.OperationsManagement/solutions",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.OperationsManagement/solutions/', variables('ApplicationInsights').Name)]",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
],
"properties": {
"workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
},
"plan": {
"name": "[variables('ApplicationInsights').Name]",
"publisher": "Microsoft",
"product": "[Concat('OMSGallery/', variables('ApplicationInsights').GalleryName)]",
"promotionCode": ""
},
"resources": [
]
},
{
"apiVersion": "2015-11-01-preview",
"location": "[parameters('LogsWorkspaceLocation')]",
"name": "[variables('KeyVaultAnalytics').Name]",
"type": "Microsoft.OperationsManagement/solutions",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.OperationsManagement/solutions/', variables('KeyVaultAnalytics').Name)]",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
],
"properties": {
"workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
},
"plan": {
"name": "[variables('KeyVaultAnalytics').Name]",
"publisher": "Microsoft",
"product": "[Concat('OMSGallery/', variables('KeyVaultAnalytics').GalleryName)]",
"promotionCode": ""
}
},
{
"apiVersion": "2015-11-01-preview",
"location": "[parameters('LogsWorkspaceLocation')]",
"name": "[variables('AzureSQLAnalytics').Name]",
"type": "Microsoft.OperationsManagement/solutions",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.OperationsManagement/solutions/', variables('AzureSQLAnalytics').Name)]",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
],
"properties": {
"workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
},
"plan": {
"name": "[variables('AzureSQLAnalytics').Name]",
"publisher": "Microsoft",
"product": "[Concat('OMSGallery/', variables('AzureSQLAnalytics').GalleryName)]",
"promotionCode": ""
}
},
{
"apiVersion": "2015-11-01-preview",
"location": "[parameters('LogsWorkspaceLocation')]",
"name": "[variables('AzureActivity').Name]",
"type": "Microsoft.OperationsManagement/solutions",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.OperationsManagement/solutions/', variables('AzureActivity').Name)]",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
],
"properties": {
"workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
},
"plan": {
"name": "[variables('AzureActivity').Name]",
"publisher": "Microsoft",
"product": "[Concat('OMSGallery/', variables('AzureActivity').GalleryName)]",
"promotionCode": ""
}
},
{
"apiVersion": "2015-11-01-preview",
"location": "[parameters('LogsWorkspaceLocation')]",
"name": "[variables('AzureWebAppsAnalytics').Name]",
"type": "Microsoft.OperationsManagement/solutions",
"id": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.OperationsManagement/solutions/', variables('AzureWebAppsAnalytics').Name)]",
"dependsOn": [
"[concat('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
],
"properties": {
"workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
},
"plan": {
"name": "[variables('AzureWebAppsAnalytics').Name]",
"publisher": "Microsoft",
"product": "[Concat('OMSGallery/', variables('AzureWebAppsAnalytics').GalleryName)]",
"promotionCode": ""
}
}
],
"outputs": {
"workspaceId": {
"type": "string",
"value": "[resourceId('Microsoft.OperationalInsights/workspaces/', parameters('workspaceName'))]"
}
}
}

Просмотреть файл

@ -0,0 +1,433 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"baseResourceName": {
"type": "string",
"metadata": {
"description": "Name of the resource"
},
"maxLength": 15,
"defaultValue": "[uniqueString(resourceGroup().id)]"
},
"databaseName": {
"type": "string",
"defaultValue": "[concat('db-', parameters('baseResourceName'))]",
"metadata": {
"description": "Name of the Database to be deployed"
}
},
"databaseServerName": {
"type": "string",
"defaultValue": "[concat('svr-', uniqueString(resourceGroup().id))]",
"metadata": {
"description": "Name of the Database Server to be deployed"
}
},
"transparentDataEncryption": {
"type": "string",
"allowedValues": [
"Enabled",
"Disabled"
],
"defaultValue": "Enabled",
"metadata": {
"description": "Enable or disable Transparent Data Encryption (TDE) for the database."
}
},
"AuditRetentionPeriodInDays": {
"type": "int",
"defaultValue": 7
},
"sqlServerAdminLogin": {
"type": "string",
"metadata": {
"description": "The username for administering the SQL Server"
},
"defaultValue":"dbaMan"
},
"sqlServerAdminPassword": {
"type": "securestring",
"metadata": {
"description": "The password for administering the SQL Server"
},
"defaultValue": "[concat('L1',uniqueString(subscription().id),'#')]"
},
"sqlDatabaseEdition": {
"type": "string",
"metadata": {
"description": "The type of database to create."
},
"allowedValues": [
"Basic",
"Standard",
"Premium"
],
"defaultValue": "Basic"
},
"sqlDatabaseCollation": {
"type": "string",
"defaultValue": "SQL_Latin1_General_CP1_CI_AS",
"metadata": {
"description": "The database collation for governing the proper use of characters."
}
},
"sqlDatabaseMaxSizeBytes": {
"type": "string",
"defaultValue": "1073741824",
"metadata": {
"description": "The maximum size, in bytes, for the database"
}
},
"useAADForSQLAdmin": {
"type": "string",
"metadata": {
"description": "Should the SQL Database be set to support Azure Active Directory User/Group for Administration. If set the 'AADAdminObjectID' and 'AADLogin' parameters must be set."
},
"allowedValues": [
"Yes",
"No"
],
"defaultValue": "No"
},
"AADAdminLogin": {
"type": "string",
"metadata": {
"description": "The Login ID for the Azure Active Directory user or group to be a server admin"
},
"defaultValue": "ignore"
},
"AADAdminObjectID": {
"type": "string",
"metadata": {
"description": "The Object ID for the Azure Active Directory user or group to be a server admin"
},
"defaultValue": "ignore"
},
"AlertWindowSizeInMinutes": {
"type": "string",
"metadata": {
"description": "Window size used for alerts in minutes"
},
"defaultValue": "5"
},
"AlertSendToServiceOwners": {
"type": "bool",
"metadata": {
"description": "Should the alerts be sent to the service owners?"
},
"defaultValue": true
},
"AlertSendToEmailAddress": {
"type": "string",
"metadata": {
"description": "Custom Email Address for alerts"
},
"defaultValue": "ignore"
},
"BlockedFirewallConnectionsAlertEnabled": {
"type": "bool",
"metadata": {
"description": "Sets the Enabled Flag for Database alert rule for connections blocked by the firewall"
},
"defaultValue": true
},
"BlockedFirewallConnectionsThreshold": {
"type": "string",
"metadata": {
"description": "Number of Blocked Connections in the period to trigger the alert"
},
"defaultValue": "10"
},
"FailedConnectionsAlertEnabled": {
"type": "bool",
"metadata": {
"description": "Sets the Enabled Flag for Database alert rule for failed connections "
},
"defaultValue": true
},
"FailedConnectionsThreshold": {
"type": "string",
"metadata": {
"description": "Number of failed connections in the period to trigger the alert"
},
"defaultValue": "10"
},
"UseBYOK": {
"type": "bool",
"metadata": {
"description": "Should we use Bring Your Own Key for TDE, if set BYOKKeyVaultId and BYOKCertUri must be set"
},
"defaultValue": false
},
"BYOKKeyVaultId": {
"type": "string",
"metadata": {
"description": "The Resource Id of the Key Vault"
},
"defaultValue": "ignore"
},
"storageAccountId": {
"type": "string",
"metadata": {
"description": "Resource Id for the storage account to store diagnostics"
}
},
"workspaceId": {
"type": "string",
"metadata": {
"description": "Resource Id for the Log Analytics workspace to store diagnostics"
}
}
},
"variables": {
"AAD TenantID": "[subscription().tenantId]",
"arrayStorageId": "[split(parameters('storageAccountId'), '/')]",
"storageAccountName": "[last(variables('arrayStorageId'))]",
"storageEndpoint": "[concat('https://',variables('storageAccountName'),'.blob.core.windows.net')]",
"customEmails": "[split(parameters('AlertSendToEmailAddress'), ',')]"
},
"resources": [
{
"name": "[parameters('databaseServerName')]",
"type": "Microsoft.Sql/servers",
"apiVersion": "2015-05-01-preview",
"location": "[resourceGroup().location]",
"identity": {
"type": "SystemAssigned"
},
"properties": {
"administratorLogin": "[parameters('sqlServerAdminLogin')]",
"administratorLoginPassword": "[parameters('sqlServerAdminPassword')]",
"version": "12.0"
},
"resources": [
{
"name": "[parameters('databaseName')]",
"type": "databases",
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"dependsOn": [
"[parameters('databaseServerName')]"
],
"properties": {
"edition": "[parameters('sqlDatabaseEdition')]",
"collation": "[parameters('sqlDatabaseCollation')]",
"maxSizeBytes": "[parameters('sqlDatabaseMaxSizeBytes')]"
},
"resources": [
{
"comments": "Transparent Data Encryption",
"name": "current",
"type": "transparentDataEncryption",
"apiVersion": "2014-04-01",
"properties": {
"status": "[parameters('transparentDataEncryption')]"
},
"dependsOn": [
"[parameters('databaseName')]"
]
}
]
},
{
"apiVersion": "2015-05-01-preview",
"type": "auditingSettings",
"name": "Default",
"location": "[resourceGroup().location]",
"dependsOn": [
"[concat('Microsoft.Sql/servers/', parameters('databaseServerName'))]"
],
"properties": {
"State": "Enabled",
"storageEndpoint": "[variables('storageEndpoint')]",
"storageAccountAccessKey": "[listKeys(parameters('storageAccountId'),providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value]",
"retentionDays": "[parameters('AuditRetentionPeriodInDays')]",
"auditActionsAndGroups": null,
"storageAccountSubscriptionId": "[subscription().subscriptionId]",
"isStorageSecondaryKeyInUse": false
}
},
{
"apiVersion": "2015-05-01-preview",
"type": "securityAlertPolicies",
"name": "DefaultSecurityPolicies",
"dependsOn": [
"[concat('Microsoft.Sql/servers/', parameters('databaseServerName'))]",
"[concat('Microsoft.Sql/servers/', parameters('databaseServerName'), '/auditingSettings/Default')]"
],
"properties": {
"state": "Enabled",
"disabledAlerts": "",
"emailAddresses": "[if(equals(parameters('AlertSendToEmailAddress'),'ignore'),json('null'),parameters('AlertSendToEmailAddress'))]",
"emailAccountAdmins": "[if(equals(string(parameters('AlertSendToServiceOwners')),'true'),'Enabled','Disabled')]",
"storageEndpoint": "[variables('storageEndpoint')]",
"storageAccountAccessKey": "[listKeys(parameters('storageAccountId'), providers('Microsoft.Storage', 'storageAccounts').apiVersions[0]).keys[0].value]",
"retentionDays": "[parameters('AuditRetentionPeriodInDays')]"
}
},
{
"condition": "[equals(parameters('useAADForSQLAdmin'), 'Yes')]",
"type": "administrators",
"name": "activeDirectory",
"apiVersion": "2014-04-01-preview",
"location": "[resourceGroup().location]",
"properties": {
"administratorType": "ActiveDirectory",
"login": "[parameters('AADAdminLogin')]",
"sid": "[parameters('AADAdminObjectID')]",
"tenantId": "[variables('AAD TenantID')]"
},
"dependsOn": [
"[concat('Microsoft.Sql/servers/', parameters('databaseServerName'))]"
]
},
{
"type": "firewallrules",
"apiVersion": "2014-04-01-preview",
"dependsOn": [
"[parameters('databaseServerName')]"
],
"location": "[resourceGroup().location]",
"name": "AllowAllWindowsAzureIps",
"properties": {
"endIpAddress": "0.0.0.0",
"startIpAddress": "0.0.0.0"
}
}
]
},
{
"name": "FirewallBlockedConnections",
"type": "microsoft.insights/alertrules",
"apiVersion": "2016-03-01",
"location": "[resourceGroup().location]",
"dependsOn": [
"[parameters('databaseName')]"
],
"properties": {
"name:": "FirewallBlockedConnections",
"description": "Alerts on connection attempts blocked by the Firewall",
"isEnabled": "[parameters('BlockedFirewallConnectionsAlertEnabled')]",
"condition": {
"odata.type": "Microsoft.Azure.Management.Insights.Models.ThresholdRuleCondition",
"dataSource": {
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleMetricDataSource",
"resourceUri": "[resourceId('Microsoft.Sql/servers/databases', parameters('databaseServerName'), parameters('databaseName'))]",
"metricName": "blocked_by_firewall"
},
"operator": "GreaterThanOrEqual",
"threshold": "[parameters('BlockedFirewallConnectionsThreshold')]",
"windowSize": "[concat('PT',parameters('AlertWindowSizeInMinutes'),'M')]",
"timeAggregation": "Average"
},
"actions": [
{
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
"sendToServiceOwners": "[parameters('AlertSendToServiceOwners')]",
"customEmails": "[if(empty(variables('customEmails')),json('null'),variables('customEmails'))]"
}
]
},
"resources": []
},
{
"type": "Microsoft.Insights/alertRules",
"name": "FailedDatabaseConnections",
"dependsOn": [
"[parameters('databaseName')]"
],
"location": "[resourceGroup().location]",
"apiVersion": "2014-04-01",
"properties": {
"name:": "FailedDatabaseConnections",
"description": "Alerts on failed connection attempts",
"isEnabled": "[parameters('FailedConnectionsAlertEnabled')]",
"condition": {
"odata.type": "Microsoft.Azure.Management.Insights.Models.ThresholdRuleCondition",
"dataSource": {
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleMetricDataSource",
"resourceUri": "[resourceId('Microsoft.Sql/servers/databases', parameters('databaseServerName'), parameters('databaseName'))]",
"metricName": "connection_failed"
},
"operator": "GreaterThan",
"threshold": "[parameters('FailedConnectionsThreshold')]",
"windowSize": "[concat('PT',parameters('AlertWindowSizeInMinutes'),'M')]"
},
"actions": [
{
"odata.type": "Microsoft.Azure.Management.Insights.Models.RuleEmailAction",
"sendToServiceOwners": "[parameters('AlertSendToServiceOwners')]",
"customEmails": "[if(empty(variables('customEmails')),json('null'),variables('customEmails'))]"
}
]
}
},
{
"type": "Microsoft.Sql/servers/databases/providers/diagnosticSettings",
"name": "[concat(parameters('databaseServerName'),'/', parameters('databaseName'),'/Microsoft.Insights/SQLLogAnalyticsIntegration')]",
"apiVersion": "2017-05-01-preview",
"dependsOn": [
"[parameters('databaseServerName')]",
"[parameters('databaseName')]"
],
"properties": {
"name": "SQLLogAnalyticsIntegration",
"workspaceId": "[parameters('workspaceId')]",
"logs": [
{
"category": "Errors",
"enabled": true,
"retentionPolicy": {
"days": 7,
"enabled": false
}
},
{
"category": "Audit",
"enabled": true,
"retentionPolicy": {
"days": 90,
"enabled": false
}
},
{
"category": "SQLSecurityAuditEvents",
"enabled": true,
"retentionPolicy": {
"days": 90,
"enabled": false
}
}
],
"metrics": [
{
"category": "AllMetrics",
"enabled": true,
"retentionPolicy": {
"enabled": false,
"days": 7
}
}
]
}
}
],
"outputs": {
"azureSQLPaaSMSITenantId": {
"type":"string",
"value": "[reference(concat('Microsoft.Sql/servers/', parameters('databaseServerName')), '2015-05-01-preview', 'Full').identity.tenantId]"
},
"azureSQLPaaSMSIObjectId": {
"type":"string",
"value": "[reference(concat('Microsoft.Sql/servers/', parameters('databaseServerName')), '2015-05-01-preview', 'Full').identity.principalId]"
},
"azureSQLFQDN": {
"type":"string",
"value": "[reference(concat('Microsoft.Sql/servers/', parameters('databaseServerName'))).fullyQualifiedDomainName]"
}
}
}

Просмотреть файл

@ -0,0 +1,121 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"type": "string",
"metadata": {
"description": "Name of the storage account, must be globally unique all lower case"
},
"defaultValue": "[uniqueString(resourceGroup().id)]"
},
"UseBYOK": {
"type": "string",
"allowedValues": [
"Yes",
"No"
],
"metadata": {
"description": "If set storage account will be encrypted using BYOK"
},
"defaultValue": "No"
},
"keyVaultUri": {
"type": "string",
"metadata": {
"description": "Uri of the Key Vault containing the BYOK certificate, required if 'UseBYOK' is set, ignored otherwise"
},
"defaultValue": "ignore"
},
"KeyName": {
"type": "string",
"metadata": {
"description": "The name of the Key"
},
"defaultValue": "ignore"
},
"KeyVersion": {
"type": "string",
"metadata": {
"description": "The version of the Key"
},
"defaultValue": "ignore"
}
},
"variables": {
"lowerStorageAccountName": "[toLower(parameters('storageAccountName'))]"
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('lowerStorageAccountName')]",
"apiVersion": "2017-10-01",
"location": "[resourceGroup().location]",
"comments": "",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"properties": {
"encryption": {
"keySource": "Microsoft.Storage",
"services": {
"blob": {
"enabled": true
},
"file": {
"enabled": true
}
}
},
"supportsHttpsTrafficOnly": true
},
"identity": {
"type": "SystemAssigned"
}
},
{
"condition": "[equals(parameters('UseBYOK'), 'Yes')]",
"apiVersion": "2015-01-01",
"type": "Microsoft.Resources/deployments",
"name": "applyBYOK",
"dependsOn": [
"[variables('lowerStorageAccountName')]"
],
"properties": {
"mode": "Incremental",
"parameters": {},
"template": {
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"name": "[variables('lowerStorageAccountName')]",
"apiVersion": "2017-10-01",
"location": "[resourceGroup().location]",
"properties": {
"encryption": {
"keySource": "[if(equals(parameters('UseBYOK'), 'No'), 'Microsoft.Storage', 'Microsoft.Keyvault')]",
"keyvaultproperties": {
"keyname": "[if(equals(parameters('UseBYOK'), 'No'), json('null'), parameters('KeyName'))]",
"keyversion": "[if(equals(parameters('UseBYOK'), 'No'), json('null'), parameters('KeyVersion'))]",
"keyvaulturi": "[if(equals(parameters('UseBYOK'), 'No'), json('null'), parameters('keyVaultUri'))]"
}
}
}
}
]
}
}
}
],
"outputs": {
"storageAccountId": {
"type": "string",
"value": "[resourceId('Microsoft.Storage/storageAccounts',variables('lowerStorageAccountName'))]"
}
}
}

Просмотреть файл

@ -0,0 +1,304 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"baseResourceName": {
"type": "string",
"metadata": {
"description": "Base name to ensure unique names where required for deployments"
},
"maxLength": 15,
"defaultValue": "[uniqueString(resourceGroup().id)]"
},
"appServicePlanName": {
"type": "string",
"metadata": {
"description": "Name of the App Service Plan to deploy"
},
"defaultValue": "[concat('asp','-',parameters('baseResourceName'))]"
},
"appServiceKind": {
"type": "string",
"allowedValues": [
"app",
"api"
]
},
"appName": {
"type": "string",
"metadata": {
"description": "The name of the app to deploy"
}
},
"appSlotsToDeploy": {
"type": "array",
"metadata": {
"description": "Array of slots to deploy for apps within the service plan"
},
"defaultValue": [
"Dev",
"QA",
"UAT",
"Preview"
]
},
"minTLSVersionSupported": {
"type": "string",
"metadata": {
"description": "The minimum TLS version required for SSL requests"
},
"allowedValues": [
"1.0",
"1.1",
"1.2"
],
"defaultValue": "1.2"
},
"allowedIPAddresses": {
"type": "array",
"metadata": {
"description": "An array of IP Address restriction objects in the form {'ipAddress':'<IP Address>','subnetMask':'<Subnet Mask>'"
}
},
"workspaceId": {
"type": "string",
"metadata": {
"description": "Log Analytics workspace Id to log to, if not supplied no integration will be configured."
},
"defaultValue": null
},
"storageAccountId": {
"type": "string",
"metadata": {
"description": "Storage Account Id to log to, if not supplied no integration will be configured."
},
"defaultValue": null
},
"connectionString": {
"type": "string",
"metadata": {
"description": "SQL Server Connection string for the Website"
},
"defaultValue": "ignore"
}
},
"variables": {
"standardPlanMaxAdditionalSlots": 4
},
"resources": [
{
"apiVersion": "2015-05-01",
"name": "[concat('ai-', parameters('appName'))]",
"type": "Microsoft.Insights/components",
"location": "[resourceGroup().location]",
"dependsOn": [
"[parameters('appName')]"
],
"tags": {
"[concat('hidden-link:', resourceGroup().id, '/providers/Microsoft.Web/sites/', parameters('appName'))]": "Resource",
"displayName": "AppInsightsComponent"
},
"kind": "web",
"properties": {
"ApplicationId": "[parameters('appName')]",
"Application_Type": "web"
}
},
{
"apiVersion": "2017-08-01",
"type": "Microsoft.Web/serverfarms",
"name": "[parameters('appServicePlanName')]",
"location": "[resourceGroup().location]",
"comments": "This app service plan is used for the web app and slots.",
"tags": {
},
"properties": {},
"dependsOn": [],
"sku": {
"name": "[if(lessOrEquals(length(parameters('appSlotsToDeploy')), variables('standardPlanMaxAdditionalSlots')), 'S1', 'P1')]"
}
},
{
"apiVersion": "2016-08-01",
"type": "Microsoft.Web/sites",
"kind": "[parameters('appServiceKind')]",
"name": "[parameters('appName')]",
"location": "[resourceGroup().location]",
"comments": "This is the web app, also the default 'nameless' slot.",
"tags": {
"[concat('hidden-related:', resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName')))]": "empty"
},
"identity": {
"type": "SystemAssigned"
},
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]",
"siteConfig":{
"ipSecurityRestrictions": {
"copy": [
{
"name": "deployIPAddressRestrictions",
"count": "[length(parameters('allowedIPAddresses'))]",
"input": {
"ipAddress": "[if(empty(parameters('allowedIPAddresses')[copyIndex('deployIPAddressRestrictions')]),json('null'),parameters('allowedIPAddresses')[copyIndex('deployIPAddressRestrictions')].ipAddress)]",
"subnetMask": "[if(empty(parameters('allowedIPAddresses')[copyIndex('deployIPAddressRestrictions')]), json('null'), parameters('allowedIPAddresses')[copyIndex('deployIPAddressRestrictions')].subnetMask)]"
}
}
]
}
},
"httpsOnly" : true,
"minTLSVersionSupported": "[parameters('minTLSVersionSupported')]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]"
],
"resources": [
{
"condition": "[not(equals(parameters('connectionString'),'ignore'))]",
"name": "connectionstrings",
"type": "config",
"apiVersion": "2014-11-01",
"dependsOn": [
"[resourceId('Microsoft.Web/sites/', parameters('appName'))]"
],
"properties": {
"DefaultConnectionString": {
"value": "[parameters('connectionString')]",
"type": "SQLAzure"
}
}
},
{
"apiVersion": "2015-08-01",
"name": "appsettings",
"type": "config",
"dependsOn": [
"[parameters('appName')]",
"[concat('ai-', parameters('appName'))]"
],
"properties": {
"applicationInsightsInstrumentationKey": "[reference(resourceId('Microsoft.Insights/components', concat('ai-', parameters('appName'))), '2014-04-01').InstrumentationKey]"
}
},
{
"apiVersion": "2015-08-01",
"name": "logs",
"type": "config",
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('appName'))]"
],
"properties": {
"applicationLogs": {
"fileSystem": {
"level": "Warning"
}
},
"httpLogs": {
"fileSystem": {
"retentionInMb": 40,
"enabled": true
}
},
"failedRequestsTracing": {
"enabled": true
},
"detailedErrorMessages": {
"enabled": false
}
}
}
]
},
{
"apiVersion": "2016-08-01",
"type": "Microsoft.Web/sites/slots",
"name": "[concat(parameters('appName'), '/', parameters('appSlotsToDeploy')[copyIndex('deployWebAppSlots')])]",
"kind": "[parameters('appServiceKind')]",
"location": "[resourceGroup().location]",
"comments": "This specifies the web app slots.",
"tags": {
"Environment": "parameters('appSlotsToDeploy')[copyIndex()]"
},
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('appServicePlanName'))]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/Sites', parameters('appName'))]"
],
"copy": {
"name": "deployWebAppSlots",
"count": "[length(parameters('appSlotsToDeploy'))]"
}
},
{
"condition": "[not(equals(parameters('workspaceId'), json('null')))]",
"type": "Microsoft.Insights/components/providers/diagnosticSettings",
"name": "[concat('ai-', parameters('appName'),'/Microsoft.Insights/LogAnalyticsIntegrationCustomer')]",
"apiVersion": "2017-05-01-preview",
"dependsOn": [
"[concat('Microsoft.Insights/components/','ai-', parameters('appName'))]"
],
"properties": {
"name": "[concat('LogAnalyticsIntegration-', parameters('appName'))]",
"workspaceId": "[parameters('workspaceId')]"
}
},
{
"condition": "[not(equals(parameters('workspaceId'), json('null')))]",
"type":"Microsoft.Web/serverfarms/providers/diagnosticsettings",
"name":"[concat(parameters('appServicePlanName'),'/Microsoft.Insights/service')]",
"apiVersion":"2016-09-01",
"location":"[resourceGroup().location]",
"dependsOn":[
"[parameters('appServicePlanName')]"
],
"properties":{
"workspaceId": "[parameters('workspaceId')]",
"metrics":[
{
"category":"AllMetrics",
"enabled":true,
"retentionPolicy":{
"enabled":true,
"days": 7
}
}
]
}
},
{
"type":"Microsoft.Web/sites/providers/diagnosticsettings",
"name":"[concat(parameters('appName'), '/Microsoft.Insights/service')]",
"apiVersion":"2016-09-01",
"location":"[resourceGroup().location]",
"dependsOn":[
"[parameters('appName')]"
],
"properties":{
"workspaceId": "[parameters('workspaceId')]",
"storageAccountId": "[parameters('storageAccountId')]",
"metrics":[
{
"category":"AllMetrics",
"enabled":true,
"retentionPolicy": {
"enabled": true,
"days": 7
}
}
]
}
}
],
"outputs": {
"appServiceMSITenantId": {
"type": "string",
"value": "[reference(concat('Microsoft.Web/sites/', parameters('appName')), '2016-08-01', 'Full').identity.tenantId]"
},
"appServiceMSIObjectId": {
"type": "string",
"value": "[reference(concat('Microsoft.Web/sites/', parameters('appName')), '2016-08-01', 'Full').identity.principalId]"
}
}
}

142
README.md
Просмотреть файл

@ -1,14 +1,138 @@
# Solution Overview
For more information about this solution, see [Azure Security and Compliance Blueprint - UK-OFFICAL Three-Tier Web Applications using Platform as a Service](https://aka.ms/ukofficialpaas).
For deployment this blueprint uses linked ARM Templates. There are a series of individual templates for each component that can be used to deploy each component indivudually, each of these templates have their own series of paramters and defaults. In the root folder we have azuredeploy.json, this exposes a subset of parameters which has been derived to enable a simple deployment. More advanced configurations can be achived via customising the templates.
# Deploy the Solution
As mentioned above these templates will deploy a 3 Tier architecture using Azure Platform as a Service components. Progress can be monitored from the Resource Group blade and Deployment output blade in the Azure Portal.
There are two methods that deployment users may use to deploy this reference architecture. The first method uses a Bash script, whereas the second method utilises Azure Portal to deploy the reference architecture. These two methods are detailed in the sections below.
As a pre-requisite to deployment, users should ensure that they have:
- An Azure Subscription
- Contributor or Owner rights to the Subscription
> If you would like to configure an Azure Active Directory Group as part of the scripted deployment you will need to have suitable permissions within your Azure Active Directory.
Other Azure architectural best practices and guidance can be found in [Azure Reference Architectures](https://docs.microsoft.com/azure/guidance/guidance-architecture). Supporting Microsoft Visio templates are available from the [Microsoft download center](http://download.microsoft.com/download/1/5/6/1569703C-0A82-4A9C-8334-F13D0DF2F472/RAs.vsdx) with the corresponding ARM Templates found at [Azure Reference Architectures ARM Templates](https://github.com/mspnp/reference-architectures).
## Method 1: Azure CLI 2 (Express version)
To deploy this solution through the Azure CLI, you will need the latest version of the [Azure CLI 2](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest) to use the BASH script that deploys the solution. Alternatively you can use the [Azure Cloud Shell](https://shell.azure.com/). To deploy the reference architecture, follow these steps:
1. If you have access to multiple subscriptions use the command ```az account set --subscription <subscription>``` to ensure you are targetting the correct subscription
2. Download the BASH script pre_reqs.sh, for example with the command ```wget https://raw.githubusercontent.com/ianalderman/ukopaas/master/scripts/pre_reqs.sh```
3. Execute the script by using the command ```bash pre_reqs.sh```
4. If you do not know the short name of the region you wish to deploy to enter ```Y``` else enter ```N```
5. Enter the short name of the region you wish to deploy to e.g. ```northeurope```
> Note: The parameter files include hard-coded passwords in various places. It is strongly recommended that you change these values.
> If the parameters files are not updated, the default values will be used which may not be compatible with your on-premises environment.
### Method 1a: Azure CLI 2 (Configuring the deployment via script arguments)
The ```pre_reqs.sh``` script supports a number of command line arguments that allow you to customise the deployment. These are:
1. Region - should be a valid shortname for a region
2. Base Resource Name (used for uniqueness) - should be less than 15 chars and all lower case
3. Base Resource Group Name
4. SQL Admin configuration - valid options are ```Group```, ```User```, ```None```
5. Log Analytics SKU - valid options are ```Free``` or ```pergb2018```
>As the arguments are positional, rather than named you need to add them in the correct order. If you specify arguments you don't have to specify all of them, for example you could provide just the first argument, or arguments 1,2 & 3. You cannot supply them out of order.
```bash pre_reqs.sh northeurope paasbp rg-ne-paas-blueprint```
## Method 2: Azure Portal Deployment Process
A deployment for this reference architecture is available on
[GitHub](https://aka.ms/ukofficialpaasrepo). The templates can be cloned or downloaded if customisation of parameters is requried. To deploy the architecture, follow the steps below.
<a href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fianalderman%2Fukopaas%2Fmaster%2Fazuredeploy.json" target="_blank">
<img src="https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/deploytoazure.png"/>
</a>
1. Click on the **Deploy to Azure** button to begin the first stage of the deployment. The link takes you to the Azure Portal.
2. Select **Create New** and enter a value such as `rg-uks-paas-blueprint` in the **Resource group** textbox.
3. Select a region such as `UKSouth` or `UKWest`, from the **Location** drop down box. **All Resource Groups required for this architecture should be in the same Azure region (e.g., `UKSouth` or `UKWest`).**
4. Review the available parameters and enter the appropriate values for your deployment - note that you will need to replace the function based defaults such as ```[uniqueString(resourceGroup().id)]```
5. Unlike the bash script in Method 1 the portal method will not create the additional resource groups, you can enter the resource group name from step 2 in **App Service Resource Group**, **Key Vault Resource Group**, **Storage Resource Group** and **Azure SQL Resource Group** - if you would like to deploy these resources to different resource groups you must create them seperately first.
6. Review the terms and conditions, then click the **I agree to the terms and conditions stated above** checkbox.
7. Click on the **Purchase** button.
8. Check the Azure Portal notifications for a message stating that this stage of deployment is complete, and proceed to the next deployment stage if completed.
9. If for some reason your deployment fails, it is advisable to delete the resource group in its entirety to avoid incurring cost and orphan resources, fix the issue, and redeploy the resource groups and template.
## Deployment parameters
The table below provides additional information about deployment parameters.
Parameter|Default|Comment|
---|---|---
baseResourceName|uniqueString(resourceGroup().id)|Base resource name to use for the deployed resources. For example a value of "bpdemo" would provide a keyvault name kvbpdemo
appServiceResourceGroup|Deployment Resource Group|Name of the Resource Group to deploy the App Service Plan to
keyVaultResourceGroup|Deployment Resource Group|Name of the Resource Group to deploy the Key Vaults to
storageResourceGroup|Deployment Resource Group|Name of the Resource Group to deploy the storage and log analytics workspace to
azureSQLResourceGroup|Deployment Resource Group|Name of the Resource Group to deploy the Azure SQL instance to
LogsWorkspaceLocation|westeurope|Which Azure Region to deploy the Log Analytics workspace to
LogAnalyticsSKU|N/A|The SKU for provisioning the Log Analytics solution. Note if your subscription has been moved to the "new" pricing only "pergb2018" will work, if not it is "Free"
databaseServerName|concat('svr-', uniqueString(resourceGroup().id))|Name of the database server to deploy
sqlServerAdminPassword|concat('L1',uniqueString(subscription().id),'#')|The default password for the SQL Admin user
useAADForSQLAdmin|No|Allowed Values "Yes", "No". Sets whether Azure Active Directory will be used for SQL Server Administration
AADAdminLogin|ignore|The Login ID for the Azure Active Directory user or group to be Server Admin, e.g., sg_azure_sql_dbo@contoso.com
AADAdminObjectID|ignore|The underlying ObjectID (in the form of a GUID) representing the assigned Azure Active Directory user / group
AlertSendToEmailAddress|N/A|The email address to send alerts to
# UK Government Private Network Connectivity
Microsoft's customers are able to use [private connections](https://news.microsoft.com/2016/12/14/microsoft-now-offers-private-internet-connections-to-its-uk-data-centres/#sm.0001dca7sq10r1couwf4vvy9a85zx)
to the Microsoft UK datacentres (UK West and UK South). Microsoft's partners a providing a gateway from PSN/N3 to [ExpressRoute](https://azure.microsoft.com/services/expressroute/) and into Azure, and this is just one of the new services the group has unveiled since Microsoft launched its [**Azure**](https://azure.microsoft.com/blog/) and Office 365 cloud offering in the UK. (https://news.microsoft.com/2016/09/07/not-publish-microsoft-becomes-first-company-open-data-centres-uk/). Since then, [**thousands of customers**](https://enterprise.microsoft.com/industries/public-sector/microsoft-uk-data-centres-continue-to-build-momentum/?wt.mc_id=AID563187_QSG_1236), including the Ministry of Defence, the Met Police, and parts of the NHS, have signed up to take advantage of the sites. These UK datacentres offer UK data residency, security and reliability.
# Cost
Deploying this template will create one or more Azure resources. You will be responsible for the costs generated by these resources, so it is important that you review the applicable pricing and legal terms associated with all resources and offerings deployed as part of this template. For cost estimates, you can use the [Azure Pricing Calculator](https://azure.microsoft.com/pricing/calculator).
The indicative cost based on the services defined in the Blueprint are below. These are based on Standard pricing tiers for App Services and Database and free tiers for Log Analytics, Security Centre and Active Directory. As your solution expands to meet demand, further cost could be incurred.
- App Service - UK West - Standard Tier; 1 S1 (1 Core(s), 1.75 GB RAM, 50 GB Storage) x 730 Hours; Windows OS £68.01
- Key Vault UK West 100000 operations/mo, 0 advanced operations/mo, 0 renewals/mo, 0 protected keys/mo 0 advanced protected keys/mo £0.22
- Azure SQL Database UK West Single Database, DTU Purchase Model, Standard Tier, S1: 20 DTUs, 250 GB included storage per DB, 1 Database(s) x 730 Hours, 5 GB Retention £27.43
- Azure Advanced Threat detection for SQL Server charged at $15 per server per month (free for first 60 days)
- Storage UK West Block Blob Storage, General Purpose V2, LRS Redundancy, Hot Access Tier, 1000 GB Capacity, 100,000 Write operations, 100,000 List and Create Container Operations, 100,000 Read operations, 1 Other operations. 1,000 GB Data Retrieval, 1,000 GB Data Write £15.22
- Azure Active Directory West Europe Free tier, per-user MFA billing model, 10 MFA user(s), 25001-100000 directory objects, 0 Hours £10.43
-Log Analytics West Europe 0 VMs monitored, 0 GB average log size, 0 additional days of data retention £0.00
- Application Insights West Europe 1 GB Logs collected, 0 Multi-step Web Tests £0.00
- Azure Monitor West Europe 1,000,000 Standard API calls, 1 VM(s) monitored and 1 metric(s) monitored per VM, 1 Log Alert(s) at 5 Minutes Frequency, 1,000 emails, 1,000 push notifications, 100,000 web hooks, 100 SMS in United States (+1) £1.19
- Security Center Free tier £0.00
- Azure DNS West Europe 1 hosted DNS zones, 5 DNS queries £1.86
Monthly Total £139.38 Annual Total £1,672.56
# Further Reading
Information on linked templates as used within this blueprint can be found in [Using linked and nested templates when deploying Azure resources](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-linked-templates)
Details on security best practices can be found in [Azure security best practices and patterns](https://docs.microsoft.com/en-us/azure/security/security-best-practices-and-patterns)
App Service best practices can be found in [Best Practices for Azure App Service](https://docs.microsoft.com/en-us/azure/app-service/app-service-best-practices)
Azure SQL Database best practices are available in the docs page [Azure database security best practices](https://docs.microsoft.com/en-us/azure/security/azure-database-security-best-practices)
Further information for key vault can be found in [Azure Key Vault Developer's Guide](https://docs.microsoft.com/en-us/azure/key-vault/key-vault-developers-guide)
Guidance on Azure storage can be found in [Azure Storage security guide](https://docs.microsoft.com/en-us/azure/storage/common/storage-security-guide) and [Azure Storage security overview](https://docs.microsoft.com/en-us/azure/security/security-storage-overview)
# Disclaimer
- This document is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, AS TO THE INFORMATION IN THIS DOCUMENT. This document is provided "as-is." Information and views expressed in this document, including URL and other Internet website references, may change without notice. Customers reading this document bear the risk of using it.
- This document does not provide customers with any legal rights to any intellectual property in any Microsoft product or solutions.
- Customers may copy and use this document for internal reference purposes.
- Certain recommendations in this document may result in increased data, network, or compute resource usage in Azure, and may increase a customer's Azure license or subscription costs.
- This architecture is intended to serve as a foundation for customers to adjust to their specific requirements and should not be used as-is in a production environment.
- This document is developed as a reference and should not be used to define all means by which a customer can meet specific compliance requirements and regulations. Customers should seek legal support from their organization on approved customer implementations.
# Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
the rights to use your contribution. For details, visit https://cla.microsoft.com.
This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
provided by the bot. You will only need to do this once across all repos using our CLA.
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

433
azuredeploy.json Normal file
Просмотреть файл

@ -0,0 +1,433 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"baseResourceName": {
"type": "string",
"metadata": {
"description": "Name of the resource"
},
"maxLength": 15,
"defaultValue": "[uniqueString(resourceGroup().id)]"
},
"appServiceResourceGroup": {
"type": "string",
"metadata": {
"description": "Name of the Resource Group to deploy the App Services to, defaults to the current resource group for the deployment"
},
"defaultValue": "[resourceGroup().name]"
},
"keyVaultResourceGroup": {
"type": "string",
"metadata": {
"description": "Name of the Resource Group to deploy the Key Vaults to, defaults to the current resource group for the deployment"
},
"defaultValue": "[resourceGroup().name]"
},
"storageResourceGroup": {
"type": "string",
"metadata": {
"description": "Name of the Resource Group to deploy the storage accounts & log analytics workspaces for diagnostics and Customer assets defaults to the current resource group for the deployment"
},
"defaultValue": "[resourceGroup().name]"
},
"azureSQLResourceGroup": {
"type": "string",
"metadata": {
"description": "Name of the Resource Group to deploy the SQL Server to, defaults to the current resource group for the deployment"
},
"defaultValue": "[resourceGroup().name]"
},
"LogsWorkspaceLocation": {
"type": "string",
"allowedValues": [
"eastus",
"westeurope",
"southeastasia",
"australiasoutheast",
"westcentralus",
"japaneast",
"uksouth",
"centralindia",
"canadacentral"
],
"defaultValue": "westeurope",
"metadata": {
"description": "The Azure region the Logs Workspace will be deployed to"
}
},
"LogAnalyticsSKU": {
"type": "string",
"defaultValue": "pergb2018",
"allowedValues": [
"Free",
"pergb2018"
],
"metadata": {
"description": "The pricing tier of the Log Analytics workspace. New workspaces should be ok 'pergb2018', some subscritpions may require 'Free' please see http://aka.ms/PricingTierWarning"
}
},
"databaseServerName": {
"type": "string",
"metadata": {
"description": "The name of the database server to provision"
},
"defaultValue": "[concat('svr-', uniqueString(resourceGroup().id))]"
},
"sqlServerAdminPassword": {
"type": "securestring",
"metadata": {
"description": "The password for administering the SQL Server"
},
"defaultValue": "[concat('L1',uniqueString(subscription().id),'#')]"
},
"useAADForSQLAdmin": {
"type": "string",
"allowedValues": [
"Yes",
"No"
],
"defaultValue": "No",
"metadata": {
"description": "Should the deployed Azure SQL Server have an Azure Active Directory based user / group configured as an Administrator"
}
},
"AADAdminLogin": {
"type": "string",
"metadata": {
"description": "The Login ID for the Azure Active Directory user or group to be a server admin"
},
"defaultValue": "ignore"
},
"AADAdminObjectID": {
"type": "string",
"metadata": {
"description": "The Object ID for the Azure Active Directory user or group to be a server admin"
},
"defaultValue": "ignore"
},
"AlertSendToEmailAddress": {
"type": "string",
"metadata": {
"description": "Custom Email Address for alerts"
},
"defaultValue": null
}
},
"functions": [
{
"namespace": "contoso",
"members": {
"resourceName": {
"parameters": [
{
"name": "resourceId",
"type": "string"
}
],
"output": {
"type": "string",
"value": "[last(split(parameters('resourceId'),'/'))]"
}
}
}
}
],
"variables": {
"templateBaseUrl": "https://raw.githubusercontent.com/ianalderman/ukopaas/master/",
"appServiceTemplateUrl": "[concat(variables('templateBaseUrl'), 'Microsoft.Web/deployAppService.json')]",
"storageAccountTemplateUrl": "[concat(variables('templateBaseUrl'), 'Microsoft.Storage/deployStorageAccount.json')]",
"azureSQLTemplateUrl": "[concat(variables('templateBaseUrl'), 'Microsoft.SQL/deployAzureSQLPaaS.json')]",
"azureKeyVaultTemplateUrl": "[concat(variables('templateBaseUrl'), 'Microsoft.KeyVault/deployKeyVault.json')]",
"logAnalyticsTemplateUrl": "[concat(variables('templateBaseUrl'), 'Microsoft.OperationalInsights/deployLogAnalytics.json')]",
"storageAccountBaseName": "[uniqueString(resourceGroup().id)]"
},
"resources": [{
"apiVersion": "2017-05-10",
"name": "deployLogAnalyticsWorkspace",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('storageResourceGroup')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('logAnalyticsTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"logAnalyticsSKU": {
"value": "[parameters('logAnalyticsSKU')]"
}
}
}
},
{
"apiVersion": "2017-05-10",
"name": "deployStorageAccountForDiagnositics",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('storageResourceGroup')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('storageAccountTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"storageAccountName": {
"value": "[concat('diags',variables('storageAccountBaseName'))]"
}
}
}
},
{
"apiVersion": "2017-05-10",
"name": "deployStorageAccountForCustomerAssets",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('storageResourceGroup')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('storageAccountTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"storageAccountName": {
"value": "[concat('cust',variables('storageAccountBaseName'))]"
}
}
}
},
{
"apiVersion": "2017-05-10",
"name": "deployCustomerSite",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('appServiceResourceGroup')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('appServiceTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"appName": {
"value": "[concat(parameters('baseResourceName'),'-Customer')]"
},
"appServiceKind": {
"value": "app"
},
"allowedIPAddresses": {
"value": [{}]
},
"workspaceId": {
"value": "[reference('deployLogAnalyticsWorkspace').outputs.workspaceId.value]"
},
"storageAccountId": {
"value": "[reference('deployStorageAccountForDiagnositics').outputs.storageAccountId.value]"
}
}
}
},
{
"apiVersion": "2017-05-10",
"name": "deployOperatorSite",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('appServiceResourceGroup')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('appServiceTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"appName": {
"value": "[concat(parameters('baseResourceName'),'-Operator')]"
},
"appServiceKind": {
"value": "app"
},
"allowedIPAddresses": {
"value": [{}]
},
"workspaceId": {
"value": "[reference('deployLogAnalyticsWorkspace').outputs.workspaceId.value]"
},
"storageAccountId": {
"value": "[reference('deployStorageAccountForDiagnositics').outputs.storageAccountId.value]"
}
}
}
},
{
"apiVersion": "2017-05-10",
"name": "deployAPISite",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('appServiceResourceGroup')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('appServiceTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"appName": {
"value": "[concat(parameters('baseResourceName'),'-API')]"
},
"appServiceKind": {
"value": "api"
},
"allowedIPAddresses": {
"value": [{}]
},
"workspaceId": {
"value": "[reference('deployLogAnalyticsWorkspace').outputs.workspaceId.value]"
},
"storageAccountId": {
"value": "[reference('deployStorageAccountForDiagnositics').outputs.storageAccountId.value]"
}
}
}
},
{
"apiVersion": "2017-05-10",
"name": "deployKeyVaultForCustomerAssetsSecretsManagement",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('keyVaultResourceGroup')]",
"dependsOn": [
"deployStorageAccountForCustomerAssets"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('azureKeyVaultTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"vaultNameSuffix": {
"value": "cust"
},
"storageAccountId": {
"value": "[reference('deployStorageAccountForDiagnositics').outputs.storageAccountId.value]"
},
"workspaceId": {
"value": "[reference('deployLogAnalyticsWorkspace').outputs.workspaceId.value]"
},
"accessPolicies": {
"value": [{
"tenantId": "[reference('deployCustomerSite').outputs.appServiceMSITenantId.value]",
"objectId": "[reference('deployCustomerSite').outputs.appServiceMSIObjectId.value]",
"permissions": {
"keys": [
"get"
],
"secrets": [
"get"
]
}
}]
},
"secretsAndKeys": {
"value": [{
"type": "secrets",
"name": "blobkey",
"apiVersion": "2015-06-01",
"properties": {
"value": "123"
}
}]
}
}
}
},
{
"apiVersion": "2017-05-10",
"name": "deployAzureSQLDatabase",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('azureSQLResourceGroup')]",
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('azureSQLTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"storageAccountId": {
"value": "[reference('deployStorageAccountForDiagnositics').outputs.storageAccountId.value]"
},
"databaseServerName": {
"value": "[parameters('databaseServerName')]"
},
"sqlServerAdminPassword": {
"value": "[parameters('sqlServerAdminPassword')]"
},
"AlertSendToEmailAddress": {
"value": "[parameters('AlertSendToEmailAddress')]"
},
"useAADForSQLAdmin": {
"value": "[parameters('useAADForSQLAdmin')]"
},
"AADAdminLogin": {
"value": "[parameters('AADAdminLogin')]"
},
"AADAdminObjectId": {
"value": "[parameters('AADAdminObjectID')]"
},
"workspaceId": {
"value": "[reference('deployLogAnalyticsWorkspace').outputs.workspaceId.value]"
}
}
}
},
{
"apiVersion": "2017-05-10",
"name": "deployKeyVaultForSQLServerSecretsManagement",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('keyVaultResourceGroup')]",
"dependsOn": [
"deployAzureSQLDatabase"
],
"properties": {
"mode": "Incremental",
"templateLink": {
"uri": "[variables('azureKeyVaultTemplateUrl')]",
"contentVersion": "1.0.0.0"
},
"parameters": {
"vaultNameSuffix": {
"value": "sql"
},
"storageAccountId": {
"value": "[reference('deployStorageAccountForDiagnositics').outputs.storageAccountId.value]"
},
"workspaceId": {
"value": "[reference('deployLogAnalyticsWorkspace').outputs.workspaceId.value]"
},
"accessPolicies": {
"value": [{
"tenantId": "[reference('deployAzureSQLDatabase').outputs.azureSQLPaaSMSITenantId.value]",
"objectId": "[reference('deployAzureSQLDatabase').outputs.azureSQLPaaSMSIObjectId.value]",
"permissions": {
"keys": [
"get",
"wrapKey",
"unwrapKey"
],
"secrets": []
}
}
]
},
"secretsAndKeys": {
"value": [{
"type": "secrets",
"name": "[concat(parameters('databaseServerName'),'-admin')]",
"apiVersion": "2015-06-01",
"properties": {
"value": "[parameters('sqlServerAdminPassword')]"
}
}]
}
}
}
}
]
}

Просмотреть файл

@ -0,0 +1,15 @@
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"AADAdminLogin": {
"value": "<YOUR LOGIN NAME>"
},
"AADAdminObjectID": {
"value": "<VALID GROUP ID>"
},
"AlertSendToEmailAddress": {
"value": "<YOUR EMAIL ADDRESS>"
}
}
}

Двоичные данные
images/templateDeploymentCapture.PNG Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 47 KiB

161
scripts/pre_reqs.sh Normal file
Просмотреть файл

@ -0,0 +1,161 @@
#Request user region
#!/bin/bash
declare regionToDeployTo
declare baseName
declare rgBaseName
declare useAADForSQLAdmin
declare useAADGroup
declare upn
declare paramString
declare logAnalyticsSKU
declare aadUserId
#List of regions used to validate offered region
regions=$(az account list-locations --query "[].{displayname:displayname, shortname:name}" --output tsv)
if [ $# -eq 0 ]; then
echo -n "Would you like a list of regions to deploy to? Y/N (N):"
read listlocations
if [ $listlocations == "Y" -o $listlocations == "y" ]; then
az account list-locations --query "[].{displayname:displayname, shortname:name}" --output table
fi
echo -n "Please enter the region you wish to deploy to (using the shortname):"
read regionToDeployTo
#Configure defaults
rgBaseName="rg-paas-blueprint"
useAADGroup=0
baseName=$(head -n 1 /dev/urandom | tr -dc 'a-z0-9' | fold -w 6 | head -n 1)
useAADForSQLAdmin="No"
echo "Attempting to identify Log Analytics available SKU...."
token=$(az account get-access-token | jq ".accessToken" -r)
subscriptionId=$(az account show | jq ".id" -r)
optedIn=$(curl -X POST -H "Authorization:Bearer $token" -H "Content-Length:0" https://management.azure.com/subscriptions/$subscriptionId/providers/microsoft.insights/listmigrationdate?api-version=2017-10-01 | jq ".optedInDate" -r)
echo "detected optedIn Date:$optedIn"
if [[ $optedIn == "" ]]; then
logAnalyticsSKU="pergb2018"
echo "Log Analytics SKU set to pergb2018"
else
logAnalyticsSKU="Free"
echo "Log Analytics SKU set to Free"
fi
else
if [[ $regions == *"$1"* ]]; then
regionToDeployTo=$1
else
echo -n "Unknown region - would you like a list of regions to deploy to? Y/N (N):"
read listlocations
if [ $listlocations == "Y" -o $listlocations == "y" ]; then
az account list-locations --query "[].{displayname:displayname, shortname:name}" --output table;
fi
echo -n "Please enter the region you wish to deploy to (using the shortname):"
read regionToDeployTo
fi
if [ -z "$2" ]; then
baseName=$(head -n 1 /dev/urandom | tr -dc 'a-z0-9' | fold -w 6 | head -n 1)
else
baseName=$2
fi
if [ -z "$3" ]; then
rgBaseName="rg-paas-blueprint"
else
rgBaseName=$3
fi
if [ -z "$4" ]; then
useAADGroup=0
useAADForSQLAdmin="No"
else
if [ "$4" == "Group" ]; then
useAADGroup=1
useAADForSQLAdmin="Yes"
else
if [ "$4" == "User" ]; then
useAADGroup=0
useAADForSQLAdmin="Yes"
else
useAADForSQLAdmin="No"
useAADGroup=0
fi
fi
fi
if [ -z "$5" ]; then
echo "Attempting to identify Log Analytics available SKU...."
token=$(az account get-access-token | jq ".accessToken" -r)
subscriptionId=$(az account show | jq ".id" -r)
optedIn=$(curl -X POST -H "Authorization:Bearer $token" -H "Content-Length:0" https://management.azure.com/subscriptions/$subscriptionId/providers/microsoft.insights/listmigrationdate?api-version=2017-10-01 | jq ".optedInDate" -r)
echo "detected optedIn Date:$optedIn"
if [[ $optedIn == "" ]]; then
logAnalyticsSKU="pergb2018"
echo "Log Analytics SKU set to pergb2018"
else
logAnalyticsSKU="Free"
echo "Log Analytics SKU set to Free"
fi
else
logAnalyticsSKU=$5
fi
fi
LEN=$(echo ${#regionToDeployTo})
if [[ $regions != *"$regionToDeployTo"* ]] || [[ ${#regionToDeployTo} -lt 6 ]]; then
echo "Unknown Region, exiting script"
exit 1
fi
#Create deployment resource groups
echo "Creating resource groups"
baseResourceGroup=$(az group create -l $regionToDeployTo -n $rgBaseName)
appServiceResourceGroup=$(az group create -l $regionToDeployTo -n $rgBaseName-appService)
keyVaultResourceGroup=$(az group create -l $regionToDeployTo -n $rgBaseName-keyVault)
storageResourceGroup=$(az group create -l $regionToDeployTo -n $rgBaseName-storage)
azureSQLResourceGroup=$(az group create -l $regionToDeployTo -n $rgBaseName-azureSQL)
aadUserMail=$(az account show | jq ".user.name" -r)
if [[ $aadUserMail == *"#EXT#"* ]]; then
upn=$(echo $aadUserMail | cut -d '#' -f 2)
upnLeft=$(echo ${upn/@/"_"})
upnRight=$(echo $upnLeft | cut -d "." -f 1)
upnRight=$(echo ${upnRight/_/""})
upn="$upnLeft#EXT#@$upnRight.onmicrosoft.com"
aadUserMail=$(echo $aadUserMail | cut -d '#' -f 2)
else
upn=$(echo $aadUserMail)
fi
aadUserId=$(az ad user show --upn-or-object-id $upn | jq ".objectId" -r)
if [ $useAADGroup == "Group" ]; then
echo "Creating AAD Group for SQL Admin"
groupMail="paasblueprintsqladminss"
groupName="PaaSBlueprintSQLAdministrators"
aadGroupId=$(az ad group create --display-name "$groupName" --mail-nickname "$groupMail" | jq ".objectId" -r)
paramString="baseResourceName=$baseName appServiceResourceGroup=$rgBaseName-appService keyVaultResourceGroup=$rgBaseName-keyVault storageResourceGroup=$rgBaseName-storage azureSQLResourceGroup=$rgBaseName-azureSQL useAADForSQLAdmin=$useAADForSQLAdmin AADAdminLogin=$groupName AADAdminObjectID=$aadGroupId AlertSendToEmailAddress=$aadUserMail LogAnalyticsSKU=$logAnalyticsSKU"
echo "Assigning logged in user to SQL Administrators Group"
addUser=$(az ad group member add -g $aadGroupId --member-id $aadUserId)
else
paramString="baseResourceName=$baseName appServiceResourceGroup=$rgBaseName-appService keyVaultResourceGroup=$rgBaseName-keyVault storageResourceGroup=$rgBaseName-storage azureSQLResourceGroup=$rgBaseName-azureSQL useAADForSQLAdmin=$useAADForSQLAdmin AADAdminLogin=$upn AADAdminObjectID=$aadUserId AlertSendToEmailAddress=$aadUserMail LogAnalyticsSKU=$logAnalyticsSKU"
fi
#Run the deployment
echo "Starting deployment..."
deploymentOutput=$(az group deployment create -g $rgBaseName --template-uri https://raw.githubusercontent.com/ianalderman/ukopaas/master/azuredeploy.json --parameters $paramString)
echo "Deployment completed..."
echo "Script finished"

13
scripts/tidy_up.sh Normal file
Просмотреть файл

@ -0,0 +1,13 @@
#!/bin/bash
echo "**** WARNING THIS WILL DELETE THE RESOURCE GROUPS CREATED FOR THE Azure PaaS Blueprint, ALL Resources will be lost... ****"
echo "**** You should manually grant yourself purge permissions and delete / purge the keyvaults as they have soft delete on... *****"
echo -n "Please enter the base resource group name:"
read baseResourceGroupName
az group delete --name $baseResourceGroupName --yes --no-wait
az group delete --name $baseResourceGroupName-AppService --yes --no-wait
az group delete --name $baseResourceGroupName-AzureSQL --yes --no-wait
az group delete --name $baseResourceGroupName-Storage --yes --no-wait
az group delete --name $baseResourceGroupName-KeyVault --yes --no-wait
echo "Script complete, please note it may take time for the resource groups to be fully deleted."