You can use Cloud Foundry Command Line Interface (cf CLI) commands or the Cloud Foundry API (CAPI) to push your apps to VMware Tanzu Application Service for VMs (TAS for VMs) using a canary deployment.
For information about the traditional method for addressing app downtime while pushing app updates, see Using blue-green deployment to reduce downtime and risk.
For more information about CAPI, see the Cloud Foundry API (CAPI) documentation.
Canary deployments will allow users to deploy a single instance of a new version of an application and check if it is running as expected, before continuing the rolling deployment of the rest of the instances. If the new version of the application is not running as expected, the canary deployment can be cancelled.
The expected workflow for this feature is: 1. Deploy a single canary instance with the changed code 1. Manually verify that canary instance with new code runs as expected 1. Continue the rolling deployment for the remaining instances.
The procedures in this topic require one of the following:
cf CLI v8.8.0 or later
CAPI V3.173.0 or later: If you use CAPI V3, you must install the cf CLI version 8+.
This section describes the commands for working with canary app deployments.
To deploy a canary version of an app:
Caution Review the limitations of this feature before running the command. For more information, see Limitations.
For CF CLI v8:
cf push APP-NAME --strategy canary --max-in-flight MAX_IN_FLIGHT
Where APP-NAME
is the name that you want to give your app. Where MAX_IN_FLIGHT
applies after the single canary instance is successful and specifies the maximum number of new instances to start simultaneous until the deployment is complete. Optional and defaults to 1.
Note cf CLI will exit when the canary instance is healthy. It also includes a --no-wait
flag on push for users who don't want to wait for the operation to complete.
To cancel, see Cancel a canary deployment.
For CAPI V3:
Log in to the cf CLI.
cf login
Create an empty app by running the following curl
command with POST /v3/apps
. Record the app GUID from the output.
cf curl /v3/apps \
-X POST \
-H "Content-type: application/json" \
-d '{
"name": "APP-NAME",
"relationships": {
"space": {
"data": {
"guid": "SPACE-GUID"
}
}
}
}'
Where:
APP-NAME
is the name that you want to give your app.SPACE-GUID
is the space identifier that you want to associate with your app.Create a package with the following curl
command with POST /v3/packages
. Record the package GUID from the output.
cf curl /v3/packages \
-X POST \
-H "Content-type: application/json" \
-d '{
"type": "bits",
"relationships": {
"app": {
"data": {
"guid": "APP-GUID"
}
}
}
}'
Where APP-GUID
is the app GUID that you recorded in an earlier step. This app GUID is a unique identifier for your app.
Upload the package bits by running the following curl
command with POST /v3/packages/PACKAGE-GUID/upload
.
cf curl /v3/packages/PACKAGE-GUID/upload \
-X POST \
-F bits=@"PACKAGED-APP" \
Where:
PACKAGE-GUID
is the package GUID that you recorded in an earlier step.PACKAGED-APP
is your app packaged in a file such as .zip
.Create the build by running the following curl
command with POST /v3/builds
. Record the droplet GUID from the output.
cf curl /v3/builds \
-X POST \
-H "Content-type: application/json" \
-d '{
"package": {
"guid": PACKAGE-GUID"
}
}'
Where PACKAGE-GUID
is the package GUID that you recorded in an earlier step.
Deploy your app by running the following curl
command with POST /v3/deployments
. To verify the status of the deployment or take action on the deployment, record the deployment GUID from the output.
cf curl /v3/deployments \
-X POST \
-H "Content-type: application/json" \
-d '{
"droplet": {
"guid": "DROPLET-GUID"
},
"options": {
"max_in_flight": MAX_IN_FLIGHT
},
"strategy": "canary",
"relationships": {
"app": {
"data": {
"guid": "APP-GUID"
}
}
}
}'
Where DROPLET-GUID
and APP-GUID
are the GUIDs that you recorded in earlier steps. Where MAX_IN_FLIGHT
is an integer that applies after the single canary instance is successful and specifies the maximum number of new instances to start simultaneous until the deployment is complete. Optional and defaults to 1.
For more information about this command, see How it works.
To finish the deployment after validating the canary:
For cf CLI v8+, run:
cf continue-deployment APP-NAME
Where APP-NAME
is the name of the app.
For CAPI V3, run:
cf curl /v3/deployments/DEPLOYMENT-GUID/actions/continue" -X POST
Where DEPLOYMENT-GUID
is the GUID of the deployment that you recorded after following the CAPI procedure in Deploy an app.
This continues the rolling deployment of the app.
To stop the deployment of an app that you pushed:
For cf CLI v8+, run:
cf cancel-deployment APP-NAME
Where APP-NAME
is the name of the app.
For CAPI V3, run:
cf curl /v3/deployments/DEPLOYMENT-GUID/actions/cancel" -X POST
Where DEPLOYMENT-GUID
is the GUID of the deployment that you recorded after following the CAPI procedure in Deploy an app.
This reverts the app to its state from before the deployment started by: * Removing any deployment artifacts * Resetting the current_droplet
on the app
Note The cancel command is designed to remove the canary instance of the app.
If this command is used after continue-deployment it will behave like a cancelation of a rolling deployment.This section describes the canary deployments and their limitations.
This section describes pushing an app with a canary deployment strategy.
The cf push APP-NAME --strategy canary
command:
cf app
on your app, you see multiple web
processes. After the command creates the deployment, the cc_deployment_updater
BOSH job runs in the background, updating deployments as follows:
Important This happens only if all instances of the new web process are running.
PAUSED
.After validating that the canary instance is running as expected execute the command cf continue-deployment APP-NAME
:
DEPLOYING
and starts doing a rolling deploymentAfter the command changes the status of the deployment, the cc_deployment_updater
BOSH job runs in the background, updating deployments as follows:
Important This happens only if all instances of the new web process are running.
DEPLOYED
.The following table describes the limitations of when using canary deployments.
Limitation | Description |
---|---|
Multiple app versions | During a deployment, TAS for VMs serves both the old and new version of your app at the same route. This can lead to user issues if you push backwards-incompatible API changes. |
Database migrations | Deployments do not handle database migrations. Migrating an app database when the existing app is not compatible with the migration can result in downtime. |
Non-web processes | Canary deployment will only create an instance of the web process. |
Quotas | Pushing updates to your app using a deployment strategy creates up to `max_in_flight` new instances (defaults to 1) . If you lack sufficient quota, the deployment fails. Administrators might need to increase quotas to accommodate deployments. |
Simultaneous apps when interrupting a push | If you push app before your previous push command for the same app has completed, your first push gets interrupted. Until the last deployment completes, there might be many versions of the app running at the same time. Eventually, the app runs the code from your most recent push. |
V3 APIs | During a canary deploy for an app, requests to the V3 APIs for scaling or updating a process fail with an error message like Cannot scale this process while a deployment is in flight. . For more information, see Scale a process or Update a process in the CAPI V3 documentation. |
Evaluating the Canary Instance | Because the current processes share the same route, the best way to validate that traffic is reaching the canary instance by looking at the logs. If app revision logging is enabled, the logs for all instances will be tagged with `process_id` and `revision_version` values. e.g. `APP/REV/4/PROC/WEB/1` Retrieve the logs by running the cf CLI command `cf logs APP_NAME`. |
New or stopped applications | When pushing an application for the first time, or if the app is stopped, no deployment strategy is used and all application instances are started immediately. |
You can use CAPI to view the status of canary deployment.
To view the status of a canary deployment:
Log in to the cf CLI:
cf login
Find the GUID of your app by running:
cf app APP-NAME --guid
Where APP-NAME
is the name of the app.
Find the deployment for that app by running:
cf curl GET /v3/deployments?app_guids=APP-GUID&status_values=ACTIVE
Where APP-GUID
is the GUID of the app. Deployments are listed in chronological order, with the latest deployment displayed as the last in a list.
Run:
cf curl GET /v3/deployments/DEPLOYMENT-GUID
Where DEPLOYMENT-GUID
is the GUID of the canary deployment.
cf curl GET /v3/deployments/DEPLOYMENT-GUID
returns these status properties for canary deployments:
status.value
: Indicates if the deployment is ACTIVE
or FINALIZED
.
status.reason
: Provides detail about the deployment status.
status.details
: Provides the timestamp for the most recent successful health check. The value of the status.details
property can be nil
with no successful health check for the deployment. For example, there might be no successful health check if the deployment was cancelled.
The following table describes the possible values for the status.value
and status.reason
properties:
status.value |
status.reason |
Description |
---|---|---|
ACTIVE |
DEPLOYING |
The deployment is deploying. |
ACTIVE |
PAUSED |
The deployment is paused waiting for the user to continue with the deployment. |
ACTIVE |
CANCELLING |
The deployment is cancelling. |
FINALIZED |
DEPLOYED |
The deployment was deployed. |
FINALIZED |
CANCELLED |
The deployment was cancelled. |
FINALIZED |
SUPERSEDED |
The deployment was stopped and did not finish deploying because there was another deployment created for the app. |