Operate a Deployment

Change behavior through configuration first, then move to a new version, then diagnose and remove.

Ask about this Page
Copy for AI
View as Markdown

After completing this page, you should be able to:

  • Resolve a change request by updating configuration values and redeploying, before you change code.

  • Move a Deployment to a new Connector version.

  • Diagnose a Deployment using its logs, its reports, and the resources it creates.

  • Uninstall a Connector and confirm that its resources are removed.

Prove that a change isn't configuration before you change code. Most change requests to an installed Connector are a value in its install form, and a redeploy applies them in minutes without a pull request, a tag, or a new validation run.

Zen Electron's marketing team asks for a different sender address on order confirmations, by tomorrow. By the end of this page, you can tell whether that needs a pull request, apply it, and confirm it. You can also move the Deployment to new code, diagnose the common failures, and remove the Connector cleanly.

This page applies step 2 of the adoption ladder: before you decide a Connector falls short, check whether configuration closes the gap. It operates the zen-order-confirmation-sandbox Deployment from Install and test your Connector.

Change request: a new sender address

The sender address isn't in the code. It's the SENDER_EMAIL_ADDRESS key in the mail-sender application's securedConfiguration, which the handler reads from the environment. The change is therefore a redeploy with a new value, not a pull request.

What the redeploy does to the other values

The Redeploy reference states that if you omit configurationValues, existing values are unchanged. Don't assume the same for individual keys: when you send some keys, treat the keys you omit as unknown.

Two rules keep the change safe:

  • Keep every secured value in your own secrets store. Secured values can't be read back from the Deployment after they're set, so the store is the only place you can recover them from.
  • Send the full set of values, and never a placeholder for a secured key you can't recover. Resending the full set from your secrets store works whether a redeploy merges or replaces.

For this module, the other values are stubs, so the examples that follow resend the full set with the new sender.

With the Connect CLI

Replace the sender in the CONFIG array from Stage, preview, and publish privately, then pass the whole array:
CONFIG=("${CONFIG[@]/SENDER_EMAIL_ADDRESS=orders@example.com/SENDER_EMAIL_ADDRESS=confirmations@example.com}")

commercetools connect deployment redeploy \
  --key zen-order-confirmation-sandbox \
  "${CONFIG[@]}"

With the Connect API

The Redeploy update action is the only update action on a Deployment. It also works on a Failed Deployment, so you can correct a bad configuration value without deleting the Deployment. The reference lists every state that it accepts. Use the token and variables from Stage, preview, and publish privately. Replace the sender in the CONFIGURATIONS array from Stage, preview, and publish privately, then send the whole array:
CONFIGURATIONS=$(jq 'map(.securedConfiguration |= map(
  if .key == "SENDER_EMAIL_ADDRESS" then .value = "confirmations@example.com" else . end))' <<< "$CONFIGURATIONS")

VERSION=$(curl -sS --fail-with-body "$CONNECT_URL/$CTP_PROJECT_KEY/deployments/key=zen-order-confirmation-sandbox" \
  -H "Authorization: Bearer $TOKEN" | jq .version)

jq -n --argjson version "$VERSION" --argjson configurations "$CONFIGURATIONS" '{
  version: $version,
  actions: [{ action: "redeploy", configurationValues: $configurations }]
}' | curl -sS --fail-with-body -X POST "$CONNECT_URL/$CTP_PROJECT_KEY/deployments/key=zen-order-confirmation-sandbox" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @- | jq '{status, version}'

Scripts run again

A redeploy reruns postDeploy by default. The template's postDeploy deletes and recreates the Subscription, so Messages created during that gap aren't delivered. That's why Implement and test the event app to the contract asked for repeatable lifecycle scripts.
For a change that doesn't affect the Subscription, such as a sender address, you can add --skipScripts in the CLI, or "skipScripts": true in the API, to keep the Subscription as it is. Don't skip scripts when the change affects what postDeploy creates, such as a new Message type.

Confirm the change

