Identical environments: infrastructure as code

One of the greatest challenges of those who manage environments for development teams is to have identical, versioned and integrated environments in an IC / CD. Setting off from a first beta version of the operating system, until reaching a final production version. There are several tools to solve this big problem but in this article the idea is to focus on some that have already been tested by the team and are in production in some customers, in this case, we are going to talk about HashiCorp Packer, normally integrated with Terraform for the deployment, but we will leave this last tool for the next article.

Automatically builds images of VMs

What is Packer?

Packer is an open source tool for creating images of identical virtual machines for multiple platforms from a single source configuration. Packer is lightweight, runs on all operating systems and has high performance, creating virtual machine images for multiple platforms in parallel. Packer does not replace configuration management like Chef, Puppet, PowerShell or Ansible. In fact, when building images, it can use tools such as Chef, Puppet, PowerShell, or Ansible to install software on the image.

A virtual machine image is a single static unit that contains a preconfigured operating system and installed software that is used to quickly create new running machines. The image formats of the machine change for each platform. Some examples include AMI for EC2, VMDK / VMX files for VMware, OVF exports for VirtualBox, etc.

Advantages of using Packer

Super fast infraestructure implementation

Packer images allow the use of complete configurations and configurations in seconds, instead of several minutes or hours. This will not only benefit production environments but also development as that virtual computer can also start in seconds, without waiting for a generally longer provisioning time.

Portability of multiple providers

Because it creates identical images for multiple platforms, you can run the provisioning of an image in AWS, at the same time provisioning the same image in a Staging / QA environment in a private cloud such as OpenStack and a development environment in virtualization solutions. desktop as VMware or VirtualBox. Each environment executes an identical machine image, providing maximum portability.


Packer installs and configures all the software for a machine at the moment the image is built. If there are errors in these scripts, they will be detected early, instead of several minutes after a machine is launched.

Greater test capacity

After building a machine image, it can be started quickly and tested in what we call a “smoke test”, to verify that everything seems to be working. If the tests turn out well, you can be sure that any other machine launched from that image will work correctly.

Case study

Packer can be used in multiple scenarios, here we name only some:

  • CI/CD
  • Deploy of identical DEV/PROD environments
  • Generation of identical environments to create demos of pre-installed applications
  • Servers hardening


Packer is an OpenSource multi-platform tool, so we can install it on all existing operating systems, Windows, OSx, Linux, etc.

In this case, we will show you how to install packer on Mac, by executing the following command from the terminal:

 After installing Packer, we can check its correct installation, executing the command:

So far, we have the tool installed. But … how do we build an image?

In the following example we are going to build an image with the following characteristics, in the Azure cloud:

  • Windows Server 2016.
  • IIS rol with all its reliances (.Net Fx4.6, etc).

The template

As we have already seen, Packer allows us to work with multiple suppliers at the same time. The template or Packer recipe is a file in JSON format, which can be modified very easily. In the official documentation of the supplier we have the structures and options to be able to modify it according to the needs of each one.

Now, to understand the template and its options, we must consider the concepts of some main options of the template structure:

  • Builders a “builder, is responsible for creating the virtual machine and generating the image from it, there are multiple builders which we can work with: Azure, AWS, Digital Ocean, VMWare, Docker, etc.
  • Provisioners: they prepare the system for its use, executing scripts, commands and third-party software. Everything that is necessary so that we can customize our image. There are multiple provisioners with which we can work: PowerShell, Ansible, Puppet, Salt, Windows Shell, Chef, etc.

Once we have the concepts mentioned above clear, we turn to Packer’s recipe to create an image. In this case, we want to create a server image with Windows Server 2016 (the latest version available in the Azure cloud) that has all the characteristics to act as a Web Server.

I’ll quickly explain my recipe or template. First, we start by declaring a constructor or builder, then the connection to our service provider (Azure), and then comes the most interesting, all the configuration we want for our image. At last but not least, we declare two provisioners, in which one invokes a PowerShell script (responsible for adding the web server features) and the other executes an “in line” command that makes the sysprep of the operating system, once we have created the image.

We have the template ready … now how do we build the image?

In this case we are working with Azure, as a previous step we must create a group of resources so that Packer can work on it. As simple as connecting to an Azure console, authenticate and execute the following PowerShell command:

Once this resource group is created we execute the command to build the image invoking Packer and see it in action:

Scheme of its operation

Previously the build of the image was run against the Azure cloud, but .. What did it do? How does it work?

Now let’s see how Packer works graphically

Shortly, Packer connects to the Azure cloud, to create a temporary resource and within it a virtual machine with all the features that we declared in our template, to then generate the image and finally eliminate that resource since it won’t be used anymore. As a final result, we will have an image of the machine in our resource.

How do we create machines using these images?

Once we have one or several images created, we will create virtual machines from those images.

Now, we will see two tools:

  • PowerShell
  • Terraform



It’s the native tool of Microsoft which allows us to execute the Azure cmdlets to create our virtual machine.

Basically we are going to see a Powershell template to create this virtual machine.

We execute the following command to save the user and password of the administrator user of the machine.

The following template obtains the image and creates the virtual machine from it: