Logic Apps Hybrid runs Standard workflows on your own infrastructure: an Arc-enabled Kubernetes cluster that appears in Azure as a connected environment. You still author and manage the workflows in Azure, but the runtime is yours. Until now, setting up CI/CD for this meant writing the ARM template and the pipeline YAML by hand, and working out a few Hybrid-specific details along the way. The Azure Logic Apps (Standard) extension for Visual Studio Code can now generate all of it for you: the infrastructure template, its parameter file, and both pipelines. A separate Azure DevOps extension supplies the pipeline tasks that do the Hybrid-specific work. This post covers the whole path: generating the assets, what is inside them, the service connections and variables you need to supply, and running both pipelines. Three things work differently in Hybrid than in a cloud-only Standard deployment. The generated assets handle all of them, but the pipelines are much easier to follow once you know what they are. Infrastructure as code for Standard normally produces managed API connections that authenticate with Hybrid connections use The A Hybrid logic app uses Azure Container Apps on Arc-enabled Kubernetes. It is deployed as a There is no App Service publishing involved. The package is posted to the Hybrid logic app’s A CI pipeline that packages your workflows and publishes the application ZIP and infrastructure templates, and a CD pipeline that deploys the infrastructure and releases the package to your Hybrid logic app. The runtime runs on your Arc-enabled Kubernetes cluster, with SQL for workflow state and an SMB share for application content. This post assumes the Hybrid environment already exists. If you have not set one up yet, follow the official guide to set up your infrastructure for Standard logic app workflows with hybrid deployment. For an automated AKS-based evaluation environment, you can also use the Azure Arc Jumpstart template, Hybrid deployment for Azure Logic Apps on AKS. Use it for evaluation and validation, not as a production reference architecture. On the Azure side you need: On the tooling side: Install the Azure DevOps extension before you create the pipelines. It provides the pipeline tasks used below as well as the Hybrid Logic App service connection type, and without it the YAML fails validation with an unknown task error. Open your Logic App Standard project in VS Code and work through the wizard: A couple of things happen for you here. The connected environment list only shows environments in the same region as the resource group you picked, so you cannot end up with a cross-region mismatch. The environment’s resource group is read from its resource ID rather than typed in, which helps because the connected environment often sits in a different resource group from the logic app. The wizard creates a It also creates the secrets and app settings the runtime needs, among them: The sensitive values (
Overview
Things to consider first
Connections cannot use managed identity
ManagedServiceIdentity. That does not work in Hybrid, because the runtime executes inside a container on your own cluster where no Azure managed identity is available.
ActiveDirectoryOAuth with a Microsoft Entra ID app registration instead. The Hybrid Build task rewrites this at build time, so you do not have to. Any *-Authentication parameter of type ManagedServiceIdentity becomes:
{
“type”: “ActiveDirectoryOAuth”,
“tenant”: “@appsetting(‘WORKFLOWAPP_AAD_TENANTID’)”,
“clientId”: “@appsetting(‘WORKFLOWAPP_AAD_CLIENTID’)”,
“secret”: “@appsetting(‘WORKFLOWAPP_AAD_CLIENTSECRET’)”,
“audience”: “https://management.core.windows.net/”
}
@appsetting() references resolve at runtime against Container App environment variables that the infrastructure template sets. The same package can therefore go to any environment; only the app settings change.
The runtime runs on your cluster
Microsoft.App/containerApps resource with kind: workflowapp, tied to your cluster through a custom location. Workflow content lives on an SMB file share mounted at /home/site/wwwroot.
Deployment goes through a ZIP deploy endpoint
zipdeploy endpoint, authorized with a bearer token from the client credentials flow. That is why the release task needs its own Hybrid Logic App service connection holding the Entra ID tenant, client ID, and client secret.
What you’ll build
Prerequisites
Microsoft.App/connectedEnvironments) and a custom location
Step 1 — Generate the deployment scripts from VS Code
Step 2 — Review what was generated
deployment folder in your workspace:
deployment/
└── <logic-app-name>/
├── infrastructure/
│ ├── hybrid-logicapp-template.json
│ └── hybrid-logicapp-parameters.json
├── pipelines/
│ ├── CI-pipeline.yml
│ ├── CI-pipeline-variables.yml
│ ├── CD-pipeline.yml
│ └── CD-pipeline-variables.yml
└── workflowparameters/
└── parameters.json
The infrastructure template
hybrid-logicapp-template.json deploys:
Resource
Purpose
Microsoft.App/connectedEnvironments/storagesRegisters the SMB file share with the connected environment
Microsoft.App/containerApps (kind: workflowapp)The Hybrid logic app, pinned to your custom location, with the file share mounted at
/home/site/wwwroot
Workflows.Sql.ConnectionString for the runtime state store
WORKFLOWAPP_AAD_TENANTID, WORKFLOWAPP_AAD_CLIENTID, WORKFLOWAPP_AAD_CLIENTSECRET and WORKFLOWAPP_AAD_OBJECTID, which the rewritten connection authentication resolves against
APP_KIND, FUNCTIONS_EXTENSION_VERSION and IS_ZIP_DEPLOY_ENABLED for runtime configuration
sqlConnectionString, fileSharePassword, aadClientSecret) are declared as securestring and passed in by the pipeline at deployment time, so nothing sensitive is committed to the repository.
The CI pipeline
jobs:
– job: logic_app_build
displayName: ‘Build and publish Hybrid Logic App’
steps:
– task: AzureLogicAppsHybridBuild@0
displayName: ‘Azure Logic Apps Hybrid Build’
inputs:
sourceFolder: ‘$(Build.SourcesDirectory)/$(sourceFolderName)’
deploymentFolder: ‘$(System.DefaultWorkingDirectory)/deployment/$(logicAppName)/’
archiveFile: ‘$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip’
– task: PublishPipelineArtifact@1
displayName: ‘Publish logic app zip artifact’
…
– task: PublishPipelineArtifact@1
displayName: ‘Publish infrastructure artifacts’
…
The Hybrid Build task copies the project, skipping local-only files such as local.settings.json, applies the authentication rewrite described above, and produces the deployment ZIP. It publishes the application package and the infrastructure templates as separate artifacts, so CD deploys exactly what CI built.
The CD pipeline
– task: AzureResourceManagerTemplateDeployment@3
displayName: ‘Deploy Hybrid Logic App Infrastructure’
…
– task: AzureLogicAppsHybridRelease@0
displayName: ‘Azure Logic Apps Hybrid Release’
…| Task | What it does |
|---|---|
AzureResourceManagerTemplateDeployment@3 |
Deploys the Hybrid logic app and registers its file share, injecting the three secrets as override parameters |
AzureLogicAppsHybridRelease@0 |
Resolves the Hybrid logic app’s deployment endpoint, applies runtime settings, acquires an Entra ID token, and deploys the ZIP package |
Known limitation. The generated CD pipeline also contains a Deploy Managed Connections step, gated by a
deployConnectionsvariable. Deploying managed API connections for Hybrid is not supported yet, so leavedeployConnectionsset tofalse. Create any managed connections your workflows need separately for now.
Step 3 — Commit and push
Commit the generated deployment folder together with your logic app project and push to your Azure DevOps repository. Both pipelines read their templates and variables from the repo.
Step 4 — Create the service connections
Hybrid deployment uses two service connections. Both are created under Project settings > Service connections.
Azure Resource Manager. Used to deploy the infrastructure and to read and update the Hybrid logic app’s configuration. Select your subscription and give it a name, for example azureServiceConnection.
Hybrid Logic App. Used to authenticate against the ZIP deploy endpoint. This connection type comes from the Azure DevOps extension. Supply the Entra ID tenant ID, the app registration’s client ID, and its client secret, then name it, for example hybridServiceConnection.
Step 5 — Fill in variables and secrets
The generated variable files contain placeholders. Replace them with your own values.
pipelines/CI-pipeline-variables.yml
variables:
logicAppName: ‘my-hybrid-logicapp’
# Folder in the repo that contains the Logic App project (host.json, workflows).
# This is the local project name, which can differ from the deployed Logic App name above.
sourceFolderName: ‘my-project-folder’
logicAppCIArtifactName: ‘logic-app-artifact’
sourceFolderNameis the folder in your repository that containshost.jsonand your workflows.logicAppNameis the name of the deployed Hybrid logic app, and it also decides thedeployment/<logicAppName>/folder path. The two are often different, which is why they are separate variables.
pipelines/CD-pipeline-variables.yml
variables:
azureServiceConnection: ‘<your-azure-service-connection>’
hybridServiceConnection: ‘<your-hybrid-service-connection>’
subscriptionId: ‘<your-subscription-id>’
containerAppName: ‘my-hybrid-logicapp’
resourceGroupName: ‘<your-resource-group>’
location: ‘<your-location>’
logicAppCIArtifactName: ‘logic-app-artifact’
logicAppEnvironment: ‘production’
deployConnections: ‘false’Set deployConnections to false, as noted in the limitation above.
Do not put the secrets in YAML. Add them as secret pipeline variables on the CD pipeline, under Edit > Variables, with Keep this value secret selected:
| Secret variable | Used for |
|---|---|
sqlConnectionString |
Hybrid runtime state store |
fileSharePassword |
SMB file share authentication |
aadClientSecret |
Entra ID app registration secret |
YAML variables take precedence over pipeline variables, so declaring these in the variables file would quietly override whatever you set in the UI. Keep them in the pipeline UI, a variable group, or Key Vault.
Last, fill in infrastructure/hybrid-logicapp-parameters.json with your connected environment name and resource group, the custom location ID, the file share details, and the Entra ID identifiers. Most of these are already populated from your wizard selections.
Step 6 — Create and run the CI pipeline
Go to Pipelines > New pipeline > Azure Repos Git, select your repository, choose Existing Azure Pipelines YAML file, and point it at /deployment/<logic-app-name>/pipelines/CI-pipeline.yml. Then run it.
When it finishes you should see two published artifacts: the logic app ZIP and the infrastructure templates.
Step 7 — Create and run the CD pipeline
Create a second pipeline pointing at CD-pipeline.yml.
Before the first run, open the CD YAML and change the pipeline resource to match the name of your CI pipeline:
resources:
pipelines:
– pipeline: cipipeline
# TODO: Update with the name of your CI pipeline
source: CI PipelineThen run it. The steps run in order: infrastructure deployment, then release.
Verify the deployment
In the Azure portal, open your Logic App (Hybrid) resource. Open the Workflows blade to confirm the workflows are there, then trigger one and check the run history.
Making changes later
Which pipeline you need depends on what you changed.
| You changed | Run |
|---|---|
| Workflow definitions or connections | CI, then CD |
ARM template or hybrid-logicapp-parameters.json |
CI, then CD |
| CD variables or secrets only | CD only |
The middle row is the one that catches people out. CD reads the ARM template from the artifact that CI published, not from the repository:
csmFile: ‘$(Pipeline.Workspace)/cipipeline/infrastructure/hybrid-logicapp-template.json’An infrastructure change that is committed but not rebuilt through CI will not be picked up, so run CI first.
Troubleshooting
Not found SourceFolderin the Hybrid Build tasksourceFolderNamedoes not match the folder in your repository that containshost.json. Remember it is the project folder, not the deployed logic app name.<path>/workflowparameters does not exist- The
deployment/<logicAppName>/path is derived fromlogicAppName. If you rename the logic app, rename the generated folder to match, otherwise the build will not find the deployment assets. Failed to check the resource group status. Error: {“statusCode”:400}- Usually a placeholder left behind in
subscriptionId. A malformed subscription value produces an invalid ARM URL, and the request fails with a 400 before authentication is even attempted. AADSTS7000222: The provided client secret keys for app ‘…’ are expired- The client secret behind the service connection has expired. Create a new secret on the app registration and update the service connection. If you would rather not track expiry dates at all, use workload identity federation for the ARM connection.
- Unknown task
AzureLogicAppsHybridBuild@0 - The Azure DevOps extension is not installed in the organization, or the pipeline is running in a different organization than the one it was installed into.
Wrapping up
The generated pipelines package your workflows, deploy the Hybrid logic app infrastructure, and publish the application through its authenticated ZIP deploy endpoint. With the environment details and service connections configured, you can use the same process for subsequent deployments.
If you try this out and hit something we have not covered, let us know in the comments.
References
- Azure Logic Apps documentation: learn.microsoft.com/azure/logic-apps
- Connect to Microsoft Azure with an ARM service connection: learn.microsoft.com/azure/devops/pipelines/library/connect-to-azure
- Set up your infrastructure for Standard logic app workflows with hybrid deployment
- Azure Arc Jumpstart: Hybrid deployment for Azure Logic Apps on AKS
- Azure Logic Apps Standard Tasks extension on Visual Studio Marketplace


