Deployment Dependencies

Squash supports linking apps/microservices from multiple code repositories. This facilitates the deployment of complex apps with multiple microservices living in separate repositories.

You can use this feature with repositories using Docker/docker-compose, and also for repos without Docker. Squash also makes it easy to automatically link matching branches between dependencies. For instance, you may define a parent deployment running on branch “abc” and have Squash automatically deploy dependencies matching the same “abc” branch, when the branch is available on each dependent repo(more info and examples below).

How it works

  • You need to define the dependency chain within the Squash YAML file, for the desired repositories.
  • Each dependency triggers its own deployment/VM on Squash. This has several benefits:
    • Each dependency is started in parallel making the entire dependency chain start faster.
    • Optimal server resources isolation for each dependency/microservice, avoiding issues where services compete with each other causing potential QA bottlenecks.
    • You can easily debug and detect issues on specific services
  • Squash supports one-to-one, one-to-many and multiple levels of dependencies (see examples below).
  • Easy way to start and restart each dependency as well as restarting or stoping the entire dependency chain at once.

Communication/link between dependencies

The way each deployment on a dependency chain communicates with each other is by using environment variables.

Child deployments:

  • Squash automatically sets a SQUASH_MASTER_DEPLOYMENT environment variable on each child deployment with the exact end point of the master deployment. This environment variable is set right after the master deployment receives a success response.
  • The content of the SQUASH_MASTER_DEPLOYMENT env variable will look like this:
    • SQUASH_MASTER_DEPLOYMENT=//js-refactor-am1y7.squash.io

Master deployments:

  • Squash automatically sets a SQUASH_CHILD_DEPLOYMENT_X environment variable on each master/parent deployment with the exact end point of each child deployment associated with the parent. These environment variables are set right after each child receives a success response.
    • The “X” component on SQUASH_CHILD_DEPLOYMENT_X is an integer, starting with 1, representing each unique child deployment.
    • This X component follows the exact order defined in the depends_on field in the Squash YAML file. Starting with 1 for the first dependency at the top of the list and so on (see examples below).
  • The content of the SQUASH_CHILD_DEPLOYMENT_X env variable will look like this:
    • SQUASH_CHILD_DEPLOYMENT_1=//js-refactor-a1w8z.squash.io

Example:

For this example we are using the most basic scenario with a one-to-one relationship:

  • CRM app: this is the actual repository that holds the YAML file below
  • API service that supplies product data to the CRM application. This API service is defined in a different repository. Repository name: “api-products”.

Squash YAML file:

deployments:
  CRM:
    filename:
      ./src/Dockerfile
    depends_on:
      - api-products

For the example above, the CRM app deployment will contain the following environment variable:

  • SQUASH_CHILD_DEPLOYMENT_1=//js-refactor-a1w8z.squash.io

And the deployment associated with “api-products” will have an environment variable similar to this:

  • SQUASH_MASTER_DEPLOYMENT=//js-refactor-am1y7.squash.io

Managing dependencies in the Squash UI

You can easily view and manage the entire dependency chain from the Squash UI, allowing you to restart specific dependencies and SSH to each VM for debugging purposes.

When loading a deployment with dependencies Squash displays right away, during its build process, each dependent deployment and their own build status:

This is how a 3 step (one parent and 2 dependencies) deployment looks like in the Squash dashboard. Note the parent deployment at the bottom and its two dependencies above. These deployments are all off branch “master”.

And when you open each deployment on a dependency chain you can see the other associated deployments within the chain:

Please note that the “Multi-Step” tab is not visible for regular deployments without dependencies. This tab is also not visible to child deployments that don’t have any dependencies.

Stop/Restart of deployments with dependencies

You may also restart or stop the entire dependency chain at once:

The following restart options are only visible to deployments with one or more dependencies:

  • Stop (+ dependencies)
  • Restart (+ dependencies)

What happens when a given deployment within a dependency chain is already running

  • Let’s use for example the following deployment chain:
    • CRM App
      • api-products
      • api-search
  • In the example above we have a parent (CRM App) with two children (api-products and api-search).
  • When we start the CRM App deployment Squash will automatically deploy api-products and api-search.
  • However, if any of the dependencies are already running Squash will skip such dependencies and they will not be associated with environment variables.

YAML file example #1

The examples below will illustrate different scenarios using the Squash depends_on field to define dependencies within the YAML file.

For this example we are using the most basic scenario with a one-to-one relationship:

  • A web app for a hypothetical CRM application.
  • API service that supplies product data to the CRM application. This API service is defined in a different repository. Repository name: “api-products”.

Squash YAML file:

deployments:
  CRM:
    filename:
      ./src/Dockerfile
    depends_on:
      - api-products

YAML file example #2

This example shows a one-to-many relationship, with 3 repositories:

  • “crm” repository: A web app for a hypothetical CRM application. This is the actual repository that holds the first YAML file defined below. This repo depends on repositories “api-products” and “api-search”.
  • “api-products” repository.
  • “api-search” repository.

Squash YAML file:

deployments:
  CRM:
    filename:
      ./src/Dockerfile
    depends_on:
      - api-products
      - api-search

For the example above we are not defining any branch names within each dependency. Squash will automatically fetch the same branch of the parent repo, if available on each dependent repository. If a matching branch doesn’t exist Squash will use the default branch (such as branch “master”) on the respective repository.

Let’s illustrate this process step by step:

  • Let’s assume we are about to test a branch named “app_v2” in the parent repository (the repo that holds the YAML file below and that defines the CRM app).
  • When we start this deployment Squash will first look for branches with the name “app_v2” on both repositories “api-products” and “api-search”. If these branches are available Squash will automatically start deployments for these branches.
  • Otherwise Squash will deploy whatever default branch is defined on each child repository (branch “master” in most cases).

You may also define specific branches on each dependency to fit your needs. For this example below Squash will only  use branch master for the child repository “api-products” (and therefore it will never attempt to use the same branch as the parent repo):

deployments:
  CRM:
    filename:
      ./src/Dockerfile
    depends_on:
      - api-products/master
      - api-search

And for this next example Squash will only use a specific application named “App2” on repository “api-search”:

deployments:
  CRM:
    filename:
      ./src/Dockerfile
    depends_on:
      - api-products/master
      - api-search:App2

Lastly, you can get even more specific and define a repository, branch and application name:

deployments:
  CRM:
    filename:
      ./src/Dockerfile
    depends_on:
      - api-products/master:App2
      - api-search

More details on specifying multiple applications in a single Squash YAML file.

YAML file example #3

This example shows a multi level relationship, with 3 repositories:

  • “crm” repository: A web app for a hypothetical CRM application. This is the actual repository that holds the first YAML file defined below.  This depends on the “api-products” repository
  • “api-products” repository. This depends on “api-search” repository
  • “api-search” repository

Squash YAML file:

“crm” repository:

deployments:
  CRM:
    filename:
      ./src/Dockerfile
    depends_on:
      - api-products

“api-products” repository:

# api-products repo
deployments:
  CRM:
    filename:
      ./src/Dockerfile
    depends_on:
      - search-service