75

Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has
Page 2: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Acknowledgements:

Many people have been involved in this project, everyone playing an important role.

A big THANK YOU goes to my good friend Flemming for letting us, and especially me, play around

in his real-world fabric and also in some of his Azure subscriptions. Thanks for all the trips you have

made to your datacenter, just to clean up after my mess and bring things online again. I would also

use this opportunity to apologize for testing the VM Scale Set template that created 20 VMs in

Azure, and for not deleting them in time….

Stanislav Zhelyazkov deserves a big thank you in this book as well, for always being helpful, doing

reviews and testing code on a frequent basis. Thanks for all the value you provide to the

community

Thanks to Aleksandar Nikolic for doing an awesome job with the graphics for our cover! If you ever

plan to retire from the PowerShell community, I think you have a great future as a graphical

designer

Thanks to Robert Reynolds. Ryan Jones and David Armour from the product groups at Microsoft for

their ongoing support. I apologize for all the questions, but I think it was worth it.

And last but not least thanks to my fiancé, Kristine, for letting me sneak into the office to participate

on this book, instead of running after our (four!!) kids.

You are the best!

Kristian Nese

Page 3: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

About the authors

Kristian Nese | @KristianNese CTO at Lumagate Corp and a Microsoft MVP within Cloud Computing & Datacenter. Kristian is a visionary, entrepreneur, cloud-first engineer, and high-performance leader that has successfully demonstrated entrepreneurship and incubation at scale, and been able to reach his goals and objectives. As an experienced, data-driven leader with excellent results from product and program management, business development, leadership and IT engineering, Kristian have proven that he has the capability to deliver creative strategies that have a true impact on the bottom line He is an experienced speaker, delivering both keynotes and highly technical sessions (level 400) on subjects like Azure technologies (IaaS, PaaS), Windows Server, Hyper-V, automation and container/microservices technologies, and often used by Microsoft nationally and globally, both as a speaker and writer. To stay sharp, Kristian spend a lot of his time in the TechNet forums as well, trying to help the community so they can get the most out of the technology. Currently he is a moderator in 13 Microsoft TechNet forums, all from Azure Pack, Azure, Cloud and virtualization. Kristian has also contributed as an author of several books, whitepapers and contributes to open source projects, and you can read his blog at http://kristiannese.blogspot.com/

Flemming Riis | @FlemmingRiis Senior advisor, Subject-Matter Expert and a Microsoft MVP within Cloud Computing & Datacenter Flemming is known as the go-to person for everything around infrastructure and has been around since the early days, covering everything from the metal and up. He runs and operates his own datacenter that he frequently uses for research & development. Flemming is known as an excellent speaker on Microsoft technologies and contributes to the community on several arenas, such as blogging, forums, books and speaking engagements. Flemming blogs at http://flemmingriis.com

Page 4: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Content Acknowledgements:...................................................................................................................................... 2

About the authors ......................................................................................................................................... 3

Kristian Nese | @KristianNese .................................................................................................................. 3

Flemming Riis | @FlemmingRiis ............................................................................................................... 3

Background ................................................................................................................................................... 5

Introduction .................................................................................................................................................. 5

Microsoft Azure ............................................................................................................................................ 8

Microsoft Azure Stack ................................................................................................................................... 9

Cloud Computing and Modern Application Modeling ................................................................................ 13

Step 1 – Service Templates ..................................................................................................................... 14

Step 2 – VM Roles ................................................................................................................................... 15

Step 3 – Azure Resource Manager .......................................................................................................... 16

Summary ................................................................................................................................................. 16

IaaS v2 – Azure Resource Manager API replaces Service Management API .............................................. 17

Consistent Management Layer ................................................................................................................... 20

Azure PowerShell ................................................................................................................................ 20

Azure CLI ............................................................................................................................................. 21

Azure Resource Manager Rest API ...................................................................................................... 21

Azure Portal......................................................................................................................................... 22

Azure Resource Manager Templates .......................................................................................................... 23

Deploying with Azure Resource Manager............................................................................................... 23

Where can we deploy our Azure Resource Manager Templates ........................................................... 24

Explaining the template format .............................................................................................................. 26

Authoring the first Azure Resource Manager Template ......................................................................... 27

Adding parameter file ............................................................................................................................. 36

Visual Studio............................................................................................................................................ 37

PowerShell .............................................................................................................................................. 43

Azure Portal ............................................................................................................................................ 46

Idempotency with Azure Resource Manager ......................................................................................... 50

Resource Explorer ............................................................................................................................... 57

Imperative Deployment with Azure Resource Manager .................................................................... 59

Advanced Azure Resource Manager Templates ..................................................................................... 60

Page 5: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Functions ............................................................................................................................................. 60

Extensions ........................................................................................................................................... 67

Write once, deploy anywhere ............................................................................................................. 72

Closing notes ............................................................................................................................................... 75

Background During the Ignite conference last year, Microsoft announced a new solution which is now in its first Technical Preview: Microsoft Azure Stack. Compared to Windows Azure Pack – which is an add-on to Windows Server and System Center, the Azure Stack is something completely different and not a version 2 Windows Azure Pack. To put it simple, the Azure Stack is the full alignment with Microsoft Azure that will be running in your own datacenter. Azure Stack will be released as part of the 2016 wave, together with Windows Server 2016 and System Center 2016. This book is focusing on Azure Resource Manager and will prepare you on how to create templates, deploy IaaS and PaaS as well as exploring many of its management capabilities, that you can leverage towards both Microsoft Azure and Microsoft Azure Stack This book is subject to change and once we get more information to share, we will try to keep this as updated as possible moving forward.

Introduction It has been a while since we saw the first presentations from Microsoft where they explained their Cloud OS vision with a “one consistent platform”. The Cloud OS vision consists of three clouds, covering the private cloud – owned and operated by the enterprise, a hosted cloud, owned and operated by a partner/service provider, and last but not least – the public cloud with Microsoft Azure. The vision and hybrid cloud spans datacenters and clouds to simplify IT and deliver apps and data to users on any device, anywhere.

Page 6: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

To explain the hybrid approach, Microsoft thinks that regardless of cloud, Windows Server with Hyper-V should be the foundation. In fact, Hyper-V is the hypervisor that powers Azure today. Having the same technology available on-prem through Windows Server gave customers and partners some choices when it came to portability. You can effectively move your VMs VHDs between Hyper-V on-prem and Azure, and vice versa. A typical – and very popular scenario in Azure today is Disaster Recovery through the Azure Site Recovery which gives you a secondary datacenter for recovery, where you can replicate your virtual machines to Azure to ensure business continuity. In addition, System Center is capable of managing fabric, VMs, applications, networks and much more – across clouds. So we could look at System Center as the universal management platform for all of these clouds. However, management through System Center and Hyper-V in Windows Server wasn’t enough to claim a unified consistent platform. This is where Windows Azure Pack came into the picture. Windows Azure Pack – or WAP, gave us a consistent platform through a familiar user interface (tenant portal and API) regardless of cloud. In addition, WAP was built upon a common Service Management API that had its roots from Microsoft Azure.

Page 7: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

From the picture above, starting from the left, we can see that Azure provided a Subscriber Self-Service Portal that let tenants create, delete and manage their resources through the Service Management API. The Service Management API communicated with its underlying Resource Provides that was made available through REST APIs. The platform itself was based on Hyper-V technologies. Moving to on-prem, we got two portals. The exact same Subscriber Self-Service Portal (tenant portal) but also a Provider Portal. This provider portal let the admins manage and expose their Resource Providers through something called Hosting Plans, which could contain one of more services such as Web Sites, VMs and SQL databases. Both the provider portal and the tenant portal was built upon the Service Management API that again communicated with its underlying resource providers through a REST API. Speaking about REST APIs, we have a component as part of System Center which is called Service Provider Foundation (SPF). SPF together with Virtual Machine Manager (VMM) is what gives you the IaaS service model with Azure Pack today. The SPF component is a REST API that effectively enables the IaaS capabilities in Hyper-V and VMM, so that tenants through self-service can create, delete and manage their resources such as Virtual Machines, Virtual Machine Roles and Virtual Networks. When we look at the services that’s available in Azure today, the majority if those aren’t available as part of Windows Azure Pack. The reason behind that is quite understandable, as Microsoft with their “Mobile first, Cloud first” approach will deliver services to Azure before they eventually become available on-prem.

Page 8: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

One of the challenges they have in order to bring Azure services “down to earth” is that the entire stack isn’t consistent to what we have in Azure today, hence the result of the upcoming Microsoft Azure Stack.

Microsoft Azure In 2007, we saw the first pieces of Azure. Back then it was called Windows Azure and the main focus was all around PaaS services and we could leverage Service Bus, Web and Worker Roles as well as blob, queue and table storage and SQL Azure. The journey of Azure has been interesting and we have seen that Microsoft has opened up their platform more and more. Originally it was Windows-only and only Microsoft technologies were supported in the context of PaaS. During the spring in 2011 they announced support for IaaS so that customers could do lift & shift of their virtual machines to Azure, primarily from Hyper-V as the native Hypervisor in Azure. This has also changed and you can now – regardless of preferred platform and technologies take advantage of Azure both from a PaaS and IaaS perspective. Microsoft Azure is a true hyper-scale cloud that spans nearly the entire globe with multiple datacenters in each region where it’s present. The datacenters are completely based on software-defined technologies which has led to a new way of designing, building and operating datacenters. The cloud-scale datacenters provide the core infrastructure and foundational technologies for its 200-plus online services, such as Bing, MSN, Office365, Xbox Live, Skype, OneDriv and of course Microsoft Azure. The infrastructure is comprised of a large global portfolio of more than 100 datacenters, 1 million servers, content distribution networks, edge computing nodes and fiber optic networks. This portfolio is built and managed by a team of experts working 24x7x365 to support services for more than 1 billion customers. With these numbers in mind, it is a good opportunity to remind you of some of the key learnings here. Since Microsoft invested heavily in their own datacenters and cloud offerings, they have constantly been taking their learnings and made them available for customers who want to run and operate their own datacenters, using the same technical foundation. The products that Microsoft ships are now becoming more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has a native hybrid functionality so you can plug into the cloud and combine the best of both worlds. From a licensing perspective, Azure has also become a lot more mature and there’s now good benefits for customers and partners through the Cloud Service Provider (CSP) program, where partners can host and run workload and value added services in Azure and manage the entire customer relationship directly, using Azure as their backbone for their services and offerings. There has of course been some breaking changes in Azure during its childhood and in the time of writing we are witnessing a transformation from “classic” management portal and APIs towards the new world – which is based on Azure Resource Manager that also is the main focus for this book and is aiming to give you the best possible start to interact with your clouds and services regardless of using Azure or Azure Stack.