When the Deployment is Deployed again, import another Order as in Trigger an Order and read the logs. The stub's line now shows the new sender:
Email provider stub: email not sent {"sender":"confirmations@example.com","templateId":"order-confirmation","lineItemCount":1}

Marketing's request needed no pull request. If the change had been to the email's content or to which Orders get an email, it would have been code: a new version.

Move to a new version

A code change reaches a running Deployment through the steps in Update your Connector. Publishing runs the validation pipeline again, so a new tag can fail before any Deployment moves. With the CLI and the tag v0.2.1, the sequence is:
git tag v0.2.1 && git push origin v0.2.1

commercetools connect connectorstaged update \
  --key zen-order-confirmation \
  --repository-tag v0.2.1

commercetools connect connectorstaged publish --key zen-order-confirmation
# Wait until `connectorstaged describe` shows status Published.

commercetools connect deployment redeploy \
  --key zen-order-confirmation-sandbox \
  --updateConnector

If the Deployment still behaves the old way, one of the first three steps didn't land. Compare the tag that the Deployment runs with the tag of the published Connector and of the ConnectorStaged:

curl -sS --fail-with-body "$CONNECT_URL/$CTP_PROJECT_KEY/deployments/key=zen-order-confirmation-sandbox" \
  -H "Authorization: Bearer $TOKEN" | jq '{deployed: .connector.version, tag: .connector.repository.tag}'

curl -sS --fail-with-body "$CONNECT_URL/connectors/key=zen-order-confirmation" \
  -H "Authorization: Bearer $TOKEN" | jq '{published: .version, tag: .repository.tag}'

curl -sS --fail-with-body "$CONNECT_URL/connectors/drafts/key=zen-order-confirmation" \
  -H "Authorization: Bearer $TOKEN" | jq '{status, tag: .repository.tag, report: .publishingReport.entries}'
If the ConnectorStaged's tag is new but its status is Failed, read publishingReport: the new tag didn't pass the validation pipeline, so there's no new version to move to. If the published Connector has the new tag but the Deployment's tag is old, the redeploy ran without updateConnector.

Read logs and reports

Connect gives you three views of a Deployment. Each answers a different question.

Logs show what your application wrote while it ran. Use logs to debug a Deployment lists where to read them and how far back you can query. For Zen Electron's Connector, filter to the mail-sender application with commercetools connect deployment logs --key zen-order-confirmation-sandbox --application mail-sender. Logs are only as useful as what the application writes, which is why Implement and test the event app to the contract added the Message type, resource.id, and sequenceNumber to the success and failure lines for every decoded Message.
Reports show what Connect did while it built and deployed the application. Read them on the installation's Build details tab, or in the Deployment's details.build.report.entries:
curl -sS --fail-with-body "$CONNECT_URL/$CTP_PROJECT_KEY/deployments/key=zen-order-confirmation-sandbox" \
  -H "Authorization: Bearer $TOKEN" | jq '{status, report: .details.build.report.entries}'
Since 2 July 2026, the report updates in real time, and the release note says that a failed Deployment's report shows where and why it stopped. The report doesn't always explain why provisioning failed, so read the report first, then the logs, then the resources.
Resources show whether the Connector's lifecycle scripts did their job. postDeploy output might not appear in the Deployment logs, so query the Subscription, as in Verify the resource, not the status.
SymptomLook first at
Deployment FailedThe report, then the logs
Deployment Deployed, but no events arriveThe Subscription by key: exists, Healthy, expected Message types
Events arrive, but no email is requestedThe logs for that resource.id
The provider has no record of an email that the logs say was handed overThe provider's activity log
New code isn't runningThe Deployment's connector.version and the ConnectorStaged's publishingReport

Debug a failed Deployment

How to debug a Deployment describes the general approach. The following scenarios are the ones this Connector is likely to hit.

A configuration value is missing or rejected

