From UI to Code – Calm DSL and Blueprint Decompile

From UI to Code - Calm DSL and Blueprint Decompile

Regular readers of will be familiar with the Nutanix Calm DSL. If you haven’t yet taken a dive into the Nutanix Calm DSL, please feel welcome to check out the resources below before moving on.

Isn’t that title backwards?

Depending on where you’re standing, yes it could be. Essentially what we’ll cover today is taking a blueprint that’s been designed in the Nutanix Calm UI and decompiling it into DSL Python code. We’ll also take the same blueprint, export it from the Nutanix Calm UI and then decompile it into Python code. Why? The Nutanix Calm DSL is the first Calm SDK and allows programmatic control of many Calm elements – blueprints, for example.

Again, why? In many cases, automation engineers or developers will want to interact with Nutanix Calm from their own scripts, code or applications. By allowing programmatic access to Nutanix Calm via the DSL, this becomes a relatively simple task.

The ability to decompile blueprints is actually quite new, having only been made available in the DSL master branch in mid-July 2020.

Today’s Blueprint

The contents of the blueprint aren’t particularly relevant, since we’re not making any changes to the blueprint itself. That said, I’m working with a blueprint that’s about as basic as they come.

  • 1x service (VM)
  • Deploys CentOS 7.8 from the public CentOS 7.8 cloud image
  • Sets up the VM to allow login with SSH key pair
  • Carries out some basic configuration e.g. package updates

What You’ll Need

If you are planning to follow along with the steps in this article, you’ll need to have the Nutanix Calm DSL already setup and connected to Prism Central. The easiest way to do that is to follow the article titled Introducing the Nutanix Calm DSL as it covers the installation of the Calm DSL on Linux, as well as the use of the Calm DSL via Docker Container.

Basic Calm DSL Blueprint Structure

Before getting started, let’s take a quick look at the basic structure of a Calm DSL blueprint. My blueprint, named “BasicLinuxVM”, is as follows. Note this is the structure of the blueprint after it’s been decompiled using the Calm DSL – we’ll get to that step in a moment.

BasicLinuxVM blueprint, after export using the Calm DSL

Here are the key components:

  • “scripts” directory. This contains the scripts that are used at various stages during the blueprint deployment. In this example, there is a base configuration script (ConfigureBaseVM) and a firewall configuration script (ConfigureFirewall).
  • “specs” directory. This contains the specs for our VM, including the Cloud-Init data that’s used during the deployment.
  • “”. This is the blueprint itself and ties together the code required by the DSL so that the blueprint can be deployed, launched (etc).

How did we get there?

This is where we get to the main part of today’s article – blueprint decompile. Let’s consider two different blueprint “states”. Please note these shouldn’t be confused with the blueprint “state” within Calm itself e.g. draft and active. Our two states are:

  • Accessible via the Nutanix Calm UI
  • Available as a local JSON file. These JSON files are typically created when exporting a blueprint from the Calm UI

However, neither of those two states are editable as Nutanix Calm DSL Python blueprints. In order to prepare the blueprint for editing as Python code, we need to decompile it.

Method 1 – Decompiling Blueprint from Prism Central

As mentioned earlier, my blueprint is called “BasicLinuxVM”. With the Nutanix Calm DSL installed and available, we can decompile the blueprint from Prism Central with this simple command.

calm decompile bp BasicLinuxVM

Running that command will proceed as shown below.

Converting a Prism Central blueprint to DSL Python code using “calm decompile”

Looking a bit closer, we can see the path to the decompiled blueprint is as follows:


Method 2 – Decompiling Blueprint from JSON file

The method above makes great use of a blueprint that you already have access to. However, what if a colleague has provided an exported blueprint from their own Calm instance, and it needs to be edited as DSL Python code? Let’s look at the command required for that. I have a copy of the BasicLinuxVM blueprint in my “~/Downloads” folder as BasicLinuxVM.json.

calm decompile bp --file ~/Downloads/BasicLinuxVM.json

Let’s take a look at the results of running that command:

Converting a local JSON blueprint to DSL Python code using “cam decompile” with the “–file” argument

In this version, the Calm DSL has carried out an almost identical procedure to that of decompiling from Prism Central, but it has taken input from the local JSON file instead.


It’s worth noting at this point that the decompilation of a blueprint from Prism Central and the decompilation of a blueprint from a local JSON file will produce identical results. Both folder structures are the same and contain the same “scripts” and “specs” folders as shown earlier.