Page 9: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Microsoft Azure Stack With the announcement of Microsoft Azure Stack, Microsoft is very clear that they will now drive a complete consistency across clouds.

If we go back a bit to Azure Pack, we saw that the Service Management APIs was common to the ones we had in Azure, but they weren’t consistent nor identical. You could easily see this if you have ever played around with the Azure Powershell Module as Windows Azure Pack had its own commands with a “WAPack” prefix, such as “Get-WAPackVM”. The actual level of interaction was however the same, so you could access the Azure Pack endpoint (Tenant Public API) in the exact same way as you would interact with Azure Tenant Public API. For the portal experience, we got 2 portals. One portal for the Service Provider/Cloud Admin – where the admin could configure the underlying resource providers, create hosting plans and define settings and quotas through the admin API. These hosting plans were made available to the tenants in the

Page 10: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

tenant portal with subscriptions, where that portal – was accessing the resources through the tenant API. The underlying resource providers were different REST APIs that could contain several different resource types. Take the VM Cloud resource provider for example, that is a combination of System Center Virtual Machine Manager and System Center Service Provider Foundation. Let us stop here as well, and reflect of what we have just read.

1) So far, we have had a common set of APIs between Azure Pack and Azure 2) On-prem, we are relying on System Center in order to bring IaaS into Azure Pack

With cloud consistency in mind, it is about time to point out that to move forward, we have to get the exact same APIs on-prem as we have in Microsoft Azure. Second, we all know that there’s no System Center components that are managing the Hyper-Scale cloud in Azure. Let us take a closer look at the architecture of Microsoft Azure Stack

Page 11: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Starting at the top, we can see that we have the same – consistent browser experience. The user facing services consists of hubs, a portal shell site and RP extensions for both admins (service provider) and tenant. This shows that we won’t have two different portals as we have in Azure Pack today, but things are differentiated through the extensions and what level of access you have. These components are all living on top of Azure Resource Manager, which is where all the fun and consistency for real is born. Previously in Azure, we were accessing the Service Management API when interacting with our cloud services. Now, this has changed and Azure Resource Manager is the new, consistent and powerful API that will be managing all the underlying resource providers, regardless of clouds. Azure Resource Manager introduces an entirely new way of thinking about your cloud resources. A challenge with both Azure Pack and the former Azure portal was that once we had several components that made up an application, it was really hard to manage the life-cycle of it. This has drastically changed with ARM, where we can now imagine a complex service, such as a SharePoint farm – containing many different tiers, instances, scripts, and applications. With ARM, we can use a template that will create a resource group (a logical group that will let you control RBAC, life-cycle, policies, billing etc on the entire group of resources, but you can also specify these at a lower level on the resources itself) with the resources you need to support the service. Also, the ARM itself is idempotent, which means it has a declarative approach. You can already start to imagine how powerful this will be. In the context of the architecture of Azure Stack as we are looking at right now, this means we can:

1) Create an Azure Resource Manager Template (.json) a. Deploy the template to Microsoft Azure

or/and b. Deploy the template to Microsoft Azure Stack

Page 12: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Now, let us explain the architecture a bit further. Under the Azure Resource Manager, we will have several Service Resource Providers as well as Resource Providers. The Service Resource Providers consists of Authorization – which is where all the RBAC settings and policies are living. All the services will also share the same Gallery now, instead of having separate galleries for Web, VMs etc as we have in Azure Pack today. Also, all the events, monitoring and usage related settings are living in these core management resource providers. One of the benefits here is that third parties can now plug in their resource providers and harness the existing architecture of these core RPs. Think of the Service Resource Providers as the requirement for building third party RPs. Further, we have currently Compute, Network and Storage as Resource Providers – which are all based on cloud-inspired infrastructure. If we compare this with what we already have in Azure Pack today through our VM Cloud Resource Provider, we have all of this through a single resource provider (VMM/SPF) that basically provides us with everything we need to deliver IaaS. As we wrote earlier: there isn’t any System Center components that runs or operates in Microsoft Azure today, hence we won’t find System Center in any of the Service Resource Providers for Compute, Network or Storage as part of the provisioning path. So why do we have 3 different resource providers in Azure Stack for compute, network and storage, when we could potentially have everything from the same RP? In order to leverage the beauty of a cloud, we need the opportunity to have a loosely coupled infrastructure – where the resources and different units can scale separately and independent of each other. Also note that Microsoft.Compute, Microsoft.Network and Microsoft.Storage RPs are literally powering many of the other Resource Providers you see in Azure today, such as Batch, Service Fabric and other PaaS services. Here’s an example of how you can take advantage of this, and what we will do in this book:

1) You want to deploy an advanced application to an Azure/Azure Stack cloud, so you create a base template containing the common artifacts, such as image, OS settings etc

2) Further, you create a separate template for the NIC settings and the storage settings 3) As part of the deployment, you create references and eventually some “depends-on” between

these templates so that everything will be deployed within the same Azure Resource Group (that shares the same common life-cycle, billing, RBAC etc)

4) Next, you might want to change – or eventually replace some of the components in this resource group. As an example, let us say that you put some effort into the NIC configuration. You can then delete the VM (from the Compute RP) itself, but keep the NIC (in the Network RP).

This gives us much more flexibility compared to what we are used to. Moving forward

Page 13: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

So, Microsoft is for real bringing Azure services to your datacenters now as part of the 2016 wave that will be shipped this year. It is an entirely new product for your datacenter – which is a cloud-optimized application platform, using Azure-based compute, network and storage services

Cloud Computing and Modern Application Modeling The way we are deploying our applications and infrastructure has changed quite rapidly during the last couple of years, as a result of cloud computing. If we think about how we have traditionally been authoring, designing and deploying both applications and infrastructure in the past, we think it’s fair to say that it has always involved different tools, APIs and workflows for each layer and component that you were responsible to stitch together on your own post deployment. The entire process was relatively manual and all the tools took for granted that the following was in place:

1) You had access to the computer/service over the network 2) You had the required credentials in order to deploy, manage and service any application on any

machine

Going back to the cloud, this would obviously never work as the underlying fabric won’t have access into any of the virtual machines – and vice versa. There’s an abstraction layer here which gives us a lot of flexibility when it comes to service offerings, but at the same time gives us a lot of complexity.

Page 14: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

The Infrastructure –as a Service offering from the definition of cloud computing shows clearly where the responsibility of the cloud provider ends. As we can see, the blue boxes show that the cloud provider is responsible for the entire fabric – including the hypervisor itself. Then, the tenant will have access to the virtual machines they deploy into this cloud as well as their storage and networking. What the tenant decides to do within these virtual machines is completely their own responsibility, as the responsibility for the cloud provider stops at the hypervisor layer. In a world where more and more of the datacenter components becomes software-defined, it is important to remember that the networks that are being used here are also virtualized. In short, that means we aren’t connected at the network layer from a fabric standpoint into the tenants. Microsoft have tried to solve this over time and we will now cover the 3 steps to provide you with some more context. The first attempt we saw was with System Center 2012 where we got Service Templates and Clouds as part of Virtual Machine Manager.

Step 1 – Service Templates The concept of a cloud in VMM was an abstraction based on the underlying physical resources, such as compute, storage and network. Users – through self-service in either the VMM console or App Controller, could log on and get access to their assigned cloud that contained resources, quotas and more. From a VMM library share associated with this cloud, they could deploy either VMs based on VM Templates or services based on Service Templates. The latter is interesting because this gave the provider the opportunity to model services that could be a multi-tier application consisting of a backend-tier (SQL server), middle-tier (Server App-V) and a frontend-tier (web app). The true difference between a VM template and a Service Template was that the Service Template would leverage the VMM agent within the guests post deployment, in order to deploy and configure server roles, features and custom applications, where VM templates stops at OS deployment.

At that time, we didn’t have any Azure Pack on-prem, nor network virtualization. So the self-service experience through a web portal was based on App Controller and the templates were based on XML, and the tenant would have access directly to a logical network defined in VMM.

Page 15: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

With Windows Server 2012 R2 and System Center 2012 R2 we got new enhancements related to IaaS in the private cloud.

Step 2 – VM Roles As of the beginning of alignment with Azure, we got Windows Azure Pack as described earlier. This introduced us for a new way to do application modeling and delivery within the IaaS clouds. At the same time, we were leveraging the concept of Clouds in VMM with Azure Pack too, presented as a REST API with Service Provider Foundation. Instead of using Service Templates in VMM, we could now start to use VM Roles that gave an extension to the virtual machines. Although very similar to the concept of Service Template, but also very different.

The significant changes were that the VM Roles were based on JSON, and the extension (VMM) we had was also available in Microsoft Azure. This meant that we could deploy the same extensions to Azure IaaS VMs as we could do to a WAP IaaS VM during deployment. However, also note the drawback that the VM Roles were only single-nodes and IaaS only. We could author the VM Roles using a tool available on codeplex (VM Role Authoring tool) and create a resource definition file that we imported into Azure Pack, and the resource extension file to VMM if we wanted to do anything beyond the normal OS customization. As a side note, we have seen many people become quite creative with VM Roles since the release of Azure Pack. The underlying platform has also started to support the concept a lot more, letting us threat these VM Roles more like normal virtual machines when it comes to life-cycle management and servicing. In addition, Azure Pack can be integrated with Service Management Automation (SMA) which again can be linked to certain actions performed by a tenant in the tenant portal. One typical action here is the creation of a VM Role. This can again link an automated workflow as part of a SMA Runbook and perform different sets of actions as part of this process. Also, we see that more and more organizations are leveraging Desired State Configuration to do the in-guest deployment and configuration instead of imperative Powershell scripts.

