diff --git a/1-contribution-guide/README.md b/1-contribution-guide/README.md new file mode 100644 index 0000000..947ef9e --- /dev/null +++ b/1-contribution-guide/README.md @@ -0,0 +1,44 @@ +# Azure Managed Application samples + +This repository contains all currently available Azure Managed Application samples contributed by the community. The following information is relevant to get started with contributing to this repository. + ++ [**Contribution guide**](/1-contribution-guide/README.md#contribution-guide). Describes the minimal guidelines for contributing. ++ [**Best practices**](/1-contribution-guide/best-practices.md#best-practices). Best practices for improving the quality of Azure Managed Application design. ++ [**Git tutorial**](/1-contribution-guide/git-tutorial.md#git-tutorial). Step by step to get you started with Git. ++ [**Useful Tools**](/1-contribution-guide/useful-tools.md#useful-tools). Useful resources and tools for Azure development. + +## Contribution guide + +To make sure your Managed Application sample is added to this repository, please follow these guidelines. Any Managed Application sample that are out of compliance will be added to the **blacklist** and not be merged. + +## Files, folders and naming conventions + +1. Every Managed Application sample its associated files must be contained in its own **folder**. Name this folder so it represents what your Managed Application does. Usually this naming pattern looks like **appName-osName** or **level-platformCapability** (e.g. 101-managed-storage) + + **Required** - Numbering should start at 101. 100 is reserved for things that need to be at the top. + + **Protip** - Try to keep the name of your template folder short so that it fits inside the Github folder name column width. +2. Github uses ASCII for ordering files and folder. For consistent ordering **create all files and folders in lowercase**. The only **exception** to this guideline is the **README.md**, that should be in the format **UPPERCASE.lowercase**. +3. Include a **README.md** file that explains how the Managed Application works, and how to deploy. + + Guidelines on the README.md file below. +4. A Managed Application needs to include the following files: + + **mainTemplate.json** - The Resource Manager template that will deploy resources (and nested templates) + + **createUiDefinition.json** - The user interface definition file, to generate input parameters to the customer facing template in the [Azure portal](https://portal.azure.com) + + A generalized .zip file with all the artifacts for the Managed Application. +5. The custom scripts that are needed for successful template execution must be placed in a sub-folder called **scripts**. +6. Linked templates must be placed in a sub-folder called **nestedtemplates**. +7. Images used in the README.md must be placed in a folder called **images**. +8. an *azuredeploy.json* template which will create and initialize the Managed Application offering directly in the Azure subscription, referencing the artifacts in the reposotiry. + +![alt text](./images/structure.png "Files, folders and naming conventions") + +## README.md + +The README.md describes your deployment. A good description helps other community members to understand your deployment. The README.md uses [Github Flavored Markdown](https://guides.github.com/features/mastering-markdown/) for formatting text. If you want to add images to your README.md file, store the images in the **images** folder. Reference the images in the README.md with a relative path (e.g. `![alt text](images/namingConvention.png "Files, folders and naming conventions")`). This ensures the link will reference the target repository if the source repository is forked. A good README.md contains the following sections + ++ Deployment instructions ++ AzureDeploy/PowerShell/CLI example of automated import ++ Description of what the Managed Application will deploy ++ *Optional: Prerequisites ++ *Optional: Description on how to use the Managed Application ++ *Optional: Notes + +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. diff --git a/1-contribution-guide/best-practices.md b/1-contribution-guide/best-practices.md new file mode 100644 index 0000000..6b25397 --- /dev/null +++ b/1-contribution-guide/best-practices.md @@ -0,0 +1,205 @@ +# Best practices + +## In general.. + ++ It is a good practice to pass your Managed Application templates and UiDefinition through a JSON linter to remove extraneous commas, parenthesis, brackets that may break the deployment. Try http://jsonlint.com/ or a linter package for your favorite editing environment (Visual Studio Code, Atom, Sublime Text, Visual Studio etc.) ++ It's also a good idea to format your JSON for better readability. You can use a JSON formatter package for your local editor or [format online using this link](https://www.bing.com/search?q=json+formatter). + +## The following guidelines are relevant to the Managed Application Resource Manager templates. + +* Template parameters should follow **camelCasing** + +Example: +````json + "parameters": { + "storagePrefixName": { + "type": "string", + "metadata": { + "description": "Specify the prefix of the storage account name" + } + } + } +```` + +* Minimize parameters whenever possible, this allows for a good "hello world" experience where the user doesn't have to answer a number of questions to complete a deployment. If you can use a variable or a literal, do so. + +* Only provide parameters for: + + * Things that are globally unique (e.g. website name). These are usually the endpoints the user will interact with post deployment, and need to be aware of. However, in many cases a unique name can be generated automatically by using the [uniqueString()](https://azure.microsoft.com/en-us/documentation/articles/resource-group-template-functions/#uniquestring) template language function. + * Other things a user must know to complete a workflow (e.g. admin user name on a VM) + * Secrets (e.g. admin password on a VM) + * Every template **must** include a parameter that specifies the location of the resources, and the *defaultValue* should be *resourceGroup().location* + * If you must include a parameter, define a defaultValue, unless the parameter is used for a passwords, storage account name prefix, or domain name label + +* Every parameter in the template should have the **lower-case description** tag specified using the metadata property. This looks like below + +````json + "parameters": { + "storageAccountType": { + "type": "string", + "metadata": { + "description": "The type of the new storage account created to store the VM disks" + } + } + } +```` + +* Template parameters **must not** include *allowedValues* for the following parameter types + * Vm Size + * Location + + +>**Note**:Use *createUiDefinition.json* for this purpose + +* When nested templates or scripts are being used, the *mainTemplate.json* **must** include a variable with the uri() function with deployment().properties.templateLink.uri - to automatically resolve the URL for nested templates and scripts. The variable(s) would look similar to this: + +````json + "variables": { + "nestedTemplateUrl": "[uri(deployment().properties.templateLink.uri, 'nestedtemplates/mytemplate.json')]", + "scriptsUrl": "[uri(deployment().properties.templateLink.uri, 'scripts/myscript.ps1')]" + } +```` + +* Template parameters **must not** include default values for parameters that represents the following types + * Storage Account Name prefix + * Domain Name Label + +>**Note**: Use *createUiDefinition.json* for this purpose, to avoid conflict + +* Do not create a parameter for a **storage account name**, but specify it is for **storage account name prefix**. Storage account names need to be lower case and can't contain hyphens (-) in addition to other domain name restrictions. A storage account has a limit of 24 characters. They also need to be globally unique. To prevent any validation issue configure a variables (using the expression **uniqueString** and a static value **storage**). Storage accounts with a common prefix (uniqueString) will not get clustered on the same racks. + +Example: + +````json + "parameters": { + "storageAccountNamePrefix": { + "type": "string", + "metadata": { + "description": "Prefix for the storage account name" + } + } + }, + "variables": { + "storageAccountName": "[concat(parameters('storageAccountNamePrefix'), uniqueString('storage'))]" + }, +```` + + +* Passwords **must** be passed into parameters of type **securestring**. Do not specify a defaultValue for a parameter that is used for a password or an SSH key. Passwords must also be passed to **customScriptExtension** using the **commandToExecute** property in protectedSettings. + +````json + "properties": { + "publisher": "Microsoft.Azure.Extensions", + "type": "CustomScript", + "version": "2.0", + "autoUpgradeMinorVersion": true, + "settings": { + "fileUris": [ + "[concat(variables('template').assets, '/lamp-app/install_lamp.sh')]" + ] + }, + "protectedSettings": { + "commandToExecute": "[concat('sh install_lamp.sh ', parameters('mySqlPassword'))]" + } + } +```` + +>**Note**: In order to ensure that secrets which are passed as parameters to virtualMachines/extensions are encrypted, the protectedSettings property of the relevant extensions must be used. + +* Using tags to add metadata to resources allows you to add additional information about your resources. A good use case for tags is adding metadata to a resource for billing detail purposes. + +* You can group variables into complex objects. You can reference a value from a complex object in the format variable.subentry (e.g. `"[variables('storage').storageAccounts.type]"`). Grouping variables helps you keep track of related variables and improves readability of the template. + +>**Note**: A complex object cannot contain an expression that references a value from a complex object. Define a separate variable for this purpose. + +* If you include Azure management services to your Managed Application, such as Log Analytics, Azure Automation, Backup and Site Recovery, you **must** **not** use additional parameters for these resource locations. Instead, use the following pattern using variables, to place those services in the closest available Azure region to the Resource Group + +````json + "logAnalyticsLocationMap": { + "eastasia": "southeastasia", + "southeastasia": "southeastasia", + "centralus": "westcentralus", + "eastus": "eastus", + "eastus2": "eastus", + "westus": "westcentralus", + "northcentralus": "westcentralus", + "southcentralus": "westcentralus", + "northeurope": "westeurope", + "westeurope": "westeurope", + "japanwest": "southeastasia", + "japaneast": "southeastasia", + "brazilsouth": "eastus", + "australiaeast": "australiasoutheast", + "australiasoutheast": "australiasoutheast", + "southindia": "southeastasia", + "centralindia": "southeastasia", + "westindia": "southeastasia", + "canadacentral": "eastus", + "canadaeast": "eastus", + "uksouth": "westeurope", + "ukwest": "westeurope", + "westcentralus": "westcentralus", + "westus2": "westcentralus", + "koreacentral": "southeastasia", + "koreasouth": "southeastasia", + "eastus2euap": "eastus" + }, + "logAnalyticsLocation": "[variables('logAnalyticsLocationMap')[parameters('location')]]" +```` + +>**NOTE**: To find the available Azure regions for a Resource Provider, you can use the following PowerShell cmdlet: +>```Get-AzureRmResourceProvider -ProviderNamespace Microsoft.OperationalInsights | select -ExpandProperty Locations``` + +The domainNameLabel property for publicIPAddresses **must** be **unique**. domainNameLabel is required to be between 3 and 63 characters long and to follow the rules specified by this regular expression ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. As the uniqueString function will generate a string that is 13 characters long in the example below it is presumed that the dnsPrefixString prefix string has been checked to be no more than 50 characters long and to conform to those rules. + +>**Note**: The recommended approach for creating a publicIPAddresses is to use the Microsoft.Network.PublicIpAddressCombo in createUIDefinition.json which will validate the input and make sure the domainNameLabel is available, however if a Managed Application creates new publicIPAddresses in a template without using this element to provide parameters then it should ensure that the domainNameLabel properties used for them are unique + +````json + "parameters": { + "dnsPrefixString": { + "type": "string", + "maxLength": 50, + "metadata": { + "description": "DNS Label for the Public IP. Must be lowercase. It should match with the following regular expression: ^[a-z][a-z0-9-]{1,61}[a-z0-9]$ or it will raise an error." + } + } + }, + "variables": { + "dnsPrefix": "[concat(parameters('dnsPrefixString'),uniquestring(resourceGroup().id))]" + } +```` + +* For the public endpoints the user will interact with, you **must** provide this information in the **output** section in the templates, so it can be easily retrieved post deployment + +````json + "outputs": { + "vmEndpoint": { + "type": "string", + "value": "[reference(concat(parameters('vmName'), 'IP')).dnsSettings.fqdn]" + } + } +```` + +* If using *nested templates*, ensure you are referencing the outputs from the nested templates into the *mainTemplate.json* + +````json + "outputs": { + "vmEndpoint": { + "type": "string", + "value": "[reference('nestedDeployment').outputs.vmEndpoint.value]" + } + } +```` + +* To set the managed application resource name, you must use ````"applicationResourceName"```` in the ````createUiDefinition.json```` file. If not, the application will automatically get a GUID for this resource. +Example usage: + +````json + "outputs": { + "vmName": "[steps('appSettings').vmName]", + "trialOrProduction": "[steps('appSettings').trialOrProd]", + "userName": "[steps('vmCredentials').adminUsername]", + "pwd": "[steps('vmCredentials').vmPwd.password]", + "applicationResourceName": "[steps('appSettings').vmName]" + } +```` diff --git a/1-contribution-guide/images/artifacts.png b/1-contribution-guide/images/artifacts.png new file mode 100644 index 0000000..659c3cb Binary files /dev/null and b/1-contribution-guide/images/artifacts.png differ diff --git a/1-contribution-guide/images/downloadrepo.png b/1-contribution-guide/images/downloadrepo.png new file mode 100644 index 0000000..64a7589 Binary files /dev/null and b/1-contribution-guide/images/downloadrepo.png differ diff --git a/1-contribution-guide/images/managedapps.png b/1-contribution-guide/images/managedapps.png new file mode 100644 index 0000000..6b57213 Binary files /dev/null and b/1-contribution-guide/images/managedapps.png differ diff --git a/1-contribution-guide/images/structure.png b/1-contribution-guide/images/structure.png new file mode 100644 index 0000000..b77b2f6 Binary files /dev/null and b/1-contribution-guide/images/structure.png differ diff --git a/1-contribution-guide/images/validation.png b/1-contribution-guide/images/validation.png new file mode 100644 index 0000000..db2a3b1 Binary files /dev/null and b/1-contribution-guide/images/validation.png differ diff --git a/1-contribution-guide/psscript.md b/1-contribution-guide/psscript.md new file mode 100644 index 0000000..c047511 --- /dev/null +++ b/1-contribution-guide/psscript.md @@ -0,0 +1,152 @@ +# PowerShell sample to initialize Managed Application in Service Catalog + +1. Navigate to the folder where you extracted the sample you want to use +2. Use the following script to auto generate the *mainTemplate.json* to have the *"applianceDefinitionId"* property to match your environment. +**Ensure you change the parameters with your own values before you proceed.** +```powershell +[cmdletbinding()] +param( + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $location = 'westcentralus', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $rgName = 'knappliancedef', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $ManagedApplicationName = 'ManagedServiceFabric', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $ManagedApplicationDisplayName = 'Managed Service Fabric', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $ManagedApplicationDescription = 'Managed Service Fabric with Azure management', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $principalId = '78343385-2886-470d-a12a-dd31f8758617', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $roleDefinitionId = '8e3af657-a8ff-443c-a75c-2fe8c4bcb635', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $zipFilename = 'servicefabric.zip', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $storageAccountName = 'mystorageaccount', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [string] $storageContainerName = 'container1' +) + +$localpath = if ($env:Build_Repository_LocalPath) { + $env:Build_Repository_LocalPath +} else { + '.' +} + +try { + # Set the mainTemplate resource Id to match parameters + # Add the parameters from the applianceMainTemplate.json to the mainTemplate.json + # Set the name of the resource to match the name of the Managed Application + + $applianceMainTemplate = (Get-Content -path ${LocalPath}\applianceMainTemplate.json) -join "`n" | ConvertFrom-Json + + $azuredeployjson = @' + { + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": { + "applianceInfraResourceGroupId": "[concat(resourceGroup().id,'-application-resources')]" + }, + "resources": [ + { + "type": "Microsoft.Solutions/appliances", + "name": "", + "apiVersion": "2016-09-01-preview", + "location": "[resourceGroup().Location]", + "kind": "ServiceCatalog", + "properties": { + "managedResourceGroupId": "[variables('applianceInfraResourceGroupId')]", + "applianceDefinitionId": "appDefId", + "parameters": {} + } + } + ], + "outputs": {} + } +'@ + + $azuredeploytemplate = $azuredeployjson | ConvertFrom-Json + $azuredeploytemplate.parameters = $applianceMainTemplate.parameters + $applianceparameters = @{} + foreach ($parameter in $applianceMainTemplate.parameters.psobject.properties) { + $applianceparameter = @{'value' = "[parameters('$($parameter.Name)')]"} + $value = New-Object PSObject -Property $applianceparameter + $applianceparameters.Add($($parameter.Name), $value) + } + $azuredeploytemplate.resources[0].properties.parameters = New-Object PSObject -Property $applianceparameters + $ResourceId = "[concat('/subscriptions/',subscription().subscriptionId,'/resourceGroups/${rgName}/providers/Microsoft.Solutions/applianceDefinitions/${ManagedApplicationName}')]" + $azuredeploytemplate.resources[0].properties.applianceDefinitionId = $ResourceId + $azuredeploytemplate.resources[0].name = $ManagedApplicationName + + Write-Output "Creating mainTemplate with new applianceDefinitionId $ResourceId" + (ConvertTo-Json $azuredeploytemplate -Depth 10 ).Replace('\u0027', '''')|Out-File -FilePath ${LocalPath}\mainTemplate.json -Force -Encoding UTF8 + + Write-Output "Creating Zip File" + Compress-Archive -Path ${localPath}\applianceCreateUiDefinition.json, ${localPath}\mainTemplate.json, ${localPath}\applianceMainTemplate.json, ${localPath}\nestedtemplates -DestinationPath ${localPath}\${zipFilename} -Force + + Write-Output "Uploading Zip File" + $storageResource = Find-AzureRmResource -ResourceType Microsoft.Storage/storageAccounts -ResourceNameEquals $storageAccountName + $storageAccount = Get-AzureRmStorageAccount -StorageAccountName $storageAccountName -ResourceGroupName $storageResource.ResourceGroupName + $container = Get-AzureStorageContainer -Name $storageContainerName -MaxCount 1 -Context $storageAccount.Context -ErrorAction SilentlyContinue + + if ($container) { + if ($container.PublicAccess -eq 'off') { + throw 'Container must allow public access to blobs' + } + } else { + New-AzureStorageContainer -Name $StorageContainerName -Permission Blob -Context $storageAccount.Context + } + + $null = Set-AzureStorageBlobContent -Container $storageContainerName -File $zipFilename -Context $storageAccount.Context -Force + $packageFileUri = "https://${storageAccountName}.blob.core.windows.net/${storageContainerName}/${zipFilename}" + + $propertyObject = @{ + "LockLevel" = "ReadOnly" + "DisplayName" = $ManagedApplicationDisplayName + "Description" = $ManagedApplicationDescription + "Authorizations" = @( + @{ + "principalId" = $principalId + "roleDefinitionId" = $roleDefinitionId + } + ) + "PackageFileUri" = $packageFileUri + } + + Write-Output "Creating Application Definition" + $rg = Get-AzureRmResourceGroup -Name $rgname -location $location -ErrorAction SilentlyContinue + if (-not $rg) { + Write-Output "Creating Resource Group -Name $rgname -location $location" + New-AzureRmResourceGroup -Name $rgname -location $location + } + + Write-Output "Creating or Updating the Appliance Definiton" + New-AzureRmResource -ResourceName $ManagedApplicationName -ResourceType 'Microsoft.Solutions/applianceDefinitions' -ResourceGroupName $rgName -Location $location -ApiVersion '2016-09-01-preview' -PropertyObject $propertyObject -force +} catch { + throw $_ +} +``` +Open [Azure portal](https://portal.azure.com), Managed Application, Add, and you should see your newly created Managed Application offering + +![media](./images/managedapps.png) diff --git a/1-contribution-guide/useful-tools.md b/1-contribution-guide/useful-tools.md new file mode 100644 index 0000000..a0d964e --- /dev/null +++ b/1-contribution-guide/useful-tools.md @@ -0,0 +1,7 @@ +Learn more about [Creating and deploying Azure resource groups through Visual Studio](https://azure.microsoft.com/en-us/documentation/articles/vs-azure-tools-resource-groups-deployment-projects-create-deploy) + +Learn more about [Resource manager for VS Code](https://azure.microsoft.com/en-us/documentation/articles/resource-manager-vs-code/) + +Learn more about [Azure SDK and Tools for Visual Studio](https://www.visualstudio.com/features/azure-tools-vs) + +Learn more about all the Azure tools: https://azure.microsoft.com/en-us/tools/ \ No newline at end of file diff --git a/README.md b/README.md index a6fd71f..b09d153 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,23 @@ +# Azure Managed Application samples ## Abstract This repository contains samples of Azure Managed Applications that can be used as reference for creating and consuming managed applications. +## Documentation + +[Azure Managed Application overview](https://docs.microsoft.com/en-us/azure/azure-resource-manager/managed-application-overview) + +[Create and publish Azure Managed Applications to Service Catalog](https://docs.microsoft.com/en-us/azure/azure-resource-manager/managed-application-publishing) + +[Create and publish Azure Managed Applications to Azure Marketplace](https://docs.microsoft.com/en-us/azure/azure-resource-manager/managed-application-author-marketplace) + +[Consume an Azure Managed Application](https://docs.microsoft.com/en-us/azure/azure-resource-manager/managed-application-consumption) + +[Create UI definitions](https://docs.microsoft.com/en-us/azure/azure-resource-manager/managed-application-createuidefinition-overview) + + ## Contributing -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. +To contribute and get started, please visit our [**contribution guide**](./1-contribution-guide/README.md#contribution-guide). + +*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.* diff --git a/samples/101-managed-storage-account/createUiDefinition.json b/samples/101-managed-storage-account/createUiDefinition.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/samples/101-managed-storage-account/createUiDefinition.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/samples/101-managed-storage-account/mainTemplate.json b/samples/101-managed-storage-account/mainTemplate.json new file mode 100644 index 0000000..33163fd --- /dev/null +++ b/samples/101-managed-storage-account/mainTemplate.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "storageAccountName": { + "type": "string" + } + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "name": "[parameters('storageAccountName')]", + "apiVersion": "2016-01-01", + "location": "[resourceGroup().location]", + "sku": { + "name": "Standard_LRS" + }, + "kind": "Storage", + "properties": {} + } + ], + "outputs": {} +} \ No newline at end of file diff --git a/samples/101-managed-storage-account/readme.md b/samples/101-managed-storage-account/readme.md new file mode 100644 index 0000000..8311fa5 --- /dev/null +++ b/samples/101-managed-storage-account/readme.md @@ -0,0 +1,42 @@ +# Managed Azure Storage Account (without Ui Definition) + +>Note: This sample is for Managed Application in Service Catalog. For Marketplace, please see these instructions: +[**Marketplace Managed Application**](/1-contribution-guide/marketplace.md#transitioning-to-marketplace) + +## How to try out this Azure Managed Application + +Step 1: Create an ARM template (Use the applianceMainTemplate.json) + +Step 2: Create a ManagedApp template (User the mainTemplate.json) + +Step 3: Create create ui definition file (Use applianceCreateUiDefinition.json) + +Step 4: Zip the files above (Use managed_singlestorageaccount.zip) and upload to public blob storage or upload to public github accout and get the URL. + + e.g. if you have upload to azure storage blob it would look something like https://.blob.core.windows.net//managed_singlestorageaccount.zip) + Please make sure that you copy paste this URL in browser and see if you see zip file is being downloaded. If this doesn't happen change container's access to "public ReadOnly" + +Step 5: Create ManagedApp Definition + +1. Get principal id: + + Create user group (From Azure Portal Go to "Azure Active Directory" -> "All groups" -> "New group" ->Create a new group and add other than your azure account in the group) + Copy paste "Object Id" of the user group and use it as principal id + +2. For the demo use roleDefinitionId as 8e3af657-a8ff-443c-a75c-2fe8c4bcb635 (This is built in role definition for the "Owner") + +3. Go to Azure Portal (portal.azure.com) -> from the top right corner select "Cloud Shell" and run following commmand: + + az managedapp definition create --display-name HelloManagedAppDef --description "A simple managedApp definition consist of a storage account" -a ":8e3af657-a8ff-443c-a75c-2fe8c4bcb635" -l westcentralus --lock-level ReadOnly -g appdefRG -n helloManagedAppDef --package-file-uri https://.blob.core.windows.net//managed_singlestorageaccount.zip + +Step 6: Create ManagedApp + +Create managed app using managed app definition created above + + az managedapp create --location westcentralus --kind serviceCatalog --managed-rg-id /subscriptions//resourceGroups/helloManagedByRG --name helloworldmanagedApp --resource-group helloManagedApp --managedapp-definition-id "/subscriptions//resourceGroups/appdefRG/providers/Microsoft.Solutions/applianceDefinitions/helloManagedAppDef" + +After this you should be able to see two resource group appdefRG and helloManagedByRG. +appdefRG should have helloManagedAppDef resource +helloManagedByRG resource group should have a storage account + +Now if you have selected other than your storage account in the user group you won't be able to delete or modify any thing on the helloManagedByRG and the storage account underneath. User part of the principal id (user group) an even do all the operation on the storage account \ No newline at end of file diff --git a/samples/101-managed-vm/README.md b/samples/101-managed-vm/README.md new file mode 100644 index 0000000..263cba4 --- /dev/null +++ b/samples/101-managed-vm/README.md @@ -0,0 +1,49 @@ +# Managed Virtual Machine + +>Note: This sample is for Managed Application in Service Catalog. For Marketplace, please see these instructions: +[**Marketplace Managed Application**](https://docs.microsoft.com/en-us/azure/managed-applications/publish-marketplace-app) + +## Deploy this sample to your Service Catalog + +### Deploy using Azure Portal + +Clicking on the button below, will create the Managed Application definition to a Resource Group in your Azure subscription. + +[![Deploy to Azure](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-managedapp-samples%2Fmaster%2Fsamples%2F101-managed-vm%2Fazuredeploy.json) + +### Deploy using PowerShell + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````powershell +$rgname = "" +$location = "" +$authorization = ":" +$uri = "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/101-managed-vm/managedvm.zip" + +New-AzureRmManagedApplicationDefinition -Name "ManagedVM" ` + -ResourceGroupName $rgname ` + -DisplayName "Managed VM" ` + -Description "Managed virtual machine" ` + -Location $location ` + -LockLevel ReadOnly ` + -PackageFileUri $uri ` + -Authorization $authorization ` + -Verbose +```` + +### Deploy using AzureCLI + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````azureCLI +az managedapp definition create \ + --name "ManagedWebApp" \ + --location \ + --resource-group \ + --lock-level ReadOnly \ + --display-name "Managed VM" \ + --description "Managed virtual machine" \ + --authorizations ":" \ + --package-file-uri "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/101-managed-vm/managedvm.zip" +```` \ No newline at end of file diff --git a/samples/101-managed-vm/azuredeploy.json b/samples/101-managed-vm/azuredeploy.json new file mode 100644 index 0000000..adf3a73 --- /dev/null +++ b/samples/101-managed-vm/azuredeploy.json @@ -0,0 +1,82 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "type": "string", + "defaultValue": "ManagedWebApp", + "metadata": { + "description": "Provide a name for the managed application" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Specify the Azure region to place the application definition" + } + }, + "lockLevel": { + "type": "string", + "allowedValues": [ + "ReadOnly", + "CanNotDelete" + ], + "defaultValue": "ReadOnly", + "metadata": { + "description": "Specify the resource lock being used for the managed application" + } + }, + "authorizations": { + "type": "array", + "metadata": { + "description": "Provide the authorization mapping for the managed application." + } + }, + "description": { + "type": "string", + "defaultValue": "Managed Azure IaaS Web Application", + "metadata": { + "description": "Provide a brief description of the managed application" + } + }, + "displayName": { + "type": "string", + "defaultValue": "Managed Azure Web Application", + "metadata": { + "description": "Display name for the managed application" + } + } + }, + "variables": { + "packageFileUri": "[uri(deployment().properties.templateLink.uri, 'managedwebapp.zip')]" + }, + "resources": [ + { + "apiVersion": "2017-09-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "type": "Microsoft.Solutions/applicationDefinitions", + "properties": { + "lockLevel": "[parameters('lockLevel')]", + "authorizations": "[array(parameters('authorizations'))]", + "description": "[parameters('description')]", + "displayName": "[parameters('displayName')]", + "packageFileUri": "[variables('packageFileUri')]" + } + } + ], + "outputs": { + "managedApplicationName": { + "type": "string", + "value": "[parameters('name')]" + }, + "lockLevel": { + "type": "string", + "value": "[parameters('locklevel')]" + }, + "packageFileUri": { + "type": "string", + "value": "[variables('packageFileUri')]" + } + } +} \ No newline at end of file diff --git a/samples/101-managed-vm/createUiDefinition.json b/samples/101-managed-vm/createUiDefinition.json new file mode 100644 index 0000000..3294d1f --- /dev/null +++ b/samples/101-managed-vm/createUiDefinition.json @@ -0,0 +1,130 @@ +{ + "handler": "Microsoft.Compute.MultiVm", + "version": "0.1.2-preview", + "parameters": { + "basics": [ + {} + ], + "steps": [ + { + "name": "credentialsConfig", + "label": "VM Credential", + "subLabel": { + "preValidation": "Configure the VM credentials", + "postValidation": "Done" + }, + "bladeTitle": "Credential", + "elements": [ + { + "name": "adminUsername", + "type": "Microsoft.Compute.UserNameTextBox", + "label": "User name", + "toolTip": "Admin username for the virtual machine", + "osPlatform": "Windows", + "constraints": { + "required": true + } + }, + { + "name": "adminPassword", + "type": "Microsoft.Compute.CredentialsCombo", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": { + "password": "Admin password for the virtual machine" + }, + "osPlatform": "Windows", + "constraints": { + "required": true + } + } + ] + }, + { + "name": "vmConfig", + "label": "Virtual Machine settings", + "subLabel": { + "preValidation": "Configure the virtual machine settings", + "postValidation": "Done" + }, + "bladeTitle": "VM Settings", + "elements": [ + { + "name": "vmNamePrefix", + "type": "Microsoft.Common.TextBox", + "label": "Virtual Machine Name prefix", + "toolTip": "Prefix for the virtual machine", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "[a-z][a-z0-9-]{2,5}[a-z0-9]$", + "validationMessage": "Must be 3-5 characters." + } + }, + { + "name": "vmSize", + "type": "Microsoft.Compute.SizeSelector", + "label": "Virtual machine size", + "toolTip": "The size of the virtual machine", + "recommendedSizes": [ + "Standard_D1_v2" + ], + "constraints": { + "allowedSizes": [ + "Standard_D1_v2" + ] + }, + "osPlatform": "Windows", + "count": 1 + } + ] + }, + { + "name": "webConfig", + "label": "Endpoint settings", + "subLabel": { + "preValidation": "Configure the VM endpoint", + "postValidation": "Done" + }, + "bladeTitle": "VM Endpoint settings", + "elements": [ + { + "name": "dnsAndPublicIP", + "type": "Microsoft.Network.PublicIpAddressCombo", + "label": { + "publicIpAddress": "Public IP address", + "domainNameLabel": "DNS label" + }, + "toolTip": { + "domainNameLabel": "DNS endpoint for the Managed VM IP address." + }, + "defaultValue": { + "publicIpAddressName": "ip01" + }, + "options": { + "hideNone": true, + "hideDomainNameLabel": false + }, + "constraints": { + "required": { + "domainNameLabel": true + } + } + } + ] + } + ], + "outputs": { + "location": "[location()]", + "vmSize": "[steps('vmConfig').vmSize]", + "vmNamePrefix": "[steps('vmConfig').vmNamePrefix]", + "applicationResourceName": "[steps('vmConfig').vmNamePrefix]", + "userName": "[steps('credentialsConfig').adminUsername]", + "pwd": "[steps('credentialsConfig').adminPassword.password]", + "dnsName": "[steps('webConfig').dnsAndPublicIP.domainNameLabel]", + "publicIPAddressName": "[steps('webConfig').dnsAndPublicIP.name]" + } + } +} \ No newline at end of file diff --git a/samples/101-managed-vm/mainTemplate.json b/samples/101-managed-vm/mainTemplate.json new file mode 100644 index 0000000..71a6a6d --- /dev/null +++ b/samples/101-managed-vm/mainTemplate.json @@ -0,0 +1,212 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmNamePrefix": { + "type": "string", + "metadata": { + "description": "Assign a prefix for the VM name" + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Select the Azure region for the resources" + } + }, + "vmSize": { + "type": "string", + "metadata": { + "description": "Selec the vm size" + } + }, + "userName": { + "type": "string", + "defaultValue": "azureadmin", + "metadata": { + "description": "Specify the OS username" + } + }, + "pwd": { + "type": "securestring", + "metadata": { + "description": "If Windows, specify the password for the OS username" + } + }, + "dnsName": { + "type": "string", + "metadata": { + "description": "Specify the DNS name for the managed web app" + } + }, + "publicIPAddressName": { + "type": "string", + "metadata": { + "description": "Assign a name for the public IP address" + } + } + }, + "variables": { + "vnetID": "[resourceId('Microsoft.Network/virtualnetworks', 'vmVnet')]", + "subnetRef": "[concat(variables('vnetID'),'/subnets/', 'subnet1')]", + "osTypeWindows": { + "imageOffer": "WindowsServer", + "imageSku": "2016-Datacenter", + "imagePublisher": "MicrosoftWindowsServer" + } + }, + "resources": [ + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2017-03-01", + "name": "vmVnet", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups/', 'NSG')]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "10.0.0.0/16" + ] + }, + "subnets": [ + { + "name": "subnet1", + "properties": { + "addressPrefix": "10.0.0.0/24", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups/', 'NSG')]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2017-03-01", + "name": "NSG", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "RDP", + "properties": { + "access": "Allow", + "description": "Inbound RDP rule", + "direction": "Inbound", + "destinationAddressPrefix": "*", + "protocol": "Tcp", + "destinationPortRange": 3389, + "sourcePortRange": "*", + "priority": 500, + "sourceAddressPrefix": "*" + } + }, + { + "name": "HTTP", + "properties": { + "access": "Allow", + "description": "Inbound HTTP rule", + "direction": "Inbound", + "destinationAddressPrefix": "*", + "protocol": "Tcp", + "destinationPortRange": 80, + "sourcePortRange": "*", + "priority": 550, + "sourceAddressPrefix": "*" + } + } + ] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2017-04-01", + "name": "[concat(parameters('publicIPAddressName'), 'IP')]", + "location": "[parameters('location')]", + "properties": { + "publicIPallocationmethod": "Dynamic", + "dnsSettings": { + "domainNameLabel": "[toLower(parameters('dnsName'))]" + } + } + }, + { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2017-04-01", + "name": "[concat(parameters('vmNamePrefix'), 'nic')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'), 'IP')]", + "[resourceId('Microsoft.Network/virtualNetworks/', 'vmVnet')]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(parameters('publicIPAddressName'), 'IP'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2017-03-30", + "name": "[concat(parameters('vmNamePrefix'), '-app')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/networkinterfaces/', parameters('vmNamePrefix'), 'nic')]" + ], + "properties": { + "hardwareProfile": { + "vmsize": "[parameters('vmSize')]" + }, + "osProfile": { + "computername": "[concat(parameters('vmNamePrefix'), '-app')]", + "adminusername": "[parameters('username')]", + "adminpassword": "[parameters('pwd')]" + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('osTypeWindows').imagePublisher]", + "offer": "[variables('osTypeWindows').imageOffer]", + "version": "latest", + "sku": "[variables('osTypeWindows').imageSku]" + }, + "osdisk": { + "name": "[concat(parameters('vmNamePrefix'), '-osDisk')]", + "createOption": "FromImage", + "managedDisk": { + "storageAccountType": "Standard_LRS" + }, + "caching": "ReadWrite" + } + }, + "networkprofile": { + "networkinterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkinterfaces', concat(parameters('vmNamePrefix'),'nic'))]" + } + ] + } + } + } + ], + "outputs": { + "vmEndpoint": { + "type": "string", + "value": "[reference(concat(parameters('publicIPAddressName'), 'IP')).dnsSettings.fqdn]" + } + } +} \ No newline at end of file diff --git a/samples/101-managed-vm/managedvm.zip b/samples/101-managed-vm/managedvm.zip new file mode 100644 index 0000000..9f3c0d3 Binary files /dev/null and b/samples/101-managed-vm/managedvm.zip differ diff --git a/samples/201-managed-app-using-existing-vnet/README.md b/samples/201-managed-app-using-existing-vnet/README.md new file mode 100644 index 0000000..bebdb8e --- /dev/null +++ b/samples/201-managed-app-using-existing-vnet/README.md @@ -0,0 +1,59 @@ +# Managed Application (Trial or Production) into a new or existing virtual network + +This Managed Application supports demonstrates how you can create flexible deployment options for customers, using native ARM template language expressions, together with UI elements. + +* New or Existing virtual network? + +This managed application can either be deployed to a new virtual network the customer specifices, or plug into an existing virtual network. + +* Trial or Production? + +Let your customer explore the managed application using trial, where they will run an implementation with minimal cost and footprint. If they opt-in for production, they will get the optimized experienc which can have additional costs (vm size, additional resources for HA etc.) + +>Note: This sample is for Managed Application in Service Catalog. For Marketplace, please see these instructions: +[**Marketplace Managed Application**](https://docs.microsoft.com/en-us/azure/managed-applications/publish-marketplace-app) + +## Deploy this sample to your Service Catalog + +### Deploy using Azure Portal + +Clicking on the button below, will create the Managed Application definition to a Resource Group in your Azure subscription. + +[![Deploy to Azure](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-managedapp-samples%2Fmaster%2Fsamples%2F201-managed-app-using-existing-vnet%2Fazuredeploy.json) + +### Deploy using PowerShell + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````powershell +$rgname = "" +$location = "" +$authorization = ":" +$uri = "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-app-using-existing-vnet/managedAppVnet.zip" + +New-AzureRmManagedApplicationDefinition -Name "ManagedWebApp" ` + -ResourceGroupName $rgname ` + -DisplayName "Managed Web App" ` + -Description "Managed Web App with Azure mgmt" ` + -Location $location ` + -LockLevel ReadOnly ` + -PackageFileUri $uri ` + -Authorization $authorization ` + -Verbose +```` + +### Deploy using AzureCLI + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````azureCLI +az managedapp definition create \ + --name "ManagedWebApp" \ + --location \ + --resource-group \ + --lock-level ReadOnly \ + --display-name "Managed Web Application" \ + --description "Web App with Azure mgmt" \ + --authorizations ":" \ + --package-file-uri "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-app-using-existing-vnet/managedAppVnet.zip" +```` \ No newline at end of file diff --git a/samples/201-managed-app-using-existing-vnet/createUiDefinition.json b/samples/201-managed-app-using-existing-vnet/createUiDefinition.json new file mode 100644 index 0000000..6298923 --- /dev/null +++ b/samples/201-managed-app-using-existing-vnet/createUiDefinition.json @@ -0,0 +1,142 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Compute.MultiVm", + "version": "0.1.2-preview", + "parameters": { + "basics": [ + {} + ], + "steps": [ + { + "name": "vmCredentials", + "label": "Azure Managed Application", + "bladeTitle": "Application credentials", + "subLabel": { + "preValidation": "Provide VM credentials", + "postValidation": "Great - let's move on!" + }, + "elements": [ + { + "name": "adminUserName", + "type": "Microsoft.Compute.UserNameTextBox", + "label": "Admin username", + "osPlatform": "Windows", + "constraints": { + "required": true + }, + "toolTip": "Provide admin username for the virtual machine" + }, + { + "name": "vmPwd", + "type": "Microsoft.Compute.CredentialsCombo", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "osPlatform": "Windows", + "constraints": { + "customPasswordRegex": "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$", + "customValidationMessage": "The password must contain at least 8 characters", + "required": true + }, + "options": { + "hideConfirmation": false + }, + "toolTip": { + "password": "Provide admin password for the virtual machine" + }, + "visible": true + } + ] + }, + { + "name": "appSettings", + "label": "Application settings", + "subLabel": { + "preValidation": "Configure the managed application", + "postValidation": "Done!" + }, + "bladeTitle": "Settings", + "elements": [ + { + "name": "vmName", + "type": "Microsoft.Common.TextBox", + "label": "Application name", + "toolTip": "Assign a name to your Azure application", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "[a-z][a-z0-9-]{2,5}[a-z0-9]$", + "validationMessage": "Must be 3-5 characters." + } + }, + { + "name": "trialOrProd", + "type": "Microsoft.Common.OptionsGroup", + "label": "Trial or Production?", + "defaultValue": "Trial", + "toolTip": "For trial, cost will be minimal. For prod, resources are optimized.", + "constraints": { + "allowedValues": [ + { + "label": "Trial", + "value": "Trial" + }, + { + "label": "Production", + "value": "Production" + } + ] + }, + "visible": true + }, + { + "name": "virtualNetwork", + "type": "Microsoft.Network.VirtualNetworkCombo", + "label": { + "virtualNetwork": "Virtual network", + "subnets": "Subnets" + }, + "toolTip": { + "virtualNetwork": "Virtual Network Name", + "subnets": "Subnet requried for Azure Application" + }, + "defaultValue": { + "name": "app-vnet", + "addressPrefixSize": "/22" + }, + "constraints": { + "minAddressPrefixSize": "/22" + }, + "subnets": { + "subnet1": { + "label": "Subnet name", + "defaultValue": { + "name": "app-subnet", + "addressPrefixSize": "/24" + }, + "constraints": { + "minAddressPrefixSize": "/24", + "minAddressCount": 12, + "requireContiguousAddresses": false + } + } + } + } + ] + } + ], + "outputs": { + "vmName": "[steps('appSettings').vmName]", + "trialOrProduction": "[steps('appSettings').trialOrProd]", + "userName": "[steps('vmCredentials').adminUsername]", + "pwd": "[steps('vmCredentials').vmPwd.password]", + "applicationResourceName": "[steps('appSettings').vmName]", + "subnetName": "[steps('appSettings').virtualNetwork.subnets.subnet1.name]", + "subnetAddressPrefix": "[steps('appSettings').virtualNetwork.subnets.subnet1.addressPrefix]", + "vNetAddressPrefix": "[steps('appSettings').virtualNetwork.addressPrefix]", + "virtualNetworkName": "[steps('appSettings').virtualNetwork.name]", + "vNetRgName": "[steps('appSettings').virtualNetwork.resourceGroup]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-app-using-existing-vnet/mainTemplate.json b/samples/201-managed-app-using-existing-vnet/mainTemplate.json new file mode 100644 index 0000000..16163f7 --- /dev/null +++ b/samples/201-managed-app-using-existing-vnet/mainTemplate.json @@ -0,0 +1,249 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmName": { + "type": "string", + "metadata": { + "description": "Virtual machine name" + } + }, + "trialOrProduction": { + "type": "string", + "allowedValues": [ + "Trial", + "Production" + ], + "metadata": { + "description": "Select whether the VM should be in production or not." + } + }, + "userName": { + "type": "string", + "defaultValue": "azureadmin", + "metadata": { + "description": "Username for the guest OS" + } + }, + "pwd": { + "type": "securestring", + "metadata": { + "description": "Application password" + } + }, + "virtualNetworkName": { + "type": "string", + "defaultValue": "vnet1", + "metadata": { + "description": "Virtual network name" + } + }, + "subnetName": { + "type": "string", + "defaultValue": "subnet1", + "metadata": { + "description": "Subnet name" + } + }, + "vNetRgName": { + "type": "string", + "metadata": { + "description": "Virtual network resource group name" + } + }, + "vNetAddressPrefix": { + "type": "string", + "defaultValue": "192.168.0.0/16", + "metadata": { + "description": "Virtual network address prefix" + } + }, + "subnetAddressPrefix": { + "type": "string", + "metadata": { + "description": "Subnet address prefix" + } + } + }, + "variables": { + "diskSizes": [20, 30], + "productionvNetName": "[resourceId(parameters('vNetRgName'), 'Microsoft.Networks/virtualNetworks/', parameters('virtualNetworkName'))]", + "productionSubnetId": "[concat(variables('productionvNetName'), '/subnets/', parameters('subnetName'))]", + "vNetName": "trialvNet", + "sNetName": "trialSubnet", + "vnetID": "[resourceId('Microsoft.Network/virtualnetworks', variables('vNetName'))]", + "subnetRef": "[concat(variables('vNetId'),'/subnets/', variables('sNetName'))]", + "windowsOffer": "WindowsServer", + "windowsSku": "2016-Datacenter", + "windowsPublisher": "MicrosoftWindowsServer", + "availabilitySetName": "[concat(parameters('vmName'), '-', 'avset')]", + "availabilitySetId": { + "id": "[resourceId('Microsoft.Compute/availabilitySets', variables('availabilitySetName'))]" + }, + "vNicName": "[concat(parameters('vmName'), '-', 'nic')]", + "pNicName": "[concat(parameters('vmName'), '-', 'pip')]", + "copy": [ + { + "name": "managedDiskId", + "count": "[length(variables('diskSizes'))]", + "input": { + "lun": "[copyIndex('managedDiskId')]", + "createOption": "Empty", + "diskSizeGB": "[variables('diskSizes')[copyIndex('managedDiskId')]]" + } + } + ] + }, + "resources": [ + { + "condition": "[equals(parameters('trialOrProduction'), 'Trial')]", + "apiVersion": "2017-04-01", + "type": "Microsoft.Network/virtualNetworks", + "name": "[variables('vNetName')]", + "location": "[resourceGroup().location]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[parameters('vNetAddressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('sNetName')]", + "properties": { + "addressPrefix": "[parameters('subnetAddressPrefix')]" + } + } + ] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2017-04-01", + "name": "[variables('pNicName')]", + "location": "[resourceGroup().location]", + "properties": { + "publicIPallocationmethod": "Dynamic", + "dnsSettings": { + "domainNameLabel": "[toLower(parameters('vmName'))]" + } + } + }, + { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2017-04-01", + "name": "[variables('vNicName')]", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[resourceId('Microsoft.Network/publicIPAddresses/', variables('pNicName'))]", + "[resourceId('Microsoft.network/virtualNetworks/', variables('vNetName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('pNicName'))]" + }, + "subnet": { + "id": "[if(equals(parameters('trialOrProduction'), 'Production'), variables('productionSubnetId'), variables('subnetRef'))]" + } + } + } + ] + } + }, + { + "condition": "[equals(parameters('trialOrProduction'), 'Production')]", + "type": "Microsoft.Compute/availabilitySets", + "apiVersion": "2017-03-30", + "name": "[variables('availabilitySetName')]", + "location": "[resourceGroup().location]", + "properties": { + "platformFaultDomainCount": 2, + "platformUpdateDomainCount": 3 + }, + "sku": { + "name": "Aligned" + } + }, + { + "condition": "[equals(parameters('trialOrProduction'), 'Production')]", + "type": "Microsoft.Compute/disks", + "apiVersion": "2017-03-30", + "name": "[concat(parameters('vmName'), '-mdisk')]", + "location": "[resourceGroup().location]", + "sku": { + "name": "Premium_LRS" + }, + "properties": { + "creationData": { + "createOption": "Empty" + }, + "diskSizeGB": 200 + } + }, + { + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2017-03-30", + "name": "[parameters('vmName')]", + "location": "[resourceGroup().location]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkinterfaces/', variables('vNicName'))]", + "[resourceId('Microsoft.Compute/availabilitySets/', variables('availabilitySetName'))]", + "[resourceId('Microsoft.Compute/disks', concat(parameters('vmName'), '-mDisk'))]" + ], + "properties": { + "availabilitySet": "[if(equals(parameters('trialOrProduction'), 'Production'), variables('availabilitySetId'), json('null'))]", + "hardwareprofile": { + "vmsize": "[if(equals(parameters('trialOrProduction'), 'Production'), 'Standard_DS3_v2', 'Standard_DS1_v2')]" + }, + "osProfile": { + "computername": "[parameters('vmName')]", + "adminusername": "[parameters('username')]", + "adminpassword": "[parameters('pwd')]" + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('windowsPublisher')]", + "offer": "[variables('windowsOffer')]", + "version": "latest", + "sku": "[variables('windowsSku')]" + }, + "osdisk": { + "name": "[concat(parameters('vmName'), '-osDisk')]", + "createOption": "FromImage", + "managedDisk": { + "storageAccountType": "[if(equals(parameters('trialOrProduction'), 'Production'), 'Premium_LRS', 'Standard_LRS')]" + }, + "caching": "ReadWrite" + }, + "dataDisks": "[if(equals(parameters('trialOrProduction'), 'Production'), variables('managedDiskId'), json('null'))]" + }, + "networkprofile": { + "networkinterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkinterfaces', variables('vNicName'))]" + } + ] + } + } + } + ], + "outputs": { + "connectionInfo": { + "type": "string", + "value": "Use RDP to connect to the VM endpoint" + }, + "vmEndpoint": { + "type": "string", + "value": "[reference(concat(variables('pNicName'))).dnsSettings.fqdn]" + }, + "environment":{ + "type": "string", + "value": "[if(equals(parameters('trialOrProduction'), 'Trial'), 'This is a trial', 'Production')]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-app-using-existing-vnet/managedAppVnet.zip b/samples/201-managed-app-using-existing-vnet/managedAppVnet.zip new file mode 100644 index 0000000..fbc223c Binary files /dev/null and b/samples/201-managed-app-using-existing-vnet/managedAppVnet.zip differ diff --git a/samples/201-managed-service-fabric/azuredeploy.json b/samples/201-managed-service-fabric/azuredeploy.json new file mode 100644 index 0000000..6c32070 --- /dev/null +++ b/samples/201-managed-service-fabric/azuredeploy.json @@ -0,0 +1,82 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "type": "string", + "defaultValue": "ManagedServiceFabric", + "metadata": { + "description": "Provide a name for the managed application" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Specify the Azure region to place the application definition" + } + }, + "lockLevel": { + "type": "string", + "allowedValues": [ + "ReadOnly", + "CanNotDelete" + ], + "defaultValue": "ReadOnly", + "metadata": { + "description": "Specify the resource lock being used for the managed application" + } + }, + "authorizations": { + "type": "array", + "metadata": { + "description": "Provide the authorization mapping for the managed application." + } + }, + "description": { + "type": "string", + "defaultValue": "Managed Azure Service Fabric with Azure mgmt services", + "metadata": { + "description": "Provide a brief description of the managed application" + } + }, + "displayName": { + "type": "string", + "defaultValue": "Managed Azure Service Fabric", + "metadata": { + "description": "Display name for the managed application" + } + } + }, + "variables": { + "packageFileUri": "[uri(deployment().properties.templateLink.uri, 'managedservicefabric.zip')]" + }, + "resources": [ + { + "apiVersion": "2017-09-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "type": "Microsoft.Solutions/applicationDefinitions", + "properties": { + "lockLevel": "[parameters('lockLevel')]", + "authorizations": "[array(parameters('authorizations'))]", + "description": "[parameters('description')]", + "displayName": "[parameters('displayName')]", + "packageFileUri": "[variables('packageFileUri')]" + } + } + ], + "outputs": { + "managedApplicationName": { + "type": "string", + "value": "[parameters('name')]" + }, + "lockLevel": { + "type": "string", + "value": "[parameters('locklevel')]" + }, + "packageFileUri": { + "type": "string", + "value": "[variables('packageFileUri')]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-service-fabric/createUiDefinition.json b/samples/201-managed-service-fabric/createUiDefinition.json new file mode 100644 index 0000000..f32252d --- /dev/null +++ b/samples/201-managed-service-fabric/createUiDefinition.json @@ -0,0 +1,120 @@ +{ + "handler": "Microsoft.Compute.MultiVm", + "version": "0.1.2-preview", + "parameters": { + "basics": [ + { + "name": "serviceFabricName", + "type": "Microsoft.Common.TextBox", + "label": "Service Fabric Cluster Name", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "^[a-z0-9A-Z]{1,10}$", + "validationMessage": "Only letters and numbers are allowed, and the value must be 1-10 characters long." + } + } + ], + "steps": [ + { + "name": "infrastructureConfig", + "label": "Infrastructure settings", + "subLabel": { + "preValidation": "Configure the infrastructure settings", + "postValidation": "Done" + }, + "bladeTitle": "Infrastructure settings", + "elements": [ + { + "name": "adminUsername", + "type": "Microsoft.Compute.UserNameTextBox", + "label": "Username", + "toolTip": "Admin username for the virtual machines.", + "osPlatform": "Windows", + "constraints": { + "required": true + } + }, + { + "name": "adminPassword", + "type": "Microsoft.Compute.CredentialsCombo", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": { + "password": "Admin password for the virtual machines and the Active Directory domain." + }, + "osPlatform": "Windows", + "constraints": { + "required": true + } + }, + { + "name": "premiumMgmt", + "type": "Microsoft.Common.OptionsGroup", + "label": "Enable premium management of your Service Fabric Cluster?", + "defaultValue": "Yes", + "toolTip": "Select Yes to set up premium Azure management for your Service Fabric cluster", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + } + ] + }, + { + "name": "sfConfig", + "label": "Service Fabric Cluster settings", + "subLabel": { + "preValidation": "Configure the Service Fabric Cluster", + "postValidation": "Done" + }, + "bladeTitle": "Service Fabric Cluster settings", + "elements": [ + { + "name": "sfDnsAndPublicIP", + "type": "Microsoft.Network.PublicIpAddressCombo", + "label": { + "publicIpAddress": "Public IP address", + "domainNameLabel": "DNS label" + }, + "toolTip": { + "domainNameLabel": "DNS endpoint for the Service Fabric public IP address, which hosts your microservices." + }, + "defaultValue": { + "publicIpAddressName": "ip01" + }, + "options": { + "hideNone": true, + "hideDomainNameLabel": false + }, + "constraints": { + "required": { + "domainNameLabel": true + } + } + } + ] + } + ], + "outputs": { + "computeLocation": "[location()]", + "clusterName": "[basics('serviceFabricName')]", + "adminUsername": "[steps('infrastructureConfig').adminUsername]", + "adminPassword": "[steps('infrastructureConfig').adminPassword.password]", + "dnsName": "[steps('sfConfig').sfDnsAndPublicIP.domainNameLabel]", + "sfpublicIPAddressName": "[steps('sfConfig').sfDnsAndPublicIP.name]", + "enablePremiumManagement":"[steps('infrastructureConfig').premiumMgmt]" + } + } +} diff --git a/samples/201-managed-service-fabric/images/appliance.png b/samples/201-managed-service-fabric/images/appliance.png new file mode 100644 index 0000000..574febc Binary files /dev/null and b/samples/201-managed-service-fabric/images/appliance.png differ diff --git a/samples/201-managed-service-fabric/mainTemplate.json b/samples/201-managed-service-fabric/mainTemplate.json new file mode 100644 index 0000000..1437398 --- /dev/null +++ b/samples/201-managed-service-fabric/mainTemplate.json @@ -0,0 +1,914 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "clusterName": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Name of your cluster - Between 3 and 23 characters. Letters and numbers only" + } + }, + "computeLocation": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Select the location for your SF resources" + } + }, + "adminUserName": { + "type": "string", + "defaultValue": "azureadmin", + "metadata": { + "description": "Remote desktop user Id" + } + }, + "adminPassword": { + "type": "securestring", + "metadata": { + "description": "Remote desktop user password. Must be a strong password" + } + }, + "dnsName": { + "type": "string", + "defaultvalue": "", + "metadata": { + "description": "DNS name for your Service Fabric Cluster endpoint" + } + }, + "overProvision": { + "type": "string", + "defaultValue": "false", + "metadata": { + "description": "true or false" + } + }, + "vmNodeType0Name": { + "type": "string", + "defaultValue": "sfvmss", + "maxLength": 9, + "metadata": { + "description": "Specify type name" + } + }, + "enablePremiumManagement": { + "type": "string", + "allowedValues": [ + "Yes", + "No" + ], + "metadata": { + "description": "Enable premium management of your Service Fabric Cluster" + } + }, + "sfpublicIPAddressName": { + "type": "string" + } + }, + "variables": { + "addressPrefix": "10.0.0.0/16", + "omsWorkspaceName": "[concat(take(resourceGroup().name, 5), '-', 'oms')]", + "subnet0Prefix": "10.0.0.0/24", + "publicIPAddressName": "[toLower(concat('pip', parameters('sfpublicIPAddressName')))]", + "lbName": "[concat('lbn', uniqueString(resourceGroup().Id))]", + "nicName": "[concat('nic', uniqueString(resourceGroup().Id))]", + "lbIPName": "[concat('lb', uniqueString(resourceGroup().Id))]", + "storageAccountType": "Standard_LRS", + "vmImageVersion": "latest", + "vmImageSku": "2016-Datacenter", + "vmImageOffer": "WindowsServer", + "vmNodeType0Size": "Standard_D1_v2", + "vmImagePublisher": "MicrosoftWindowsServer", + "supportLogStorageAccountType": "Standard_LRS", + "nt0applicationStartPort": 20000, + "nt0applicationEndPort": 30000, + "nt0ephemeralStartPort": 49152, + "nt0ephemeralEndPort": 65534, + "nt0fabricTcpGatewayPort": 19000, + "nt0fabricHttpGatewayPort": 19080, + "subnet0Name": "Subnet-0", + "vmStorageAccountContainerName": "vhds", + "virtualNetworkName": "Vnet1", + "supportLogStorageAccountName": "[toLower(concat('sf', uniqueString(resourceGroup().id),'2'))]", + "applicationDiagnosticsStorageAccountType": "Standard_LRS", + "applicationDiagnosticsStorageAccountName": "[toLower(concat('oms', uniqueString(resourceGroup().id), '3' ))]", + "omsSolution": { + "batch": [ + { + "solutionName": "[concat('Containers', '(', variables('omsWorkspacename'), ')')]", + "solution": "Containers" + }, + { + "solutionName": "[concat('ServiceFabric', '(', variables('omsWorkspacename'), ')')]", + "solution": "ServiceFabric" + } + ] + }, + "omsLocation": { + "eastasia": "southeastasia", + "southeastasia": "southeastasia", + "centralus": "westcentralus", + "eastus": "eastus", + "eastus2": "eastus", + "westus": "westcentralus", + "northcentralus": "westcentralus", + "southcentralus": "westcentralus", + "northeurope": "westeurope", + "westeurope": "westeurope", + "japanwest": "southeastasia", + "japaneast": "southeastasia", + "brazilsouth": "eastus", + "australiaeast": "australiasoutheast", + "australiasoutheast": "australiasoutheast", + "southindia": "southeastasia", + "centralindia": "southeastasia", + "westindia": "southeastasia", + "canadacentral": "eastus", + "canadaeast": "eastus", + "uksouth": "westeurope", + "ukwest": "westeurope", + "westcentralus": "westcentralus", + "westus2": "westcentralus", + "koreacentral": "southeastasia", + "koreasouth": "southeastasia", + "eastus2euap": "eastus" + }, + "omsWorkspaceLocation": "[variables('omsLocation')[parameters('computeLocation')]]", + "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]", + "subnet0Ref": "[concat(variables('vnetID'),'/subnets/',variables('subnet0Name'))]", + "lbID0": "[resourceId('Microsoft.Network/loadBalancers', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]", + "lbIPConfig0": "[concat(variables('lbID0'),'/frontendIPConfigurations/LoadBalancerIPConfig')]", + "lbPoolID0": "[concat(variables('lbID0'),'/backendAddressPools/LoadBalancerBEAddressPool')]", + "lbProbeID0": "[concat(variables('lbID0'),'/probes/FabricGatewayProbe')]", + "lbHttpProbeID0": "[concat(variables('lbID0'),'/probes/FabricHttpGatewayProbe')]", + "lbNatPoolID0": "[concat(variables('lbID0'),'/inboundNatPools/LoadBalancerBEAddressNatPool')]", + "vmStorageAccountName0": "[toLower(concat(uniqueString(resourceGroup().id), '1', '0' ))]", + "uniqueStringArray0": [ + "[concat(variables('vmStorageAccountName0'), '0')]", + "[concat(variables('vmStorageAccountName0'), '1')]", + "[concat(variables('vmStorageAccountName0'), '2')]", + "[concat(variables('vmStorageAccountName0'), '3')]", + "[concat(variables('vmStorageAccountName0'), '4')]" + ] + }, + "resources": [ + { + "apiVersion": "2017-06-01", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('supportLogStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "kind": "Storage", + "sku": { + "name": "[variables('storageAccountType')]" + } + }, + { + "apiVersion": "2017-06-01", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('applicationDiagnosticsStorageAccountName')]", + "location": "[parameters('computeLocation')]", + "kind": "Storage", + "sku": { + "name": "[variables('applicationDiagnosticsStorageAccountType')]" + } + }, + { + "apiVersion": "2017-06-01", + "type": "Microsoft.Network/virtualNetworks", + "name": "[variables('virtualNetworkName')]", + "location": "[parameters('computeLocation')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[variables('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[variables('subnet0Name')]", + "properties": { + "addressPrefix": "[variables('subnet0Prefix')]" + } + } + ] + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "2017-06-01", + "type": "Microsoft.Network/publicIPAddresses", + "name": "[concat(variables('lbIPName'),'-','0')]", + "location": "[parameters('computeLocation')]", + "properties": { + "dnsSettings": { + "domainNameLabel": "[parameters('dnsName')]" + }, + "publicIPAllocationMethod": "Dynamic" + }, + "tags": { + "resourceType": "Service Fabric", + "clusterName": "[parameters('clusterName')]" + } + }, + { + "apiVersion": "2017-06-01", + "type": "Microsoft.Network/loadBalancers", + "name": "[concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name'))]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/',concat(variables('lbIPName'),'-','0'))]" + ], + "properties": { + "frontendIPConfigurations": [ + { + "name": "LoadBalancerIPConfig", + "properties": { + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses',concat(variables('lbIPName'),'-','0'))]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "LoadBalancerBEAddressPool", + "properties": {} + } + ], + "loadBalancingRules": [ + { + "name": "LBRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[variables('nt0fabricTcpGatewayPort')]", + "enableFloatingIP": false, + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[variables('nt0fabricTcpGatewayPort')]", + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[variables('lbProbeID0')]" + }, + "protocol": "Tcp" + } + }, + { + "name": "LBHttpRule", + "properties": { + "backendAddressPool": { + "id": "[variables('lbPoolID0')]" + }, + "backendPort": "[variables('nt0fabricHttpGatewayPort')]", + "enableFloatingIP": false, + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPort": "[variables('nt0fabricHttpGatewayPort')]", + "idleTimeoutInMinutes": 5, + "probe": { + "id": "[variables('lbHttpProbeID0')]" + }, + "protocol": "Tcp" + } + } + ], + "probes": [ + { + "name": "FabricGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[variables('nt0fabricTcpGatewayPort')]", + "protocol": "Tcp" + } + }, + { + "name": "FabricHttpGatewayProbe", + "properties": { + "intervalInSeconds": 5, + "numberOfProbes": 2, + "port": "[variables('nt0fabricHttpGatewayPort')]", + "protocol": "Tcp" + } + } + ], + "inboundNatPools": [ + { + "name": "LoadBalancerBEAddressNatPool", + "properties": { + "backendPort": 3389, + "frontendIPConfiguration": { + "id": "[variables('lbIPConfig0')]" + }, + "frontendPortRangeEnd": 4500, + "frontendPortRangeStart": 3389, + "protocol": "Tcp" + } + } + ] + } + }, + { + "apiVersion": "2015-06-15", + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('uniqueStringArray0')[copyIndex()]]", + "location": "[parameters('computeLocation')]", + "properties": { + "accountType": "[variables('storageAccountType')]" + }, + "copy": { + "name": "storageLoop", + "count": 5 + } + }, + { + "apiVersion": "2017-03-30", + "type": "Microsoft.Compute/virtualMachineScaleSets", + "name": "[parameters('vmNodeType0Name')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[0])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[1])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[2])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[3])]", + "[concat('Microsoft.Storage/storageAccounts/', variables('uniqueStringArray0')[4])]", + "[concat('Microsoft.Network/loadBalancers/', concat('LB','-', parameters('clusterName'),'-',parameters('vmNodeType0Name')))]", + "[concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName'))]", + "[concat('Microsoft.Storage/storageAccounts/', variables('applicationDiagnosticsStorageAccountName'))]" + ], + "properties": { + "overprovision": "[parameters('overProvision')]", + "upgradePolicy": { + "mode": "Automatic" + }, + "virtualMachineProfile": { + "extensionProfile": { + "extensions": [ + { + "name": "[concat(parameters('vmNodeType0Name'),'_ServiceFabricNode')]", + "properties": { + "type": "ServiceFabricNode", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "StorageAccountKey1": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-06-15').key1]", + "StorageAccountKey2": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('supportLogStorageAccountName')),'2015-06-15').key2]" + }, + "publisher": "Microsoft.Azure.ServiceFabric", + "settings": { + "clusterEndpoint": "[reference(parameters('clusterName')).clusterEndpoint]", + "nodeTypeRef": "[parameters('vmNodeType0Name')]", + "dataPath": "D:\\\\SvcFab", + "durabilityLevel": "Bronze", + "enableParallelJobs": true + }, + "typeHandlerVersion": "1.0" + } + }, + { + "name": "[concat(parameters('vmNodeType0Name'),'OMS')]", + "properties": { + "publisher": "Microsoft.EnterpriseCloud.Monitoring", + "type": "MicrosoftMonitoringAgent", + "typeHandlerVersion": "1.0", + "autoUpgradeMinorVersion": true, + "settings": { + "workspaceId": "[reference(resourceId('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspacename')), '2015-11-01-preview').customerId]" + }, + "protectedSettings": { + "workspaceKey": "[listKeys(resourceId('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspacename')),'2015-11-01-preview').primarySharedKey]" + } + } + }, + { + "name": "[concat('VMDiagnosticsVmExt','_vmNodeType0Name')]", + "properties": { + "type": "IaaSDiagnostics", + "autoUpgradeMinorVersion": true, + "protectedSettings": { + "storageAccountName": "[variables('applicationDiagnosticsStorageAccountName')]", + "storageAccountKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('applicationDiagnosticsStorageAccountName')),'2015-06-15').key1]", + "storageAccountEndPoint": "https://core.windows.net/" + }, + "publisher": "Microsoft.Azure.Diagnostics", + "settings": { + "WadCfg": { + "DiagnosticMonitorConfiguration": { + "overallQuotaInMB": "50000", + "EtwProviders": { + "EtwEventSourceProviderConfiguration": [ + { + "provider": "Microsoft-ServiceFabric-Actors", + "scheduledTransferKeywordFilter": "1", + "scheduledTransferPeriod": "PT5M", + "DefaultEvents": { + "eventDestination": "ServiceFabricReliableActorEventTable" + } + }, + { + "provider": "Microsoft-ServiceFabric-Services", + "scheduledTransferPeriod": "PT5M", + "DefaultEvents": { + "eventDestination": "ServiceFabricReliableServiceEventTable" + } + } + ], + "EtwManifestProviderConfiguration": [ + { + "provider": "cbd93bc2-71e5-4566-b3a7-595d8eeca6e8", + "scheduledTransferLogLevelFilter": "Information", + "scheduledTransferKeywordFilter": "4611686018427387904", + "scheduledTransferPeriod": "PT5M", + "DefaultEvents": { + "eventDestination": "ServiceFabricSystemEventTable" + } + } + ] + } + } + }, + "StorageAccount": "[variables('applicationDiagnosticsStorageAccountName')]" + }, + "typeHandlerVersion": "1.5" + } + } + ] + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "[concat(variables('nicName'), '-0')]", + "properties": { + "ipConfigurations": [ + { + "name": "[concat(variables('nicName'),'-',0)]", + "properties": { + "loadBalancerBackendAddressPools": [ + { + "id": "[variables('lbPoolID0')]" + } + ], + "loadBalancerInboundNatPools": [ + { + "id": "[variables('lbNatPoolID0')]" + } + ], + "subnet": { + "id": "[variables('subnet0Ref')]" + } + } + } + ], + "primary": true + } + } + ] + }, + "osProfile": { + "adminPassword": "[parameters('adminPassword')]", + "adminUsername": "[parameters('adminUsername')]", + "computernamePrefix": "[parameters('vmNodeType0Name')]" + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('vmImagePublisher')]", + "offer": "[variables('vmImageOffer')]", + "sku": "[variables('vmImageSku')]", + "version": "[variables('vmImageVersion')]" + }, + "osDisk": { + "managedDisk": { + "storageAccountType": "[variables('storageAccountType')]" + }, + "caching": "ReadOnly", + "createOption": "FromImage" + } + } + } + }, + "sku": { + "name": "[variables('vmNodeType0Size')]", + "capacity": 5, + "tier": "Standard" + } + }, + { + "apiVersion": "2016-03-01", + "type": "Microsoft.ServiceFabric/clusters", + "name": "[parameters('clusterName')]", + "location": "[parameters('computeLocation')]", + "dependsOn": [ + "[concat('Microsoft.Storage/storageAccounts/', variables('supportLogStorageAccountName'))]" + ], + "properties": { + "clientCertificateCommonNames": [], + "clientCertificateThumbprints": [], + "clusterState": "Default", + "diagnosticsStorageAccountConfig": { + "blobEndpoint": "[concat('https://',variables('supportLogStorageAccountName'),'.blob.core.windows.net/')]", + "protectedAccountKeyName": "StorageAccountKey1", + "queueEndpoint": "[concat('https://',variables('supportLogStorageAccountName'),'.queue.core.windows.net/')]", + "storageAccountName": "[variables('supportLogStorageAccountName')]", + "tableEndpoint": "[concat('https://',variables('supportLogStorageAccountName'),'.table.core.windows.net/')]" + }, + "fabricSettings": [], + "managementEndpoint": "[concat('http://',reference(concat(variables('lbIPName'),'-','0')).dnsSettings.fqdn,':',variables('nt0fabricHttpGatewayPort'))]", + "nodeTypes": [ + { + "name": "[parameters('vmNodeType0Name')]", + "applicationPorts": { + "endPort": "[variables('nt0applicationEndPort')]", + "startPort": "[variables('nt0applicationStartPort')]" + }, + "clientConnectionEndpointPort": "[variables('nt0fabricTcpGatewayPort')]", + "durabilityLevel": "Bronze", + "ephemeralPorts": { + "endPort": "[variables('nt0ephemeralEndPort')]", + "startPort": "[variables('nt0ephemeralStartPort')]" + }, + "httpGatewayEndpointPort": "[variables('nt0fabricHttpGatewayPort')]", + "isPrimary": true, + "vmInstanceCount": 5 + } + ], + "provisioningState": "Default", + "reliabilityLevel": "Silver", + "vmImage": "Windows" + } + }, + { + "apiVersion": "2015-11-01-preview", + "location": "[variables('omsWorkspaceLocation')]", + "name": "[variables('omsWorkspacename')]", + "type": "Microsoft.OperationalInsights/workspaces", + "properties": { + "sku": { + "name": "Standard" + } + }, + "resources": [ + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "name": "[concat(variables('applicationDiagnosticsStorageAccountName'),variables('omsWorkspacename'))]", + "type": "storageInsightConfigs", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspacename'))]", + "[concat('Microsoft.Storage/storageAccounts/', variables('applicationDiagnosticsStorageAccountName'))]" + ], + "properties": { + "containers": [], + "tables": [ + "WADServiceFabric*EventTable", + "WADWindowsEventLogsTable", + "WADETWEventTable" + ], + "storageAccount": { + "id": "[resourceId('Microsoft.Storage/storageaccounts/', variables('applicationDiagnosticsStorageAccountName'))]", + "key": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('applicationDiagnosticsStorageAccountName')),'2015-06-15').key1]" + } + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk1", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Avg Disk sec/Read" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk2", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Avg Disk sec/Write" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk3", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Current Disk Queue Lenght" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk4", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Disk Reads/sec" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk5", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Disk Transfers/sec" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk6", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Disk Writes/sec" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk7", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Free Megabytes" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk8", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "% Free Space" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Memory1", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Memory", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Available MBytes" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Memory2", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Memory", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "% Committed Bytes In Use" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Network1", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Network Adapter", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Bytes Received/sec" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Network2", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Network Adapter", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Bytes Sent/sec" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Network3", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Network Adapter", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Bytes Total/sec" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "CPU1", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Processor", + "instanceName": "_Total", + "intervalSeconds": 10, + "counterName": "% Processor Time" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "CPU2", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "System", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Processor Queue Lenght" + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "System", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsEvent", + "properties": { + "eventLogName": "System", + "eventTypes": [ + { + "eventType": "Error" + }, + { + "eventType": "Warning" + } + ] + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Application", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "WindowsEvent", + "properties": { + "eventLogName": "Application", + "eventTypes": [ + { + "eventType": "Error" + }, + { + "eventType": "Warning" + } + ] + } + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "IISLog", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspaceName'))]" + ], + "kind": "IISLogs", + "properties": { + "state": "OnPremiseEnabled" + } + } + ] + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "location": "[variables('omsWorkspaceLocation')]", + "name": "[concat(variables('omsSolution').batch[copyIndex()].solutionName)]", + "type": "Microsoft.OperationsManagement/solutions", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', variables('OMSWorkspacename'))]", + "[concat('Microsoft.ServiceFabric/clusters/', parameters('clusterName'))]" + ], + "copy": { + "name": "solutionCopy", + "count": "[length(variables('omsSolution').batch)]" + }, + "properties": { + "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces/', variables('omsWorkspacename'))]" + }, + "plan": { + "name": "[variables('omsSolution').batch[copyIndex()].solutionName]", + "publisher": "Microsoft", + "product": "[Concat('OMSGallery/', variables('omsSolution').batch[copyIndex()].solution)]", + "promotionCode": "" + } + } + ], + "outputs": { + "clusterMgmtEndpoint": { + "value": "[concat(parameters('dnsName'), '.', parameters('computeLocation'), '.cloudapp.azure.com:19080/explorer')]", + "type": "string" + }, + "reliabilityLevel": { + "value": "[reference(parameters('clusterName')).reliabilityLevel]", + "type": "string" + }, + "platform": { + "value": "[reference(parameters('clusterName')).vmImage]", + "type": "string" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-service-fabric/managedservicefabric.zip b/samples/201-managed-service-fabric/managedservicefabric.zip new file mode 100644 index 0000000..3a4c144 Binary files /dev/null and b/samples/201-managed-service-fabric/managedservicefabric.zip differ diff --git a/samples/201-managed-service-fabric/output.json b/samples/201-managed-service-fabric/output.json new file mode 100644 index 0000000..0f44bc3 --- /dev/null +++ b/samples/201-managed-service-fabric/output.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": {}, + "variables": { + "oms": "[concat(take(resourceGroup().name, 5), '-', 'OMS')]" + }, + "resources": [], + "outputs": { + "oms": { + "type": "string", + "value": "[variables('oms')]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-service-fabric/readme.md b/samples/201-managed-service-fabric/readme.md new file mode 100644 index 0000000..fceb05d --- /dev/null +++ b/samples/201-managed-service-fabric/readme.md @@ -0,0 +1,51 @@ +# Managed Service Fabric with Azure management services + +>Note: This sample is for Managed Application in Service Catalog. For Marketplace, please see these instructions: +[**Marketplace Managed Application**](https://docs.microsoft.com/en-us/azure/managed-applications/publish-marketplace-app) + +## Deploy this sample to your Service Catalog + +### Deploy using Azure portal + +Clicking on the button below, will create the Managed Application definition to a Resource Group in your Azure subscription. + +[![Deploy to Azure](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-managedapp-samples%2Fmaster%2Fsamples%2F201-managed-service-fabric%2Fazuredeploy.json) + +### Deploy using PowerShell + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````powershell +$rgname = "" +$location = "" +$authorization = ":" +$uri = "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-service-fabric/managedservicefabric.zip" + +New-AzureRmManagedApplicationDefinition -Name "ManagedServiceFabric" ` + -ResourceGroupName $rgname ` + -DisplayName "Managed Service Fabric" ` + -Description "Managed Service Fabric with Azure mgmt." ` + -Location $location ` + -LockLevel ReadOnly ` + -PackageFileUri $uri ` + -Authorization $authorization ` + -Verbose +```` + +### Deploy using AzureCLI + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````azureCLI +az managedapp definition create \ + --name "ManagedServiceFabric" \ + --location \ + --resource-group \ + --lock-level ReadOnly \ + --display-name "Managed Service Fabric" \ + --description "Managed Service Fabric with Azure mgmt." \ + --authorizations ":" \ + --package-file-uri "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-service-fabric/managedservicefabric.zip" +```` + +![alt text](images/appliance.png "Azure Managed Application") \ No newline at end of file diff --git a/samples/201-managed-sql-iaas/README.md b/samples/201-managed-sql-iaas/README.md new file mode 100644 index 0000000..088721e --- /dev/null +++ b/samples/201-managed-sql-iaas/README.md @@ -0,0 +1,49 @@ +# Managed SQL 2017 IaaS with automated patching and backup + +>Note: This sample is for Managed Application in Service Catalog. For Marketplace, please see these instructions: +[**Marketplace Managed Application**](https://docs.microsoft.com/en-us/azure/managed-applications/publish-marketplace-app) + +## Deploy this sample to your Service Catalog + +### Deploy using Azure Portal + +Clicking on the button below, will create the Managed Application definition to a Resource Group in your Azure subscription. + +[![Deploy to Azure](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-managedapp-samples%2Fmaster%2Fsamples%2F201-managed-sql-iaas%2Fazuredeploy.json) + +### Deploy using PowerShell + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````powershell +$rgname = "" +$location = "" +$authorization = ":" +$uri = "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-sql-iaas/managedSql.zip" + +New-AzureRmManagedApplicationDefinition -Name "ManagedSql" ` + -ResourceGroupName $rgname ` + -DisplayName "Managed SQL IaaS" ` + -Description "Managed SQL IaaS with automated patching and backup" ` + -Location $location ` + -LockLevel ReadOnly ` + -PackageFileUri $uri ` + -Authorization $authorization ` + -Verbose +```` + +### Deploy using AzureCLI + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````azureCLI +az managedapp definition create \ + --name "ManagedSql" \ + --location \ + --resource-group \ + --lock-level ReadOnly \ + --display-name "Managed SQL IaaS" \ + --description "Managed SQL IaaS with automated patching and backup" \ + --authorizations ":" \ + --package-file-uri "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-sql-iaas/managedSql.zip" +```` \ No newline at end of file diff --git a/samples/201-managed-sql-iaas/azuredeploy.json b/samples/201-managed-sql-iaas/azuredeploy.json new file mode 100644 index 0000000..da0b71f --- /dev/null +++ b/samples/201-managed-sql-iaas/azuredeploy.json @@ -0,0 +1,82 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "type": "string", + "defaultValue": "ManagedSqlIaaS", + "metadata": { + "description": "Provide a name for the managed application" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Specify the Azure region to place the application definition" + } + }, + "lockLevel": { + "type": "string", + "allowedValues": [ + "ReadOnly", + "CanNotDelete" + ], + "defaultValue": "ReadOnly", + "metadata": { + "description": "Specify the resource lock being used for the managed application" + } + }, + "authorizations": { + "type": "array", + "metadata": { + "description": "Provide the authorization mapping for the managed application." + } + }, + "description": { + "type": "string", + "defaultValue": "Managed SQL IaaS", + "metadata": { + "description": "Provide a brief description of the managed application" + } + }, + "displayName": { + "type": "string", + "defaultValue": "Managed SQL Application", + "metadata": { + "description": "Display name for the managed application" + } + } + }, + "variables": { + "packageFileUri": "[uri(deployment().properties.templateLink.uri, 'managedSql.zip')]" + }, + "resources": [ + { + "apiVersion": "2017-09-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "type": "Microsoft.Solutions/applicationDefinitions", + "properties": { + "lockLevel": "[parameters('lockLevel')]", + "authorizations": "[array(parameters('authorizations'))]", + "description": "[parameters('description')]", + "displayName": "[parameters('displayName')]", + "packageFileUri": "[variables('packageFileUri')]" + } + } + ], + "outputs": { + "managedApplicationName": { + "type": "string", + "value": "[parameters('name')]" + }, + "lockLevel": { + "type": "string", + "value": "[parameters('locklevel')]" + }, + "packageFileUri": { + "type": "string", + "value": "[variables('packageFileUri')]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-sql-iaas/createUiDefinition.json b/samples/201-managed-sql-iaas/createUiDefinition.json new file mode 100644 index 0000000..6acf298 --- /dev/null +++ b/samples/201-managed-sql-iaas/createUiDefinition.json @@ -0,0 +1,168 @@ +{ + "handler": "Microsoft.Compute.MultiVm", + "version": "0.1.2-preview", + "parameters": { + "basics": [ + {} + ], + "steps": [ + { + "name": "credentialsConfig", + "label": "SQL VM Credential", + "subLabel": { + "preValidation": "Configure the SQL VM credentials", + "postValidation": "Done" + }, + "bladeTitle": "Credential", + "elements": [ + { + "name": "adminUsername", + "type": "Microsoft.Compute.UserNameTextBox", + "label": "User name", + "toolTip": "Admin username for the virtual machine", + "osPlatform": "Windows", + "constraints": { + "required": true + } + }, + { + "name": "adminPassword", + "type": "Microsoft.Compute.CredentialsCombo", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": { + "password": "Admin password for the virtual machine" + }, + "osPlatform": "Windows", + "constraints": { + "required": true + } + } + ] + }, + { + "name": "vmConfig", + "label": "SQL VM settings", + "subLabel": { + "preValidation": "Configure the SQL virtual machine settings", + "postValidation": "Done" + }, + "bladeTitle": "SQL VM Settings", + "elements": [ + { + "name": "vmNamePrefix", + "type": "Microsoft.Common.TextBox", + "label": "Virtual Machine Name", + "toolTip": "Provide a name for the virtual machine", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "[a-z][a-z0-9-]{2,5}[a-z0-9]$", + "validationMessage": "Must be 3-5 characters." + } + }, + { + "name": "vmSize", + "type": "Microsoft.Compute.SizeSelector", + "label": "Virtual machine size", + "toolTip": "Select the virtual machine size", + "recommendedSizes": [ + "Standard_DS12_v2" + ], + "constraints": { + "allowedSizes": [ + "Standard_D1_v2", + "Standard_DS12_v2" + ] + }, + "osPlatform": "Windows", + "count": 1 + } + ] + }, + { + "name": "sqlConfig", + "label": "SQL settings", + "subLabel": { + "preValidation": "Configure the SQL connectivity endpoint", + "postValidation": "Done" + }, + "bladeTitle": "SQL endpoint settings", + "elements": [ + { + "name": "dnsAndPublicIP", + "type": "Microsoft.Network.PublicIpAddressCombo", + "label": { + "publicIpAddress": "Public IP address", + "domainNameLabel": "DNS label" + }, + "toolTip": { + "domainNameLabel": "DNS endpoint for the Managed SQL VM IP address." + }, + "defaultValue": { + "publicIpAddressName": "ip01" + }, + "options": { + "hideNone": true, + "hideDomainNameLabel": false + }, + "constraints": { + "required": { + "domainNameLabel": true + } + } + }, + { + "name": "virtualNetwork", + "type": "Microsoft.Network.VirtualNetworkCombo", + "label": { + "virtualNetwork": "Virtual network", + "subnets": "Subnets" + }, + "toolTip": { + "virtualNetwork": "Virtual Network Name", + "subnets": "Subnet requried for SQL VM" + }, + "defaultValue": { + "name": "sql-vnet", + "addressPrefixSize": "/22" + }, + "constraints": { + "minAddressPrefixSize": "/22" + }, + "subnets": { + "subnet1": { + "label": "Subnet name", + "defaultValue": { + "name": "sql-subnet", + "addressPrefixSize": "/24" + }, + "constraints": { + "minAddressPrefixSize": "/24", + "minAddressCount": 12, + "requireContiguousAddresses": false + } + } + } + } + ] + } + ], + "outputs": { + "location": "[location()]", + "virtualMachineSize": "[steps('vmConfig').vmSize]", + "virtualMachineName": "[steps('vmConfig').vmNamePrefix]", + "adminUsername": "[steps('credentialsConfig').adminUsername]", + "adminPassword": "[steps('credentialsConfig').adminPassword.password]", + "dnsName": "[steps('sqlConfig').dnsAndPublicIP.domainNameLabel]", + "publicIPAddressName": "[steps('sqlConfig').dnsAndPublicIP.name]", + "applicationResourceName": "[steps('vmConfig').vmName]", + "subnetName": "[steps('sqlConfig').virtualNetwork.subnets.subnet1.name]", + "subnetPrefix": "[steps('sqlConfig').virtualNetwork.subnets.subnet1.addressPrefix]", + "addressPrefix": "[steps('sqlConfig').virtualNetwork.addressPrefix]", + "virtualNetworkName": "[steps('sqlConfig').virtualNetwork.name]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-sql-iaas/mainTemplate.json b/samples/201-managed-sql-iaas/mainTemplate.json new file mode 100644 index 0000000..9df80b2 --- /dev/null +++ b/samples/201-managed-sql-iaas/mainTemplate.json @@ -0,0 +1,294 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]" + }, + "virtualMachineName": { + "type": "string" + }, + "virtualMachineSize": { + "type": "string" + }, + "adminUsername": { + "type": "string" + }, + "virtualNetworkName": { + "type": "string" + }, + "adminPassword": { + "type": "securestring" + }, + "addressPrefix": { + "type": "string" + }, + "subnetName": { + "type": "string" + }, + "subnetPrefix": { + "type": "string" + }, + "publicIpAddressName": { + "type": "string" + }, + "dnsName": { + "type": "string" + } + }, + "variables": { + "sqlPortNumber": 1433, + "networkInterfaceName": "sqlNic", + "networkSecurityGroupName": "sqlNsg", + "publicIpAddresstype": "Dynamic", + "publicIpAddressSku": "Basic", + "sqlConnectivityType": "Private", + "sqlStorageDisksCount": 1, + "sqlStorageWorkloadType": "GENERAL", + "sqlStorageDisksConfigurationType": "NEW", + "sqlStorageStartingDeviceId": 2, + "sqlStorageDeploymentToken": 98818, + "sqlAutoPatchingDayOfWeek": "Sunday", + "sqlAutopatchingStartHour": 2, + "sqlAutopatchingWindowDuration": 60, + "sqlAutobackupRetentionPeriod": 30, + "sqlAutoBackupStorageAccountName": "[toLower(concat('bak', uniqueString(resourceGroup().id),'2'))]", + "sqlAutobackupStorageAccountType": "Standard_LRS", + "backupSystemDBs": "true", + "backupScheduleType": "Automated", + "rServicesEnabled": "false", + "vnetId": "[resourceId('Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]", + "subnetRef": "[concat(variables('vnetId'), '/subnets/', parameters('subnetName'))]" + }, + "resources": [ + { + "name": "[parameters('virtualMachineName')]", + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2017-03-30", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkInterfaces/', variables('networkInterfaceName'))]" + ], + "properties": { + "osProfile": { + "computerName": "[parameters('virtualMachineName')]", + "adminUsername": "[parameters('adminUsername')]", + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "provisionVmAgent": "true" + } + }, + "hardwareProfile": { + "vmSize": "[parameters('virtualMachineSize')]" + }, + "storageProfile": { + "imageReference": { + "publisher": "MicrosoftSQLServer", + "offer": "SQL2017-WS2016", + "sku": "Enterprise", + "version": "latest" + }, + "osDisk": { + "createOption": "fromImage", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + }, + "dataDisks": [ + { + "createOption": "empty", + "lun": 0, + "diskSizeGB": "1023", + "caching": "ReadOnly", + "managedDisk": { + "storageAccountType": "Premium_LRS" + } + } + ] + }, + "networkProfile": { + "networkInterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]" + } + ] + } + } + }, + { + "apiVersion": "2017-03-30", + "type": "Microsoft.Compute/virtualMachines/extensions", + "name": "[concat(parameters('virtualMachineName'), '/SqlIaasExtension')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Compute/virtualMachines/', parameters('virtualMachineName'))]" + ], + "properties": { + "type": "SqlIaaSAgent", + "publisher": "Microsoft.SqlServer.Management", + "typeHandlerVersion": "1.2", + "autoUpgradeMinorVersion": "true", + "settings": { + "AutoTelemetrySettings": { + "Region": "[parameters('location')]" + }, + "AutoPatchingSettings": { + "PatchCategory": "WindowsMandatoryUpdates", + "Enable": true, + "DayOfWeek": "[variables('sqlAutopatchingDayOfWeek')]", + "MaintenanceWindowStartingHour": "[variables('sqlAutopatchingStartHour')]", + "MaintenanceWindowDuration": "[variables('sqlAutopatchingWindowDuration')]" + }, + "AutoBackupSettings": { + "Enable": true, + "RetentionPeriod": "[variables('sqlAutobackupRetentionPeriod')]", + "EnableEncryption": true, + "BackupSystemDbs": "[variables('backupSystemDbs')]", + "BackupScheduleType": "[variables('backupScheduleType')]" + }, + "KeyVaultCredentialSettings": { + "Enable": false, + "CredentialName": "" + }, + "ServerConfigurationsManagementSettings": { + "SQLConnectivityUpdateSettings": { + "ConnectivityType": "[variables('sqlConnectivityType')]", + "Port": "[variables('sqlPortNumber')]" + }, + "SQLWorkloadTypeUpdateSettings": { + "SQLWorkloadType": "[variables('sqlStorageWorkloadType')]" + }, + "SQLStorageUpdateSettings": { + "DiskCount": "[variables('sqlStorageDisksCount')]", + "NumberOfColumns": "[variables('sqlStorageDisksCount')]", + "StartingDeviceID": "[variables('sqlStorageStartingDeviceId')]", + "DiskConfigurationType": "[variables('sqlStorageDisksConfigurationType')]" + }, + "AdditionalFeaturesServerConfigurations": { + "IsRServicesEnabled": "[variables('rServicesEnabled')]" + } + } + }, + "protectedSettings": { + "StorageUrl": "[reference(resourceId('Microsoft.Storage/storageAccounts', variables('sqlAutobackupStorageAccountName')), '2015-06-15').primaryEndpoints['blob']]", + "StorageAccessKey": "[listKeys(resourceId('Microsoft.Storage/storageAccounts', variables('sqlAutobackupStorageAccountName')), '2015-06-15').key1]", + "Password": "[parameters('adminPassword')]" + } + } + }, + { + "name": "[variables('sqlAutobackupStorageAccountName')]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2015-06-15", + "location": "[parameters('location')]", + "properties": { + "accountType": "[variables('sqlAutobackupStorageAccountType')]" + } + }, + { + "name": "[parameters('virtualNetworkName')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2017-08-01", + "location": "[parameters('location')]", + "properties": { + "addressSpace": { + "addressPrefixes": [ + "[parameters('addressPrefix')]" + ] + }, + "subnets": [ + { + "name": "[parameters('subnetName')]", + "properties": { + "addressPrefix": "[parameters('subnetPrefix')]" + } + } + ] + } + }, + { + "name": "[variables('networkInterfaceName')]", + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2016-09-01", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]", + "[concat('Microsoft.Network/publicIpAddresses/', parameters('publicIpAddressName'))]", + "[concat('Microsoft.Network/networkSecurityGroups/', variables('networkSecurityGroupName'))]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "subnet": { + "id": "[variables('subnetRef')]" + }, + "privateIPAllocationMethod": "Dynamic", + "publicIpAddress": { + "id": "[resourceId('Microsoft.Network/publicIpAddresses', parameters('publicIpAddressName'))]" + } + } + } + ], + "enableAcceleratedNetworking": true, + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]" + } + } + }, + { + "name": "[parameters('publicIpAddressName')]", + "type": "Microsoft.Network/publicIpAddresses", + "apiVersion": "2017-08-01", + "location": "[parameters('location')]", + "properties": { + "publicIpAllocationMethod": "[variables('publicIpAddressType')]", + "dnsSettings":{ + "domainNameLabel": "[parameters('dnsName')]" + } + }, + "sku": { + "name": "[variables('publicIpAddressSku')]" + } + }, + { + "name": "[variables('networkSecurityGroupName')]", + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2017-06-01", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "default-allow-rdp", + "properties": { + "priority": 1000, + "protocol": "TCP", + "access": "Allow", + "direction": "Inbound", + "sourceAddressPrefix": "*", + "sourcePortRange": "*", + "destinationAddressPrefix": "*", + "destinationPortRange": "3389" + } + } + ] + } + } + ], + "outputs": { + "adminUsername": { + "type": "string", + "value": "[parameters('adminUsername')]" + }, + "sqlEndpoint": { + "type": "string", + "value": "[reference(concat(parameters('publicIPAddressName'))).dnsSettings.fqdn]" + }, + "sqlPort": { + "type": "int", + "value": "[variables('sqlPortNumber')]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-sql-iaas/managedSql.zip b/samples/201-managed-sql-iaas/managedSql.zip new file mode 100644 index 0000000..71c7596 Binary files /dev/null and b/samples/201-managed-sql-iaas/managedSql.zip differ diff --git a/samples/201-managed-storage-account/azuredeploy.json b/samples/201-managed-storage-account/azuredeploy.json new file mode 100644 index 0000000..88cb2c4 --- /dev/null +++ b/samples/201-managed-storage-account/azuredeploy.json @@ -0,0 +1,82 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "type": "string", + "defaultValue": "ManagedStorageAccount", + "metadata": { + "description": "Provide a name for the managed application" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Specify the Azure region to place the application definition" + } + }, + "lockLevel": { + "type": "string", + "allowedValues": [ + "ReadOnly", + "CanNotDelete" + ], + "defaultValue": "ReadOnly", + "metadata": { + "description": "Specify the resource lock being used for the managed application" + } + }, + "authorizations": { + "type": "array", + "metadata": { + "description": "Provide the authorization mapping for the managed application." + } + }, + "description": { + "type": "string", + "defaultValue": "Managed Azure Storage Account", + "metadata": { + "description": "Provide a brief description of the managed application" + } + }, + "displayName": { + "type": "string", + "defaultValue": "Managed Storage Account", + "metadata": { + "description": "Display name for the managed application" + } + } + }, + "variables": { + "packageFileUri": "[uri(deployment().properties.templateLink.uri, 'managedstorage.zip')]" + }, + "resources": [ + { + "apiVersion": "2017-09-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "type": "Microsoft.Solutions/applicationDefinitions", + "properties": { + "lockLevel": "[parameters('lockLevel')]", + "authorizations": "[array(parameters('authorizations'))]", + "description": "[parameters('description')]", + "displayName": "[parameters('displayName')]", + "packageFileUri": "[variables('packageFileUri')]" + } + } + ], + "outputs": { + "managedApplicationName": { + "type": "string", + "value": "[parameters('name')]" + }, + "lockLevel": { + "type": "string", + "value": "[parameters('locklevel')]" + }, + "packageFileUri": { + "type": "string", + "value": "[variables('packageFileUri')]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-storage-account/createUiDefinition.json b/samples/201-managed-storage-account/createUiDefinition.json new file mode 100644 index 0000000..3e1eb4d --- /dev/null +++ b/samples/201-managed-storage-account/createUiDefinition.json @@ -0,0 +1,45 @@ +{ + "handler": "Microsoft.Compute.MultiVm", + "version": "0.1.2-preview", + "parameters": { + "basics": [ + {} + ], + "steps": [ + { + "name": "storageConfig", + "label": "Storage settings", + "subLabel": { + "preValidation": "Configure the infrastructure settings", + "postValidation": "Done" + }, + "bladeTitle": "Storage settings", + "elements": [ + { + "name": "storageAccounts", + "type": "Microsoft.Storage.MultiStorageAccountCombo", + "label": { + "prefix": "Storage account name prefix", + "type": "Storage account type" + }, + "defaultValue": { + "type": "Standard_LRS" + }, + "constraints": { + "allowedTypes": [ + "Premium_LRS", + "Standard_LRS", + "Standard_GRS" + ] + } + } + ] + } + ], + "outputs": { + "storageAccountNamePrefix": "[steps('storageConfig').storageAccounts.prefix]", + "storageAccountType": "[steps('storageConfig').storageAccounts.type]", + "location": "[location()]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-storage-account/images/storage.png b/samples/201-managed-storage-account/images/storage.png new file mode 100644 index 0000000..7c4f6e2 Binary files /dev/null and b/samples/201-managed-storage-account/images/storage.png differ diff --git a/samples/201-managed-storage-account/mainTemplate.json b/samples/201-managed-storage-account/mainTemplate.json new file mode 100644 index 0000000..1a62a48 --- /dev/null +++ b/samples/201-managed-storage-account/mainTemplate.json @@ -0,0 +1,50 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "storageAccountNamePrefix": { + "type": "string" + }, + "storageAccountType": { + "type": "string" + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]" + } + }, + "variables": { + "nestedTemplateUri": "[uri(deployment().properties.templateLink.uri, 'nestedtemplates/storageAccount.json')]" + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2016-02-01", + "name": "nestedDeployment", + "properties": { + "mode": "Incremental", + "templateLink": { + "contentVersion": "1.0.0.0", + "uri": "[variables('nestedTemplateUri')]" + }, + "parameters": { + "storageAccountNamePrefix": { + "value": "[parameters('storageAccountNamePrefix')]" + }, + "storageAccountType": { + "value": "[parameters('storageAccountType')]" + }, + "location": { + "value": "[parameters('location')]" + } + } + } + } + ], + "outputs": { + "storageEndpoint": { + "type": "string", + "value": "[reference('nestedDeployment').outputs.storageEndpoint.value]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-storage-account/managedstorage.zip b/samples/201-managed-storage-account/managedstorage.zip new file mode 100644 index 0000000..3a6e044 Binary files /dev/null and b/samples/201-managed-storage-account/managedstorage.zip differ diff --git a/samples/201-managed-storage-account/nestedtemplates/storageAccount.json b/samples/201-managed-storage-account/nestedtemplates/storageAccount.json new file mode 100644 index 0000000..05d1ead --- /dev/null +++ b/samples/201-managed-storage-account/nestedtemplates/storageAccount.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "storageAccountNamePrefix": { + "type": "string", + "metadata": { + "description": "Prefix for the storage account name" + } + }, + "storageAccountType": { + "type": "string", + "metadata": { + "description": "Storage account type" + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Storage account location" + } + } + }, + "variables": { + "storageAccountName": "[concat(parameters('storageAccountNamePrefix'), uniqueString('storage'))]" + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "name": "[variables('storageAccountName')]", + "apiVersion": "2016-01-01", + "location": "[parameters('location')]", + "sku": { + "name": "[parameters('storageAccountType')]" + }, + "kind": "Storage", + "properties": {} + } + ], + "outputs": { + "storageEndpoint": { + "type": "string", + "value": "[reference(resourceId('Microsoft.Storage/storageAccounts/', variables('storageAccountName')), '2016-01-01').primaryEndpoints.blob]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-storage-account/readme.md b/samples/201-managed-storage-account/readme.md new file mode 100644 index 0000000..3aed891 --- /dev/null +++ b/samples/201-managed-storage-account/readme.md @@ -0,0 +1,49 @@ +# Managed Azure Storage Account + +>Note: This sample is for Managed Application in Service Catalog. For Marketplace, please see these instructions: +[**Marketplace Managed Application**](https://docs.microsoft.com/en-us/azure/managed-applications/publish-marketplace-app) + +## Deploy this sample to your Service Catalog + +### Deploy using Azure Portal + +Clicking on the button below, will create the Managed Application definition to a Resource Group in your Azure subscription. + +[![Deploy to Azure](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-managedapp-samples%2Fmaster%2Fsamples%2F201-managed-storage-account%2Fazuredeploy.json) + +### Deploy using PowerShell + +````powershell +$rgname = "" +$location = "" +$authorization = ":" +$uri = "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-storage-account/managedstorage.zip" + +New-AzureRmManagedApplicationDefinition -Name "ManagedStorage" ` + -ResourceGroupName $rgname ` + -DisplayName "Managed Storage Account" ` + -Description "Managed Azure Storage Account" ` + -Location $location ` + -LockLevel ReadOnly ` + -PackageFileUri $uri ` + -Authorization $authorization ` + -Verbose +```` + +### Deploy using AzureCLI + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````azureCLI +az managedapp definition create \ + --name "ManagedStorage" \ + --location \ + --resource-group \ + --lock-level ReadOnly \ + --display-name "Managed Storage Account" \ + --description "Managed Azure Storage Account" \ + --authorizations ":" \ + --package-file-uri "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-storage-account/managedstorage.zip" +```` + +![alt text](images/storage.png "Azure Managed Application") \ No newline at end of file diff --git a/samples/201-managed-web-app/README.md b/samples/201-managed-web-app/README.md new file mode 100644 index 0000000..3714533 --- /dev/null +++ b/samples/201-managed-web-app/README.md @@ -0,0 +1,49 @@ +# Managed Web Application (IaaS) with Azure management services + +>Note: This sample is for Managed Application in Service Catalog. For Marketplace, please see these instructions: +[**Marketplace Managed Application**](https://docs.microsoft.com/en-us/azure/managed-applications/publish-marketplace-app) + +## Deploy this sample to your Service Catalog + +### Deploy using Azure Portal + +Clicking on the button below, will create the Managed Application definition to a Resource Group in your Azure subscription. + +[![Deploy to Azure](http://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FAzure%2Fazure-managedapp-samples%2Fmaster%2Fsamples%2F201-managed-web-app%2Fazuredeploy.json) + +### Deploy using PowerShell + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````powershell +$rgname = "" +$location = "" +$authorization = ":" +$uri = "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-web-app/managedwebapp.zip" + +New-AzureRmManagedApplicationDefinition -Name "ManagedWebApp" ` + -ResourceGroupName $rgname ` + -DisplayName "Managed Web App" ` + -Description "Managed Web App with Azure mgmt" ` + -Location $location ` + -LockLevel ReadOnly ` + -PackageFileUri $uri ` + -Authorization $authorization ` + -Verbose +```` + +### Deploy using AzureCLI + +Modify the snippet below to deploy Managed Application definition to a Resource Group in your Azure subscription + +````azureCLI +az managedapp definition create \ + --name "ManagedWebApp" \ + --location \ + --resource-group \ + --lock-level ReadOnly \ + --display-name "Managed Web Application" \ + --description "Web App with Azure mgmt" \ + --authorizations ":" \ + --package-file-uri "https://raw.githubusercontent.com/Azure/azure-managedapp-samples/master/samples/201-managed-web-app/managedwebapp.zip" +```` \ No newline at end of file diff --git a/samples/201-managed-web-app/azuredeploy.json b/samples/201-managed-web-app/azuredeploy.json new file mode 100644 index 0000000..70ca238 --- /dev/null +++ b/samples/201-managed-web-app/azuredeploy.json @@ -0,0 +1,82 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "type": "string", + "defaultValue": "ManagedWebApp", + "metadata": { + "description": "Provide a name for the managed application" + } + }, + "location": { + "type": "string", + "metadata": { + "description": "Specify the Azure region to place the application definition" + } + }, + "lockLevel": { + "type": "string", + "allowedValues": [ + "ReadOnly", + "none" + ], + "defaultValue": "ReadOnly", + "metadata": { + "description": "Specify the resource lock being used for the managed application" + } + }, + "authorizations": { + "type": "array", + "metadata": { + "description": "Provide the authorization mapping for the managed application." + } + }, + "description": { + "type": "string", + "defaultValue": "Managed Azure IaaS Web Application", + "metadata": { + "description": "Provide a brief description of the managed application" + } + }, + "displayName": { + "type": "string", + "defaultValue": "Managed Azure Web Application", + "metadata": { + "description": "Display name for the managed application" + } + } + }, + "variables": { + "packageFileUri": "[uri(deployment().properties.templateLink.uri, 'managedwebapp.zip')]" + }, + "resources": [ + { + "apiVersion": "2017-09-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "type": "Microsoft.Solutions/applicationDefinitions", + "properties": { + "lockLevel": "[parameters('lockLevel')]", + "authorizations": "[array(parameters('authorizations'))]", + "description": "[parameters('description')]", + "displayName": "[parameters('displayName')]", + "packageFileUri": "[variables('packageFileUri')]" + } + } + ], + "outputs": { + "managedApplicationName": { + "type": "string", + "value": "[parameters('name')]" + }, + "lockLevel": { + "type": "string", + "value": "[parameters('locklevel')]" + }, + "packageFileUri": { + "type": "string", + "value": "[variables('packageFileUri')]" + } + } +} diff --git a/samples/201-managed-web-app/createUiDefinition.json b/samples/201-managed-web-app/createUiDefinition.json new file mode 100644 index 0000000..fb811af --- /dev/null +++ b/samples/201-managed-web-app/createUiDefinition.json @@ -0,0 +1,150 @@ +{ + "handler": "Microsoft.Compute.MultiVm", + "version": "0.1.2-preview", + "parameters": { + "basics": [ + {} + ], + "steps": [ + { + "name": "credentialsConfig", + "label": "VM Credential", + "subLabel": { + "preValidation": "Configure the Web App VM credentials", + "postValidation": "Done" + }, + "bladeTitle": "Credential", + "elements": [ + { + "name": "adminUsername", + "type": "Microsoft.Compute.UserNameTextBox", + "label": "User name", + "toolTip": "Admin username for the virtual machine", + "osPlatform": "Windows", + "constraints": { + "required": true + } + }, + { + "name": "adminPassword", + "type": "Microsoft.Compute.CredentialsCombo", + "label": { + "password": "Password", + "confirmPassword": "Confirm password" + }, + "toolTip": { + "password": "Admin password for the virtual machine" + }, + "osPlatform": "Windows", + "constraints": { + "required": true + } + } + ] + }, + { + "name": "vmConfig", + "label": "Web App Virtual Machine settings", + "subLabel": { + "preValidation": "Configure the virtual machine settings", + "postValidation": "Done" + }, + "bladeTitle": "Web App VM Settings", + "elements": [ + { + "name": "vmNamePrefix", + "type": "Microsoft.Common.TextBox", + "label": "Virtual Machine Name prefix", + "toolTip": "Prefix of the VM for your web app", + "defaultValue": "", + "constraints": { + "required": true, + "regex": "[a-z][a-z0-9-]{2,5}[a-z0-9]$", + "validationMessage": "Must be 3-5 characters." + } + }, + { + "name": "vmSize", + "type": "Microsoft.Compute.SizeSelector", + "label": "Virtual machine size", + "toolTip": "The size of the virtual machine for web app", + "recommendedSizes": [ + "Standard_D1_v2" + ], + "constraints": { + "allowedSizes": [ + "Standard_D1_v2" + ] + }, + "osPlatform": "Windows", + "count": 1 + } + ] + }, + { + "name": "webConfig", + "label": "Web App settings", + "subLabel": { + "preValidation": "Configure the web app endpoint", + "postValidation": "Done" + }, + "bladeTitle": "Web App Endpoint settings", + "elements": [ + { + "name": "dnsAndPublicIP", + "type": "Microsoft.Network.PublicIpAddressCombo", + "label": { + "publicIpAddress": "Public IP address", + "domainNameLabel": "DNS label" + }, + "toolTip": { + "domainNameLabel": "DNS endpoint for the Managed Web App IP address." + }, + "defaultValue": { + "publicIpAddressName": "ip01" + }, + "options": { + "hideNone": true, + "hideDomainNameLabel": false + }, + "constraints": { + "required": { + "domainNameLabel": true + } + } + }, + { + "name": "management", + "type": "Microsoft.Common.OptionsGroup", + "label": "Enable premium management?", + "defaultValue": "Yes", + "toolTip": "Select Yes to set up premium management for the virtual machines and web app", + "constraints": { + "allowedValues": [ + { + "label": "Yes", + "value": "Yes" + }, + { + "label": "No", + "value": "No" + } + ] + }, + "visible": true + } + ] + } + ], + "outputs": { + "location": "[location()]", + "vmSize": "[steps('vmConfig').vmSize]", + "vmNamePrefix": "[steps('vmConfig').vmNamePrefix]", + "userName": "[steps('credentialsConfig').adminUsername]", + "pwd": "[steps('credentialsConfig').adminPassword.password]", + "dnsName": "[steps('webConfig').dnsAndPublicIP.domainNameLabel]", + "publicIPAddressName": "[steps('webConfig').dnsAndPublicIP.name]", + "enablePremiumManagement": "[steps('webConfig').management]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-web-app/images/webapp.png b/samples/201-managed-web-app/images/webapp.png new file mode 100644 index 0000000..89d4fda Binary files /dev/null and b/samples/201-managed-web-app/images/webapp.png differ diff --git a/samples/201-managed-web-app/mainTemplate.json b/samples/201-managed-web-app/mainTemplate.json new file mode 100644 index 0000000..013a7da --- /dev/null +++ b/samples/201-managed-web-app/mainTemplate.json @@ -0,0 +1,173 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Specify the location for the Azure resources" + } + }, + "vmSize": { + "type": "string", + "defaultValue": "Standard_D1_v2", + "metadata": { + "description": "Select the VM Size" + } + }, + "vmNamePrefix": { + "type": "string", + "metadata": { + "description": "Assign a prefix for the VM name" + } + }, + "userName": { + "type": "string", + "metadata": { + "description": "Specify the user name for the virtual machine guest OS" + } + }, + "pwd": { + "type": "securestring", + "metadata": { + "description": "Specify the password for the user account for the virtual machine" + } + }, + "enablePremiumManagement": { + "type": "string", + "allowedValues": [ + "Yes", + "No" + ], + "metadata": { + "description": "Select whether premium management should be enabled or not" + } + }, + "dnsName": { + "type": "string", + "metadata": { + "description": "Specify the DNS name for the managed web app" + } + }, + "publicIPAddressName": { + "type": "string", + "metadata": { + "description": "Assign a name for the public IP address" + } + } + }, + "variables": { + "artifacts": { + "logAnalytics": "[uri(deployment().properties.templateLink.uri, 'nestedtemplates/oms.json')]", + "compute": "[uri(deployment().properties.templateLink.uri, 'nestedtemplates/managedVm.json')]", + "scripts": "[uri(deployment().properties.templateLink.uri, 'scripts/ManagedWebApplication.ps1.zip')]" + }, + "logAnalyticsLocationMap": { + "eastasia": "southeastasia", + "southeastasia": "southeastasia", + "centralus": "westcentralus", + "eastus": "eastus", + "eastus2": "eastus", + "westus": "westcentralus", + "northcentralus": "westcentralus", + "southcentralus": "westcentralus", + "northeurope": "westeurope", + "westeurope": "westeurope", + "japanwest": "southeastasia", + "japaneast": "southeastasia", + "brazilsouth": "eastus", + "australiaeast": "australiasoutheast", + "australiasoutheast": "australiasoutheast", + "southindia": "southeastasia", + "centralindia": "southeastasia", + "westindia": "southeastasia", + "canadacentral": "eastus", + "canadaeast": "eastus", + "uksouth": "westeurope", + "ukwest": "westeurope", + "westcentralus": "westcentralus", + "westus2": "westcentralus", + "koreacentral": "southeastasia", + "koreasouth": "southeastasia", + "eastus2euap": "eastus" + }, + "logAnalyticsLocation": "[variables('logAnalyticsLocationMap')[parameters('location')]]", + "logAnalyticsWorkspaceName": "[concat(resourceGroup().name, '-', uniqueString('oms'))]" + }, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2016-09-01", + "name": "logAnalytics", + "properties": { + "mode":"Incremental", + "templateLink": { + "contentVersion": "1.0.0.0", + "uri": "[variables('artifacts').logAnalytics]" + }, + "parameters": { + "omsWorkspaceName": { + "value": "[variables('logAnalyticsWorkspaceName')]" + }, + "omsWorkspaceRegion": { + "value": "[variables('logAnalyticsLocation')]" + }, + "enablePremiumManagement": { + "value": "[parameters('enablePremiumManagement')]" + } + } + } + }, + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2016-09-01", + "name": "compute", + "dependsOn": [ + "logAnalytics" + ], + "properties": { + "mode":"Incremental", + "templateLink": { + "contentVersion": "1.0.0.0", + "uri": "[variables('artifacts').compute]" + }, + "parameters": { + "location": { + "value": "[parameters('location')]" + }, + "vmSize": { + "value": "[parameters('vmSize')]" + }, + "vmNamePrefix": { + "value": "[parameters('vmNamePrefix')]" + }, + "userName": { + "value": "[parameters('userName')]" + }, + "pwd": { + "value": "[parameters('pwd')]" + }, + "dscScript": { + "value": "[variables('artifacts').scripts]" + }, + "logAnalyticsWorkspaceName": { + "value": "[variables('logAnalyticsWorkspaceName')]" + }, + "publicIPAddressName": { + "value": "[parameters('publicIPAddressName')]" + }, + "dnsName": { + "value": "[parameters('dnsName')]" + } + } + } + } + ], + "outputs": { + "applicationEndpoint": { + "type": "string", + "value": "[reference('compute').outputs.vmEndpoint.value]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-web-app/managedwebapp.zip b/samples/201-managed-web-app/managedwebapp.zip new file mode 100644 index 0000000..dce2f16 Binary files /dev/null and b/samples/201-managed-web-app/managedwebapp.zip differ diff --git a/samples/201-managed-web-app/nestedtemplates/managedVm.json b/samples/201-managed-web-app/nestedtemplates/managedVm.json new file mode 100644 index 0000000..ab75951 --- /dev/null +++ b/samples/201-managed-web-app/nestedtemplates/managedVm.json @@ -0,0 +1,284 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "vmNamePrefix": { + "type": "string", + "metadata": { + "description": "Assign a prefix for the VM name" + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Select the Azure region for the resources" + } + }, + "vmSize": { + "type": "string", + "defaultValue": "Standard_D1_v2", + "metadata": { + "description": "Selec the vm size" + } + }, + "userName": { + "type": "string", + "defaultValue": "azureadmin", + "metadata": { + "description": "Specify the OS username" + } + }, + "pwd": { + "type": "securestring", + "metadata": { + "description": "If Windows, specify the password for the OS username" + } + }, + "dscScript": { + "type": "string", + "metadata": { + "description": "Specify the path to the DSC artifacts" + } + }, + "logAnalyticsWorkspaceName": { + "type": "string", + "metadata": { + "description": "The name of the Azure Log Analytics workspace" + } + }, + "dnsName": { + "type": "string", + "metadata": { + "description": "Specify the DNS name for the managed web app" + } + }, + "publicIPAddressName": { + "type": "string", + "metadata": { + "description": "Assign a name for the public IP address" + } + } + }, + "variables": { + "storageAccountName": "[toLower(concat('st', uniquestring(resourceGroup().name)))]", + "vnetID": "[resourceId('Microsoft.Network/virtualnetworks', 'vmVnet')]", + "subnetRef": "[concat(variables('vnetID'),'/subnets/', 'subnet1')]", + "managementTypeWindows": { + "omsType": "MicrosoftMonitoringAgent", + "scriptType": "DSC" + }, + "osTypeWindows": { + "imageOffer": "WindowsServer", + "imageSku": "2016-Datacenter", + "imagePublisher": "MicrosoftWindowsServer" + } + }, + "resources": [ + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2017-06-01", + "name": "[variables('storageAccountName')]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard_LRS" + }, + "kind": "Storage" + }, + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2017-03-01", + "name": "vmVnet", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Network/networkSecurityGroups/', 'NSG')]" + ], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "10.0.0.0/16" + ] + }, + "subnets": [ + { + "name": "subnet1", + "properties": { + "addressPrefix": "10.0.0.0/24", + "networkSecurityGroup": { + "id": "[resourceId('Microsoft.Network/networkSecurityGroups/', 'NSG')]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Network/networkSecurityGroups", + "apiVersion": "2017-03-01", + "name": "NSG", + "location": "[parameters('location')]", + "properties": { + "securityRules": [ + { + "name": "RDP", + "properties": { + "access": "Allow", + "description": "Inbound RDP rule", + "direction": "Inbound", + "destinationAddressPrefix": "*", + "protocol": "Tcp", + "destinationPortRange": 3389, + "sourcePortRange": "*", + "priority": 500, + "sourceAddressPrefix": "*" + } + }, + { + "name": "HTTP", + "properties": { + "access": "Allow", + "description": "Inbound HTTP rule", + "direction": "Inbound", + "destinationAddressPrefix": "*", + "protocol": "Tcp", + "destinationPortRange": 80, + "sourcePortRange": "*", + "priority": 550, + "sourceAddressPrefix": "*" + } + } + ] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2017-04-01", + "name": "[concat(parameters('publicIPAddressName'), 'IP')]", + "location": "[parameters('location')]", + "properties": { + "publicIPallocationmethod": "Dynamic", + "dnsSettings": { + "domainNameLabel": "[toLower(parameters('dnsName'))]" + } + } + }, + { + "type": "Microsoft.Network/networkInterfaces", + "apiVersion": "2017-04-01", + "name": "[concat(parameters('vmNamePrefix'), 'nic')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Network/publicIPAddresses/', parameters('publicIPAddressName'), 'IP')]", + "[resourceId('Microsoft.Network/virtualNetworks/', 'vmVnet')]" + ], + "properties": { + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(parameters('publicIPAddressName'), 'IP'))]" + }, + "subnet": { + "id": "[variables('subnetRef')]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Compute/virtualMachines", + "apiVersion": "2017-03-30", + "name": "[concat(parameters('vmNamePrefix'), '-app')]", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.Storage/StorageAccounts/', variables('storageAccountName'))]", + "[concat('Microsoft.Network/networkinterfaces/', parameters('vmNamePrefix'), 'nic')]" + ], + "properties": { + "hardwareProfile": { + "vmsize": "[parameters('vmSize')]" + }, + "osProfile": { + "computername": "[concat(parameters('vmNamePrefix'), '-app')]", + "adminusername": "[parameters('username')]", + "adminpassword": "[parameters('pwd')]" + }, + "storageProfile": { + "imageReference": { + "publisher": "[variables('osTypeWindows').imagePublisher]", + "offer": "[variables('osTypeWindows').imageOffer]", + "version": "latest", + "sku": "[variables('osTypeWindows').imageSku]" + }, + "osdisk": { + "name": "osdisk", + "vhd": { + "uri": "[concat('http://', variables('storageAccountName'), '.blob.core.windows.net/', 'vhds', '/', 'osdisk','.vhd')]" + }, + "caching": "readwrite", + "createoption": "FromImage" + } + }, + "networkprofile": { + "networkinterfaces": [ + { + "id": "[resourceId('Microsoft.Network/networkinterfaces', concat(parameters('vmNamePrefix'),'nic'))]" + } + ] + } + }, + "resources": [ + { + "type": "extensions", + "apiVersion": "2017-03-30", + "name": "PowerShellDSC", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', concat(parameters('vmNamePrefix'), '-app'))]" + ], + "properties": { + "autoUpgradeMinorVersion": true, + "typeHandlerVersion": "2.20", + "publisher": "Microsoft.Powershell", + "type": "[variables('managementTypeWindows').scriptType]", + "settings": { + "configurationFunction": "ManagedWebApplication.ps1\\ManagedWebApplication", + "modulesUrl": "[parameters('dscScript')]" + } + } + }, + { + "type": "extensions", + "apiVersion": "2017-03-30", + "name": "OMS", + "location": "[parameters('location')]", + "dependsOn": [ + "[resourceId('Microsoft.Compute/virtualMachines/', concat(parameters('vmNamePrefix'), '-app'))]" + ], + "properties": { + "autoUpgradeMinorVersion": true, + "typeHandlerVersion": "1.0", + "publisher": "Microsoft.EnterpriseCloud.Monitoring", + "type": "MicrosoftMonitoringAgent", + "settings": { + "workspaceId": "[reference(resourceId('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName')), '2015-11-01-preview').customerId]", + "azureResourceId": "[resourceId('Microsoft.Compute/virtualMachines/', concat(parameters('vmNamePrefix'), '-app'))]" + }, + "protectedSettings": { + "workspaceKey": "[listKeys(resourceId('Microsoft.OperationalInsights/workspaces/', parameters('logAnalyticsWorkspaceName')), '2015-11-01-preview').primarySharedKey]" + } + } + } + ] + } + ], + "outputs": { + "vmEndpoint": { + "type": "string", + "value": "[reference(concat(parameters('publicIPAddressName'), 'IP')).dnsSettings.fqdn]" + } + } +} \ No newline at end of file diff --git a/samples/201-managed-web-app/nestedtemplates/oms.json b/samples/201-managed-web-app/nestedtemplates/oms.json new file mode 100644 index 0000000..658849a --- /dev/null +++ b/samples/201-managed-web-app/nestedtemplates/oms.json @@ -0,0 +1,510 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "omsWorkspaceName": { + "type": "string", + "metadata": { + "description": "Assign a name for the Log Analytic Workspace Name" + } + }, + "omsWorkspaceRegion": { + "type": "string", + "metadata": { + "description": "Specify the region for your Workspace" + } + }, + "enablePremiumManagement": { + "type": "string", + "allowedValues": [ + "Yes", + "No" + ], + "metadata": { + "description": "Select whether premium management should be enabled or not" + } + } + }, + "variables": { + "batch1": { + "solutions": [ + { + "name": "[concat('Security', '(', parameters('omsWorkspaceName'), ')')]", + "marketplaceName": "Security" + }, + { + "name": "[concat('AgentHealthAssessment', '(', parameters('omsWorkspaceName'), ')')]", + "marketplaceName": "AgentHealthAssessment" + }, + { + "name": "[concat('ChangeTracking', '(', parameters('omsWorkspaceName'), ')')]", + "marketplaceName": "ChangeTracking" + }, + { + "name": "[concat('Updates', '(', parameters('omsWorkspaceName'), ')')]", + "marketplaceName": "Updates" + }, + { + "name": "[concat('AlertManagement', '(', parameters('omsWorkspaceName'), ')')]", + "marketplaceName": "AlertManagement" + }, + { + "name": "[concat('AntiMalware', '(', parameters('omsWorkspaceName'), ')')]", + "marketplaceName": "AntiMalware" + }, + { + "name": "[concat('AzureNSGAnalytics', '(', parameters('omsWorkspaceName'), ')')]", + "marketplaceName": "AzureNSGAnalytics" + } + ] + } + }, + "resources": [ + { + "apiVersion": "2015-11-01-preview", + "location": "[parameters('omsWorkspaceRegion')]", + "name": "[parameters('omsWorkspaceName')]", + "type": "Microsoft.OperationalInsights/workspaces", + "comments": "Log Analytics workspace", + "properties": { + "sku": { + "name": "pernode" + } + }, + "resources": [ + { + "name": "[concat(parameters('omsWorkspaceName'), '/', 'SoftwareUpdateFailed1')]", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "tags": {}, + "properties": { + "ETag": "*", + "query": "Type=Event EventID=20 Source=\"Microsoft-Windows-WindowsUpdateClient\" EventLog=\"System\" TimeGenerated>NOW-24HOURS | Measure Count() By Computer", + "displayName": "A Software Update Installation Failed", + "category": "Software Updates" + } + }, + { + "name": "[concat(parameters('omsWorkspaceName'), '/', 'SoftwareUpdateFailed2')]", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "tags": {}, + "properties": { + "ETag": "*", + "query": "Type=Event EventID=20 Source=\"Microsoft-Windows-WindowsUpdateClient\" EventLog=\"System\" TimeGenerated>NOW-168HOURS", + "displayName": "A Software Update Installation Failed", + "category": "Software Updates" + } + }, + { + "name": "[concat(parameters('omsWorkspaceName'), '/', 'Network1')]", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "tags": {}, + "properties": { + "ETag": "*", + "query": "Type=Event EventID=4202 Source=\"TCPIP\" EventLog=\"System\" TimeGenerated>NOW-24HOURS | Measure Count() By Computer", + "displayName": "A Network adatper was disconnected from the network", + "category": "Networking" + } + }, + { + "name": "[concat(parameters('omsWorkspaceName'), '/', 'Network2')]", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "tags": {}, + "properties": { + "ETag": "*", + "query": "Type=Event EventID=4198 OR EventID=4199 Source=\"TCPIP\" EventLog=\"System\" TimeGenerated>NOW-24HOURS", + "displayName": "Duplicate IP address has been detected", + "category": "Networking" + } + }, + { + "name": "[concat(parameters('omsWorkspaceName'), '/', 'NTFS1')]", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "tags": {}, + "properties": { + "ETag": "*", + "query": "Type=Event EventID=98 Source=\"Microsoft-Windows-Ntfs\" EventLog=\"System\" TimeGenerated>NOW-24HOURS | Measure Count() By Computer", + "displayName": "NTFS File System Corruption", + "category": "NTFS" + } + }, + { + "name": "[concat(parameters('omsWorkspaceName'), '/', 'NTFS2')]", + "type": "Microsoft.OperationalInsights/workspaces/savedSearches", + "apiVersion": "2015-11-01-preview", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "tags": {}, + "properties": { + "ETag": "*", + "query": "Type=Event EventID=40 OR EventID=36� Source=\"DISK\" EventLog=\"System\" TimeGenerated>NOW-24HOURS | Measure Count() By Compute", + "displayName": "NTFS Quouta treshold limit reached", + "category": "NTFS" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk1", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Avg Disk sec/Read" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk2", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Avg Disk sec/Write" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk3", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Current Disk Queue Lenght" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk4", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Disk Reads/sec" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk5", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Disk Transfers/sec" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk6", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Disk Writes/sec" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk7", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Free Megabytes" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "LogicalDisk8", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "LogicalDisk", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "% Free Space" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Memory1", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Memory", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Available MBytes" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Memory2", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Memory", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "% Committed Bytes In Use" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Network1", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Network Adapter", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Bytes Received/sec" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Network2", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Network Adapter", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Bytes Sent/sec" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Network3", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Network Adapter", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Bytes Total/sec" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "CPU1", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "Processor", + "instanceName": "_Total", + "intervalSeconds": 10, + "counterName": "% Processor Time" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "CPU2", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsPerformanceCounter", + "properties": { + "objectName": "System", + "instanceName": "*", + "intervalSeconds": 10, + "counterName": "Processor Queue Lenght" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "System", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsEvent", + "properties": { + "eventLogName": "System", + "eventTypes": [ + { + "eventType": "Error" + }, + { + "eventType": "Warning" + } + ] + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Application", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "WindowsEvent", + "properties": { + "eventLogName": "Application", + "eventTypes": [ + { + "eventType": "Error" + }, + { + "eventType": "Warning" + } + ] + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "IISLog", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "IISLogs", + "properties": { + "state": "OnPremiseEnabled" + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "Syslog", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "LinuxSyslog", + "properties": { + "syslogName": "kern", + "syslogSeverities": [ + { + "severity": "emerg" + }, + { + "severity": "alert" + }, + { + "severity": "crit" + }, + { + "severity": "err" + }, + { + "severity": "warning" + } + ] + } + }, + { + "apiVersion": "2015-11-01-preview", + "type": "datasources", + "name": "SyslogCollection", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "kind": "LinuxSyslogCollection", + "properties": { + "state": "Enabled" + } + } + ] + }, + { + "condition": "[equals(parameters('enablePremiumManagement'), 'Yes')]", + "apiVersion": "2015-11-01-preview", + "type": "Microsoft.OperationsManagement/solutions", + "name": "[concat(variables('batch1').solutions[copyIndex()].Name)]", + "location": "[parameters('omsWorkspaceRegion')]", + "dependsOn": [ + "[concat('Microsoft.OperationalInsights/workspaces/', parameters('omsWorkspaceName'))]" + ], + "copy": { + "name": "solutionCopy", + "count": "[length(variables('batch1').solutions)]" + }, + "properties": { + "workspaceResourceId": "[resourceId('Microsoft.OperationalInsights/workspaces', parameters('omsWorkspaceName'))]" + }, + "plan": { + "name": "[variables('batch1').solutions[copyIndex()].name]", + "product": "[concat('OMSGallery/', variables('batch1').solutions[copyIndex()].marketplaceName)]", + "promotionCode": "", + "publisher": "Microsoft" + } + } + ], + "outputs": {} +} \ No newline at end of file diff --git a/samples/201-managed-web-app/scripts/ManagedWebApplication.ps1.zip b/samples/201-managed-web-app/scripts/ManagedWebApplication.ps1.zip new file mode 100644 index 0000000..453e8d7 Binary files /dev/null and b/samples/201-managed-web-app/scripts/ManagedWebApplication.ps1.zip differ diff --git a/samples/readme.md b/samples/readme.md index 044fd1c..42a05a0 100644 --- a/samples/readme.md +++ b/samples/readme.md @@ -1 +1 @@ -This folder contains the different managed application samples for your reference. +This folder contains the different Managed Application samples for your reference.