Schedule icon
AwsCLI icon
If icon
SlackIncomingWebhook icon
Log icon

AWS CodeDeploy Failed Deployment Sentinel

Audit AWS CodeDeploy for failed deployments and alert Slack with the exact deployment ID and error before it is missed.

Categories
CloudInfrastructure

A CodeDeploy deployment that fails - a health-check constraint violated, a missing application revision, a script hook that exits non-zero - produces no proactive Slack notification on its own; someone has to open the CodeDeploy console or already be watching the pipeline output. This blueprint lists recent deployments filtered server-side to Failed and alerts Slack with the exact deployment ID and CodeDeploy's own error code and message.

How it works

  1. periodic_deployment_check (io.kestra.plugin.core.trigger.Schedule) runs every 15 minutes, explicitly passing aws_region, application_name, and deployment_group_name through its own inputs: block so the flow is self-contained when the trigger fires. Shipped disabled so a manual run can be verified first.
  2. probe_failed_deployment_ids (io.kestra.plugin.aws.cli.AwsCLI) runs aws deploy list-deployments --include-only-statuses Failed, capturing the result's deployments list (IDs only) as a named task output.
  3. evaluate_failed_deployments_presence (io.kestra.plugin.core.flow.If) branches on whether that list has any entries at all.
    • then (FAILED_DEPLOYMENTS_DETECTED): get_deployment_details fetches the full deploymentsInfo objects for those IDs, then alert_failed_deployments reports each one's errorInformation.code and .message to Slack.
    • else (HEALTHY): log_deployments_healthy records a clean sweep.
  4. log_audit_complete always runs last, printing the failed count regardless of which branch fired.
  5. The errors block alerts Slack separately if the flow itself fails outright - a missing application or deployment group, or bad credentials, must not read as HEALTHY.

What you get

  • A HEALTHY/FAILED_DEPLOYMENTS_DETECTED answer computed by CodeDeploy's own server-side status filter, not by paging through every deployment (succeeded and in-progress included) and filtering client-side.
  • CodeDeploy's own errorInformation.code and .message in the Slack alert itself, instead of requiring someone to open the console to see why a deployment failed.
  • A two-step probe-then-detail pattern (list-deployments for the cheap existence check, batch-get-deployments only when something is actually found) so a routine HEALTHY check never pays for the full detail fetch.
  • A worked example of io.kestra.plugin.aws.cli.AwsCLI chaining two read-only CodeDeploy CLI calls, reusing the same corrected output-capture convention (newlines only, not spaces, stripped before the marker) as this repository's other AWS CLI-based sentinel blueprints.

Who it's for

  • Release engineering and platform teams running CodeDeploy who need an immediate signal when a deployment fails, without staring at the pipeline output or the CodeDeploy console.
  • On-call engineers who want one Slack alert with the exact deployment ID and CodeDeploy's own stated error instead of digging through the console to find it.
  • Anyone evaluating the AWS plugin who wants a worked example of AwsCLI chaining a filtered list call into a conditional detail fetch, the same pattern this repository's GuardDuty sentinel blueprint uses for a different service.

Why orchestrate this with Kestra

CodeDeploy itself has no cross-deployment-group "notify me the moment a deployment fails" primitive beyond what you wire up separately in CloudWatch Events/EventBridge and SNS, configuration that then has to be kept in sync as applications and deployment groups are added. Kestra supplies the schedule, the HEALTHY/FAILED_DEPLOYMENTS_DETECTED classification as a first-class branch, and an execution history that shows exactly when a deployment failed and what CodeDeploy's own error said about it.

Prerequisites

  • An AWS account with a CodeDeploy application and deployment group that has run at least one deployment (update aws_region, application_name, deployment_group_name).
  • AWS credentials with codedeploy:ListDeployments and codedeploy:BatchGetDeployments permission - entirely read-only, cannot modify, stop, or redeploy anything.
  • A Slack incoming webhook for alerts.

