<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Mike Richter</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/mikerichter/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/mikerichter/feed.xml</link>
    <description>Cloud Evangelism</description>
    <lastBuildDate>Wed, 17 Apr 2019 04:08:18 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Devops on Windows with Jenkins and Azure Resource Manager</title>
      <link>https://docs.microsoft.com/archive/blogs/mikerichter/devops-on-windows-with-jenkins-and-azure-resource-manager</link>
      <pubDate>Wed, 29 Jun 2016 14:00:30 GMT</pubDate>
      <dc:creator><![CDATA[MikeRichter_CSA_MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mikerichter/?p=75</guid>
      <description><![CDATA[Contents

	Summary
	Technologies discussed
	Key Concepts
	Requirements and...]]></description>
      <content:encoded><![CDATA[<h2>Contents</h2>
<ul>
	<li><a href="#Summary">Summary</a></li>
	<li><a href="#Technologies">Technologies discussed</a></li>
	<li><a href="#Key">Key Concepts</a></li>
	<li><a href="#Requirements">Requirements and Constraints</a></li>
	<li><a href="#Existing">Existing Infrastructure</a></li>
	<li><a href="#How">How it works</a></li>
	<li><a href="#For">For Production</a></li>
	<li><a href="#Wrapping">Wrapping up</a></li>
</ul>
<h2><a id="Summary"></a>Summary</h2>
This blog post outlines a devops process that automates deploying a somewhat legacy .NET Web API to Microsoft Azure. We'll use Jenkins, a build automation tool, to kick off the automation and we'll see all the steps involved. This post outlines practices for dev/test scenarios but at the end I've included some thoughts for using this in production. To follow along, some existing Azure experience and an existing Azure subscription is necessary.

The sample code for this post can be found on Github here: <a href="https://github.com/michaelsrichter/PasswordBot">https://github.com/michaelsrichter/PasswordBot</a>
<h3>Desired Results</h3>
By following the directions below, you should be able to use the code and assets in the Github sample repository to deploy a simple Web API that generates passwords. This is part of a larger project to create a Password Bot.

To get an idea of what we're building. Suppose we configure our build with a Resource Group Name of "<strong>blogbot</strong>." And when we do our build in Jenkins, it's build <strong>#16</strong>. The build should create the following infrastructure in Azure:

[caption id="attachment_105" align="alignnone" width="854"]<a href="https://msdnshared.blob.core.windows.net/media/2016/06/ResourceGroup1.png"><img class="size-full wp-image-105" src="https://msdnshared.blob.core.windows.net/media/2016/06/ResourceGroup1.png" alt="Bot Resource Group" width="854" height="611" /></a> Bot Resource Group[/caption]

The build also installs the Web API on the VM and it's exposed via an endpoint, like this example:

[caption id="attachment_85" align="alignnone" width="592"]<a href="https://msdnshared.blob.core.windows.net/media/2016/06/RestRequest.png"><img class="size-full wp-image-85" src="https://msdnshared.blob.core.windows.net/media/2016/06/RestRequest.png" alt="PasswordBot REST Request" width="592" height="129" /></a> PasswordBot REST Request[/caption]
<h2><a id="Technologies"></a>Technologies discussed</h2>
<ul>
	<li>Jenkins + Build Automation</li>
	<li>Powershell</li>
	<li>Azure Service Principal</li>
	<li>Azure Storage SAS Tokens</li>
	<li>Azure Resource Manager Template</li>
	<li>Azure Custom Script Extension</li>
</ul>
<h2><a id="Key"></a>Key Concepts</h2>
<ul>
	<li>Build Automation</li>
	<li>Configuration Management</li>
	<li>Immutable Infrastructure</li>
</ul>
<h2><a id="Requirements"></a>Requirements and Constraints</h2>
These are the requirements and constraints that influenced the design of this solution:
<ul>
	<li>MSI - The Web API build outputs an MSI file and that is what we need to get deployed to Azure. Ideally you'd be able to use git or WebDeploy or other cloud ready technologies for deploying to Azure. This example shows how you can automate deploying to Azure even when you have a constraint like MSI.</li>
	<li>VMs - The solution cannot use Platform-as-as-Service, it must be run on Windows VMs.</li>
	<li>Build Automation - the Web API must be deployed with automation, as part of a new or existing build automation process.</li>
	<li>Jenkins - The prescribed build automation tool.</li>
	<li>.NET 4.6.1 - The Web API needs to run on this version of the .NET framework.</li>
	<li>Non-standard Port - The Web API must use a non-standard http port, so not 80 and 443. This is sometimes a requirement in dev/test when resources are shared.</li>
	<li>No Custom Images - The VM must use the latest, patched version of Windows from the Azure catalog. Crafting a custom image with pre-loaded dependencies is not an option.</li>
</ul>
<h2><a id="Existing"></a>Existing Infrastructure</h2>
These requirements already need to be provisioned to get this example working:
<ul>
	<li>Azure Subscription</li>
	<li>Jenkins instance installed and configured</li>
	<li>Azure Storage account that can hold build artifacts</li>
</ul>
<h2><a id="How"></a>How it works</h2>
<h3>Jenkins</h3>
First, install the <a href="https://wiki.jenkins-ci.org/display/JENKINS/PowerShell+Plugin">Powershell plugin</a> for Jenkins. Here's a <a href="https://hodgkins.io/automating-with-jenkins-and-powershell-on-windows-part-1">blog post</a> with more info.

The build server(s) will need <a href="https://azure.microsoft.com/en-us/documentation/articles/powershell-install-configure/">Azure Powershell</a> installed to execute these commands.

The build server(s) will need the Azure service principal certificate installed. See below when I discuss the <strong>CertificateThumbprint</strong> parameter.

Either create a new build automation project in Jenkins or use an existing one. Add a new post build action that uses the Powershell plugin. In the Powershell plugin command window, enter the following text:
<pre>$cmd = "C:\path\to\deploy.ps1"
$arg = @()
$arg += ("-buildNumber", $ENV:BUILD_NUMBER)
$arg += ("-CertificateThumbprint", "YOURCERTTHUMBPRINT")
$arg += ("-ApplicationId", "YOUR-APP-ID-GUID")
$arg += ("-TenantId", "YOUR-AAD-TENANT-GUID")
$arg += ("-sourceFile", "'C:\path\to\PasswordBot API.msi'")
$arg += ("-templateFilePath", "C:\path\to\template.json")
$arg += ("-subscriptionId", "YOUR-SUBSCRIPTION-ID-GUID")
$arg += ("-resourceGroupName", "resourcegroupname")
$arg += ("-resourceGroupLocation", "eastus")
$arg += ("-storageAccountKey", "YOURSTORAGEACCOUNTKEY")
$arg += ("-storageAccountName", "yourstorageaccount")
$arg += ("-artifactContainerName", "artifacts")
$arg += ("-configurationScriptFile", "C:\path\to\ConfigurationScript.ps1")
iex  "$cmd $arg" -Verbose</pre>
This is all the Powershell Jenkins needs to build a parameters object and pass it into the deploy.ps1 script. Make sure you update the path to your actual deploy.ps1 file. It's in the Devops folder if you synced the sample code from Github. You will need to insert your values into the parameters.
<ul>
	<li><strong>buildNumber</strong>: Use Jenkins' environment variable so that each deployment # is incremented (this will also be used to label the Azure resources).</li>
	<li><strong>CertificateThumbprint</strong>: You will need to create a service principal so that Azure resources can be deployed with automation. Please see this documentation for <a href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-authenticate-service-principal/#create-ad-application-with-certificate">creating a service principal with a certificate in Azure</a>. You will need to be an administrator of the Azure subscription and a global admin of the default Azure Active Directory tenant for that subscription. A certificate is generated when you create a service principal. The certificate needs to be stored on the build server and in the Azure AD application. Make sure you create the service principal with <strong>owner</strong> permissions. You can share the certificate with other build serves or dev machines. You will need to generate a private key to do this. Be careful where you store the certificate and the private key. Anyone who has this combination has "owner" rights to your Azure subscription! You can always delete the Azure AD application service principal if your credentials become compromised.</li>
	<li><strong>ApplicationId</strong>: The GUID ID for the Azure AD Application associated with your service principal.</li>
	<li><strong>TenantId</strong>: The GUID ID for the Azure AD Tenant associated with your service principal.</li>
	<li><strong>sourceFile</strong>: The path to the MSI file you want to deploy. A sample MSI is provided in the Devops folder from the Github sample. This MSI file will install the PasswordBot Web API application, it will also create a new Website in IIS on port 81.</li>
	<li><strong>templateFilePath</strong>: The path to the JSON template that defines the Azure resources we are going to deploy. This is also in the Devops folder in the Github sample.</li>
	<li><strong>subscriptionId</strong>: The GUID ID for your Azure Subscription.</li>
	<li><strong>resourceGroupName</strong>: The resource group that all the Azure resources will deployed within. You can choose any name you want within <a href="https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-linux-infrastructure-service-guidelines/">the guidelines</a>.</li>
	<li><strong>resourceGroupLocation</strong>: The Azure region that your resources are deployed to.</li>
	<li><strong>storageAccountKey</strong>: A limitation of this example requires a pre-existing standard Azure storage account. Put the storage account key here.</li>
	<li><strong>storageAccountName</strong>: the name of the pre-existing storage account.</li>
	<li><strong>artifactContainerName</strong>: The name of the container in the pre-existing storage account where the build artifacts will be stored and accessed from the deploy script and eventually the VM.</li>
	<li><strong>configurationScriptFile</strong>: The path to the file that will configure the VM and install the MSI. This can be found in the Devops folder in the Github sample.</li>
</ul>
That's it for Jenkins.
<h3>Deploy File - deploy.ps1</h3>
This file is central  to the entire process. It will deploy all our resources to Azure. We pass in all the parameters above. Here are some of the important items to point out.
<ul>
	<li>Line 31: Add-AzureRmAccount. This logs you into the Azure subscription for the Powershell session with the service principal credentials.</li>
	<li>Line 55: This uploads the Configuration file to Azure storage</li>
	<li>Line 65: We get a URL to the Configuration file that has a SAS token, which gives temporary (2 hour) permissions to read this file. We will pass this into the template so that once the Azure VM is provisioned, it can run this Configuration script.</li>
	<li>Line 72:  This time we are uploading the MSI File to Azure storage.</li>
	<li>Line 79: Now we get the URL to the MSI file with the SAS token. This is the MSI the configuration file will install on the VM.</li>
	<li>Line 84: We define the parameters for the Azure Resource Manager template. These could also be pushed back up into the parameters for the deploy file itself if we wanted to be able to control these items at the Jenkins level. You'll notice that we use the buildNumber and the Resource Group Name to dynamically name the different Azure resources we are creating.</li>
	<li>Line 106: We are looking to see if a Resource Group with the same name already exists. If it doesn't, we create it.</li>
	<li>Line 123: This is where the magic happens. We deploy our Azure Resource Manager template with the parameters we defined at line 84.  See the Template File section below to understand what happens inside the template file.</li>
	<li>Line 126: Our configuration requires the Windows VM to restart.</li>
</ul>
<h3>Template File - template.json</h3>
This is a simple <a href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/">Azure Resource Manager (ARM) </a>template file that has 2 sections:
<ul>
	<li>parameters</li>
	<li>resources</li>
</ul>
The parameters section contains fields that map to the parameters we passed in from the deploy file.

The resources section contains the following items:
<ul>
	<li><strong>availabilitySets</strong>: Defines the <a href="https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-windows-manage-availability/">availability set</a> that the Azure VMs will live in. VMs in an availability set are deployed in separate fault and upgrade domains so that they aren't all taken down at the same time due to scheduled maintenace or unscheduled outages. If you've ever heard of splitting up travel executives on separate planes, it's the same idea.</li>
	<li><strong>virtualMachines</strong>: The attributes for the Azure VM we are creating. Notice a couple of important things:
<ul>
	<li><strong>dependsOn</strong>. Before the VM can be created, it has dependencies on other resources. It needs the availability set that it will be placed in, it needs the storage account that will hold it's virtual disk(s), and it needs the NIC card that it will use to connect to networks. The Azure Resource Manager uses these dependencies to figure out what resources to build first and, if possible, which resources can be built in parallel.</li>
	<li><strong>resources</strong>. The VM resource has its own resources section. In this case we are defining a <a href="https://azure.microsoft.com/en-us/documentation/articles/virtual-machines-windows-extensions-customscript/">Custom Script Extension</a>. The custom script extension pulls down the Configuration script and the MSI file onto the provisioned VM and executes the configuration script.</li>
	<li><strong>imageReference</strong>. You can see we are deploying the latest patched version of Windows Server 2012 R2. This is important to understand for configuration management. We are not building custom images with our app baked in. We are building plain vanilla Windows VMs and automating all the configuration of the VMs including installing our app on it.</li>
	<li><strong>Count.</strong> We are only deploying 1 VM here. If we choose to, it is simple to deploy many VMs at the same time with this template.</li>
</ul>
</li>
	<li><strong>networkInterfaces</strong>: The NIC card for our VM</li>
	<li><strong>networkSecurityGroups</strong>: The <a href="https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-nsg/">Network Security Group</a> that defines what traffic is permitted through to subnet where the VM is located.</li>
	<li><strong>publicIPAddresses</strong>. We create a public IP address so the VM is available over the internet.  Notice dnsSettings/domainNameLabel, we can use that to reach our VM with a domain name.</li>
	<li><strong>virtualNetworks</strong>: We create an <a href="https://azure.microsoft.com/en-us/services/virtual-network/">Azure Virtual Network</a> with a subnet that will host our VM.</li>
</ul>
That is all we need to create our resources in Azure. There is a lot of information about <a href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-authoring-templates/">ARM templates </a>and a <a href="https://github.com/Azure/azure-quickstart-templates">github repo</a> with hundreds of examples.
<h3>Configuration Script File - ConfigurationScript.ps1</h3>
Once our VM has been provisioned, the template will execute the custom script extension which will call our configuration script. This file is at the heart of configuration management and immutable infrastructure. We started with a vanilla version of Windows Server and now we are going to configure it for our needs. Once our app is deployed to the VM, the VM shouldn't be changed further. Any iterative development or new release of the app in production should require starting with a fresh new (and patched) OS. Let's look at what this script does:
<ul>
	<li>Line 1, takes the MSI file as a parameter. When the Custom Script Extension calls this configuration script it passes in the MSI as parameter. Both the ConfigurationScript.ps1 and MSI are downloaded to the VM by the template after it provisions the VM.</li>
	<li>Line 15, installs IIS - we need this to serve the Web API inside of the MSI.</li>
	<li>Line 27, our API is 32 bit, but the Windows Server is 64 bit. So we need to set this so that IIS can serve our API.</li>
	<li>Line 32, we open port 81 for bot API - the MSI will install a new Website in IIS on port 81.</li>
	<li>Line 36, we install the MSI file.</li>
	<li>Line 42, the required .NET Framework is downloaded and installed.</li>
</ul>
This configuration uses powershell. There's an opportunity here to use a more modern framework, like Powershell Desired State Configuration (DSC) or 3rd party tools like Chef or Puppet; both have full support on Azure.
<h3>Build</h3>
With everything in place, you can kick of a build in Jenkins. The entire setup takes about 12 minutes. When your'e done, if there aren't any errors, you should be able to hit your public ip address or domain name appended with :81/api/v1/simple and start seeing sample passwords.
<h2><a id="For"></a>For Production</h2>
We can use this devops process for pushing code into production. Here are some things to think about:
<ul>
	<li>The ARM template can be updated to publish multiple VMs or to VM Scale Sets.</li>
	<li>A load balancer can be added to send requests to all VMs</li>
	<li>The VM(s) can be further locked down by shutting down unneeded ports.</li>
	<li>Add server diagnostics for the VMs for monitoring in production.</li>
	<li>An NSG rule is created for RDPing into the VMs. This can be removed when immutable infrastructure is used in production.</li>
	<li>Use a Windows Server Core Image for faster/lighter weight deployment.</li>
	<li>If your app is I/O intensive, use a VM with disks hosted on Azure Premium Storage.</li>
	<li>If your app is RAM intensive, use a VM size with more RAM.</li>
	<li>Re-deploy every month to get a patched Windows Environment.</li>
</ul>
<h2><a id="Wrapping"></a>Wrapping Up</h2>
This blog post explained how to build a Devops process for deploying a Web API to Azure. The Devops process uses automation even when the application isn't necessarily designed for automation. In this case our API is delivered as an MSI file. Using Azure Resource Manager Templates and powershell, we can automate the deployment of this app. This example can be adjusted for your own applications and it can be used as a starting point for deploying production applications.]]></content:encoded>
    </item>
    <item>
      <title>How to Start with Dev/Test Environments in Microsoft Azure</title>
      <link>https://docs.microsoft.com/archive/blogs/mikerichter/devtestinmicrosoftazure</link>
      <pubDate>Wed, 06 Apr 2016 14:03:46 GMT</pubDate>
      <dc:creator><![CDATA[MikeRichter_CSA_MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mikerichter/?p=61</guid>
      <description><![CDATA[Contents

	Introduction
	Resources
	Resource Groups vs Subscriptions
	Developing with...]]></description>
      <content:encoded><![CDATA[<h3>Contents</h3>
<ul>
	<li><a href="#introduction">Introduction</a></li>
	<li><a href="#resources">Resources</a></li>
	<li><a href="#resourcegroups">Resource Groups vs Subscriptions</a></li>
	<li><a href="#vnets">Developing with VNets</a></li>
	<li><a href="#governance">Governance</a></li>
	<li><a href="#tools">Tools</a></li>
</ul>
<h2 id="introduction">Introduction</h2>
If you are starting to do Dev/Test on the cloud, but you're new to Microsoft Azure. You may have some questions:
<ul>
	<li>How do I get organized in Azure?</li>
	<li>How can I see what's happening with Azure services in my subscription?</li>
	<li>How do I manage my spend with Azure?</li>
	<li>How can I control access to resources inside of Azure?</li>
	<li>How can I make sure my apps are being developed securely in the cloud?</li>
</ul>
This post is a guide to hit the ground running. Note that this post assumes a greenfield dev/test environment using the new <a title="Azure Resource Manager" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/" target="_blank">Azure Resource Manage</a>r deployment model. Azure services deployed with the older <a title="Azure Service Management" href="https://azure.microsoft.com/en-us/blog/introducing-the-windows-azure-service-management-api/" target="_blank">Azure Service Management </a>(ASM) model does not expose many of the dev/test features mentioned in this post. There are extremely <a title="ARM vs ASM" href="https://azure.microsoft.com/en-us/documentation/articles/resource-manager-deployment-model/" target="_blank">few reasons to use ASM</a> for new projects. Note that when you're are using the Azure Portal, you'll see resources associated with ASM labeled as "(classic)". Avoid classic VMs, Storage Accounts, Virtual Networks, etc for your new dev/test environment.
<h2 id="resources">Resources</h2>
Think of a resource in Azure as distinct billable units.  A resource in Azure can be different types; for example a database, a storage account, a VM, or a Web app. From a billing and permissions perspective, a resource is an atomic unit; it cannot be reduced further.  Resources are grouped into Resource Groups. You deploy resources into Azure Subscriptions. Subscriptions are members of Azure Accounts. Here's a breakdown of how these elements are organized and relate to each other:
<table>
<tbody>
<tr>
<td><a title="Account" href="https://account.windowsazure.com/Home/Index" target="_blank">Accounts</a></td>
<td>Accounts are containers for subscriptions. Every Azure customer gets an account. Enterprise Azure customers can have multiple accounts. Accounts contain subscriptions.</td>
</tr>
<tr>
<td><a title="Subscriptions" href="https://azure.microsoft.com/en-us/pricing/purchase-options/" target="_blank">Subscriptions</a></td>
<td>Subscriptions are a collection of resources. Subscriptions belong to only one account. When a subscription is created, a service administrator is assigned to the subscription with full admin rights. It's important to understand that the account owner is not necessarily the subscription admin. This helps keeping the financial management and the technical management of Azure subscriptions as separate concerns. The business manager may want insight into the spending pattern of Azure subscriptions, rolled up to the account level, but may/should not have access to the actual services deployed. There are several types of Subscriptions available, see the link for more information.</td>
</tr>
<tr>
<td><a title="Azure Resource Groups" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/#resource-groups">Resource Groups</a></td>
<td>Resource groups are a container for various resources. Resource groups can only belong to one subscription. You can create resources and resource groups with the same name across subscriptions (they don't need to be globally unique), but there is no affinity between them across subscriptions. A resource group lives in a single Azure datacenter region, but the resources inside of it can be in any location. For instance, my website resource group lives in the East US, but it contains Azure Web apps deployed to both East US and West US regions. The group location is just a logical construct and has no physical impact on the resources inside of it. Resource Groups can contain different kinds of resources: For instance, a resource group can contain a database, VMs, and a network. Resource groups only contain resources; Resource Groups cannot be nested.</td>
</tr>
<tr>
<td><a title="Azure Resources" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-overview/#resource-providers" target="_blank">Resource</a></td>
<td>A distinct billable unit for an Azure service. A resource can only belong to one resource group. A resource is an instance of a Resource Provider. The providers details what the resource type is, the properties on the type and what versions are available.</td>
</tr>
</tbody>
</table>
&nbsp;

This logical separation of resources into groups, subscriptions and accounts is a way to organize according to one dimension. There are other ways you can organize resources that are cross-group or cross-subscription.
<table>
<tbody>
<tr>
<td><a title="Tags" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-using-tags/" target="_blank">Tags</a></td>
<td>You can tag resources with an arbitrary set of key-value pairs. This allows you to create associations between resources even though they live in different groups or subscriptions</td>
</tr>
<tr>
<td><a title="Regions" href="https://azure.microsoft.com/en-us/regions/" target="_blank">Location</a></td>
<td>Resources can live in different Azure datacenter region, despite being part of the same group or subscription. A database can live in the West US, while a geographically load-balanced set of web sites live in West US, Central US and East US. These can all be in the same subscription and the same resource group. When deciding where to locate your dev/test resources, it may be useful to test the latency between where your developers and testers are and the various Azure regions. There are <a title="Azure Speed" href="https://www.azurespeed.com/" target="_blank">tools</a> available to help you with this.</td>
</tr>
</tbody>
</table>
&nbsp;

In addition to organizing your resources, you can also dictate who can access resources and how they are created.
<table>
<tbody>
<tr>
<td><a title="RBAC" href="https://azure.microsoft.com/en-us/documentation/articles/role-based-access-control-configure/" target="_blank">RBAC</a></td>
<td>RBAC is Role Based Access Control. For each resource, you can assign different levels of permissions to different users and groups in your organization. You can use pre-built roles or define your own. You can assign roles at the resource level, or to entire resource groups or subscriptions. In the case of resource groups and subscriptions, roles are inherited by the underlying resources.</td>
</tr>
<tr>
<td><a title="ARM Policy" href="https://azure.microsoft.com/en-us/documentation/articles/resource-manager-policy/" target="_blank">Azure Policy</a></td>
<td>You can write specific policies about how resources are created. You can enforce rules like required tagging, naming policies or location choice.</td>
</tr>
</tbody>
</table>
<p style="padding-left: 30px"><strong>Recommendation</strong>: If you're just starting in Azure, don't create RBAC or Policies yet. Give everyone on the team a chance to explore Azure and get comfortable with deploying different resources. Give your developers a chance to discover native Azure solutions to help them meet their needs. Once a cloud architecture for your apps has been decided upon, then it makes sense to start locking down the dev environment in preparation for production.</p>

<h2 id="resourcegroups">Resource Groups vs Subscriptions</h2>
Now that you understand how to organize our resources in Azure, how should you move forward with our dev/test environment? If you're developing a single app or you have a single team that will be working with Azure, it makes sense to keep the development in a single subscription. But what if you have multiple teams working on multiple projects? Should they all be in the same subscription with separate resource groups or should they each get their own subscription? There are some factors to consider when making this decision:
<table>
<tbody>
<tr>
<th>Factor</th>
<th>Separate Subscription</th>
<th>Resource Groups</th>
</tr>
<tr>
<td>Apps have nothing in common</td>
<td>Use separate subscriptions if resource limitations may become an issue (Public IP Addresses, Storage account instances, etc). Use separate subscriptions for spending caps.</td>
<td>Use to Reduce costs</td>
</tr>
<tr>
<td>Applications Share some tiers (UX, App, and/or DB)</td>
<td>A good option, reduces stepping on toes; clear separation of concerns, but may require automated updating of environments to keep changes from either team in sync</td>
<td>Challenging option, makes resource ownership less clear</td>
</tr>
<tr>
<td>Applications have dependencies on other applications</td>
<td>Can work well if the depended-upon apps can be deployed into the dependent subscription. Or, if the depended-upon apps deployed in other subscriptions are reachable via Internet</td>
<td>Easier to implement if the Azure resources in each solution are not shared (and can be assigned to separate groups).</td>
</tr>
<tr>
<td>Apps need to be on the same VNet (see "Developing with VNets" section too)</td>
<td>A site-to-site VPN can be established between VNets across subscription. Or, a 3rd subscription can be created to host the VNet and other shared resources (AD Controller, DevOps orchestrator, etc).</td>
<td>This works, but you can use RBAC to set up a shared VNet and give each team contributor access to it so any changes need to be agreed upon.</td>
</tr>
<tr>
<td>Apps will be managed andmonitored tested</td>
<td>Dashboards are currently subscription-specific so it's hard to see all resources under one pane of glass</td>
<td>Creating dashboards is easier</td>
</tr>
<tr>
<td><a title="Enterprise Azure Portal" href="https://azure.microsoft.com/en-us/pricing/enterprise-agreement/">Enterprise Azure Portal</a></td>
<td>If you've signed up for the Enterprise Azure portal (via a Microsoft Enterprise Agreement), creating and managing multiple subscriptions across different organizational departments can be required. Creating separate subscriptions</td>
<td>A better option for smaller teams</td>
</tr>
</tbody>
</table>
<p style="padding-left: 30px"><strong>Recommendation</strong>: If everyone is new to Azure, start off by giving every team their own Azure subscription so nobody is stepping on anybody else's toes. If teams need to work together, they will eventually self-organize and choose a primary subscription to work in.</p>

<h2 id="vnets">Developing with VNets</h2>
Developing applications on VMs that need to talk to other applications on a <a title="VNets" href="https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-create-VNet-arm-pportal/">VNet </a>can present some challenges:
<ul>
	<li>Who owns the VNet?</li>
	<li>What port are allowed on the VNet?</li>
	<li>What subnets can talk to what subnets?</li>
	<li>What VMs can reach the Internet?</li>
	<li>What VMs can be reached by the Internet?</li>
	<li>Can I connect my VNet to another VNet?</li>
</ul>
To solve these challenges, Azure provides several capabilities:
<table>
<tbody>
<tr>
<td><a title="Network Security Groups" href="https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-nsg/">Network Security Groups (NSG)</a></td>
<td>These are rules that apply directly to VMs on a VNet or to a Subnet (and all the VMs inside the VNet. There are inbound and outbound rules. For each rule you can define source and target IP address ranges, ports and protocols. Multiple rules can be applied to each NSG with precedence.</td>
</tr>
<tr>
<td><a title="Azure Load Balancers" href="https://azure.microsoft.com/en-us/documentation/articles/load-balancer-overview/">Load Balancers</a></td>
<td>Internal Load Balancers and External Load Balancers for sending requests to a defined set of VMs or subnet. Rules on the load balancers can be defined per protocol and port.  External Load Balancers can have NAT rules to route to specific machines.</td>
</tr>
<tr>
<td><a title="Application Gateway" href="https://azure.microsoft.com/en-us/services/application-gateway/">Application Gateway</a></td>
<td>The Application Gateway has layer 7 load balancing features like cookie-affinity and SSL termination.</td>
</tr>
<tr>
<td><a title="IP Addresses" href="https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-reserved-public-ip/">IP Addresses</a></td>
<td>Static Public IP Addresses and Static Internal Addresses can be assigned. Public IP addresses come with a domain name. You can use Azure DNS or set up your own</td>
</tr>
<tr>
<td><a title="VNet to VNet" href="https://azure.microsoft.com/en-us/documentation/articles/vpn-gateway-VNet-VNet-rm-ps/">VNet-to-VNet</a></td>
<td>You can create connections between VNets in the same subscription or across subscriptions</td>
</tr>
</tbody>
</table>
&nbsp;

If you're developing apps in separate subscriptions, you can create a VNet-to-VNet connection so that the apps can talk to each other but not interfere with either's VNet settings.

If you're developing apps in the same subscription you can use resource groups to separate the development environments but also create a separate resource group to manage the VNet. That way each app can attach VMs to the VNet, but they can't alter the configuration or NSGs. For an example of how to do this, check out this blog post: <a href="https://na01.safelinks.protection.outlook.com/?url=https%3a%2f%2furldefense.proofpoint.com%2fv2%2furl%3fu%3dhttps-3A__na01.safelinks.protection.outlook.com_-3Furl-3Dhttps-253a-252f-252furldefense.proofpoint.com-252fv2-252furl-253fu-253dhttp-2D3A-5F-5Fblogs.technet.com-5Fb-5Fad-5Farchive-5F2015-5F10-5F12-5Fazure-2D2Drbac-2D2Dis-2D2Dga.aspx-2526d-253dAwMFAg-2526c-253dk6LEwkJiSX1kJxtgPu1uYQ-2526r-253dSeAzzv5PTR93zS6ltsO9whibqbRFEOSx3q6Kg8ysgOI-2526m-253doVBt6npziZHP3f9xl7-5F1paOz7mdEMcwkHV-2D-2DUzHJ2WI-2526s-253d9zLJTTY3LgPJKiZUUtGQxtHYgdl3-5FfMytxW1js4U7ow-2526e-253d-26data-3D01-257c01-257ckmayer-2540microsoft.com-257cf3fd180763894bb299e708d2e9122bca-257c72f988bf86f141af91ab2d7cd011db47-257c1-26sdata-3DDCjoHf7xbRwh7qYp2-252bYLwaGPv-252fqaWX-252bSyrNk0-252brGTJY-253d%26d%3dCwMFAg%26c%3dk6LEwkJiSX1kJxtgPu1uYQ%26r%3dSeAzzv5PTR93zS6ltsO9whibqbRFEOSx3q6Kg8ysgOI%26m%3d6pdIK1jUEJgTCQ-2OeSHDau6aDo_e740Fj8LJw7zTIg%26s%3dq329bHZaZXAJLl2lhEJLuTaJkguekOH3EhE-HgzHdwQ%26e%3d&amp;data=01%7c01%7ckmayer%40microsoft.com%7c2b0350e64f6d4b0ad48f08d2eb81f22e%7c72f988bf86f141af91ab2d7cd011db47%7c1&amp;sdata=DMp%2b6P7swuhlvZ9H1N7BQydheQoULnwHzigyb0Dy7bM%3d">https://blogs.technet.com/b/ad/archive/2015/10/12/azure-rbac-is-ga.aspx</a>
<h2 id="governance">Governance</h2>
Once you're up and running with Azure, how do you manage and control the environment? How do you know what's happening in your subscription(s)? Azure has several options:
<table>
<tbody>
<tr>
<td><a title="Dashboards" href="https://channel9.msdn.com/Blogs/trevor-cloud/azure-portal-dashboards">Dashboards</a></td>
<td>Many Azure resources come with counters. You can build and customize graphs based on these counters in the Azure portal. You can build a dashboard of these graphs and counters on your Azure portal homepage. You can build multiple dashboards and share them with other users in the subscription.</td>
</tr>
<tr>
<td><a title="RBAC" href="https://azure.microsoft.com/en-us/documentation/articles/role-based-access-control-configure/" target="_blank">RBAC</a></td>
<td>Use RBAC to make sure that only the right users have access to the right resources. Instead of assigning roles to individuals, use Azure AD groups to make management easier.</td>
</tr>
<tr>
<td><a title="ARM Policy" href="https://azure.microsoft.com/en-us/documentation/articles/resource-manager-policy/" target="_blank">Azure Policy</a></td>
<td>As users begin to create various resources, it may be difficult to keep track of them all. Policies can enforce naming conventions, require tagging, limit skus that can be used and regions where resources can be deployed. Policies can help the service admins keep uniformity and transparency within the subscription.</td>
</tr>
<tr>
<td><a title="Azure Security Center" href="https://azure.microsoft.com/en-us/services/security-center/">Security Center</a></td>
<td>Even though you're doing dev/test, Azure Security Center is a free advanced capability that will analyze your resources and make security recommendations for you. Catching these before production can help you make sure your apps are secure when they reach your customers.</td>
</tr>
<tr>
<td><a title="Spending Limits" href="https://azure.microsoft.com/en-us/pricing/spending-limits/">Subscription Spending Limits</a></td>
<td>In the account portal, where you see all your subscriptions, you can set spending limits per subscription. When used with policies, subscription soft limits and RBAC, you can make sure that your Azure spend is predictable and when exceptions arise, you have a transparent process for handling it.</td>
</tr>
<tr>
<td><a title="Azure Subscription Limits" href="https://azure.microsoft.com/en-us/documentation/articles/azure-subscription-service-limits/">Subscription Soft Limits</a></td>
<td>Every subscription comes with soft limits for the amount of resources you can deploy. These limits are there to protect both you (from accidentally spending more money than expected) and Azure (to maintain predictable capacity requirements). If you need to raise your limits, you can make an Azure Support request.</td>
</tr>
<tr>
<td><a title="Network Security Groups" href="https://azure.microsoft.com/en-us/documentation/articles/virtual-networks-nsg/">Network Security Groups</a></td>
<td>Use NSGs strategically to make sure that apps are built with network security in mind.</td>
</tr>
<tr>
<td><a title="Azure Trust Center" href="https://azure.microsoft.com/en-us/support/trust-center/">Azure Trust Center</a></td>
<td>If your applications need to comply with regulations or respect data sovereignty laws, the Azure Trust center can guide you on what Azure services are compliant with regulations. Don't ignore these during dev/test so that you build an application that is compliant in production.</td>
</tr>
<tr>
<td><a title="Azure Dev/Test Labs" href="https://azure.microsoft.com/en-us/services/devtest-lab/">Azure Dev/Test Labs</a></td>
<td>Azure Dev/Test Labs is a great resource for creating and managing test environments. You can set up additional quotas and policies within the dev/test lab. You can build VMs with reusable templates that match your dev/test spec requirements. To save money, you can automate shutting down those VMs at night when your dev team goes home.</td>
</tr>
</tbody>
</table>
<h2 id="tools">Tools</h2>
There are many ways to interact with Azure when building your dev/test environment. Developers should be aware of all the ways you can deploy resources to Azure. While you can use the portal to deploy resources, it's important to understand what tools are available for automating these environments.

&nbsp;
<table>
<tbody>
<tr>
<td><a title="Azure Portal" href="https://azure.microsoft.com/en-us/features/azure-portal/">Portal</a></td>
<td>Use the Azure portal for manually deploying Azure resources.</td>
</tr>
<tr>
<td><a title="Powershell" href="https://azure.microsoft.com/en-us/documentation/articles/powershell-azure-resource-manager/">Powershell</a></td>
<td>Azure can be automated with Powershell Cmdlets.</td>
</tr>
<tr>
<td><a title="Azure Command Line tools" href="https://azure.microsoft.com/en-us/documentation/articles/xplat-cli-install/">Cross Platform Command Line tools</a></td>
<td>If you're dev environment is not Windows, you can use these tools on Mac or Linux workstations.</td>
</tr>
<tr>
<td><a title="Azure APIs" href="https://msdn.microsoft.com/en-us/library/azure/dn790568.aspx">REST APIs</a></td>
<td>The Portal, Powershell and CLIs all use the REST APIs under the covers and you can too!</td>
</tr>
<tr>
<td><a title="ARM Templates" href="https://azure.microsoft.com/en-us/documentation/articles/resource-group-authoring-templates/">ARM Templates</a></td>
<td>When you have a dev/test environment defined you can <a title="Export ARM templates" href="https://azure.microsoft.com/en-us/blog/export-template/" target="_blank">easily export</a> it as a JSON-based template. You can deploy that template as a repeatable process. You can tear down the entire environment every night and automate rebuilding it every morning. You can store the JSON in source control so it's part of your app development process. You can also share the templates and have it deployed into different subscriptions (think dev, test, qa, staging, production).</td>
</tr>
</tbody>
</table>
Hopefully this will be a handy guide to get up and running with Dev/Test on Azure. If you have any feedback or further questions, please leave a comment or reach out to me directly.]]></content:encoded>
    </item>
    <item>
      <title>Migrate Existing ASP.NET Website to Azure Cloud Services</title>
      <link>https://docs.microsoft.com/archive/blogs/mikerichter/migrate-existing-asp-net-website-to-azure-cloud-services</link>
      <pubDate>Thu, 10 Dec 2015 09:00:00 GMT</pubDate>
      <dc:creator><![CDATA[MikeRichter_CSA_MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mikerichter/2015/12/10/migrate-existing-asp-net-website-to-azure-cloud-services/</guid>
      <description><![CDATA[This blog post explains how to get an existing ASP.NET application into an Azure Cloud Service...]]></description>
      <content:encoded><![CDATA[<p>This blog post explains how to get an existing ASP.NET application into an Azure Cloud Service without having to create a new Visual Studio project. Here's the outline:</p>
<ol>
<li><a href="#setup">Setup</a></li>
<li><a href="#create">Create Cloud Service Files</a></li>
<li><a href="#web">Create Web Role</a></li>
<li><a href="#copy">Copy Existing App</a></li>
<li><a href="#deploy">Deploy Cloud Service</a></li>
</ol>
<p>Do you have an existing ASP.NET website that you'd like to deploy on Azure and get the benefits of Azure's Platform as a Service capabilities? The easiest and quickest option is to use <a title="Azure Web Apps" href="https://azure.microsoft.com/en-us/services/app-service/web/">Azure Web Apps</a>. Azure Web Apps gives you create flexibility but it does not allow you to customize the underlying operating system that much. For instance, if your existing ASP.NET website has a dependency on applications being installed into the web server, Web Apps may not be the best option. In this case you have a few options:</p>
<ol>
<li>Rewrite the application to not require the dependency on installed applications.</li>
<li>Use <a title="Infrastructure as a Service" href="https://azure.microsoft.com/en-us/services/virtual-machines/">Infrastructure as a Service (IaaS)</a> to deploy a Windows IIS Web Server.</li>
<li>Use <a title="Cloud Services" href="https://azure.microsoft.com/en-us/services/cloud-services/">Azure Cloud Services</a> with Startup Tasks to install the required applications.</li>
</ol>
<p>Rewriting the application is often not a choice and using IaaS means you do not get the benefits of PaaS. This article is about using Cloud Services. Cloud Services is one of the earliest services on the Azure platform. There is already a ton of great content out there on Cloud Services. However, there is not much content about porting your existing ASP.NET app to Cloud Services, so I am going to lay out some simple steps.</p>
<h3><a name="setup"></a>SETUP</h3>
<p>For this walk-through, I have a simple ASP.NET website targeting .NET 4.0. I want to deploy it on Azure with a custom startup task that will run when the Cloud Service instance(s) are deployed.&nbsp;</p>
<h3><a name="create"></a>CREATE CLOUD SERVICE FILES</h3>
<p>Make sure you have <a href="https://azure.microsoft.com/en-us/documentation/articles/powershell-install-configure/" target="_blank">Azure Powershell</a> installed. Choose a directory to work in.</p>
<p>Run Powershell as administrator.</p>
<p>Execute</p>
<p><span style="font-family: 'courier new', courier;">PS C:\projects\CloudServices&gt; <strong>New-AzureServiceProject -ServiceName ExistingAppDemo</strong></span></p>
<p>This will create a folder with the Service Name and move into that folder:</p>
<p><span style="font-family: 'courier new', courier;">PS C:\projects\CloudServices\<strong>ExistingAppDemo</strong>&gt;</span></p>
<p>Inside you will find the following metadata files that Azure needs to create a cloud service:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/7416.DirectoryListforExistingApp.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/7416.DirectoryListforExistingApp.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/7416.DirectoryListforExistingApp.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/7416.DirectoryListforExistingApp.PNG" alt="" border="0" /></a></p>
<p>&nbsp;</p>
<ul>
<li>deploymentSettings.json - required by PowerShell for deploying Cloud Services</li>
<li>ServiceConfiguration.Cloud.cscfg - this is the cloud service configuration file Azure will use. We won't touch this file for this walkthrough.</li>
<li>ServiceConfiguration.Local.cscfg - this is the cloud service configuration file that your local emulator will use. We won't touch this file for this walkthrough.</li>
<li>ServiceDefinition.csdef - this is the service definition file. We will be making changes to this file.</li>
</ul>
<p>&nbsp;</p>
<p>Now that you have these metadata files, you need to run your website inside of a Web Role.</p>
<h3><a name="web"></a>CREATE WEB ROLE</h3>
<p>To create a web role, remain in your current directory and type:</p>
<p><span style="font-family: 'courier new', courier;">PS C:\projects\CloudServices\ExistingAppDemo&gt; Add-AzureWebRole</span></p>
<p>This does a few of things:</p>
<ul>
<li>It updates your Service Configuration files. It adds a Role element with some configuration. We will leave the defaults.</li>
<li>It updates your Service Definition file. It adds a WebRole element and includes some child elements including Startup tasks.&nbsp;</li>
</ul>
<p>We're going to edit the <span style="font-family: 'courier new', courier;">ServiceDefinition.csdef</span> file:</p>
<p>Change the vmsize attribute on the WebRole element to "ExtraLarge" - the default ExtraSmall VM size takes a while to spin up and configure so to get going faster we'll use ExtraLarge. This can always be changed later when you're ready to deploy your site for production use.</p>
<p>There are 2 Startup tasks. Remove the first task (the one that calls "setup_web.cmd"). It's not necessary for this walkthrough. So, completely remove this block of code:</p>
<pre><span style="font-family: 'courier new', courier;"> &lt;Task commandLine="setup_web.cmd &amp;gt; log.txt" executionContext="elevated"&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;Environment&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;Variable name="EMULATED"&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" /&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;/Variable&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;Variable name="RUNTIMEID" value="" /&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;Variable name="RUNTIMEURL" value="" /&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;/Environment&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;/Task&gt;</span></pre>
<p>That's it.</p>
<p>Adding the WebRole also creates a new directory called WebRole1. Inside WebRole1 are a few items. You are going to delete most of them:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/1638.WebRole1Folder.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/1638.WebRole1Folder.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/1638.WebRole1Folder.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/1638.WebRole1Folder.PNG" alt="" border="0" /></a></p>
<p><br />Delete the bin folder</p>
<p>Delete the Web.cloud.config file</p>
<p>Delete the Web.cloud.config file</p>
<p>KEEP the <strong>startup.cmd</strong> file. Notice that in your Service Defintion file, there is a task that calls startup.cmd:</p>
<pre><span style="font-family: 'courier new', courier;"> &lt;Startup&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;Task commandLine="..\<strong>startup.cmd</strong> &amp;gt; startup_log.txt" executionContext="elevated" /&gt;</span><br /><span style="font-family: 'courier new', courier;"> &lt;/Startup&gt;</span></pre>
<p>That is the same <strong>startup.cmd</strong> file that is in this folder. This where you can put in your own custom startup tasks (silent installs of your required installed apps). If your start up tasks require executables or MSIs, you can include them in the bin folder and reference them in the startup.cmd file.&nbsp;Does your Existing ASP.NET require a version of .NET newer than 4.0? You can install a newer version of the .NET framework as a startup task! See&nbsp;<a title=".NET Install for Cloud Services" href="https://azure.microsoft.com/en-us/documentation/articles/cloud-services-dotnet-install-dotnet/">https://azure.microsoft.com/en-us/documentation/articles/cloud-services-dotnet-install-dotnet/</a>. This is a great example of how to use startup tasks.</p>
<h3><a name="copy"></a>COPY EXISTING WEB APPLICATION</h3>
<p>Find the files for your existing ASP.NET application.&nbsp;</p>
<p>Here's my test app:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/6014.MyProject.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/6014.MyProject.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/6014.MyProject.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/6014.MyProject.PNG" alt="" border="0" /></a></p>
<p>Here's the magic: We are going to move (or copy and paste) the TestApp into the WebRole1 directory we just created in&nbsp;C:\projects\CloudServices\ExistingAppDemo\WebRole1. The end result should look like this:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/2671.CompleteWebRole.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/2671.CompleteWebRole.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/2671.CompleteWebRole.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/2671.CompleteWebRole.PNG" alt="" border="0" /></a></p>
<p>It should look EXACTLY the same except for the remaining startup.cmd.</p>
<p>Almost done!</p>
<h3><a name="deploy"></a>DEPLOY CLOUD SERVICE&nbsp;</h3>
<p>You've got your Cloud Service ready. You've got a WebRole defined and populated with your existing ASP.NET website's code.</p>
<p>Go back up to the Cloud Service directory:</p>
<p><span style="font-family: 'courier new', courier;">PS C:\projects\CloudServices\ExistingAppDemo&gt;&nbsp;</span></p>
<p>and type:</p>
<p><span style="font-family: 'courier new', courier;">PS C:\projects\CloudServices\ExistingAppDemo&gt; Publish-AzureServiceProject -ServiceName ExistingAppDemo</span></p>
<p>This will package up your cloud service and deploy it a service named "ExistingAppDemo." &nbsp;If you've chosen a service name that already exists, you'll get an error - just run the command name with a different service name.&nbsp;</p>
<p>It will take a few minutes to deploy your app, you should see the following messages:</p>
<pre><span style="font-family: 'courier new', courier;">WARNING: Publishing ExistingAppDemo to Microsoft Azure. This may take several minutes...</span><br /><span style="font-family: 'courier new', courier;">WARNING: 2:05:13 PM - Preparing runtime deployment for service 'ExistingAppDemo'</span><br /><span style="font-family: 'courier new', courier;">WARNING: 2:05:13 PM - Verifying storage account 'existingappdemo'...</span><br /><span style="font-family: 'courier new', courier;">WARNING: 2:05:46 PM - Preparing deployment for ExistingAppDemo with Subscription ID: b59a9b75-a297-41fc-8773-4f3713391c19...</span><br /><span style="font-family: 'courier new', courier;">WARNING: 2:05:55 PM - Connecting...</span><br /><span style="font-family: 'courier new', courier;">WARNING: 2:05:56 PM - Creating...</span><br /><span style="font-family: 'courier new', courier;">WARNING: 2:05:59 PM - Created hosted service 'ExistingAppDemo'.</span><br /><span style="font-family: 'courier new', courier;">WARNING: 2:05:59 PM - Uploading Package to storage service existingappdemo...</span><br /><span style="font-family: 'courier new', courier;">WARNING: 2:06:01 PM - Starting...</span></pre>
<pre><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/7750.CloudServiceMessages.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/7750.CloudServiceMessages.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/7750.CloudServiceMessages.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/7750.CloudServiceMessages.PNG" alt="" border="0" /></a></pre>
<p>Everything should have been successful and you'll see the unique URL for your new web app in an Azure cloud service! Your cloud service is available in the Azure portal:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/0820.AzurePortal.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/0820.AzurePortal.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/0820.AzurePortal.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-39-47/0820.AzurePortal.PNG" alt="" border="0" /></a></p>
<p>Obviously this is just the beginning. You'll need to manage the Cloud Service, scale it, secure it, add your custom domain, etc.&nbsp;</p>
<p>With your cloud service, you've now got your existing ASP.NET webapp in Azure, utilizing Azure's Platform as a Service even though your app has installed dependencies!</p>
<p>More information:</p>
<ul>
<li>Azure Cloud Services:&nbsp;<a href="https://azure.microsoft.com/en-us/documentation/services/cloud-services/">https://azure.microsoft.com/en-us/documentation/services/cloud-services/</a></li>
<li>Silent /Unattended Installs:&nbsp;<a href="https://unattended.sourceforge.net/installers.php">https://unattended.sourceforge.net/installers.php</a></li>
</ul>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>How to add a custom button and plugin to tinymce in Umbraco 4.5</title>
      <link>https://docs.microsoft.com/archive/blogs/mikerichter/how-to-add-a-custom-button-and-plugin-to-tinymce-in-umbraco-4-5</link>
      <pubDate>Mon, 20 Dec 2010 10:01:00 GMT</pubDate>
      <dc:creator><![CDATA[MikeRichter_CSA_MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mikerichter/2010/12/20/how-to-add-a-custom-button-and-plugin-to-tinymce-in-umbraco-4-5/</guid>
      <description><![CDATA[Last week I had to create some custom functionality for the tinymce editor in Umbraco. We needed to...]]></description>
      <content:encoded><![CDATA[<p>Last week I had to create some custom functionality for the tinymce editor in Umbraco. We needed to add a style-based expand/collapse dhtml region for some proof of concept code. I looked for information on customizing the editor in Umbraco 4.5 and could only find bits and pieces. So a coworker and I figured it out for ourselves. It's pretty simple, here's the steps:</p>
<p>This pertains to Umbraco 4.5.</p>
<p>1. First edit this file in the config folder: tinyMceConfig.config. Add a new set of elements to //commands:</p>
<pre class="scroll"><code class="html">    &lt;command&gt;<br />      &lt;umbracoAlias&gt;<b>mceTest</b>&lt;/umbracoAlias&gt;<br />      &lt;icon&gt;images/editor/<b>mceTest</b>.gif&lt;/icon&gt;<br />      &lt;tinyMceCommand value="<b>mceTest</b>" userInterface="false" frontendCommand="<b>mceTest</b>"&gt;<b>mceTest</b>&lt;/tinyMceCommand&gt;<br />      &lt;priority&gt;3&lt;/priority&gt;<br />    &lt;/command&gt;</code></pre>
<p>Make sure the values for <b>mceTest </b>all match. You can insert your own image or choose an existing image for icon.</p>
<p>Add to the plugins node: &nbsp;&nbsp;&nbsp; </p>
<pre class="scroll"><code class="html">&lt;plugin loadOnFrontend="false"&gt;<b>mceTest</b>&lt;/plugin&gt;</code></pre>
<p>Save the file.</p>
<p>2. Create a new folder in \umbraco_client\tinymce3\plugins with the name of your plugin (mceTest in this case).</p>
<p>Inside this folder you need at least 2 files: <b>editor_plugin.js</b> and <b>editor_plugin_src.js</b>. The editor_plugin.js file is the same as the editor_plugin_src.js just compressed. When you are working in debug in your dev environment make sure your changes to editor_plugin_src.js. When you are ready to deploy your plugin, crunch the code and put it in editor_plugin.js. </p>
<p>3. Create editor_plugin_src.js and add the following scaffolding code:</p>
<p>&nbsp;</p>
<pre class="scroll"><code class="js">(function () {<br /><br />    tinymce.create('tinymce.plugins.mceTest', {<br /><br />        init: function (ed, url) {<br /><br /><br />           var t = this;<br /><br />            t.editor = ed;<br /><br /><br /><br />            // Register buttons<br /><br />            ed.addButton(<br /><br />         'mceTest', {<br /><br />             title: 'Create collapsible area',<br /><br />             image: url + '/images/icon.gif',<br /><br />             cmd: 'testButton'<br /><br />         });<br /><br />        },<br /><br /><br /><br />        createControl: function (n, cm) { return null; },<br /><br /><br /><br />        getInfo: function () {<br /><br />            return {<br /><br />                longname: 'mceTest',<br /><br />                author: 'mceTest',<br /><br />                authorurl: 'mceTest',<br /><br />                infourl: 'mceTest',<br /><br />                version: tinymce.majorVersion + "." + tinymce.minorVersion<br /><br />            };<br /><br />        }<br /><br />    });<br /><br /><br />    // Register plugin<br /><br />    tinymce.PluginManager.add('mceTest', tinymce.plugins.mceTest);<br /><br />})();</code></pre>
<p>&nbsp;</p>
<p>Make sure you replace mceTest with the name of your plugin everywhere in this file. If you are publishing this plugin you can change the longname authorurl and infourl values.</p>
<p>There is plenty of documentation on how to create behavior in this file, and you can look at the other plugin folders to see simple and complicated examples. You can even add html files to create forms when users click your button in the tinymce toolbar.</p>
<p>4. For this example, I am going to be adding a simple Jquery-based expand/collapse widget to the tinymce toolbar, the only code necessary for this example is the following lines added just under t.editor = ed;</p>
<p>&nbsp;</p>
<pre class="scroll"><code class="js">        init: function (ed, url) {<br /><br /><br /><br />            var t = this;<br /><br />            t.editor = ed;<br /><br /><b>            ed.addCommand('testButton', function (ui, v) {<br /><br />                ed.execCommand('mceInsertContent', false, '&lt;p&gt;&lt;/p&gt;&lt;div class="ExpColCon"&gt;&lt;div class="ExpColTitle"&gt;Title Goes here&lt;/div&gt;&lt;div class="ExpColBod"&gt;&lt;p&gt;Body&lt;br/&gt;Goes&lt;/br/&gt;Here&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;');<br /><br />            });<br /><br /></b><br /><br />            // Register buttons<br /><br />            ed.addButton(<br /><br />         'mceTest', {<br /><br />             title: 'Create collapsible area',<br /><br />             image: url + '/images/icon.gif',<br /><br />             cmd: 'testButton'<br /><br />         });<br /><br />        },</code></pre>
<p>What will this code do? It will insert into the editor some html markup with styles for expand/collapse (I'll show you the Jquery to make this work on the actual templated web page below). It will be easy for the end-user to update these fields with their own text/html.</p>
<p>&nbsp;</p>
<p>5. To make sure the end-user can understand what they are seeing, edit the css for the editor form which is located in \umbraco_client\tinymce3\themes\umbraco\skins\umbraco\content.css</p>
<pre class="scroll"><code class="css"><br /><br />.ExpColCon<br /><br />{<br /><br />	padding:7px;border:1px dotted #333333<br /><br />}<br /><br /><br /><br />.ExpColTitle<br /><br />{<br /><br />		padding:3px 3px 3px 20px;border:1px dotted blue; color:blue;<br /><br />		font-family:Verdana,Arial,Helvetica,sans-serif;<br /><br />		font-size:80%;<br /><br />		font-weight:bold;<br /><br />		background-image:url('/umbraco/images/Lplus.png');<br /><br />		background-position:0px 3px;<br /><br />		background-repeat:no-repeat;<br /><br />}<br /><br /><br /><br />.ExpColBod<br /><br />{<br /><br />		padding:3px 3px 3px 20px;border:1px dotted red; color:#666666;<br /><br />}</code></pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Now when you click the button to add the expand/collapse region, you will see it outlined in the editor. NOTE that this CSS is NOT The CSS&nbsp; on the resulting public facing template. You can define other styles there. This CSS is just helpful for the end user writing content in the tinymce editor.</p>
<p>So if you've done all this, then go to your Umbraco CMS authoring environment. You may need to dump your cache as Javascript and CSS files get cached and your state may not be correct.</p>
<p>6. Create a new Datatype using the tiny MC3v3 wysiwyg Render Control. You should see your new button as one of the choices. Make sure you check that button and save your new DataType.</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/8507.datatype.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-39-47/8507.datatype.PNG" border="0" /></p>
<p>7. Save your DataType. Create a new DocumentType and add a new property based on your new DataType.</p>
<p>In your content when you create a new Document based on your DocumentType, you should see the tinymce editor show up with your new button!</p>
<p>When you click the button, some markup will be added to your editor surface. Because we added the css to the editor's content.css file, the expand/collapse fields are easily marked:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/7450.editor.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-39-47/7450.editor.PNG" border="0" /></p>
<p>Now it's easy for an end user to update the title and the body of the expand collapse field.&nbsp; To use this code in your template just add this simple Jquery:</p>
<p>&nbsp;</p>
<pre class="scroll"><code class="js">    &lt;script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.4.4.js" type="text/javascript"&gt;&lt;/script&gt;<br /><br />    &lt;script type="text/javascript"&gt;<br /><br />        var expcolconstyle = ".ExpColCon";<br /><br />        var expcoltitlebodycontainer = "div";<br /><br />        var expcolconselector = expcolconstyle + " " + expcoltitlebodycontainer + ":nth-child(#)";<br /><br />        var expcoltitleselector = expcolconselector.replace("#", "1");<br /><br />        var expcolbodyselector = expcolconselector.replace("#", "2");<br /><br />        $(document).ready(function () {<br /><br />            $(expcolbodyselector).hide();<br /><br />            $(expcoltitleselector).attr("style", "cursor:pointer");<br /><br />            $(expcoltitleselector).click(this, function () {<br /><br />                var expcolbody = $(this).parent().children(expcolbodyselector);<br /><br />                expcolbody.toggle();<br /><br />                //alert(expcolbody.text());<br /><br />            });<br /><br />        });<br /><br />    &lt;/script&gt;<br /><br /></code></pre>
<p>You'll notice only the wrapping DIV.ExpColCon is important. The first child (regardless of style) will be treated as the Title and the the second child will be treated as the body. This gives you freedom to change these styles in the future.</p>
<p>Thanks,</p>
<p>Mike</p>]]></content:encoded>
    </item>
    <item>
      <title>Solution Navigator in Productivity Power Tools Update</title>
      <link>https://docs.microsoft.com/archive/blogs/mikerichter/solution-navigator-in-productivity-power-tools-update</link>
      <pubDate>Tue, 20 Jul 2010 18:16:00 GMT</pubDate>
      <dc:creator><![CDATA[MikeRichter_CSA_MSFT]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mikerichter/2010/07/20/solution-navigator-in-productivity-power-tools-update/</guid>
      <description><![CDATA[When starting a new project in Visual Studio, there are standard ways to layout your solution. For...]]></description>
      <content:encoded><![CDATA[<p>When starting a new project in Visual Studio, there are standard ways to layout your solution. For instance, every tier in your n* tier architecture has its own project. When you get down to the feature level, sometimes it becomes more complex. For example, I've worked on older projects based on <i>classic</i> ASP.NET (as opposed to ASP.NET MVC), where all the files related to a feature were grouped together. Under the features/widgets/widgetA folder you'd find the user control for the widgetA, the javascript file for widgetA, it's css file, it's images and any other resources it needed. </p>
<p>Now I am working in ASP.NET MVC where, if done correctly, there are some serious separations of concerns. Now, my widgetA ViewModel is in the "ViewModel" folder tree, the associated View.ascx file is the "Views" folder, javascript, css and images all in separate folders under a "Content" folder.</p>
<p>When I am working on the widgetA feature, it's a little annoying to have to walk through the whole tree to find everything I need. I considered creating a solution folder called widgetA and then adding all related files to that solution folder. That seemed too hard to maintain and would take a long time to get to widgetZ.</p>
<p><img style="float: right;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/39/47/5554.Capture.JPG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-39-47/5554.Capture.JPG" border="0" /></p>
<p>&nbsp;Enter the Solution Navigator, part of the latest Productivity Power 
Tools Update extension for Visual Studio. It has a great Filter feature 
which allows you to filter your entire solution based on a string. If 
you follow the MVC "convention over configuration" paradigm and name all
 your related files similarly, the Filter will find them for you no 
matter where they are in your solution. Note this works across all the projects in your solution.</p>
<p>The Solution Navigator makes working on a big MVC project much simpler for me and I am now able to group files by function rather than feature.</p>
<p>Let me know what you think; maybe there are better ways to organize files or structure a solution. I tried to to look for ways to automate creating Solution Folders for this specific scenario, but the effort didn't seem worth it. Has anyone come up with something easier?</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
  </channel>
</rss>