Skip to main content

CI/CD

Integrate Speedscale into your CI/CD workflow to enable high-velocity deployment with confidence.

Run Speedscale after your build and unit tests, but before deploying to production.

CI Pipeline

Adding anything to your CI/CD pipeline generally involves the same 3 steps:

  1. adding a step to your pipeline
  2. setting the right environment variables
  3. executing the right script to perform a desired action

Let's walk through these steps for Speedscale.

Prerequisites

In order to integrate Speedscale into your CI/CD you will need:

Direct access to your Kubernetes cluster is optional.

info

Speedscale can also be run in Docker

The Pipeline

info

Every CI system has a different way of setting the PATH for actions, make sure ~/.speedscale is in the path after running the installer script.

The speedscale.sh script can be implemented a few ways. Choose the one that makes the most sense for your environment.

version: "2.1"
orbs:
kubernetes: circleci/kubernetes@1.3.1 # <--- if using kubectl - see below
jobs:
speedscale:
docker:
- image: "cimg/python:3.10"
environment:
SERVICE: my-service # <--- Speedscale environment variables - see below
steps:
- kubernetes/install-kubectl: # <--- if using kubectl - see below
kubectl-version: << parameters.kubectl-version >>
- run:
command: |
export PATH=${PATH}:${HOME}/.speedscale
./speedscale.sh # <--- Speedscale script - see below

See a full config.yml for more context.

The Environment

Set these environment variables to configure the replay, either in the script or through the CI/CD platform:

VariableExample ValueDescription
CLUSTERmy-clusterName of the cluster running the Speedscale Operator.
SERVICEmy-serviceService name as displayed at https://app.speedscale.com.
NAMESPACEmy-nsKubernetes namespace where your service is running.
TEST_CONFIGstandardTest configuration defined at https://app.speedscale.com/config.
SNAPSHOT_IDlatestUse the latest snapshot for this service.
TIMEOUT10mMaximum amount of time to wait for replay to complete.
BUILD_TAGv1.2.3Identifies the version of your service being tested.
Namespace inference

If NAMESPACE is omitted (or --namespace is not passed), speedctl infra replay will infer the namespace automatically when the snapshot was captured from a single namespace. If the snapshot spans multiple namespaces the variable is required.

The Script

Let's fill in the speedscale.sh script shown above. Choose the implementation that makes the most sense for your environment.

If you do not have cluster access the replay can be started and validated with speedctl.

In addition to the other environment variables, your speedscale API key should be set (securely) for authentication:

VariableExample ValueDescription
SPEEDSCALE_API_KEY2ca17dbe5b3b7a4f15f926b83d1ed567a98d38a3e47beService account API key created from https://app.speedscale.com/tenant
#!/usr/bin/env sh

if [ -z "$SPEEDSCALE_API_KEY" ];then
echo "SPEEDSCALE_API_KEY is required"
exit 1
fi

echo "installing speedctl"
sh -c "$(curl -Lfs https://downloads.speedscale.com/speedctl/install)"

echo "creating replay for service $SERVICE in cluster $CLUSTER in namespace $NAMESPACE"
REPORT_ID=$(speedctl infra replay "$SERVICE" \
--cluster "$CLUSTER" \
--namespace "$NAMESPACE" \
--test-config-id "$TEST_CONFIG" \
--snapshot-id "$SNAPSHOT_ID" \
--id-only \
--build-tag "$BUILD_TAG")

echo "waiting for replay with report ID $REPORT_ID to complete"
speedctl wait report "$REPORT_ID" \
--timeout "$TIMEOUT"

# exit script with the code from wait report command
exit $?

Customising Mock Behaviour in CI

The speedctl infra replay command supports several flags to control which outbound dependencies are mocked during a pipeline run. These can be passed directly in your speedscale.sh script or added as additional environment variables.

Disable all mocks

Pass --no-mocks to send real outbound traffic instead of using recorded responses:

REPORT_ID=$(speedctl infra replay "$SERVICE" \
--cluster "$CLUSTER" \
--namespace "$NAMESPACE" \
--test-config-id "$TEST_CONFIG" \
--snapshot-id "$SNAPSHOT_ID" \
--id-only \
--build-tag "$BUILD_TAG" \
--no-mocks)

Mock only specific dependencies

Use --mock-only (repeatable) to mock a subset of outbound services and call everything else live. Selectors accept svc:<substring>, host:<hostname>, glob:<pattern>, or an exact service key.

REPORT_ID=$(speedctl infra replay "$SERVICE" \
--cluster "$CLUSTER" \
--namespace "$NAMESPACE" \
--test-config-id "$TEST_CONFIG" \
--snapshot-id "$SNAPSHOT_ID" \
--id-only \
--build-tag "$BUILD_TAG" \
--mock-only 'svc:payments' \
--mock-only 'host:api.stripe.com')

Exclude specific dependencies from mocking

Use --mock-except to mock everything except the listed services:

REPORT_ID=$(speedctl infra replay "$SERVICE" \
--cluster "$CLUSTER" \
--namespace "$NAMESPACE" \
--test-config-id "$TEST_CONFIG" \
--snapshot-id "$SNAPSHOT_ID" \
--id-only \
--build-tag "$BUILD_TAG" \
--mock-except 'svc:db')

Exclude inbound services from replay

Use --exclude-in (repeatable) to skip specific inbound services so they are not replayed:

REPORT_ID=$(speedctl infra replay "$SERVICE" \
--cluster "$CLUSTER" \
--namespace "$NAMESPACE" \
--test-config-id "$TEST_CONFIG" \
--snapshot-id "$SNAPSHOT_ID" \
--id-only \
--build-tag "$BUILD_TAG" \
--exclude-in 'svc:frontend')

Preview the mock plan without running a replay

During pipeline development you can validate your selector configuration with --dry-run-mocks. This prints the resolved mock plan and exits without triggering a replay:

speedctl infra replay "$SERVICE" \
--cluster "$CLUSTER" \
--snapshot-id "$SNAPSHOT_ID" \
--mock-only 'svc:payments' \
--dry-run-mocks -o pretty

See the full replay reference for a complete list of flags and selector syntax.

Need Help?

Let us know on the community Slack if instructions for your deploy system are not included here.