This image has an empty alt attribute; its file name is image-23.png
Contents of a Nutanix Calm blueprint decompiled using the Nutanix Calm DSL

Uploading the Blueprint

Now that we have the blueprint available as DSL Python code, we can edit it in any way we see fit. Let’s assume for now that we’ve made our required changes and want to go through the following steps to make the blueprint usable.

  • Verify the blueprint can be compiled by the Calm DSL
  • Publish the blueprint to Prism Central

Here are the commands we use to do that. Note that the blueprint I’m creating on Prism Central will be called “BasicLinuxVM_Uploaded”.

calm compile bp --file ./BasicLinuxVM/
calm create bp --file ./BasicLinuxVM/ --name BasicLinuxVM_Uploaded

The first command will return a full blueprint in JSON format that can be saved to a file or used in any way you see fit. The second command will create a new blueprint on Prism Central, as follows:

Nutanix Calm DSL creating a blueprint from local DSL Python code

At this point it’s worth noting that because the DSL has been developed using Python, it throws easily parse-able exceptions when something goes wrong. That means we can, for example, use standard Bash return code checks to make sure a command worked.

Take a look at this very short Bash script snippet:

calm decompile bp --file "$BP_FULL" > /tmp/null 2>&1

These two lines are decompiling a local JSON blueprint the same way as above, sending the output to /tmp/null so it’s not shown on screen and then setting a variable called COMPILE_RESULT that holds the command’s return code. If successful, that return code will be 0, with any other value typically indicating something didn’t work as expected. To expand on that a little, here’s the complete block those two lines came from:

# verify the blueprint is valid
# at this point the blueprint directory and blueprint itself have been found in the user-specified locations
calm decompile bp --file "$BP_FULL" > /tmp/null 2>&1
if [ ! "$COMPILE_RESULT" == "0" ]
        echo "$ERROR_PREFIX The specified blueprint cannot be decompiled.  Please ensure the blueprint contains valid JSON."
        echo "$OK_PREFIX Blueprint decompiled successfully.  Continuing."

Wrapping Up

The topics and steps covered in today’s quick article may seem a little trivial when looked at in isolation. However, my recommendation is this. Think of the DSL as a way of creating and working with Nutanix Calm entities using a programming language that’s become somewhat ubiquitous amongst software engineers. Of course, this is a fairly general statement since there are literally thousands of programming languages available – around 9000, depending on where you look. Python, though, often shows up as the most popular programming language when software engineer and developer surveys are carried out by independent third parties. Here’s just one example, where Python makes up 31.73% of how often language tutorials are searched on Google. That’s a fairly solid indicator of how popular Python probably is.

Using built-in functions like blueprint decompile, application designers can easily create their apps using the beautiful Nutanix Calm UI and then pass the results to automation and software engineers for programmatic integration.

Thanks for reading and I hope this information comes in useful. Have a great day! 🙂


Copy the SSH public key below.  In BASH shell environments, for example, this file could be saved to ~/.ssh/

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCm+7N2tjmJw5jhPmD8MS6urZQJB42ABh73ffGQSJ0XUHgdEDfjUDFkLK0wyJCe0sF5QJnh07UQn0F0BUnBi+VwehPGeODh6S43OP5YS/14L0fyntFI06B9lckx/ygRNu82sHxXCX+6VVUFPOPC+sz6j1DQswKY9d4cEYnaMBGSzqRxrqAIf6aWIKTJTYKPFY0zaUZ6ow2iwS0Nlh5EqaXsEBWkqMmr7/auP9GV/adUgzFrGLJklYBdfH575SIK6/PZL6wNT0jE9LmFlEm7dI01ZWPclBuV16FzRyrnzmWr/ebY62A04vYBtR0vyfEfsW2ZgxgD6aAE6+ytj0v19y0elRtOaeTySN/HlXh7owKWCHnlXNpTUiSDP8SQ8LRARkhQu3KEDL0ppGCrSF87oFkp1gPzf92U+UK3LaNMMjZXMOy0zLoLEdLtbQo6S8iHggDoX4NI4sWWxcX0mtadvjy/nIOvskk9IXasQh0u0MT9ARQY5VXPluKDtEVdeow9UbvgJ1xxNkphUgsWjCiy+sjgapsuZvWqKM6TPT1i24XYaau+/Fa0vhjLb8vCMWrrtkRwGt4re243NDYcYWTzVZUFuUK0w1wqt77KgjCCeyJdsZNwrh15v780Fjqpec3EGVA0xyNbF0jn/tsnYy9jPh/6Cv767EratI97JhUxoB4gXw==