Deployments

Deployments #

A Deployment in Riser describes the desired state of a deployed App to a given Environment.

ℹ️ A Riser Deployment should not be confused with a Kubernetes Deployment. Any possible relationship with Kubernetes primitives should be treated as an implementation detail.

Creating a Deployment #

The primary mechanism for deploying your App is via the Riser CLI using the riser deploy command from inside of your app folder. Like Kubernetes, Riser works with Docker. Riser does not build or publish Docker images for you. See the Docker section for more details.

Assuming that you have already created your app and built and published your docker images, deploying an app with Riser is simple:

riser deploy (docker tag) (targetEnvironment)

For example, if your docker tag is v1.0 and your Environment is prod:

riser deploy v1.0 prod
ℹ️ Most users will prefer to trigger a deployment from a CI/CD system instead of manually executing the command. The Riser CLI is a single binary making it easy to integrate with all popular CI/CD systems.

Once the Deployment is complete, you may access it using the URL format: https://{deploymentName}.{namespace}.{riserdomain}. Note that the Deployment name is the same as your App name by default. (e.g. for an app named testdummy in the apps namespace with an Environment configured with the dev.mydomain.net domain: https://testdummy.apps.dev.mydomain.net). See the URL Routing section for more details.

Deployment Status #

Riser provides an app-centric view of your deployments across all Environments using the riser status command. Its goal is to surface only the most pertinent information regarding the state of your app.

riser status

Status Columns #

  • Deployment: The name of the deployment
  • Env: The name of the target Environment
  • Traffic: The percentage of traffic being routed to a particular Deployment in a target Environment
  • Rev: The Revision number
  • Docker Tag: The Docker tag
  • Status: A status representing the state of the deployment:
    • Ready: The deployment is ready to accept traffic
    • Waiting: The deployment is waiting for an operation to complete
    • Unhealthy: The deployment is not healthy (e.g. can’t pull the docker image, health check failed, etc)
    • Unknown: The deployment status is not known
  • Reason: When applicable, provides a description of the current Status

Additional Details #

To get additional information about a specific Deployment, use riser deployments describe (deploymentName) (targetEnvironment). This view provides a additional details beyond that of riser status and as a result is limited to a specific Deployment in a target Environment.

Revisions #

A Revision represents an immutable snapshot of your Deployment. A Revision is created whenever a Deployment is created (e.g. via riser deploy). A Revision contains the following state:

  • The App Config with any environment overrides applied
  • The docker tag
  • Secrets bound to your App

Docker image. A Revision is assigned a unique revision number for a given Deployment and Environment. This facilitates Traffic Management scenarios such as canary deployments and rollbacks. Note that there is no correlation between revision numbers in different environments or between different Deployment names.

Automatic Rollout #

By default, traffic is rolled out automatically when a new Deployment is created:

  1. A new Revision is created
  2. The new Revision is deployed using a Blue Green deployment. At this time no traffic is being routed to the Revision
  3. Once determined to be healthy, 100% of traffic is immediately routed to the new Revision
  4. After a period of time the old Revision is deemed inactive

Manual Rollout #

While an automatic rollout is sufficient for some use cases, there are reasons to employ a manual rollout:

  • Canary Deployments: There is a desire to test the new Deployment on a subset of traffic before doing a full rollout.
  • Rollback: There is a critical problem with a deployment that cannot be quickly fixed or “rolled forward”
ℹ️ Remember that all operations that affect the state of your app go through Git. As such, manual rollout changes will take a few moments to apply.

Canary Deployments #

A Canary style deployment can be achieved by deploying with the --manual-rollout flag.

riser deploy (docker tag) (targetEnvironment) --manual-rollout

riser status will now show two active Revisions for your Deployment. For example:

riser status

At this point, the new Revision is not receiving any traffic. In addition to reviewing traditional metrics and logging, you may also access the Revision directly using the URL format: https://r{revNumber}-{deployment}.{namespace}.{riserdomain} (e.g. https://r11-testdummy.apps.dev.mydomain.net). See the URL Routing section for more details.

You may now use the riser rollout command to route a percentage of traffic to the new Revision. The following example routes 10% of traffic to a new Revision (#11), and 90% of traffic to the old Revision (#10).

riser rollout dev r11:10 r10:90
ℹ️ The riser rollout command also supports a single wildcard rule. For example: riser rollout dev r11:10 r10:* is equivalent to the preceding command.

You may rollout the new Revision in as many or little steps as you wish. To route 100% of the traffic to the new Revision, simply specify a single traffic rule. For example:

riser rollout dev r11:100
ℹ️ While the information in this section implies manual steps, such as validating health metrics and initiating several riser rollout commands, it is encouraged to consider implementing these steps as part of an automated Deployment Pipeline.

Rollback #

A rollback is useful when there is a fatal problem with a Deployment that cannot be quickly fixed or “rolled forward”. Because a Revision in Riser contains a snapshot of all configuration state, it provides a “true rollback” of all state related to a Deployment.

Similar to a Canary style deployment, you may use the riser rollout command to rollback to a previous Revision. Simply specify the desired revision and route 100% of traffic to it. The following example routes 100% of traffic to Revision #10 in the dev environment:

riser rollout dev r10:100
ℹ️ You may use the riser status --all-revisions command to show all available revisions.

Garbage Collection #

While this history of each Revision will always be present in the Git state repo, the Revision itself will be garbage collected from the server based on criteria set by the platform operator. Typically at least 10 Revisions will be preserved. Once a Revision is garbage collected it is no longer visible to Riser.

Named Deployments #

Sometimes you’d like to test a different build of your App without needing a completely separate environment. To accommodate this, Riser supports naming your deployments. The name of your Deployment must:

  • Include your App name as the prefix, followed by a dash, followed by one or more lowercase letters, numbers, or dashes.
  • Must not collide with any other Deployment name regardless of the App or the Environment that a Deployment is deployed to.

Many deployment related operations carry the optional --name flag to specify the name of your deployment. The following example creates a Deployment named testdummy-pr-15 for the testdummy App:

riser deploy dev 0.1.2 --name testdummy-pr-15

You may access the named Deployment using the URL format: https://{deploymentName}.{namespace}.{riserdomain} (e.g. https://testdummy-pr-15.apps.dev.mydomain.net). See the URL Routing for more details.

riser status will show the status for all deployments associated with your App. For example:

riser status

Some points to observe:

  • A named Deployment gets its own unique Revision number. There is no correlation between revision numbers between different Deployment names.
  • You may control traffic routing via the riser rollout command with the --name parameter. Note that you may not route between deployments with different names.

Deleting a Deployment #

Some deployments, particularly for named deployments, are ephemeral. For example, let’s say that your deployment pipeline creates a named deployment for every pull request. You may wish to add a automation to automatically delete the deployment after the pull request is merged. Deleting a deployment is simple:

riser deployments delete <deploymentName>
Danger Zone! Deleting a Deployment deletes all associated Revisions along with it. You will still be able to review the history in Git, but Riser does not provide any sort of “undelete” mechanism. You may always create a new Deployment with similar configuration, realizing that there are no guarantees that the Deployment will be in the same state