Set up Pull Request Sandboxes
Overview
Setting up sandboxes for pull requests enables testing earlier in the development process, catching issues before they hit any shared environment and improving code quality.
Some of the use-cases include:
- Previews: Allows team members and stakeholders to preview changes before merging.
- Integration Testing: Ensures that changes integrate well with the existing system.
- End-to-End (E2E) Testing: Facilitates comprehensive testing of the entire application flow.
High-Level Steps
1. Create a Sandbox Specification
A sandbox spec defines a set of test workloads that will be deployed and set up
with request routing. For example, let us say that we're looking to test a new
docker image for a particular microservice route
, and this route
microservice has a baseline deployment of the same name running within the
namespace hotrod
in our cluster, the sandbox specification would look as
follows:
name: route-sbx
spec:
cluster: my-cluster # name of cluster (as per app.signadot.com)
description: sandbox for route microservice
labels:
team: route-team
# ...any other metadata
ttl:
duration: 1d
forks:
- forkOf:
kind: Deployment # With respect to the baseline environment, this
namespace: hotrod # forks (clones & customizes) route only.
name: route
customizations:
images:
- image: repo/image:abcdef # new version of the image
You can verify that the sandbox is correctly set up by applying a valid sandbox specification using the CLI and checking that it becomes ready.
Note that the above shows a simplistic example of a customization, where only the image is being changed with respect to the baseline. You can learn more about all the different customizations available to you in the sandbox reference.
2. Templatize the Sandbox Specification
Once you have a valid Sandbox specification, you can templatize it so that it can be used to generate different sandboxes for each Pull Request. An example of the above sandbox that has been templatized for use in CI is shown below:
name: "@{service}-@{pr}"
spec:
cluster: my-cluster # name of cluster (as per app.signadot.com)
description: sandbox for @{service} microservice
labels:
team: "@{service}-team"
# ...any other metadata
ttl:
duration: 1d
forks:
- forkOf:
kind: Deployment # With respect to the baseline environment, this
namespace: "@{namespace}" # forks (clones & customizes) route only.
name: "@{service}"
customizations:
images:
- image: "@{image}" # new version of the image
The variables enclosed in @{...}
can be substituted at run-time when using the
Signadot CLI. For example, when creating the above sandbox, you may supply these
parameters as shown:
signadot apply -f ./my-sbx-template.yaml \
--set namespace=hotrod \
--set service=route \
--set image=repo/image:abcdef
...
Now, this sandbox template can be applied at run-time with different parameters, such that the same template can be used to create distinctly named sandboxes for each Pull Request, as well as used to create sandboxes for different microservices as well.
3. Integrate with CI/CD Pipeline
Once you have a sandbox template, you can use that to set up sandboxes for each Pull Request automatically.
For setting up the sandbox creation from your specific CI/CD pipeline, you will
need to use the signadot
CLI. For detailed instructions, refer to the guide on
integrating with CI/CD.
Best Practices
Storing Templatized Sandbox Specs
To start, a generic sandbox template can be used across many microservices. However, if a specific microservice requires more specific configuration, it can have its own sandbox template.
Some of the common locations where sandbox specifications are typically stored include:
- Source control / git within a monorepo (example)
- Source control / git in a central infrastructure repository (typically in a multi-repo setup)
- Dynamically generated within CI/CD pipeline steps
In source control, they may take the following structure to store and maintain multiple different sandbox specs as needed:
- signadot/sandbox-template.yaml
- signadot/route-sandbox-template.yaml
- signadot/frontend-sandbox-template.yaml
...
Note that sandboxes can be updated after creation from the CLI or the UI, for several more dynamic changes like adding / removing environment variables.
Deploying Workloads within a Sandbox
Usually, it is typical to deploy a single test workload within each sandbox. This is because sandboxes can later be combined using Route Groups to preview and test multiple workloads together.
It is also possible to deploy multiple workloads into a single sandbox. This is relatively rare for PR sandboxes but may apply when you have closely coupled workloads that must always be deployed in a set. In such cases, you can create a sandbox template that includes all the necessary workloads. This allows you to manage and deploy these workloads as a single unit, ensuring that they are always deployed together.
Conclusion
By setting up sandboxes for your PRs, you can enable previews, integration testing, and E2E testing in a shift-left manner. By following the steps and best practices outlined above, you can efficiently manage sandboxes and improve the overall quality and reliability of your microservices applications.