Page 16: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

In short: we can use this open platform to create, author and deliver basically everything we want with some engineering effort. For more information and an example of a use case, follow this URL: http://kristiannese.blogspot.com/2015/03/application-modeling-with-vm-roles-dsc.html

Step 3 – Azure Resource Manager As a last step (in the time of writing this), we have reached Azure Resource Manager (ARM). With the Microsoft Azure Stack, we will get ARM on-prem as well. But right now, Azure Resource Manager is publicly available in Microsoft Azure and also as part of the Azure preview portal. Azure Resource Manager is the new API – de facto control plane for the Microsoft Cloud and everything can be based on templates. ARM itself is idempotent with its declarative approach and covers IaaS, PaaS and supports multi-node deployments. The template language is JSON and will enable you to easily leverage multiple service resource providers at once, such as compute, network and storage, involving all kinds of components like virtual machines, virtual networks, storage accounts, load balancers, public IP addresses, web sites, SQL databases – and basically everything that’s available through the Azure Resource Manager API. Even VM Extensions which is a resource type that belongs to the compute resource provider can be handled by ARM as part of the template, so that the investment you have made in DSC today, either as part of a VM Role development or any other approach, has been well spent and can continue to serve in this context too.

Summary With the evolvement of cloud computing, the tools and technologies involved for doing deployment, configuration and management of applications and infrastructure has changed drastically. Going from a GUI based experience with limited options, we are now pushing the imagination to its limits instead by using the new ARM API, while entering the era of DevOps.

Page 17: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

As we move forward we will have code for basically everything we do and everything will be software-defined. This makes it possible to create reusable building blocks and become much more agile.

IaaS v2 – Azure Resource Manager API replaces Service Management

API Compute, network and storage capabilities are all within Azure Resource Manager API and will fundamentally change – and simplify the design, deployment and management of your complex applications running in the Microsoft Clouds. One thing to point out is that Azure Resource Manager is JSON-based compared to the Service Management API which was based on XML. With the new control plane in Azure Resource Manager, there are some conceptual changes that we need to cover before we proceed. This is important for you to know, especially if you are already very familiar with the previous Azure Portal and its Service Management API. Availability Sets Service Management API In the previous portal with the service management APIs, it was recommended to create availability sets (with the same name) and associate with the virtual machines. The maximum of fault domains was 2. Azure Resource Manager API With ARM, availability sets are now a resource type that is managed by the Microsoft.Compute resource provider. If you require HA for your VMs, they must be included in the availability set. The maximum fault domains in ARM is 3. Cloud Service for Virtual Machines Service Management API Whenever you created a virtual machine through the service management API, it required a Cloud Service that served as a container for the virtual machine(s) and provided availability from the platform as well as load balancing. Azure Resource Manager API With ARM, we don’t have Cloud Service anymore as a required object for virtual machines. Load Balancing Service Management API Load Balancing was provided as part of the creation of a Cloud Service, serving its virtual machines within this container. Azure Resource Manager API Through the Microsoft.Network resource provider, we now have Load Balancer as a resource type. The Load Balancer can be internal or external and the vNIC of the VM will be referencing the Load Balancer.

Page 18: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Affinity Groups Service Management API Whenever you wanted to create a virtual network, it also required an Affinity Group. Azure Resource Manager API Affinity Groups are no longer required, and to simplify, it doesn’t exist in the APIs exposed through ARM. Virtual IP Address Service Management API The Virtual IP address (VIP) is associated with the implicit load balancer, and Cloud Services would get a default VIP once a VM was added to it. Azure Resource Manager API As with Load Balancers, a Public IP is a resource type exposed by the Microsoft.Network resource provider. A Public IP can be reserved or dynamic. The dynamic IPs can be assigned to a Load Balancer, and the IPs can be secured using Security Groups. Reserved IP Address Service Management API An IP had to be associated with a Cloud Service in order to be reserved. Azure Resource Manager API Public IP addresses can be created in something called “static mode” which effectively is the same as a reserved IP. At the time of writing this, a static public IP can only be assigned to a Load Balancer. DNS Name Service Management API During creation of a Cloud Service, an implicit globally unique name would be assigned, like “somecoffee.cloudapp.net” Azure Resource Manager API With ARM, the DNS names are optional parameters that can be specified on a Public IP address resource in this format: <domain>.<region>.cloudapp.azure.com Network Interface Service Management API The Virtual Machine itself was the container for the primary and eventually - the secondary Network Interface. Azure Resource Manager API In ARM, a Network Interface is a resource that is exposed by the Microsoft.Network resource provider, and the lifecycle is no longer tied to a virtual machine.

Page 19: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Endpoints Service Management API Any Endpoints had to be configured at the VM level. Azure Resource Manger API Load Balancers can now be configured with Inbound NAT Rules.

Page 20: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Consistent Management Layer You might have some preferences when it comes to how you would like to interact with your services in the cloud. What’s good here is that Microsoft hasn’t excluded any specific interface, so you can choose between state-of-the-art PowerShell modules, x platform interfaces and even a GUI through the Azure Management Portal – if that’s what you prefer. With Azure Resource Manager, we will have a consistent API and a consistent management layer. In the following picture, you can see that the Azure Portal, the command line and also Visual Studio are consuming the ARM API – which again aggregates the underlying service Resource Providers – and resource providers through the provider Rest points.

Today, we have the following interfaces available:

Azure PowerShell The Azure PowerShell module has been around for some years now, and has served us very well. However, some changes were introduced as part of Azure Resource Manager and we now have an entirely new PowerShell Module (AzureRM) that let us interact with the ARM Rest API. Beginning in version 1.0.x and greater, the Azure PowerShell Module can easily be installed directly from the PowerShell gallery, and if you are running Windows 10 – or has Windows Management Framework 5.x installed, you can simply run: Find-Module AzureRM* | Install-Module Install-Module AzureRM installs a bootstrapping module for the AzureRM modules, which contains cmdlets to help update, uninstall and import the AzureRM modules in a safe and consistent way. The

Page 21: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

AzureRM Module contains a list of modules and the version range required to ensure no breaking changes will be introduced for the major version of AzureRM. Here is an example on how to create a new Resource Group using the AzureRM module:

Whenever you create or do any actions outside of the portal, it is specifically logged in the events by ARM.

Azure CLI For Mac, Linux and also Windows, you can use Azure CLI which provides a set of open source shell-based commands. The CLI is written in JavaScript and implemented using the Azure SDK for Node under the Apache 2.0 license. The project repository is located at https://github.com/azure/azure-xplat-cli

Azure Resource Manager Rest API You can manage your resources through ARM and its REST APIs directly. We will cover the structure a bit more in detail later, but here is an example on how to create a new Resource Group directly, using the REST API: Method = PUT Request URI = https://management.azure.com/subscriptions/{subscription-id}/resourcegroups/{resource-group-name}?api-version={api-version}

Page 22: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

JSON =

If you want to explore the APIs further, please visit https://resources.azure.com

Azure Portal The Azure Management Portal is accessible on https://portal.azure.com The portal and its designs and functions reflects what we have already stated several times in this document, that ARM is in charge of everything and that every resource is associated with a Resource Group. Here is an example on how a new VM deployment will map to a Resource Group that can either be an existing one or a new one:

{ "location": "West Europe", "tags": { "tagnameexample1": "tagvalueexample1" }

}

Page 23: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

We should now have a basic understanding on how we can interact with Azure Resource Manager.

Azure Resource Manager Templates We are just about to start with the action! So far, we have been looking at Azure Resource Manager from a broader perspective and tried to explain the capabilities and how it fits into the story around the Microsoft Cloud. Now we want to dive deeper into the ARM capabilities and explore the APIs, interfaces and perhaps most important – how to author and deploy resources with templates. Throughout this document, we will be using templates and resources that are located on the following GitHub repo: https://github.com/krnese/AzureDeploy In this section of the book, we will cover many different functions, examples and practices around ARM templates that will be pointed out whenever it is applicable and relevant given the topic we are discussing. So I encourage you to read through the entire chapter where you hopefully will find what you are looking for.

Deploying with Azure Resource Manager Everything you can deploy with ARM is template-driven. This means you can create a template and bootstrap your environments, applications and resources in the cloud. As you will see, we can also parameterize the templates and make it usable for others as well. The template model itself is declarative and idempotent, which means you can define the exact state of your template and deploy it over and over again. This will ensure that the resources are in the correct state – and also simplify the update process of your resources by simply deploying the same template again only with different values. That means that if the resources are already created, they will be updated the way you have described in the template. If they aren’t created, the deployment process will create them. Additionally, Azure Resource Manager is natively multi-service (both IaaS and PaaS) and multi-region. Instead of creating individual resources and later stitch them together, we can create a template that deploys a virtual machine, storage, network resources and also application payload through VM extensions. Everything in a single operation that is executed in parallel. Whenever you create a resource in Azure, it will be associated with a Resource Group – which is a logic container for all of its resources, such as virtual machines, networks and storage accounts. When you deploy a multi-node application to Azure using a template for Azure Resource Manager, these resources will belong to the same resource group. You can later add – or remove resources to the resource group and have quite a flexible way of doing life-cycle management. Life-cycle management is key, and you are now able to structure this in your own whenever and wherever it makes sense. An example of how you can use the concept of resource groups is when you deploy an application where all of its resources has a common life-cycle management. Another example is when you want to define management within your organization, and put all IaaS VMs running SQL server into the same resource group and grant the SQL SMEs access at the group level.

Page 24: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

With access we mean that Azure Resource Manager integrates natively with RBAC through the authorization Service Resource Provider, so that you can define role based access for you and your team with the granular control you demand. In addition, Azure Resource Manager supports tagging of resources and resource groups for simplified management, chargeback and billing purposes. Each resource supports up to 15 tags assigned. From a security point of view, you should also note that Azure Resource Manager supports Policies and that you can leverage Key Vault as part of your templates. With the use of policies, ARM let you control access through custom policies you can prevent users in your organization from breaking conventions that are needed to manage your organization’s resources. The policy definitions describes the actions or resources that are denied, and you can assign those policy definitions at the desired scope, like on the subscription level, Resource Group or even an individual resource. When you need to pass a secure value (like a password) as a parameter during deployment of an Azure Resource Manager template, you can store that value as a secret in an Azure Key Vault and reference the value in the templates. The secret is never exposed as you only reference to that secret in the template itself. You are in charge from the very beginning and can also specify which users or service principals can access the secret.

