Let’s Create a Cloudify Plugin!
Hi there – I’m Trammell, and I just joined the Cloudify team as a Cloud Solutions Architect.
Being new to a project is a unique opportunity to view things with a fresh perspective.
Seeing as I’m pretty much in the same boat as a new Cloudify user, and am just trying to learn the ropes myself, I’d like to share my discoveries through this learning process with you.
I’m going to document and share on this blog the different obstacles, epiphanies or issues I may have along the way, and attempt to help the community learn through my experiences, to ultimately help simplify the adoption process for you.
Cloudify – workflow automation through our policy engine. Try it! Go
So, I’m going to start with my initial experience with writing my first Cloudify plugin.
Discovery #1 – It actually is not as intimidating as it may seem to write a Cloudify plugin, if:
- You love reading docs (you really really need to like reading docs), or
- You have a super easy example that will show you the basics of everything that goes into a writing Cloudify plugin – that’s much more easily consumable for the average human.
But fret not – we’ll be providing a super duper easy example in this post. So we’ve got you covered.
I’m going to start from the very beginning and possibly most obvious, because I want to make sure I cover everything.
“Where shall I begin, please your Majesty?,” asked the White Rabbit
“Begin at the beginning,” the King said, very gravely, “and go on till you come to the end: then stop.”
So, what is a Cloudify plugin?
Essentially, it’s a Python package. This Python package contains operations that you want to run at certain times in a Cloudify deployment.
Cloudify has a workflow engine that executes workflows (as its name implies), which determine when such operations run.
Currently, there are three types of built-in workflows: install, uninstall, and execute operation. The example here uses install.
Install basically means that you can create, configure and start something. Advanced users can take advantage of other features, but that’s another story.
A Simple Script
Just for the sake of the learning process, let’s create a plugin that has one operation, ‘write_to_file’, which as the name suggests, just writes to a file. So, the first part is a bit of Python code that just writes to a temp file (adjust the path to your operating system):
Save that in a file called ‘tasks.py‘ in a folder called cloudify_plugin. (I give the sample directory structure you should use below).
This script can run on any machine with Python installed.
Reopen that file, because you need to add some stuff that is specific to Cloudify.
First, import the Cloudify Decorators, which allow Cloudify to manage tasks:
from cloudify.decorators import operation
Then add the operation decorator above the definition to our write_to_file task.
@operation
def write_to_file(**kwargs):
This lets Cloudify know that the function is an operation that one of its agents will need to execute.
During a Cloudify deployment process, one of two agents will execute the operation – the central deployment agent will run the script on the manager machine, or a host agent will run the script on an agent machine.
The Plugin Files
You can create a node type, and this node type will then be able to be reused by multiple node definitions in a blueprint.
Essentially all that says is, “Cloudify can deploy and execute this script during the start phase of the install workflow.”
Then, in order for Cloudify to be able to use that blueprint, you need to declare the plugins that you’re going to use within it.
Save the file as ‘plugin.yaml‘.
As you noticed, here we say which agent will run the script: central deployment agent, therefore it runs on the manager machine. If you wanted to write something to the tmp directory of every agent, you could change that to “host_agent”.
Ok, so you’ve created your script, in tasks.py, you’ve established the workflow you’d like to use, and created your node type in a YAML document called plugin.yaml.
Now, you need to package this all into a Python package.
You can use the template: https://github.com/cloudify-cosmo/cloudify-plugin-template.
<!–
Or you can see this actual plugin at: https://github.com/EarthmanT/
–>
You can save this Python package wherever you want, but for ease it would be best to save on Github like us, that way you can download it to your manager, wherever it is.
I’ve provided the directory structure of a very basic Python package, below.
./plugin_package/
./plugin_package/setup.py
./plugin_package/plugin.yaml
./plugin_package/cloudify_plugin/
./plugin_package/cloudify_plugin/tasks.py
This is the minimal information you would need to have in your setup.py file, based on what we’re looking to do:
Last thing that you need is to create a blueprint, because there’s no using Cloudify without blueprints.
Blueprints are documents that describe what Cloudify will deploy and which workflows it will use. Everything is described in terms of nodes.
So let’s create a blueprint with a single node. Import Cloudify’s types and then your own plugin.yaml types from above.
imports:
– http://www.getcloudify.org/spec/cloudify/3.1/types.yaml
– https://raw.githubusercontent.com/EarthmanT/cloudify-plugin-example/master/plugin.yaml
Next, you need a template that describes the node you want to create.
Above, we created a template and named the node “test_the_plugin”, and it is of the node type: cloudify.cloudify.example.Example
.
Cloudify works with the TOSCA standard for cloud applications. Import the TOSCA definitions by adding this to the top of that document:
tosca_definitions_version: cloudify_dsl_1_0
There you go, now you have your blueprint and your plugin.
The only thing left to do is to create a deployment and run it.
Change to the directory of the example blueprint:
$ cd cloudify_plugin/tests/blueprint/
Then initialize the cloudify CLI:
$ cfy init
Provide the URL of the manager:
$ cfy use -t my.manager.ip
Upload the blueprint:
$ cfy blueprints upload -p blueprint.yaml -b test-example
Create a deployment:
$ cfy deployments create -b test-example -d test1
And execute the workflow:
$ cfy executions start -w install -d test1
If you watch the logs you should see the executions succeed!
Here is a link to a zip file that contains everything (the blueprint, the plugin.yaml, and the plugin_package).
For more information on running deployments, see the quickstart guide: /guide/3.1/quickstart.html.
There is a lot of documentation online that can help you find all you can do with plugins. Try starting out here:
/guide/3.1/guide-plugin-creation.html
https://github.com/cloudify-cosmo/cloudify-plugin-template
A more detailed example of a plugin is the script plugin, which enables you to run shell scripts. You can learn more about it here (or in one of our upcoming blog posts – stay tuned):
/guide/3.1/plugin-script.html
https://github.com/cloudify-cosmo/cloudify-script-plugin
You can also reach out to the Cloudify users and Cloudify developers Google groups for any questions you have about what information you can get from Cloudify plugins common or the contexts for properties or anything else really about getting started with your first plugin.