New to Kestra?
Use blueprints to kickstart your first workflows.
Audit an Azure AI Foundry deployment's model, alert Slack on drift from the approved version, and log the result for AI platform teams.
A production AI deployment's underlying model can change without the team that approved it ever finding out: a redeploy that quietly points at a newer model version, a shared deployment someone repointed at a different model entirely. Azure AI Foundry's own console shows the current configuration if someone opens it; it does not compare that configuration against what was actually approved or notify anyone when it drifts.
This blueprint was created by Mohit Jeswani.
get_deployment (io.kestra.plugin.azure.aifoundry.GetDeployment) fetches
deployment_name's real configuration via the Azure AI Projects DeploymentsClient,
authenticated with Entra ID (service principal). Read-only; nothing in Azure AI Foundry
is changed. allowFailure: true covers a missing deployment or an auth error without
failing the flow outright.evaluate (io.kestra.plugin.core.output.OutputValues) compares the real modelName
(and, when set, modelVersion) against expected_model_name/expected_model_version.route (io.kestra.plugin.core.flow.If):summary logs the final severity, closing the governance cycle.errors alerts Slack if the flow itself fails, for example an expired service principal
secret.CRITICAL vs. MODEL_DRIFT) so you know which one happened without reading logs.aifoundry.GetDeployment used as a standing compliance check, the first blueprint in this
repo to use the aifoundry sub-package of the Azure plugin at all.Azure AI Foundry reports a deployment's configuration on request; it does not know what
your organization approved, compare the two, or notify a Slack channel when they diverge.
Kestra keeps expected_model_name/expected_model_version as flow inputs instead of
institutional memory, turns a drift into a Slack page naming the exact model and version
found, and keeps a full execution history of every check.
tenantId, clientId, clientSecret) with read
access to that project; API-key authentication is not supported by this specific client.This flow calls the Azure AI Foundry API directly over HTTPS; there is no official local
Azure AI Foundry emulator, so get_deployment cannot be exercised against a local Docker
container.
AZURE_TENANT_ID / AZURE_CLIENT_ID / AZURE_CLIENT_SECRET: the Entra ID service
principal credentials used by get_deployment. In Kestra OSS, provide them as the
base64-encoded environment variables SECRET_AZURE_TENANT_ID, SECRET_AZURE_CLIENT_ID,
and SECRET_AZURE_CLIENT_SECRET.SLACK_WEBHOOK_URL: used by alert and the errors block. In Kestra OSS, provide it as
the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.| Input | Default | Purpose |
|---|---|---|
deployment_name |
gpt-4o |
Deployment to audit |
expected_model_name |
gpt-4o |
Model name the deployment is approved to run |
expected_model_version |
`` (empty) | Model version to enforce; blank skips the version check |
{{ outputs.get_deployment.name }} / .type / .configuration: the real deployment, as
GetDeployment reports it (configuration.modelName, .modelVersion, .modelPublisher,
.connectionName).{{ outputs.evaluate.values.actual_model_name }} / .actual_model_version: the real
model identity found.{{ outputs.evaluate.values.severity }}: OK, MODEL_DRIFT, or CRITICAL.GetDeployment only supports Entra ID (service principal) authentication; setting an
apiKey on this task makes it throw immediately, by design, since the underlying Azure
client has no API-key code path.configuration.modelName/.modelVersion are only populated when the deployment is a
ModelDeployment; a different deployment type on the same endpoint reports unknown for
both here rather than a false match.expected_model_version blank intentionally only enforces the model name; set a
real version once your deployment's rollout process pins to specific versions.AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and
SLACK_WEBHOOK_URL secrets.ai_foundry_endpoint and deployment_name to a real deployment.expected_model_name/expected_model_version to match its current real
configuration, run the flow, and confirm compliant logs the match.expected_model_name to a different value to confirm alert fires as
MODEL_DRIFT.daily trigger.deployment_name values with io.kestra.plugin.core.flow.Loop to
audit every production deployment in a project in one scheduled run.connectionName to the drift check alongside model name and version, to also catch a
deployment silently repointed at a different backing connection.