What are ephemeral databases?
Ephemeral databases are temporary, isolated databases that are created for the purpose of running tests or previewing features without causing any permanent changes that may impact production systems harness.io. They are part of the broader category of ephemeral environments, which are also temporary and isolated, but can include other elements like servers, memory, and storage harness.io.
The key features of ephemeral databases include:
- Integration tests are not affected by inconsistencies or pollution in the environment. This means that the tests are more reliable and accurate because they are not influenced by changes made by other developers or tests uffizzi.com.
- Optimized for resource consumption and costs. Ephemeral databases are created and destroyed as needed, which prevents them from running longer than necessary and incurring extra costs uffizzi.com.
- Support for multiple databases. Ephemeral databases can support various types of databases, including MongoDB, Redis, Postgres, and MySQL uffizzi.com.
Ephemeral databases are particularly useful for continuous testing for several reasons:
- Isolation: Each developer or test has its own database, which prevents changes from one developer or test from affecting others. This isolation greatly reduces the risk of inconsistencies and errors uffizzi.com.
- Integration into CI/CD workflow: A new ephemeral environment can be created for each PR and updated with every change to the PR, thus integrating agile development practices into the SDLC uffizzi.com.
- Resilience: If something breaks in an environment, it can be easily destroyed and a new one can be created. This makes the process more resilient to errors and failures uffizzi.com.
- Ease of creation and destruction: Ephemeral databases can be easily created and destroyed, which allows for rapid iteration and development. This is especially useful in a continuous testing environment, where tests are often run frequently and changes are made regularly uffizzi.com.
Spawn
The Spawn service is a Database-as-a-Service (DBaaS) tool developed by Redgate Foundry. Spawn enables you to easily manage databases in containers, handling all the complexity of spinning up and managing databases with you just connecting to an endpoint to use the database voiceofthedba.com.
Spawnctl - the command-line interface for the Spawn service allows you to interact with the Spawn service to create, manage, and destroy data containers. In the context of a CI/CD pipeline, Spawnctl can be used to create a data container based on a specific image, authenticate to Spawn using an access token, and retrieve information about the data container, such as the host, port, user, and password littlekendra.com.
Using Spawn for Continuous Testing in Azure Pipelines with .NET
In this tutorial, I'll share my experience using Spawn database-as-a-service to continuously test .NET project's unit tests using Azure Pipelines. For our case study, we will employ the use of a PostgreSQL data-image instantiated by Spawn.
Generating a Personal Access Token
Authentication with Spawn is straightforward. After logging into Spawn, I created a personal access token (PAT). This token facilitates automation interactions with Spawn via the Spawnctl command-line interface (CLI).
Creating Spawn Data-Image
Conceptually, think of a Spawn data image as a mold from which data containers get cast. For this project, I configured our data-image using a YAML descriptor file, postgresql.yaml, containing SQL scripts present in our Database folder. The file's content is as follows:
sourceType: scripts
name: unit-testing-db
engine: postgresql
version: 11.0
scriptsFolders:
- ./spawn-dbs
This configuration specifies that our data-image will be PostgreSQL 11.0, created from scripts located in ./spawn-dbs directory.
The pipeline
To create a pipeline for continuous testing using Spawn in Azure Pipelines, start with an empty job using the classic editor and configure the branch’s policies under the Build Validation section to be triggered when a new pull request is created in the Azure Git repository. My pipeline contains the following tasks:
- Bash task 1: Download and install the Spawnctl CLI onto our agent, create a data-container from our data-image, inject the PAT as an environment variable, and output our Spawn-controlled database connection strings. We are using a free Spawn account which allows you to have no more than 5 data-containers running at the same time, however you can set a lifetime to your data-containers so that they can be deleted shortly after the tests have been run. This being said, tests from different services are triggered daily and we need to delete residual data-containers which remain after the tests have finished, so I have added a condition which deletes the 2 oldest data-containers if there is no more space to create a new one.

curl -sL https://run.spawn.cc/install | sh
sudo apt-get install jq -y
set -e
export PATH=$PATH:$HOME/.spawnctl/bin
mapfile -t dataContainersArray < <(spawnctl get data-containers | tail -n +2)
# Check the number of containers and delete the first three if there are 5 or more
if [ ${#dataContainersArray[@]} -ge 5 ]; then
for i in {0..2}; do
containerName=$(echo ${dataContainersArray[$i]} | awk '{print \$2}')
echo "Deleting data-container: $containerName"
spawnctl delete data-container $containerName
done
fi
dataContainer=$(spawnctl create data-container --image $(DATA_IMAGE_NAME) --lifetime 30m -q )
dataContainerJson=$(spawnctl get data-container $dataContainer -o json)
server=$(echo $dataContainerJson | jq -r ".host")
port=$(echo $dataContainerJson | jq -r ".port")
user=$(echo $dataContainerJson | jq -r ".user")
password=$(echo $dataContainerJson | jq -r ".password")
EntryJobs_ConnectionString="Server=$server;Port=$port;Database=postgres;User Id=$user;Password=$password;"
# Output connection string
echo "##vso[task.setvariable variable=EntryJobsConnectionString;]$EntryJobs_ConnectionString"
spawnctl get data-containers
echo $EntryJobs_ConnectionString- Replace tokens task: This task substitutes the .NET project's appsettings.json connection string fields with our Spawn database connection string values.

- Final tasks: The Build, Restoration, and Test functions for the .NET solution
Problems with Mongo and solution
Spawn doesn’t support mongodb even though it says it does. Client library for .NET allows you to spin up an ephemeral database at the time of running the tests.
https://github.com/Mongo2Go/Mongo2Go
https://github.com/asimmon/ephemeral-mongo
Conclusion
Spawn is an indispensable tool for continuous testing in Azure Pipelines with .NET. As software development becomes more complex, it is essential to have a robust testing process that ensures the quality and reliability of software products. Continuous testing is an essential part of modern software development that enables developers to test their code continuously throughout the development process.
Spawn is particularly useful because it enables developers to focus on writing code and testing features rather than worrying about the impact on production systems. The creation of ephemeral databases that are isolated from other developers and tests reduces the risk of inconsistencies and errors. Furthermore, the ability to create and destroy databases as needed allows for rapid iteration and development. Spawn has support for multiple databases, including MongoDB, Redis, Postgres, and MySQL, making it a versatile tool for developers.
In conclusion, Spawn is an excellent tool for continuous testing that enables developers to create ephemeral databases that are isolated, optimized for resource consumption and costs, and easily created and destroyed. By using Spawn in Azure Pipelines, developers can focus on writing code and testing features without worrying about the impact on production systems, and the resilience of the testing process to errors and failures is increased.

