Skip to main content

Bitbucket

Overview

This document provides an overview of integrating the Signadot CLI with Bitbucket, using Bitbucket Pipelines.

Implementing the integration follows this basic outline:

  • Adding a sandbox specification to the repository.
  • Setting up the Signadot configuration.
  • Creating the pipeline.

Finally, there is a description of an optional, more advanced custom image which speeds up CI runs by pre-installing dependencies in a custom pipelines container image.

Adding a Sandbox Specification

When a sandbox is created in a CI context, in general it needs to be tailored to run the changes represented in a pull request or commit. These customizations serve to identify the sandbox in a way that can be associated with the commit and to have the sandbox set up to run the changes in the commit.

To accomplish this, a template of the sandbox specification, in the form of a yaml file is stored within the git repository, by convention in .signadot/<service-name>-template.yaml. The sandbox template below provides a simple example that is setting up a sandbox for a single service called my-svc.

name: "@{name}"
spec:
cluster: "@{cluster}"
forks:
- forkOf:
kind: Deployment
namespace: default
name: my-svc
customizations:
images:
- image: "@{image}"

Setting up the Signadot configuration

The signadot command needs to have two parameters configured.

  1. Signadot Org, which is the name of your organization's account with Signadot. In CI contexts, this is usually easiest to accomplish by setting the environmental variable SIGNADOT_ORG when running the command.
  2. API Key, which is required to access the Signadot Control Plane. This is also usally easiest to accommplish by setting the environmental variable SIGNADOT_API_KEY when running the command, which in turn should be stored as a Bitbucket secured variable.

Both of these values are made available when a new API Key is created via the Signadot Dashboard.

Refer to Bitbucket variables for more information about setting variables.

Pipeline YAML

Below is an example Bitbucket pipeline configuration yaml file which sets up a single service sandbox for a my-svc service.

image: atlassian/default-image:4

pipelines:
default:
- step:
name: Run Tests
script:
- |
# Set up env vars
export SIGNADOT_CLUSTER=demo
export IMAGE_TAG="${BITBUCKET_COMMIT}"
# Define the sandbox name using a short version of the gitsha to respect the
# limit (30 chars)
export SANDBOX_NAME="my-svc-${BITBUCKET_COMMIT:0:6}"

# Set up Signadot CLI
apt update; apt install -y jq
curl -sSLf https://raw.githubusercontent.com/signadot/cli/main/scripts/install.sh | sh

# Create a sandbox
echo "Creating sandbox ${SANDBOX_NAME}..."
signadot sandbox apply \
--set name=${SANDBOX_NAME} \
--set image=docker-user/repo:${IMAGE_TAG} \
--set cluster=${SIGNADOT_CLUSTER} \
-f - \
< ${BITBUCKET_CLONE_DIR}/.signadot/my-svc-template.yaml

# Run the proxy. In this example we will map the in-cluster
# http://my-svc.default.svc:8080 to http://localhost:8080 (the proxy will take
# care of performing the routing key injection)
#
echo "Starting signadot proxy..."
signadot local proxy --sandbox ${SANDBOX_NAME} \
--map http://my-svc.default.svc:8080@localhost:8080 > /tmp/signadot-proxy.log &
PROXY_PID=$!
sleep 1
cat /tmp/signadot-proxy.log

# Run integration test scripts here. In this example, we use curl
# as a minimal placeholder that will run on most systems.
#
curl --fail localhost:8080

# Stop the proxy
echo "Stopping signadot proxy..."
cat /tmp/signadot-proxy.log
kill ${PROXY_PID}

# Delete the sandbox
echo "Deleting sandbox..."
signadot sandbox delete ${SANDBOX_NAME}

Set up Automatic Deletion of Sandboxes

In the previous example, we are deleting the Sandbox inline with the execution of the Run Tests step, which is fine if you are only running automated tests, but if you are also using Signadot to perform previews, you will want to keep the sandbox alive until the PR is merged or closed.

In that regard, Sandbox TTLs is a simple way to ensure deletion of sandboxes which may fit your organization's use cases. Here is an example of the previously defined sandbox spec including a TTL (defined as 10 days after the last sandbox update):

name: "@{name}"
spec:
cluster: "@{cluster}"
forks:
- forkOf:
kind: Deployment
namespace: default
name: my-svc
customizations:
images:
- image: "@{image}"
ttl:
duration: 10d
offsetFrom: updatedAt

However, using Sandbox TTLs has limitations, in particular with respect to preview URLs which do not work when their associated sandbox has been deleted. To guarantee all sandboxes are available as long as the PR is open, and that all sandboxes associated with closed PRs are deleted, you may consider using the Bitbucket ability to run pipelines in a scheduled basis (refer to Scheduled and manually triggered pipelines). This feature opens the door for running a periodic script (for example, every 30 minutes) that using the Signadot and Bitbucket APIs could reconcile the running sandboxes against the open pull requests, deleting any sandbox linked to a merged or closed PR.

Optimization with a Custom Image

Bitbucket allows using a custom docker image, and doing so can speed up the execution of the steps associated with sandboxes. A custom image for Bitbucket can be built providing the signadot command directly, as in the Dockerfile below.

# signadot
FROM signadot/signadot-cli as signadot

# here use whatever image you are using as base for performing the tests (in the
# example above atlassian/default-image:4)
FROM atlassian/default-image:4

# add the tools for working with signadot
COPY --from=signadot /signadot /usr/bin/signadot