Local testing: LocalStack added CodeDeploy support from v4.5 onward, with ListDeployments confirmed supported in its own documentation; BatchGetDeployments support was not explicitly confirmed one way or the other at the time of writing, and LocalStack's own documentation notes CodeDeploy operations there are fully mocked (no genuine deployment logic runs behind the API). LocalStack also now requires its own account and auth token as of March 2026 regardless. A real AWS account remains the most complete way to exercise this blueprint.

Secrets

  • AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY: credentials for io.kestra.plugin.aws.cli.AwsCLI.
  • SLACK_WEBHOOK_URL: Slack incoming webhook used by alert_failed_deployments and the errors block.
  • In Kestra OSS (no Enterprise secrets backend), secrets are supplied as environment variables prefixed SECRET_, base64-encoded - for example SECRET_AWS_SECRET_ACCESS_KEY=$(echo -n '<your-secret-key>' | base64) - and read back in flows with {{ secret('NAME') }}.

Inputs

  • aws_region (STRING, default us-east-1): region whose deployments are audited.
  • application_name (STRING, default <your-codedeploy-application-name>, must be replaced): CodeDeploy application to audit.
  • deployment_group_name (STRING, default <your-deployment-group-name>, must be replaced): deployment group to audit.

Outputs

  • outputs.probe_failed_deployment_ids.vars.deployments: the list of failed deployment IDs (verified field from CodeDeploy's own ListDeployments API reference).
  • outputs.get_deployment_details.vars.deploymentsInfo: the full deployment objects, only populated on the alert branch, each with deploymentId, applicationName, deploymentGroupName, status, errorInformation, createTime, completeTime, deploymentOverview (verified fields from CodeDeploy's own BatchGetDeployments API reference).

Quick start

  1. Set up a CodeDeploy application and deployment group in a real AWS account and run at least one deployment.
  2. Add the AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and SLACK_WEBHOOK_URL secrets.
  3. Run the flow manually after a successful deployment and confirm log_deployments_healthy fires.
  4. Force a deployment to fail (for example, point appspec.yml at a script hook that exits non-zero) and re-run to confirm alert_failed_deployments fires with the real deployment ID and errorInformation.
  5. Enable periodic_deployment_check once you trust the check against your real deployment group.

How to extend

  • Loop over several application_name / deployment_group_name combinations with io.kestra.plugin.core.flow.Loop to audit every deployment group in an account in one run.
  • Add --create-time-range to list-deployments to scope the check to a recent window once a deployment group has accumulated enough history that unscoped Failed results start including old, already-handled failures.
  • Add a remediation branch that triggers aws deploy stop-deployment on a still-InProgress deployment that is clearly failing, behind an explicit approval gate - deliberately kept out of this sentinel so the monitoring path never stops a deployment on its own.

Pitfalls

  • batch-get-deployments accepts at most 25 deployment IDs per call, per CodeDeploy's own API reference - if probe_failed_deployment_ids returns more than 25 matching IDs, get_deployment_details fails outright rather than silently truncating, surfacing through the errors block.
  • Pagination is not handled on the list call either. list-deployments is itself paginated (nextToken); if more failed deployments exist than fit in one page, this blueprint's single call only sees the first page.
  • errorInformation is not guaranteed on every failed deployment - some failure modes populate only status: Failed without a structured code/message, which is why the Slack payload falls back to "no code" / "no message" rather than assuming the field is always present.
  • The output-capture convention (tr -d '\n' | xargs -0 -I {} echo '::{"outputs":{}}::') deliberately does not strip spaces, the same corrected pattern used throughout this repository's AWS CLI-based sentinel blueprints, since errorInformation.message is a human-readable sentence.
  • This blueprint is UNTESTED against a live AWS account. The CLI syntax, the --include-only-statuses enum, and the deployments / deploymentsInfo / errorInformation output fields are taken verbatim from AWS's own CLI reference documentation - but no Kestra engine was run to execute this flow end to end.

Links

See How

New to Kestra?

Use blueprints to kickstart your first workflows.