Blog

Creating a Google Cloud SDK Installer for Azure Pipelines

28 Apr, 2020
Xebia Background Header Wave

Google Cloud CI/CD pipelines require Google Cloud SDK. Azure Pipelines however doesn’t provide a Tool Installer-task for it. Therefore we created it.
View all sources on GitHub.

Google Cloud CI/CD with Azure Pipelines

The following example shows a Pipeline that deploys a service to App Engine.

First Google Cloud SDK is installed using our Tool installer. Secondly a service-account credential is configured and finally the service is deployed to app engine.
This blog explains what our tool installer does and how it’s implemented.

Azure Pipelines Tool Installers

Azure Pipelines uses tasks to simplify pipeline development. Instead of specifying CLI commands a developer configures a task.
Tool installers are tasks that install and enable a tool such as Docker and Node. The installation process typically involves downloading the required version, copying it to the tool cache and setting the PATH variable.

Google Cloud SDK Tool Installer

Installing Google Cloud SDK in a continuous integration environment requires several steps:

  • download the required version;
  • add the tool to PATH;
  • apply tool configuration.
    Our tool installer downloads the tool and updates PATH. Finally it assign a pipeline-specific configuration directory to ensure that your configuration is destroyed when the pipeline ends. doesn’t apply any other configuration as this is up to the developer.
    The task is implemented using the following Node script.
import * as tasks from 'azure-pipelines-task-lib';
import * as tools from 'azure-pipelines-tool-lib';
import * as path from 'path';

async function run() {
    try {
        let version = getVersion();
        await install(version);
        setConfigurationDirectory();
    }
    catch (err) {
        tasks.setResult(tasks.TaskResult.Failed, err);
    }
}

...

async function install(version: string) {
    // Install
    let toolPath = tools.findLocalTool('google-cloud-sdk', version);

    if (!toolPath) {
        toolPath = await downloadCloudSDK(version);
        tasks.debug("google-cloud-sdk tool is cached under " + toolPath);
    }

    toolPath = path.join(toolPath, 'bin');
    tools.prependPath(toolPath);
}

function setConfigurationDirectory() {
    // Store tool configuration folder in job-specific folder.
    let configPath = tasks.getVariable("CLOUDSDK_CONFIG");
    if (configPath) {
        console.log(`Reusing google-cloud-sdk configuration directory: ${configPath} (from CLOUDSDK_CONFIG)`);
    } else {
        let tempPath = tasks.getVariable('Agent.TempDirectory');
        if (!tempPath) {
            throw new Error("Expected Agent.TempDirectory to be set");
        }

        console.log(`Configured google-cloud-sdk configuration directory: ${tempPath}`);
        tasks.setVariable("CLOUDSDK_CONFIG", tempPath);
    }
}

...

run();

View all sources on GitHub.

Running The Task

The Pipeline agent runs the script with Node. This executes the run-method due to the run-function call at line 49.

run();

Installing Google Cloud SDK

Lines 18-29 use the Tool installer-package to get or add Google Cloud SDK to the tool cache and update PATH. Using the tool-cache prevents unnecessary downloads.

async function install(version: string) {
    // Install
    let toolPath = tools.findLocalTool('google-cloud-sdk', version);

    if (!toolPath) {
        toolPath = await downloadCloudSDK(version);
        tasks.debug("google-cloud-sdk tool is cached under " + toolPath);
    }

    toolPath = path.join(toolPath, 'bin');
    tools.prependPath(toolPath);
}

Setting The Configuration Directory

Lines 31-45 adds the CLOUDSDK_CONFIG pipeline environment variable to ensure the configuration is only available for this pipeline. It uses the Task Library-package to get and update the pipeline environment.

function setConfigurationDirectory() {
    // Store tool configuration folder in job-specific folder.
    let configPath = tasks.getVariable("CLOUDSDK_CONFIG");
    if (configPath) {
        console.log(`Reusing google-cloud-sdk configuration directory: ${configPath} (from CLOUDSDK_CONFIG)`);
    } else {
        let tempPath = tasks.getVariable('Agent.TempDirectory');
        if (!tempPath) {
            throw new Error("Expected Agent.TempDirectory to be set");
        }

        console.log(`Configured google-cloud-sdk configuration directory: ${tempPath}`);
        tasks.setVariable("CLOUDSDK_CONFIG", tempPath);
    }
}

Start Using The Tool Installer

Get the task from the Marketplace and ask your administrator to install it… Or build it yourself. Clone the source repository and run:

npm ci
npx task release google google-cloud-sdk
Laurens Knoll
As a cloud consultant I enjoy taking software engineering practices to the cloud. Continuously improving the customers systems, tools and processes by focusing on integration and quality.
Questions?

Get in touch with us to learn more about the subject and related solutions

Explore related posts