Published on 8 December 2015 by

As part of the release of Puppet Enterprise 2015.3, we’re introducing a new module specifically for working with Microsoft Azure with Puppet.

Puppet already works great on Azure, and we have a Puppet Enterprise Virtual Appliance in the Azure gallery. With the Azure module, we’re enabling you to manage virtual resources in Azure directly with Puppet. In this first release, we’re supporting managing Azure Virtual Machines in both the Classic API and the Resource Management API. What does that look like in code?

azure_vm { 'sample':   
  location => 'eastus'  
  image    => 'canonical:ubuntuserver:14.04.2-LTS:latest',   
  user     => 'azureuser',   
  password => 'Password',    
  size     => 'Standard_A0',   

This example creates a new virtual machine in Azure called sample. When run a second time, it will ensure the VM exists and matches the various properties. Azure currently supports two APIs (Service Management and Resource Management), and the module supports both of those. For instance, you can can create a VM in the classic space (or service management) like so:

azure_vm_classic { 'virtual-machine-name':
  ensure           => present,
  image            => 'b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_2-LTS-amd64-server-20150706-en-us-30GB',
  location         => 'West US',
  user             => 'username',
  size             => 'Medium',
  private_key_file => '/path/to/private/key',

Why Is This Useful

One of the problems Puppet solves is configuration drift. Over time, the configuration of a host under manual management tends to wander, specifically as the gap grows between how you think it’s configured, how your colleagues think it’s configured and how it’s actually configured. The wider that gap, the more often you'll get unexpected issues and failed deployments. The same thing can happen with your Azure VM infrastructure. When you're running virtualized infrastructure, you need to answer questions like:

  • Do you have 15 application servers or 20?
  • Are the database machines all at least A3/Large machines?
  • Are all new machines really being launched from the approved Windows 2013 image?

One approach to gaining this consistency is having rigid change control processes for creating or changing machines, and maybe even a dedicated team responsible for doing so. But that has the side effect of slowing down critical changes, and puts up a wall between the development team who need to run applications and the operations team running the infrastructure.

A better approach is "infrastructure as code." The desired state of Azure VMs can be described in Puppet, giving you a simple model of your VMs in code. The model can be versioned using your favourite version control system, and changes can be proposed using pull requests or other code management workflows. Those modifications can be reviewed, and tests written to enforce various constraints, all before the changes hit production. And finally, Puppet can ensure that the model in code matches the reality, by creating missing machines or by modifying back to their desired state any machines that have drifted.

A More Compelling Example

A great example of how the Azure module can simplify setting up infrastructure in Azure was shown at PuppetConf 2015 by Rob Reynolds of Puppet Labs and Scott Hanselman from Microsoft. The blog post How to setup a Load Balanced Web Farm of Virtual Machines on Windows Azure shows the power of Azure, but both approaches require a number of separate steps which have to be done precisely and in order. Converting this into Puppet code gives us the following:

azure_vm_classic { ['hanselmanfarm', 'hanselmanfarm-2', 'hanselmanfarm-3']:
  ensure           => present,
  image            => 'b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_04_3-LTS-amd64-server-20150908-en-us-30GB',
  location         => 'West US',
  user             => 'scott',
  password         => 'secretpw',
  size             => 'Small',
  custom_data      => 'sudo apt-get install apache2 libapache2-mod-php5 php5 -y && sudo sh -c "echo \'<?php echo gethostbyname(trim(\"`hostname`\")); ?><?php phpinfo(); ?>\' > /var/www/html/test.php"',
  cloud_service    => 'hanselmanfarmcs',
  availability_set => 'hanselmanfarmas',
  endpoints        => [{
    name               => 'weblb',
    public_port        => 80,
    local_port         => 80,
    protocol           => 'TCP',
    load_balancer_name => 'HttpTrafficIn',
    load_balancer      => {
      port     => 80,
      protocol => 'http',
      interval => 5,
      path     => '/test.php',

That’s it. In 24 lines of Puppet code we launch three virtual machines, install a simple PHP and Apache web server setup on each, and set up a load balancer to balance traffic between them. More powerful than that, we can add more machines to our cluster by changing one line. A real-world example might use the custom data passed to the VM to install a Puppet agent and instruct that Puppet agent to connect to a Puppet master.

Next Steps

The module we’re releasing as part of 2015.3 is only the first step. We’re actively looking for feedback from users about what works well and what could be improved, and about what other aspects of Azure you would like to see managed by Puppet.

Learn More

Share via:
Posted in:

This is very beneficial for me as I work a lot with Azure.

Do you have ways to create other things like Resource Groups, NSG, Load Balancers, etc?

Thanks for the feedback Clinton. We don't yet have support for Resource Groups, NSG, Load Balancers, VNET etc. We're looking into adding this support very soon.

A follow-up article with some examples on how to use custom images for deployment would be nice.  I've attempted to create a VM using a custom image and keep receiving an error stating "change from absent to present failed: Could not set 'present' on ensure: Failed to create virtual machine : The virtual machine image source is not valid."

The image name I'm using matches exactly what is shown in my Azure image list

The content of this field is kept private and will not be shown publicly.

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.