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