Where can we deploy our Azure Resource Manager Templates Microsoft Azure spans multiple regions and offers a rich set of premium cloud services. These offerings are powered by many Resource Providers. It is important to point out that some Azure regions might have offerings and certain Resource Providers that aren’t available in all the other regions at a given time. This is very often the case when you are seeing new services that are marked as “Preview” and only available in certain regions before becoming generally available. For you to find out where to deploy – and also which API version that’s supported for each Resource Provider in a given region, the following PowerShell cmdlets can be helpful once you start authoring your templates The first example shows that we are checking the available regions for Microsoft.Compute and the resource types that’s available: Get-AzureRmResourceProvider – ProviderNamespace Microsoft.Compute | select locations, ProviderNamespace, ResourceTypes

Locations ProviderNamespace ResourceTypes --------- ----------------- ------------- {East US, East US 2, West US, Central US...} Microsoft.Compute {availabilitySets} {East US, East US 2, West US, Central US...} Microsoft.Compute {virtualMachines} {East US, East US 2, West US, Central US...} Microsoft.Compute {virtualMachines/extensions} {East US, East US 2, West US, Central US...} Microsoft.Compute {virtualMachines/diagnosticSettings} {East US, East US 2, West US, Central US...} Microsoft.Compute {virtualMachines/metricDefinitions} {East US, East US 2, West US, Central US...} Microsoft.Compute {virtualMachineScaleSets} {East US, East US 2, West US, Central US...} Microsoft.Compute {virtualMachineScaleSets/extensions} {East US, East US 2, West US, Central US...} Microsoft.Compute {virtualMachineScaleSets/virtualMachines}

Page 25: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

{East US, East US 2, West US, Central US...} Microsoft.Compute {virtualMachineScaleSets/networkInterfaces} {East US, East US 2, West US, Central US...} Microsoft.Compute {virtualMachineScaleSets/virtualMachines/networkInterfaces} {} Microsoft.Compute {locations} {East US, East US 2, West US, Central US...} Microsoft.Compute {locations/operations} {East US, East US 2, West US, Central US...} Microsoft.Compute {locations/vmSizes} {East US, East US 2, West US, Central US...} Microsoft.Compute {locations/usages} {East US, East US 2, West US, Central US...} Microsoft.Compute {locations/publishers} {East US, East US 2, West US, Central US...} Microsoft.Compute {operations}

Next, we can drill further into the Microsoft.Compute Resource Provider to verify which version(s) is supported across available regions (Get-AzureRmResourceProvider -ProviderNamespace Microsoft.Compute).ResourceTypes ResourceTypeName : availabilitySets Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : virtualMachines Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : virtualMachines/extensions Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : virtualMachines/diagnosticSettings Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2014-04-01} ResourceTypeName : virtualMachines/metricDefinitions Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2014-04-01} ResourceTypeName : virtualMachineScaleSets Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : virtualMachineScaleSets/extensions Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : virtualMachineScaleSets/virtualMachines Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : virtualMachineScaleSets/networkInterfaces Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : virtualMachineScaleSets/virtualMachines/networkInterfaces Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : locations Locations : {} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : locations/operations Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : locations/vmSizes Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : locations/usages Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview}

Page 26: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

ResourceTypeName : locations/publishers Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview} ResourceTypeName : operations Locations : {East US, East US 2, West US, Central US...} ApiVersions : {2015-06-15, 2015-05-01-preview}

Use a similar approach when working with other Resource Providers and Resource Types, so you won’t get an error thrown at you during deployment. Remember that ARM is idempotent, so in case you receive an error that a certain Resource Provider or API version isn’t available/supported in your region, simply update the template, save and run the template all over again.

Explaining the template format As an example to show how things are deployed and managed through templates with ARM, we will create a new ARM template that will provision a storage account and later extend it with other resoruces while describing the template format and how it is structured. The template language is JSON – which is an industry standard and has become more and more common to use when you want to declarative describe how your cloud services should look like. When starting with a blank template in Visual Studio, it will look similar to this:

$schema is required and specifies the location of the JSON schema file that describes the definition of the template language. contentVersion is required too, and is the version of the template that helps you to ensure that the resources you are deploying are the correct ones. parameters isn’t required, but recommended in order to gain more flexibility for customized deployments. Parameters are used throughout the template to set values for resources. You can also specify a default value – and allowed values. variables isn’t required but contain values that are used as JSON fragments in the template to simplify template language expressions. This is also where you can “hard code” things in your template, such as extension name or other properties that should not be exposed to the users as input parameters.

