Recently, we collaborated with NooBaa, a company that provides cloud-based data abstraction, including a hybrid approach between on-premises and cloud-based storage. Their offerings support S3 and Lambda APIs that run using integrated Windows and Linux servers, Azure Blob Storage and AWS S3 resources within a single namespace. Other partners we have worked with, including Jenkins, Cloudera, and MongoDB, have had similar requirements.
Previously, NooBaa had four separate, semi-manual processes (one for each cloud platform) to execute the following pipeline:
These processes require one or more people to perform, as well as appropriate knowledge of each cloud platform on which the customer wishes to deploy their solution. The requirements for this pipeline, including the fact it contains manual tasks, turns it into a bottleneck that prevents NooBaa from running their pipeline more than once a month.
The goal of our collaboration was to enable NooBaa to achieve a seamless implementation of the following:
- Continuous Delivery (CD) to Azure Marketplace
- CD to any of their targeted clouds (using an abstraction layer to perform the CD from Jenkins)
Alternatives
We evaluated multiple CD offerings.  For NooBaa’s requirements, the best choice was Spinnaker. However, Spinnaker is better suited to deploying large environments consisting of many computers or services. In addition, Spinnaker is relatively expensive, even for small-scale deployments, which could make it less suitable for small or medium businesses (SMBs) and/or single VMs that will end up as offerings in the marketplace.
Code Alternatives
We found two OSS code repositories that abstract tasks that need to be performed in the cloud:
- pkgcloud: https://github.com/pkgcloud/pkgcloud (Node.js) – the only Node.js repo we found for this purpose
- libcloud: https://libcloud.apache.org/ (Python)
We ended up using pkgcloud. Since NooBaa had already written a lot of code with Node.js, pkgcloud made integrating into and importing from their existing code base a lot easier. While pkgcloud supports ASM on Azure, it does not support Azure Resource Manager (ARM).
Therefore we collaborated with Nooba to provide ARM support for pkgcloud.
Solution
Our collaboration was divided into three parts:
ARM Support for pkgcloud
We added ARM support to pkgcloud using a pull request. Currently, we now support compute, storage and file management on ARM.
Cloud CD GitHub Repo
We then created a new GitHub Repository: called cloud-cd, or Continuous Delivery Abstraction for Cloud Platforms. This repo abstracts the continuous delivery actions of the Create VM (using pkgcloud), Get VM (using pkgcloud), Remote Execution on Linux or Windows (using outputs from pkgcloud for running scripts on new VMs) and Destroy VM (using pkgcloud) processes.
Integrating cloud-cd into Jenkins
The integration of cloud-cd into Jenkins enables pipeline management. We did not implement some of the pipeline actions in the scope of this solution; NooBaa plans to do so in future.
The implementation of cloud-cd enables us to perform actions using simple commands such as:
cloudCD.createVM("azure", azureConfig.server);
cloudCD.remoteExecute(azureConfig.server, scriptPath);
Jenkins Integration
Jenkins is the leading open source automation server, providing hundreds of plugins to support building, deploying and automating any project. We wanted to use NooBaa’s Jenkins server to manage the process of continuous delivery to multiple cloud marketplaces.
Once we had the code ready, we needed an executable Node program with parameters. For this reason, we added the following exec.js file (full description of the executable available on GitHub).
exec.js:
var actions = require('./lib');
var action = process.argv[2];
var provider = process.argv[3];
var configString = process.argv[4];
var config = JSON.parse(configString);
var providerConfig = config[provider];
// ...
switch (action) {
case 'create':
var createVMClient = new actions.CreateVMAction(providerConfig.connection);
createVMClient.perform(providerConfig.server, function (err, server) {
if (err) {
return console.error(err);
}
console.dir(server);
});
break;
// Other cases...
}
Next, we need to call this executable from Jenkins. Let’s see how to do this call for creating a VM using the following steps:
First, create a new job in Jenkins.
Second, create 3 variables:
action
=create
json_config
={... full json configuration ...}
options
= This is optional and can be supplied for remote execute and delete
config.sample.json (available on GitHub):
{
"azure-v2": {
"connection": {
"provider": "azure-v2",
"subscriptionId": "1a56e85b-c5ed-4251-a1a7-995a1957dd40",
"resourceGroup": "resource-group",
"servicePrincipal": {
"clientId": "c6b93eba-476c-4145-a6b9-a3c52d116331",
"secret": "xasdFAsdfasdASdfasdfASdfAsdfasdfaaWrTHrfGXCVSd=",
"domain": "47ad00f4-f33f-4005-b4c6-4d6f7b3b1ada"
}
},
"server": {
"name": "vm-server-name",
"flavor": "Standard_D1",
"username": "pkgcloud",
"password": "Pkgcloud!!",
"storageOSDiskName": "osdisk",
"storageDataDiskNames": ["datadisk1"],
"osType": "Linux",
"imagePublisher": "Canonical",
"imageOffer": "UbuntuServer",
"imageSku": "16.04.0-LTS",
"imageVersion": "latest"
}
}
}
Third, create an action with the following command:
export NVM_DIR=/usr/local/nvm
. /opt/nvm/nvm.sh
nvm install 6.9.5
nvm use 6.9.5
cd $WORKSPACE
npm install
node exec.js $action azure $json_config $options
Opportunities for Reuse
Both pkgcloud and cloud-cd are reusable in any scenario that requires continuous delivery of a VM image to multiple cloud marketplaces.
Projects that need to perform abstracted actions on multiple cloud platforms — like create vm
, destroy storage
, etc. — can also use the knowledge from this project as a good starting point.
0 comments