Connect rejects a Deployment request that has keys connect.yaml doesn't declare, or that leaves a required global key empty. The Create Deployment and Redeploy references list these errors, such as DeploymentUnknownApplicationConfigurationKey.
A value that Connect accepts can still fail in the application. The template validates its configuration when it starts, and stops if a value is invalid. For example, a Deployment with placeholder API Client credentials can fail provisioning without a reason in its report. Check the configuration values against what the application validates on startup (mail-sender/src/validators/env.validators.js) before you change code.

Two Deployments share one Subscription

Zen Electron creates a second Deployment of the same Connector in the same Project, for example a production Deployment next to the sandbox one. Later, the team deletes the sandbox Deployment, and the production Deployment stops receiving events.

The cause is the template's fixed Subscription key, ct-connect-email-delivery-subscription. The second Deployment's postDeploy deleted the first's Subscription and created one pointing at its own topic. Deleting the sandbox Deployment then ran preUndeploy, which deleted the Subscription by the same key, leaving the production Deployment with none.

To fix it, choose one of the following:

  • Run one Deployment per Project. Delete the extra Deployment, then redeploy the remaining one so that postDeploy recreates its Subscription.
  • Derive the key from the Deployment, for example from the injected topic name, so that each Deployment owns its own Subscription. This is a code change and a new version.

The Region doesn't match

A Deployment fails with DeploymentUnsupportedRegion when its Region isn't in the ConnectorStaged's supportedRegions, as Choose the Region and environment explains. Add the Region to the ConnectorStaged's supported Regions, publish again, and deploy. Otherwise, deploy in the Project's Region unless you have a reason not to.

Check Subscription health

A Subscription that exists can still stop delivering. Its status field reports health, and the Get Health Status of Subscription endpoint returns it. Alert on any status other than Healthy in production. Each health status has its own retry window, and notifications can be dropped when the window ends. The Subscription delivery guarantees list the windows. Resolve a ConfigurationError before its window ends, and don't rely on the separate Connect broker retention for unacknowledged messages to extend it.

Uninstall and confirm cleanup

Delete the Deployment:

commercetools connect deployment delete --key zen-order-confirmation-sandbox
The command waits at a y/n prompt. Deleting runs preUndeploy, which deletes the Subscription. Confirm it with the same query as in Verify the resource, not the status. The expected result is an empty list:
curl -sS --fail-with-body -G \
  "https://api.$CTP_REGION.commercetools.com/$CTP_PROJECT_KEY/subscriptions" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode 'where=key="ct-connect-email-delivery-subscription"' \
  | jq '.count'
A count of 1 means that preUndeploy didn't run or failed. Delete the Subscription by key yourself, or it keeps sending Messages to a topic with no consumer.
To remove the Connector itself, delete the ConnectorStaged with the Connect API after every Deployment of it is gone, as Deleting a ConnectorStaged describes.
A Connector with a job application can also override the job's schedule for each Deployment. See Job. The email Connector has no job application.

Worked example: change Zen Electron's sender address

  1. Confirm the request is configuration: SENDER_EMAIL_ADDRESS is a secured key, not code.
  2. Redeploy zen-order-confirmation-sandbox with the full set of values and the new sender, using --skipScripts because the Subscription doesn't change.
  3. Wait for Deployed, import an Order, and find "sender":"confirmations@example.com" in the stub's log line.

Marketing has its new sender address the same day, with no pull request, tag, or validation run.

Key takeaways

  • Check whether a change is configuration before you change code. A redeploy with new values applies it without a new version.
  • The redeploy action leaves values unchanged when you omit configurationValues. Keep secured values in your own secrets store, because Connect can't return them.
  • A redeploy reruns postDeploy unless you skip scripts. Skip them only when the change doesn't affect what the scripts create.
  • A new version needs four steps: tag, set the repository, publish, and redeploy with updateConnector. If behavior doesn't change, compare versions and read the publishing report.
  • Logs show what your application did, reports show what Connect did, and the resources show whether the lifecycle scripts worked. Check all three.
  • A fixed Subscription key means two Deployments in one Project overwrite each other, and undeploying either removes the shared Subscription.
  • After you uninstall, confirm that preUndeploy removed the Subscription.

Test your knowledge