{ "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { }, "variables": { }, "resources": [ ], "outputs": { } }

Page 27: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

resources is required and will let you describe the resource types that are deployed or updated as part of the template in a resource group outputs isn’t required but defines the information that is returned after deployment.

Authoring the first Azure Resource Manager Template Over the next pages, we will show the different pieces of an ARM template, covering the structure we have just described. This template will gather input parameters in order to create a new storage account in Azure, where you will be able to specify location, storage account name and storage type. If you have Visual Studio installed with the latest Azure SDK’s, we encourage you to follow the examples described throughout this book. Simply start Visual Studio and create a new JSON file. You can copy and paste the examples from this book directly into your JSON file.

Page 28: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

You can start by copying the example below into your editor and follow the rest of the examples.

Creating a basic Storage Account using ARM Template: { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "resources": [ { "apiVersion": "2015-06-15", "location": "West Europe", "name": "knstorage10", "type": "Microsoft.Storage/storageAccounts", "properties": { "accountType": "Standard_LRS" } } ], "outputs": { } } The example here will basically instantiate a new storage account in either a new or an existing Resource Group. As you can see, we are currently not taking any input parameters or using variables, so the entire template can be considered as hard coded, and really not much useful for others to use.

Page 29: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Continuing to use this template as an example, we will expand it to make it reusable and also add more resources and covers some of the template language expressions you will find handy. Let us have a look at how we turn this into a reusable template. Parameters is not a requirement, but we really think it should be present so that you can “build once, deploy anywhere”. Parameters that are declared can take user inputs and use this to define variables and resources. We will add some parameters so that the user itself is able to define the storage account name, storage type and also add description to the parameter so that “anyone” can understand what they are about to do. We will also specify some default parameters in case the user won’t provide any input. This to ensure that the template deployment can be executed without any interaction. With the use of “allowedValues”, we can also ensure that the user is not trying to come up with something fancy, or something we simply know either doesn’t exist or will work. In "parameters": { "storageaccountname": { "type": "string", "defaultValue": "knstorage11", "allowedValues": [ "knstorage11", "knstorage12" ], "metadata": { "Description": "Specify Storage Account name" } }, "storagetype": { "type": "string", "defaultValue": "Standard_LRS", "allowedValues": [ "Standard_LRS", "Standard_GRS" ], "metadata": { "Description": "Specify Storage Account type" } }

If you look at the template example we started with in this guide, you can also see that the Storage Account resource has some other properties as well, such as API version and Location. If we first start with the location, you must be aware that Azure Resource Manager is multi-region aware and also multi-service aware, meaning you can have many different resources declared in one template, deploying them to different Azure regions. In this example, and also which is quite common is to follow the region where the Resource Group is created. This means we can either define that on the location property itself using "[resourceGroup().location]" on the location property, or we can put that in a variable and reference that variable whenever needed. Variables contains values that is either specified by the template author directly or/and based on values provided from the input parameters. We will now add some variables to the template that declares the API versions we will use, and also the location where we want to deploy the resources.

Page 30: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Now, we must update the resource we have in our template to reflect the changes we made.

{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "storageaccountname": { "type": "string", "defaultValue": "knstorage11", "allowedValues": [ "knstorage11", "knstorage12" ], "metadata": { "Description": "Specify Storage Account name" } }, "storagetype": { "type": "string", "defaultValue": "Standard_LRS", "allowedValues": [ "Standard_LRS", "Standard_GRS" ], "metadata": { "Description": "Specify Storage Account type" } } }, "variables": { "location": "[ResourceGroup().location]" "apiVersions": { "storage": { "storageAccounts": "2015-06-15" }

Page 31: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

If we now would do a deployment of this template, it would hopefully be deployed successfully. The reason why “hopefully” is used here, is because the storage account name has to be completely unique in Azure, and also doesn’t take any fancy input parameters.

{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "storageaccountname": { "type": "string", "defaultValue": "knstorage11", "allowedValues": [ "knstorage11", "knstorage12" ], "metadata": { "Description": "Specify Storage Account name" } }, "storagetype": { "type": "string", "defaultValue": "Standard_LRS", "allowedValues": [ "Standard_LRS", "Standard_GRS" ], "metadata": { "Description": "Specify Storage Account type" } } }, "variables": { "location": "[ResourceGroup().location]" "apiVersions": { "storage": { "storageAccounts": "2015-06-15" } } }, "resources": [ { "apiVersion": "[variables('apiVersions').storage.storageAccounts]", "location": "[variables('location')]", "name": "[parameters('storageaccountname')]", "type": "Microsoft.Storage/storageAccounts", "properties": { "accountType": "[parameters('storagetype')]" } } ], "outputs": { } }

Page 32: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

This is where we will use some of the more advance template functions we have. For us to generate a unique storage account name every time we want to create a storage account using this template, we will define a new variable that will look like this:

“storagename” is the variable, and within that variable we are using several functions. The ‘toLower’ function is used to specifically convert the string input to lower case. This is because storage account names in Azure doesn’t support upper case in this context. So if a user types in a value like “MyStorage01”, this function will convert that to “mystorage01”. Further, we are using ‘concat’ which will let us combine multiple string values. As the example above shows, we will combine the value of the parameter ‘storageaccountname’ with another function – ‘uniqueString’ – that generates a new unique string for us followed by the ID of the Resource Group being used. For us to reflect this change in the resource section in the template, we need to change the location from referencing to the parameter to use the newly created variable instead: "resources": [ { "apiVersion": "[variables('apiVersions').storage.storageAccounts]", "location": "[variables('location')]", "name": "[variables('storagename')]", "type": "Microsoft.Storage/storageAccounts", "properties": { "accountType": "[parameters('storagetype')]" } } The template has now been modified to reflect all these changes, and looks like this:

"storagename": "[toLower(concat(parameters('storageaccountname'), uniqueString(resourceGroup().id)))]"

Page 33: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

FYI: We won’t cover all of the functions/expressions right now, but be aware that these will evolve over time and you can start to leverage them when the schema is updated with more references.

{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "storageaccountname": { "type": "string", "defaultValue": "knstorage11", "allowedValues": [ "knstorage11", "knstorage12" ], "metadata": { "Description": "Specify Storage Account name" } }, "storagetype": { "type": "string", "defaultValue": "Standard_LRS", "allowedValues": [ "Standard_LRS", "Standard_GRS" ], "metadata": { "Description": "Specify Storage Account type" } } }, "variables": { "storagename": "[toLower(concat(parameters('storageaccountname'), uniqueString(resourceGroup().id)))]", "location": "[ResourceGroup().location]", "apiVersions": { "storage": { "storageAccounts": "2015-06-15" } } }, "resources": [ { "apiVersion": "[variables('apiVersions').storage.storageAccounts]", "location": "[variables('location')]", "name": "[variables('storagename')]", "type": "Microsoft.Storage/storageAccounts", "properties": { "accountType": "[parameters('storagetype')]" } } ], "outputs": { } }

Page 34: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

From the schema: Expressions are enclosed in [] and must start with a function of concat(), parameters(), variables(), reference(), resourceId(), resourceGroup(), subscription(), listKeys(), listPackage(), base64(), providers(), copyIndex(), padLeft(), replace(), toLower(), toUpper(), length(), split(), add(), sub(), mul(), div(), mod(), string(), int(), uniqueString()"

The GitHub repository mentioned earlier in this book contains many examples that touches several of these functions. We recommend you to find your own use cases for when to use them during template authoring. Before completing the template, we want to add some more input parameters and variables so that we also can provision a new virtual network in Azure using the same template. Have a look at the example below to see the what’s been added: { "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "storageaccountname": { "type": "string", "defaultValue": "knstorage11", "allowedValues": [ "knstorage11", "knstorage12" ], "metadata": { "Description": "Specify Storage Account name" } }, "storagetype": { "type": "string", "defaultValue": "Standard_LRS", "allowedValues": [ "Standard_LRS", "Standard_GRS" ], "metadata": { "Description": "Specify Storage Account type" } }, "vnetName": { "type": "string", "defaultValue": "knvnet10", "metadata": { "Description": "Specify the vNet name" } }, "addressPrefix": { "type": "string", "defaultvalue": "192.168.0.0/16", "metadata": { "Description": "Specify address prefix for vNet" } }, "subnetname": { "type": "string", "defaultValue": "subnet-1", "metadata": { "Description": "Specify the subnet name" }

Page 35: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

}, "subnetPrefix": { "type": "string", "defaultValue": "192.168.0.0/24", "metadata": { "Description": "Specify address prefix for subnet" } } }, "variables": { ": "[toLower(concat(parameters('storageaccountname'), uniqueString(resourceGroup().id)))]", "location": "[ResourceGroup().location]", "apiVersions": { "storage": { "storageAccounts": "2015-06-15" }, "network": { "virtualnetworks": "2015-06-15" } } }, "resources": [ { "apiVersion": "[variables('apiVersions').storage.storageAccounts]", "location": "[variables('location')]", "name": "[variables('storagename')]", "type": "Microsoft.Storage/storageAccounts", "properties": { "accountType": "[parameters('storagetype')]" } }, { "apiVersion": "[variables('apiVersions').network.virtualnetworks]", "location": "[variables('location')]", "name": "[parameters('vnetname')]", "type": "Microsoft.Network/virtualnetworks", "properties": { "addressSpace": { "addressPrefixes": [ "[parameters('addressprefix')]" ] }, "subnets": [ { "name": "[parameters('subnetname')]", "properties": { "addressPrefix": "[parameters('subnetprefix')]" } } ] } } ], "outputs": { } }

Save this template to a directory on your computer as azuredeploy.json

Page 36: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Adding parameter file We have almost finalized our first reusable ARM template. But before we do so, we will also create a parameter file we can use with the template itself. So in case you want to modify the parameters for different environments, and simply reference that file during deployment with PowerShell, this step is required. Here’s how the azuredeploy.parameters.json file looks like:

Save this file to your computer as azuredeploy.parameters.json We have now successfully authored the first Azure Resource Manager template, and we will explore several deployments options – as well as using other templates later in this book.

{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", "contentVersion": "1.0.0.0", "parameters": { "storageaccountname": { "value": "knstorage11" }, "storagetype": { "value": "Standard_LRS" }, "vnetName": { "value": "knvnet10" }, "addressPrefix": { "value": "192.168.0.0/16" }, "subnetname": { "value": "subnet-1" }, "subnetPrefix": { "value": "192.168.0.0/24" } } }

Page 37: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Visual Studio So far we have authored a new template in Visual Studio from scratch. However, you can benefit from an out of the box experience by leveraging some existing ARM templates integrated in Visual Studio when the Azure SDK has been installed. This guide will walk you through an example where you create your first ARM template using this approach with Visual Studio and ideally ends up deploying it to a new Resource Group. You should use a supported version of Visual Studio, such as 2012, 2013 or 2015. In this guide, we will be using the 2015 version. In addition, you must install the latest Azure SDK (currently, the version is 2.8 and you can grab the bits from here: https://azure.microsoft.com/en-us/blog/announcing-the-azure-sdk-2-8-for-net/ ) Keep in mind that there is different installer for the SDK for every VS version. With the SDK installed, you can create and edit ARM templates that contains VMs, Network topologies and storage resources – and much more through an intelligent JSON editor. It’s also integrated with PowerShell for the actual deployment to a Resource Group. Obviously, you would need an Azure subscription too where you can deploy to and test your templates. When you launch Visual Studio, you can navigate to File New Project and the ‘New Project’ dialogue box will appear.

Expand Templates, Visual C# and select Cloud. You should now be able to see Azure Resource Group that can will be deployed by Azure Resource Manager.

Page 38: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Assign a name for the project and click Ok. Once you have hit Ok, a new box will appear, listing all the available ARM templates for you to work on.

These templates can be used as a foundation where you can easily extend and modify the content. Select one template and proceed. On the left hand side, you can see that Visual Studio recognizes the JSON syntax and lists the different parameters, variables and resources within this template.

Page 39: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

This is very useful – especially when you are constructing more complex templates and need to keep track of the artifacts. One nice feature with Visual Studio and the ARM tools is that we can easily add more resources directly in this view, without having to write all the code and know all the APIs. By right-clicking on the resources tab, we can click “Add new resource” and will get a list of available resources. Also note that if you want to add a resource that would (by its nature and definition) have a dependency on another resource, you must reference that too or create it if you haven’t already. In our example, you can see that the virtual machine resource would require both storage and networking, and only storage is missing since we are actively working in our networking ARM template.

Page 40: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

When you are satisfied with your template and want to deploy it to an Azure subscription, you can either do it directly from Visual Studio, or through PowerShell. If we look at the right-hand side of the console, we can see that we have a template file (ccnetwork.json) – which is the actual .JSON template for ARM, the one we are working with. We have a param.json file (ccnetwork.param.json) which contains some predefined input parameters, so that we can separate the configuration data from the environment data. Sounds familiar? We also have a Deploy-AzureResourceGroup.ps1 PowerShell script that will deploy the template to its subscription.

By right-clicking on the project name ‘Network’, we can create a new deployment. This will connect you to an Azure subscription if you haven’t done it from Visual Studio already, so that you can specify subscription, create a new resource group for this deployment or use an existing one, and then edit the parameters.

Page 41: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Since the “Resource Group” is blank in our example, we will create a new resource group called “CCNetworkRG” where we will deploy this network. The resource group itself will also require a location, a location that will store the metadata of the resource group. Remember that Azure Resource Manager can span regions, so that you can have resources in all the 19 Azure datacenters belonging to the same resource group.

.

Page 42: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

The resource group has now been created.

Our template did also contain some default parameters, which means we are ready to deploy as it is. However, if we would like to specify the input parameters ourselves at this stage, we can click on “Edit Parameters…”.

Page 43: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

We are quite happy with how it looks like, so we will click save and then deploy the template. When you click deploy, the Deploy-AzureResourceGroup.ps1 script will be executed. The template engine will then validate the template and proceed to create the deployment if everything is OK. If you have done any typos – like doing a syntax error (I do that all the time), the engine will notify you in detail. Once the deployment has been created, the applicable Resource Providers are contacted to create the resources described in the template, in parallel. By the end of the deployment you will get an output that shows the result. If it did succeed, failed or did partially completed. Deployment details, such as which resources you deployed, to which location and what resource group is also covered. If we logon to the portal we can also see the resource group and its resources, as well as all the details related to the deployment.

PowerShell

We have already seen that we can deploy directly from Visual Studio using PowerShell, but now we will explore this a bit in more detail. The first thing we will have to do is to launch PowerShell or PowerShell ISE and connect to one of our Azure subscriptions. This can be done by executing the following cmdlet: Add-AzureRMAccount (At this step, we assume you already have the latest Azure module installed as described earlier in this guide).

Page 44: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Once you have received your token you can select the preferred Azure subscription in case you have more than once. This can be done by executing the cmdlet: Select-AzureSubscription –SubscriptionID <your subscription id> Since we already have created a template that will provision a new Resource Group with storage account and virtual network with a subnet, we will use this template when provisioning with PowerShell. The following steps will be taken using PowerShell

Create a new Resource Group

Create a new deployment

The deployment will deploy the resources based on the ARM template Although we can create everything using a single cmdlet, we will first create the resource group using the following cmdlet: New-AzureRMResourceGroup –Name KristianRG –Location “west Europe” –Verbose

The output shows that the Resource Group has been successfully deployed. Next, we will go ahead and deploy the template we created earlier. If you haven’t saved it locally on your computer, you can download and save the template to your computer by accessing the following GitHub repository: https://github.com/krnese/AzureDeploy/blob/master/ReferenceTemplates/New%20RG%20with%20Storage%20and%20vNet/azuredeploy.json

Page 45: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Run the following cmdlet (modified to reflect your environment – and point to the newly created Resource Group): New-AzureRmResourceGroupDeployment -Name test02 -ResourceGroupName kristianRG -TemplateFile 'C:\users\kristian\Documents\GitHub\AzureDeploy\ReferenceTemplates\Existing RG with Storage and vNet\azuredeploy.json' -vmname newvm -storagename knstorage11dd7qwii5jvjc6 -vnetname knvnet10 -subnetname subnet-1 -ResourceGroupFromTemplate kristianRG -Verbose

This should show a similar output

Explaining the cmdlet When using the “New-AzureResourceGroupDeployment” cmdlet, we are creating a new deployment within an existing Resource Group. We are referencing the Resource Group we created earlier, which was called “KristianRG”. We are referencing our JSON template file which is saved locally in a folder. When the template engine sees this template, it will dynamically list the available parameters. So if we suddenly had to use a different template the engine would detect that and update them for us. We are specifying a new virtual network called “knvnet” and a subnet called “subnet-1”. Instead of specifying the input parameters when deploying this template, we could rather use a parameter file – which we also have created. The cmdlet would them use the parameter –TemplateParameterFile and you would have to point to the azuredeploy.parameters.json file created earlier. The use case for a parameter file is when you want to separate the configuration data from the environmental data. So in our case, we could easily have a parameter file for test, one parameter file for demo and one parameter file for production. Each with different values. We have now successfully deployed our ARM template into a Resource Group in Azure. Later, we will use the existing Resource Group to deploy more resources as well as explore some more advanced templates, functions and Resource Types.

Page 46: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Azure Portal

One of the most obvious places to go in order to deploy new resources in Azure, is in the Azure portal. The marketplace contains a bunch of templates for you to deploy and consume into your subscription(s), both created by Microsoft and third parties.

In addition to the marketplace, you can also construct your own Azure Resource Manager templates directly in the portal. Search for ‘Template Deployment’ in the Marketplace, and you’ll get access to a live JSON editor directly in the Azure Portal

Page 47: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

This is nice when you want to write templates and deploy on the fly, but be aware that the portal isn’t helping you with the syntax. From this view you can also download the template and continue to work with it in Visual Studio, and you can of course create a complete new deployment.

In this example, we are simply authoring a template to create a new storage account

Page 48: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Once satisfied with the template, click ‘Save’ and verify that the parameter is listed. Change any input and deploy this to a new Resource Group you are creating.

Page 49: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

You will get notified that the deployment has started and you can drill further into the details directly from the portal.

Once the deployment has completed, you will get a similar view as we had in Visual Studio and PowerShell, covering the details of the deployment job.

Page 50: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Idempotency with Azure Resource Manager We have already several times in this document been referring to Azure Resource Manager as an idempotent and declarative solution which will ensure that your resources are in the desired state, regardless of the current state. From a DevOp standpoint, that means you can write incremental changes to your template, re-deploy the exact same template into the exact same resource group, using the exact same deployment name and the affected resources will be put into the desired state or eventually updated based on the changes you have made. Agility is key. So to summarize, ARM is declarative and idempotent and will take care of all the resources you instantiate in the cloud, covering IaaS, PaaS, RBAC and much more. In addition, we can use extensions with the virtual machines and achieve the same within the guest using Chef, Puppet, Azure Automation DSC and PowerShell Desired State Configuration. The following section will demonstrate this where we will use a different template to show some more of the capabilities with ARM. The template “VM Scale Sets” – which also is available at the GitHub repository (https://github.com/krnese/AzureDeploy/tree/master/VMScaleSets ) will deploy a jump host VM as well as x amount of VM Scale Set instances, using DSC Extensions to configure the VM Scale Sets as Web servers. Explore the template on GitHub to see how this template is constructed with JSON. Dependencies in ARM templates What we also would like to demonstrate with this template, is that ARM will execute these deployments in parallel, and ensure that everything happens in the right order based on the dependencies we have defined. You are responsible for defining the dependencies and references to other resources when developing templates, so in case you are planning to deploy something very complex, please contact your SME on the subject to ensure that things are designed correctly. As an example in this template, the Virtual Machine jump host (Microsoft.Compute/virtualMachines) as well as the VM Scale Set (Microsoft.Compute/virtualMachineScaleSets) has several dependencies before those resources are deployed. Both resources has defined a dependsOn which points to resources such as storage accounts and virtual network interfaces – which again has other dependencies, such as virtual network, public IP addresses and so on. dependsOn As an example, the virtual machine jump host has a dependency on a dedicated storage account as well as a virtual network interface. The dependsOn property within the template provides the ability to define this dependency for a resource. It’s value can be a comma separated list of resource names. The dependencies between resources are evaluated and resources are deployed in their dependent order.

Page 51: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

When resources doesn’t have dependencies to each other, they are attempted to be deployed in parallel. Example:

Reference function Another way to define dependencies is to use the reference function that enables an expression to derive its values from other JSON name and value pairs or runtime resources. A reference expression implicitly declare that one resource depends on another. You can use both dependsOn and the reference function to specify dependencies, but you do not need to use both for the same dependent resource.

Example:

We will now proceed with the template deployment. One of the input parameters is “instanceCount” which is configured as “int”. You must specify a number – and that number will be passed down to the individual resources and ensure that everything scales accordingly. We will first start by deploying the template as it is before we make changes and verify that ARM is declarative. We use the following cmdlet to deploy this template (everything on the same single line): New-AzureRmResourceGroupDeployment -Name preview -ResourceGroupName (New-AzureRmResourceGroup -Name KNVMSS100 -Location "west europe").ResourceGroupName -TemplateUri "https://raw.githubusercontent.com/krnese/AzureDeploy/master/VMScaleSets/azuredeploy.json" -vmssName knss -resourceLocation "West Europe" -adminUsername knadmin -instanceCount 2 -mgmtstorage knstor01 -Verbose You will be prompted for the password to be used on the jump host in this template, as this parameter is defined as ‘securestring’.

Page 52: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

When you hit enter, the template is validated by the template engine and it will proceed with the deployment job once everything is OK, and create the resource group with its resources. If you pay attention to the process, you can see that the following is happening:

All the network – and storage related resources are deployed in parallel

Once they are completed, the compute resources will start to deploy The virtual machine and the VM Scale Sets have a dependency on both the storage accounts and the networking artifacts before it can start.

If we look into the Azure Portal, we can also find the newly created Resource Group and its current resources that already has been deployed. The overview also shows that there’s a deployment job

Page 53: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

running.

Once the deployment has completed, you should see a similar summary as shown below:

Page 54: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Now, let us run the exact same PowerShell cmdlet again, as we did when deploying this template. New-AzureRmResourceGroupDeployment -Name preview -ResourceGroupName (New-AzureRmResourceGroup -Name KNVMSS100 -Location "west europe").ResourceGroupName -TemplateUri "https://raw.githubusercontent.com/krnese/AzureDeploy/master/VMScaleSets/azuredeploy.json" -vmssName knss -resourceLocation "West Europe" -adminUsername knadmin -instanceCount 2 -mgmtstorage knstor01 -Verbose

A new dialogue box will appear, telling you that the resource group already exists and ask if you want to update it. Click Yes, and then type the password for the jump host.

As there’s no changes to the template, Azure Resource Manager will only ensure that the resources are in a state that’s declared in the template.

Page 55: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

You can see from the verbose output of the job that the resources are already created. As we haven’t described the public endpoint of the virtual machines in this template, ARM will potentially allocate a new random port for the jump host virtual machine, hence the provisioning status for the virtual machines are “running” before they are “completed” in just about a few seconds. We can check the output again and see that we have the exact same result once the job has completed.

So what if we would like to perform some changes? In our case, we would like to do the following:

Add 1 more instance to the existing VM Scale Set, so change the instanceCount input parameter from 2 to 3

We will now use the following cmdlet: New-AzureRmResourceGroupDeployment -Name preview -ResourceGroupName (New-AzureRmResourceGroup -Name KNVMSS100 -Location "west europe").ResourceGroupName -TemplateUri "https://raw.githubusercontent.com/krnese/AzureDeploy/master/VMScaleSets/azuredeploy.json" -vmssName knss -resourceLocation "West Europe" -adminUsername knadmin -instanceCount 3 -mgmtstorage knstor01 -Verbose

Again I will be prompted for the password, and again I will get the dialogue box telling me that the resource group already exists but I can choose whether I’d like to update it or not.

Page 56: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

The deployment job starts and will now update the resource group by adding another instance to the VM Scale Sets:

The deployment jobs shows that the resource “Microsoft.Compute/VirtualMachineScaleSets” is the only resource that is actually running, by adding another instance to the scale set. The virtualMachineScaleSet makes a single API call to the underlying resource provider, and is abstracted from the actual VM instance itself. That’s why we are not seeing an output that shows the instance name of that virtual machine resource that is being provisioned.

Page 57: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Once completed, the output should be similar to this:

We have now been demonstrating that Azure Resource Manager is idempotent and declarative, by running the exact same template and verified that ARM will not touch any of the existing resources unless you explicitly tell it to do so. We only added another instance to the VM Scale Set, which should now contain 3 VM instances.

Resource Explorer If you want a detailed view of how your resources in Azure looks like, you can navigate to the Resource Explorer option in the Azure Portal. This shows the JSON layout of each resource and deployment, which can be very helpful during troubleshooting but also when you want to develop ARM templates.

Page 58: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

We are showing an example here to verify that our newly created VM Scale Set is counting 3 instances

From the Resource Explorer, you can also open the blade directly that contains the resource you are looking into

Page 59: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Imperative Deployment with Azure Resource Manager You have now seen how ARM works when it comes to declarative deployment. Although this is the recommended approach when doing deployments to Azure, we also need to underline that ARM also supports deployments in an imperative way, just as you did with Azure Service Management API. The following script examples goes through the deployment of a new Resource Group with storage, network and compute resources # Connect to your Azure subscription #Add-AzureRmAccount -Credential (get-credential -Credential [email protected]) # Add some variables that you will use as you move forward #Global $RGname = "testrg2" $Location = "north europe" # Storage $StorageName = "Knstor2demo" $StorageType = "Standard_LRS" # Network $vnicName = "vmvNic" $Subnet1Name = "Subnet1" $vNetName = "KNVnet01" $vNetAddressPrefix = "192.168.0.0/16" $vNetSubnetAddressPrefix = "192.168.0.0/24" # Compute $VMName = "KNVM02" $ComputerName = $VMName $VMSize = "Standard_A2" $OSDiskName = $VMName + "osDisk" # Create a new Azure Resource Grou $RG = New-AzureRmResourceGroup -Name $RGname -Location $location -Verbose # Create Storage $StorageAccount = New-AzureRmStorageAccount -ResourceGroupName $RGname -Name knstor2demo -Type $StorageType -Location $Location # Create Network $PIP = New-AzureRmPublicIpAddress -Name $vnicName -ResourceGroupName $RGname -Location $Location -AllocationMethod Dynamic $SubnetConfig = New-AzureRmVirtualNetworkSubnetConfig -Name $Subnet1Name -AddressPrefix $vNetSubnetAddressPrefix $vNET = New-AzureRmVirtualNetwork -Name $vNetName -ResourceGroupName $RGname -Location $Location -AddressPrefix $vNetAddressPrefix -Subnet $SubnetConfig $Interface = New-AzureRmNetworkInterface -Name $vnicName -ResourceGroupName $RGname -Location $Location -SubnetId $vnet.Subnets[1].Id -PublicIpAddressId $pip.Id # Create Compute # Setup local VM object $Credential = Get-Credential $VirtualMachine = New-AzureRmVMConfig -VMName $VMName -VMSize $VMSize

Page 60: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

$VirtualMachine = Set-AzureRmVMOperatingSystem -VM $VirtualMachine -Windows -ComputerName $ComputerName -Credential $credential -ProvisionVMAgent -EnableAutoUpdate $VirtualMachine = Set-AzureRmVMSourceImage -VM $VirtualMachine -PublisherName MicrosoftWindowsServer -Offer WindowsServer -Skus 2012-R2-Datacenter -Version "latest" $VirtualMachine = Add-AzureRmVMNetworkInterface -VM $VirtualMachine -Id $interface.Id $OSDiskUri = $StorageAccount.PrimaryEndpoints.Blob.ToString() + "vhds/" + $OSDiskName + ".vhd" $VirtualMachine = Set-AzureRmVMOSDisk -VM $VirtualMachine -Name $OSDiskName -VhdUri $OSDiskUri -CreateOption fromImage # Deploy the VM in Azure New-AzureRmVM -ResourceGroupName $RGname -Location $Location -VM $VirtualMachine # Add DSC Extension to the VM # Get available DSC extension in your region #Get-AzureRmVmExtensionImage -Location $location -PublisherName "Microsoft.PowerShell" -Type "DSC" #Set-AzureRmVMExtension -ResourceGroupName $RGname -VMName $VirtualMachine.Name -Name MyDSC -Publisher Microsoft.PowerShell -ExtensionType DSC -TypeHandlerVersion 2.7 -Settings $settings -Verbose # Publish DSC config to your newly created storage account Publish-AzureRmVMDscConfiguration -ResourceGroupName $RGname -ConfigurationPath .\webdsc.ps1 -StorageAccountName knstor5050 Set-AzureRmVMDscExtension -ResourceGroupName $RGname -VMName $virtualmachine.Name -ArchiveBlobName webdsc.ps1.zip -ArchiveStorageAccountName knstor5050 -ConfigurationName webdsc -Version 2.7 -Location $location

Advanced Azure Resource Manager Templates

We have already been using many functions so far, when creating our first ARM template that deployed a new virtual network and storage account into an existing Resource Group. However, it is important to point out other functions too, and show more examples of the capabilities of ARM templates so that you can succeed with your adoption of Microsoft Azure. This section will focus on the following:

Functions

Extensions

Write once, deploy anywhere

<placeholder>

Functions

resourceId

Returns the unique identifier of a resource. You use this function when the resource name is ambiguous or not provisioned within the same template.

Page 61: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Continuing on the existing Resource Group we created earlier, we will now deploy an ARM template that will create additional resources into that resource group, such as a virtual machine and virtual network interface. We are doing so by using some functions we haven’t covered so far. The template in particular we will start with is located at https://github.com/krnese/AzureDeploy/blob/master/ReferenceTemplates/Existing%20RG%20with%20Storage%20and%20vNet/azuredeploy.json If you explore this template, you can see that we have several input parameters, such as vmname, storagename, vnetname, resourcegroup and subnetname. This template will deploy a new virtual machine into an existing Resource Group, place the VHD on an existing storage account in that Resource Group, as well as connecting the new virtual network interface to the existing vnet in the existing Resource Group.

- The vmname parameter is where you will specify the computer name of the virtual machine you will be deploying.

- The resourcegroup parameter is where you will specify the name of the existing Resource Group - The vnetname parameter is where you will specify the name of the existing virtual network - The subnetname parameter is where you will specify the name of the existing subnet on the

existing virtual network - The storagename parameter is where you will specify the name of the existing storage account

Page 62: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

We are able to use the existing Resource Group and its resources by referencing the resourceId of these resources. To simplify the language expression used in the template, we have added some variables that shows how this is done.

Also note that the variable “subnetRef” is using the concat function where it takes the vnetID variable (string) and combine it with the input parameter for “subnetname”. This will become handy later in the template, where we simply can use the variable

Page 63: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

If you drill down to the Microsoft.Compute/virtualMachine resource that is being declared, yuu can see that the parameter for storagename is being used – to place the vhd on the existing storage account

You can download this template to your local disk and use –TemplateFile parameter in PowerShell, or use the –TemplateUri parameter and point to https://github.com/krnese/AzureDeploy/blob/master/ReferenceTemplates/Existing%20RG%20with%20Storage%20and%20vNet/azuredeploy.json I will run the following cmdlet to deploy this template to the Resource Group “KristianRG” created earlier, using the storage account name, vnet and subnet that already exist in that Resource Group New-AzureRmResourceGroupDeployment -Name test02 -ResourceGroupName kristianRG -TemplateFile 'C:\users\kristian\Documents\GitHub\AzureDeploy\ReferenceTemplates\Existing RG with Storage and vNet\azuredeploy.json' -vmname newvm -storagename knstorage11dd7qwii5jvjc6 -vnetname knvnet10 -subnetname subnet-1 -ResourceGroupFromTemplate kristianRG -Verbose

This template has now demonstrated how to use resourceId with ARM templates.

Page 64: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Linked templates

You create a link between two templates by adding a deployment resource within the main template that points to the linked template. You must set the templateLink property to the URI of the linked template. You can provide parameter values for the linked template either by specifying the values directly in you template or by linking to a parameter file The templates we will use in this section is located at: https://github.com/krnese/AzureDeploy/tree/master/Basic and will deploy in total of 3 templates, where the main template will reference the URI of the other two, to create the required resources for the virtual machine. This is a very useful approach and shows how powerful and complex this can become. From real world deployments, we see that organizations are letting their SME’s declare certain ARM templates, such as storage, SQL, network and so on. They are responsible for managing these templates, while the main template will point to the template it will use whenever it is applicable. As a friendly reminder, you should consider your ARM templates as source code and have version control – which is ideally for the example described above. If we explore the azuredeploy.json, we can see under resources that we are using a different type of resource compared to what we have been using so far in this book.

The type “Microsoft.Resources/deployment” must be used when using linked templates, and you can also see that this resource also supports input parameters – that can come from the main template. If we explore the SharedStorageTemplate.json which is located in the same directory, we see that we have specified an input parameter for storage blob name there that will be used when declaring the storage name under the resource section.

Page 65: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

There’s a similar approach for the SharedNetwork.json template as well I am running the following cmdlet to deploy these templates from my computer: New-AzureRmResourceGroupDeployment -Name Dep01 -ResourceGroupName (New-AzureRmResourceGroup -Name nested01 -Location "west europe").ResourceGroupName -TemplateUri "https://raw.githubusercontent.com/krnese/azuredeploy/master/Basic/azuredeploy.json" -vmname AzureDemo01 -storageblobname knaz05 -username azureadmin -Verbose

The output shows that ARM will invoke the nested templates and instantiate storage and network from those templates before continuing on the main template – that also contains the compute resource, the public IP address and the virtual network interface.

Page 66: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

This template has now demonstrated how to use linked templates with ARM templates.

copy & copyIndex

Within the resource to create multiple times, you can define a copy object that specifies the number of times to iterate. You can access the current iteration value with the copyIndex() function

We have explored the VM Scale Set resource type so far in this book, which let us deploy multiple VM instances using a single API call from ARM to the Compute Resource Provider. There’s also other options when it comes to create multiple instances of resources using ARM templates, and this example will use the copyIndex function The example template we will use is available at https://github.com/krnese/AzureDeploy/tree/master/CopyExample This template will take some input parameters for you to create resources such as virtual machines, public IP addresses and vNics. There’s also an input parameter named ‘instancecount’ defined as int, where you can specify the number of instances you want to create.

The input value here will be used throughout the template when declaring resources, such as virtual machines, public IPs and vNics. As an example you can see the public IP address resource using this

Page 67: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

parameter for creating multiple resources of the same type, by using ‘copy’ and taking the ‘instancecount’ parameter.

We will deploy this template using PowerShell and specify 2 resources, using the following cmdlet: New-AzureRmResourceGroupDeployment -name copy -ResourceGroupName (New-AzureRmResourceGroup -name copygroup -Location "west us").ResourceGroupName -TemplateUri "https://raw.githubusercontent.com/krnese/AzureDeploy/master/CopyExample/azuredeploy.json" -instancecount "2" -Verbose

The output shows that ARM will deploy 2 instances of the resources

This template has now demonstrated how to use copy and copyIndex with ARM templates

Extensions Microsoft Azure provides VM extension built by both Microsoft and by trusted third-party providers to enable security, runtime, debugging, management and other features you can take advantage of to increase your productivity with Azure IaaS virtual machines. Using Azure Resource Manager is a great way for you to declare all your cloud resources, and let you spin up networks, web apps, storage, virtual machines – you name it, in whatever region you’d like. However, this will “only” instantiate the environment you need and its dependencies. If you want to take the next step then you will look into the different Extensions you can use. This section will mainly focus on VM Extensions. For you to take the next step and also declare whatever you like within a guest operating system, VM Extensions can be used in many different ways to achieve that. When you create a basic virtual machine from the Marketplace in Azure, you get several basic VM extensions applied at the same time, such as IaaSDiagnostics, VMAccess and BGInfo. Some extensions are dedicated to Windows while some are dedicated for Linux. In some cases you can use the extensions on both platforms.

Page 68: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

One of the most common VM Extensions we are using when completing a deployment of advanced – and in some cases distributed applications, is to use Custom Script Extension and PowerShell DSC Extension. Although an explanation of DSC is out of scope for this book, we will also work with an example that covers this specifically. In fact, you have actually been using this Extension when you deployed a VM Scale Set earlier, that configured all the instances in the Scale Set with the Web-Server feature in Windows. In the first example, we will use a Custom Script Extension to do the following inside a Windows Server 2016 Technical Preview 4 virtual machine

Create a new container based on the built-in container image on the container host

Add Web-Server feature to the container

Capture these changes in the container by creating a new image

Deploy a new container with Web-Server based on the newly created image

Create firewall rules from the container host to allow traffic on port 80 to the container

Add NAT rule to route traffic on port 80 from the container host to the container The template we’re using as an example is located on GitHub https://github.com/krnese/AzureDeploy/tree/master/AzureContainerWeb First, let us explore the template and drill down to the Microsoft.Compute/virtualMachine resource. Within the properties of this resource type, we will find the details about the Extension being used

The VM extension shows as a resource type of ‘extension’ within the Compute RP and we have specified the publisher, type and its typeHandlerVersion. We are using Microsoft.Compute, CustomScriptExtension and version 1.4. Further, you can see that the fileUris is pointing to the same GitHub repo that also contains a script (.ps1) file. You can explore this script directly in the repo to see the steps that are taken. Last but not least, we have ‘commandToExecute’ that tells ARM to launch PowerShell within the VM, set the ExecutionPolicy to ‘Unrestricted’ and then point to the script and use the parameters defined – within the script itself. This shows that you can create input parameters directly in the ARM template that dives straight into the PowerShell script that will run as part of the Extension process.

Page 69: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

We will deploy this template using the following cmdlet in PowerShell: New-AzureRmResourceGroupDeployment -Name preview -ResourceGroupName (New-AzureRmResourceGroup -Name KNVMCONUS -Location "west us").ResourceGroupName -TemplateUri "https://raw.githubusercontent.com/krnese/AzureDeploy/master/AzureContainerWeb/azuredeploy.json" -containerhost knhost50 -containername tp4con -vmSize standard_a3 -adminaccount knadmin -storageAccountName knhoststor50 -StorageType Standard_LRS -vNetName knhostvnet50 -Verbose

Notice in the template that the extension has a ‘dependsOn’ that points to the virtual machine, meaning that the extension will wait for the virtual machine to be provisioned before being applied.

Once the deployment has completed, you should also be provided with an output from the template that gives you the endpoint of the web server running inside the container, so you can access it directly from the browser.

Page 70: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

DSC Extensions can be used in a similar way, and the example we will be using is also available on GitHub https://github.com/krnese/AzureDeploy/tree/master/DSCExample If you explore the azuredeploy.json file and drill down to the Microsoft.Compute/virtualMachine/extensions, you can find the detail about the DSC extension being used.

Here we will apply the DSC configuration that is available in the same GitHub repository, to configure and deploy the Web-Server role. The difference here compared to the Custom Script Extension we used earlier – besides this being a DSC configuration and not a native imperative PowerShell script, is that we will ensure that Windows Management Framework version 5 will be installed on the guest operating system. Since the image being used in this template is a Windows Server 2012 R2, this will result in a reboot which makes the deployment take longer time to complete. In Azure we are only using WMF 5, which is something you need to have in mind when investing in this. By using the DSC Extension with our virtual machines, we can ensure that the entire deployment is declarative, also whatever goes on within the virtual machine operating system. We deploy this template with the following PowerShell cmdlet: New-AzureRmResourceGroupDeployment -Name demodeployment -ResourceGroupName (New-AzureRmResourceGroup -Name DSCDemoRG -Location "west us").ResourceGroupName -TemplateUri "https://raw.githubusercontent.com/krnese/AzureDeploy/master/DSCExample/azuredeploy.json" -vmname dscvm01 -storageblobname dscstor50 -vnetname dscvnet50 -Verbose

Page 71: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

The execution behavior is quite similar as when using custom script extension. The DSC resource has a dependency on the virtual machine, and will wait for that resource to be provisioned before applying the configuration.

Once the deployment has completed, you will have a similar output

To verify that the DSC extension is in place on this virtual machine using PowerShell, run the following cmdlet (Get-AzureRmVM -Name dscvm01 -ResourceGroupName dscdemorg).ExtensionsText

We have now demonstrated the usage of Custom Script Extension and DSC Extension in an ARM template.

Page 72: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Write once, deploy anywhere One of the key aspects with Azure Resource Manager is that we now have a true consistent management layer and API across both Azure and Azure Stack. Ideally this means we can author our templates and they can be deployed across both of these clouds. In this section we will get beyond the hype and explore what we need to do in order to realize that scenario. In the templates we have been using so far, we have very often been working with virtual machines. In the preview of Azure Stack, the following Resource Providers are the foundation for the available services.

Microsoft.Compute

Microsoft.Storage

Microsoft.Network Although they are consistent, we have to bring some environmental variables into the consideration when authoring templates.

Azure has its own namespace for certain Resource Providers

Azure has a geo-redundant cloud infrastructure that spans many regions

Azure currently supports a lot more Resource Providers than Azure Stack, and has also several API versions available

Azure Stack is limited to a “local” region in the technical preview

Azure Stack environments has also their own namespace for certain Resource Providers With these considerations in mind, we are going to have a look at the following ARM template that is specifically designed to work for both Azure and Azure Stack https://github.com/krnese/AzureStackDeploy Explore the template and especially the parameters. Note that there’s “allowedValues” for the blobendpoint parameter, showing the namespace for Azure blob storage, as well as the default namespace for the Azure Stack preview blob storage.

Page 73: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

In addition, we have added “local” as an allowedValue for the location parameter.

Let us first try to do a deployment of this template to Azure using the following PowerShell cmdlet New-AzureRmResourceGroupDeployment -name tester1 -ResourceGroupName (New-AzureRmResourceGroup -Name AzureDep -Location "west europe").ResourceGroupName -TemplateUri "https://raw.githubusercontent.com/krnese/AzureStackDeploy/master/azurestackdeploy.json" -vmname knvm01 -vnetname knvnet124 -storageendpoint blob.core.windows.net -location "west europe" -storageblobname nornes01 -Verbose

Azure Resource Manager will then go ahead and deploy the template, deploying resources in parallel when appropriate

We can verify that the deployment completed successfully

Page 74: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

Next, let us try a similar deployment to Azure Stack First we have to logon and authenticate toward the Azure Stack environment, using the following cmdlets: # Add specific Azure Stack Environment $AadTenantId = "ab1eaa48-fe90-494f-9775-c4aa6543bd7a" #GUID Specific to the AAD Tenant Add-AzureRmEnvironment -Name 'Azure Stack' ` -ActiveDirectoryEndpoint ("https://login.windows.net/$AadTenantId/") ` -ActiveDirectoryServiceEndpointResourceId "https://azurestack.local-api/" ` -ResourceManagerEndpoint ("https://api.azurestack.local/") ` -GalleryEndpoint ("https://gallery.azurestack.local:30016/") ` -GraphEndpoint "https://graph.windows.net/" # Get Azure Stack Environment Information $env = Get-AzureRmEnvironment 'Azure Stack' # Authenticate to AAD with Azure Stack Environment Add-AzureRmAccount -Environment $env -Verbose # Get Azure Stack Environment Subscription Get-AzureRmSubscription -SubscriptionName "StackOffer" | Select-AzureRmSubscription

We will run the following cmdlet to deploy the same ARM template – only changing the parameters to use “local” as the region and “blob.azurestack.local” as the storage endpoint New-AzureRmResourceGroupDeployment -Name deploy01 -ResourceGroupName (New-AzureRmResourceGroup -Name MASRG -Location "local").ResourceGroupName -TemplateUri "https://raw.githubusercontent.com/krnese/AzureStackDeploy/master/azurestackdeploy.json" -vmname knvm01 -vnetname knvnet124 -storageendpoint blob.azurestack.local -location "west europe" -storageblobname nornes01 -Verbose

Azure Resource Manager in Azure Stack will deploy the template in the same fashion as we saw in Azure

Page 75: Acknowledgements - gallery.technet.microsoft.com · more and more cloud-ready and the majority of them is either specifically designed and delivered from the cloud itself, or has

We can also verify that the deployment has succeeded

We have now verified that a single template can be deployed towards Microsoft Azure and Microsoft Azure Stack.

Closing notes

Hopefully you have found this book valuable as part of your Azure Resource Manager learning. From our point of view, this has been a very interesting and valuable exercise to write this reference on Azure Resource Manager, balancing between a big document and multiple templates and scripts. It is for sure a living document and we will do our best to ensure the book is updated with fresh content whenever there’s something we really feel should be covered. For the latest template examples, feel free to check into the GitHub repository we have been using throughout this book at https://github.com/krnese/AzureDeploy Also, join the conversation on Facebook to discuss the content and Azure Resource Manager in general. https://www.facebook.com/thecloudguy Thanks for reading!