How to Build Cloudify Blueprints For Portability
At present, when you write a blueprint, you are typically writing it for a particular cloud – AWS, Openstack, etc. This is probably the simplest way to do it. And so far all of our demo blueprints are also written this way.
One of Cloudify’s purported selling points is cloud portability, and by that we are talking about one blueprint for many clouds.
The truth is that Cloudify is built to be portable and it allows users to model portable blueprints using its TOSCA-based DSL. Since nodes in TOSCA are typed, simple types can derive more complex types.
Pure-Play TOSCA-based Orchestration is here with Cloudify 3.2! Go
In Cloudify, all node types are derived from the cloudify.nodes.Root type.
For example, the “Compute” type in Cloudify, which represents a host, is derived from this cloudify.nodes.Root type:
Source: https://github.com/cloudify-cosmo/cloudify-manager/blob/3.2/resources/rest-service/cloudify/types/types.yaml#L28
All of our cloud provider plugins derive compute resources from this node type. For example, AWS EC2 and Openstack:
Sources: https://github.com/cloudify-cosmo/cloudify-openstack-plugin/blob/1.2/plugin.yaml
https://github.com/cloudify-cosmo/cloudify-aws-plugin/blob/1.2/plugin.yaml
So taking node-typing a step further, it’s quite easy to make the mythical portable cloud blueprint a reality.
I took the Nodecellar example, which we use at Cloudify as a demo app, and made a single blueprint that can be used on Openstack, AWS, Cloudstack, vCloud Air, or Softlayer.
Link: https://github.com/EarthmanT/cloudify-nodecellar-example/blob/3.2-multicloud/multicloud-blueprint.yaml
Here’s a diagram of what is contained in that blueprint archive:
- The Nodecellar blueprint file.
- The “multicloud” node types, including Openstack, Cloudstack, AWS EC2, Softlayer, and vCloud air.
Depending on which cloud I am going to use, I specify the corresponding import file. That’s the only thing that I need change when moving to a different cloud.
For example, all of the clouds require a compute type. In the Nodecellar example, we need a server with monitoring, so we created a node type for it “nodecellar.nodes.MonitoredServer”.
If you’re familiar with the Cloudify Nodecellar Example, then nothing special so far.
However, whereas in the previous examples each blueprint derives “nodecellar.nodes.MonitoredServer” from the node type specific to the Cloud, the “multicloud” example derives from “nodecellar.nodes.Server”, which has been generalized:
Notice that this node type has a dictionary property defined for each cloud provider. These properties are then remapped to the plugin types depending on which cloud you deploy in. Where that mapping is defined depends on the types file that you import at the top of the blueprint.
For example, see how these are mapped for Openstack:
Pretty fun.
Now, not every type of cloud has the same requirements.
For example, Openstack and AWS require that you create Security Groups, while others don’t.
So we define a general security group for those clouds, and then for Cloudstack and other clouds that don’t need security groups, we leave that node type with no mapping or implementation:
From here, you can download the repo at github and tweak the inputs to fit your environment.
By default, the blueprint is ready for you to deploy in AWS EC2. But this can be changed to Openstack or another cloud by uncommenting the Openstack Types import and commenting the aws-ec2 types import:
Cloudify was built with mutli-cloud in mind, so try it out and let us know what you think. And since we’re open source, if you have another cloud that you can expand support for, we’d greatly appreciate it!