Managing Azure Logic Apps in various environments can be a tedious and error-prone assignment when relying on manual deployments. Thankfully, utilizing Azure DevOps CI/CD pipelines with ARM templates allows for complete automation of Logic App deployments, removing the need for manual involvement and guaranteeing uniform infrastructure-as-code releases.
This blog walks you through setting up a complete automated deployment pipeline for Logic Apps, from exporting templates to running parameterized deployments using YAML pipelines.
Prerequisites:
Before we begin, make sure you have the following in place:
- An existing Logic App in your Azure subscription.
- An Azure DevOps project with permissions to create service connections and pipelines.
- Basic familiarity with ARM templates and YAML
Step 1: Export the ARM Template of the Logic App
- Go to the Azure Portal and navigate to your Logic App.
- In the left pane, select Automation > Export template.
- Click Download to save the template.json and parameters.json files.
These files define the infrastructure and configuration of your Logic App and are essential for reproducible deployments.
Step 2: Create a Service Connection in Azure DevOps
To allow Azure DevOps to deploy resources to Azure, you need a service connection:
- Go to your Azure DevOps project > Project settings > Service connections.
- Click New service connection > choose Azure Resource Manager.
- Select Default, Identity Type > App registration (automatic).
- Select Default, Credential > Workload Identity Federation.
- Choose Scope Level > Subscription.
- Choose your Azure subscription and resource group.
- Name the service connection (e.g., AzureServiceConnection) and save.
Step 3: Create a Repository and Add Template Files
- Create a new Git repository in Azure DevOps or use an existing one.
- Commit the downloaded files template.json and parameters.json into the repository.
- Arrange files within a specific folder structure when handling various Logic Apps or environments.
Step 4: Create a Variable Group (Optional but Recommended)
To support environment-specific deployments, create a variable group:
- Go to Pipelines > Library in Azure DevOps.
- Create a new variable group.
- Add variables to replace parameters, connections, or static values, such as:
- LogicAppName
- Location
- SubscriptionId
- ResourceGroup
- After creating the pipeline, grant it permission to access the variable group. Alternatively, you can configure the variable group to be accessible by all pipelines within the project by enabling the “Open Access” option.
- Alternatively, you can define variables directly in your YAML pipeline using variables: if you want to keep everything within the pipeline file.
Step 5: Create a YAML Pipeline
Now, create a YAML pipeline to:
- Replace parameters dynamically.
- Deploy the Logic App using ARM templates.
- Use variables for flexibility across environments.
Here’s a sample pipeline (azure-pipelines.yml).
trigger:
branches:
include:
- main
stages:
- stage: Build
displayName: "Build And Deploy"
jobs:
- job: BuildLogicApp
displayName: "Deploy Logic App to Azure"
pool:
vmImage: "windows-latest"
variables:
# Store the variables in the group for dynamic use
- group: TestLogicApp-Variables
steps:
- checkout: self
# Preprocess template.json to replace hardcoded values
- task: PowerShell@2
displayName: "Preprocess ARM Template"
inputs:
targetType: "inline"
script: |
$templatePath = "$(Build.SourcesDirectory)/template.json"
$jsonRaw = Get-Content $templatePath -Raw | ConvertFrom-Json
# Update LogicApp name parameter
if ($jsonRaw.parameters.workflows_TestLogicApp_01_name) {
Write-Host "Updating Logic App name to: $(LogicAppName)"
$jsonRaw.parameters.workflows_TestLogicApp_01_name.defaultValue = "$(LogicAppName)"
} else {
Write-Host "Error: workflows_TestLogicApp_01_name parameter not found!" -ForegroundColor Red
exit 1
}
# Update location parameter
if ($jsonRaw.resources[0].location) {
Write-Host "Replacing WorkFlow location defaultValue with $(Location)"
$jsonRaw.resources[0].location = "$(Location)"
} else {
Write-Host "Warning: Location parameter not found in resoures!" -ForegroundColor Yellow
}
# Update the connections properties
if ($jsonRaw.resources[0].properties.parameters.'$connections') {
$connections = $jsonRaw.resources[0].properties.parameters.'$connections'.value
if ($connections.sharepointonline) {
# Replace subscriptionId in the id field
$connections.sharepointonline.id = $connections.sharepointonline.id -replace '/subscriptions//', "/subscriptions/$(SubscriptionId)/"
Write-Host "Replaced sharepointonline id subscriptionId: $(SubscriptionId)"
# Replace location in the id field
$connections.sharepointonline.id = $connections.sharepointonline.id -replace '/locations//', "/locations/$(Location)/"
Write-Host "Replaced sharepointonline id location: $(Location)"
# Update connectionName
$connections.sharepointonline.connectionName = "$(SharepointConnectionName)"
Write-Host "Replaced sharepointonline connectionName: $(SharepointConnectionName)"
}
}
# Save the updated template
$jsonString = $jsonRaw | ConvertTo-Json -Depth 100 -Compress
$jsonString | Set-Content $templatePath -Encoding UTF8
Write-Host "Updated template.json with all dynamic values saved to $templatePath"
- task: PowerShell@2
displayName: "Prepare Exported Templates Directory"
inputs:
targetType: "inline"
script: |
$exportPath = "$(Build.ArtifactStagingDirectory)/exportedTemplates
# Copy template.json
$templatePath = "$(Build.SourcesDirectory)/template.json"
if (Test-Path -Path $templatePath) {
Copy-Item -Path $templatePath -Destination "$exportPath/template.json" -Force
} else {
Write-Host "Warning: template.json not found in source directory"
}
# Copy parameters.json
$parametersPath = "$(Build.SourcesDirectory)/parameters.json"
if (Test-Path -Path $parametersPath) {
Copy-Item -Path $parametersPath -Destination "$exportPath/parameters.json" -Force
} else {
Write-Host "Warning: parameters.json not found in source directory"
}
Write-Host "Exported templates prepared successfully."
- task: PowerShell@2
displayName: "Debug Exported Templates"
inputs:
targetType: "inline"
script: |
Get-Content "$(Build.ArtifactStagingDirectory)/exportedTemplates/template.json" | Write-Host
Get-Content "$(Build.ArtifactStagingDirectory)/exportedTemplates/parameters.json" | Write-Host
- task: PublishBuildArtifacts@1
displayName: "Publish Exported Templates as Artifacts"
inputs:
PathtoPublish: "$(Build.ArtifactStagingDirectory)/exportedTemplates"
ArtifactName: "LogicAppExportedTemplates"
- task: DownloadBuildArtifacts@0
displayName: "Download Published Artifacts"
inputs:
buildType: "current"
downloadType: "single"
artifactName: "LogicAppExportedTemplates"
downloadPath: "$(Pipeline.Workspace)/ExportedTemplates"
- task: PowerShell@2
displayName: "Debug Downloaded Artifacts"
inputs:
targetType: "inline"
script: |
Get-ChildItem -Recurse "$(Pipeline.Workspace)/ExportedTemplates"
Get-Content "$(Pipeline.Workspace)/ExportedTemplates/LogicAppExportedTemplates/template.json" | Write-Host
Get-Content "$(Pipeline.Workspace)/ExportedTemplates/LogicAppExportedTemplates/parameters.json" | Write-Host
- task: AzureResourceManagerTemplateDeployment@3
displayName: "Deploy Logic App ARM Template"
inputs:
deploymentScope: "Resource Group"
azureResourceManagerConnection: ""
subscriptionId: ""
resourceGroupName: ""
location: ""
templateLocation: "Linked artifact"
csmFile: "$(Pipeline.Workspace)/ExportedTemplates/LogicAppExportedTemplates/template.json"
csmParametersFile: "$(Pipeline.Workspace)/ExportedTemplates/LogicAppExportedTemplates/parameters.json"
deploymentMode: "Incremental"
The provided YAML pipeline automates the deployment of a Logic App to Azure using a dynamic, reusable approach. Key features include,
- Branch Trigger: The pipeline runs when changes are pushed to the main branch.
- Variable Group Usage: A variable group (TestLogicApp-Variables) is linked to the pipeline to store dynamic values like LogicAppName, Location, SubscriptionId, etc. These are accessed using the $(varName) syntax for flexibility and easy updates without modifying the template.
- ARM Template Preprocessing: The template.json is dynamlically updated using PowerShell to inject values from the variable group, replacing placeholders such as Logic App name, location, and connection settings.
- Template Export and Debugging: The processed templates are saved, exported as build artifacts, and verified via debug steps to ensure correctness.
- Deployment: The AzureResourceManagerTemplateDeployment@3 task deploys the Logic App ARM template to the specified Azure resource group using values from the variable group.
This modular and dynamic approach ensures reusability across environments and simplifies Logic App deployment directly from your DevOps workflow.
Step 6: Create and Run the Pipelines
- Go to Pipelines > New Pipeline.
- Select Azure Repos Git > choose your repo.
- Select YAML and point to your YAML file.
- Save and run the pipeline.
Your Logic App will now be deployed automatically with environment-specific values.
Final Thoughts
Utilizing ARM templates alongside Azure DevOps pipelines for Logic App deployments provides a secure, scalable, and repeatable method that aligns with contemporary DevOps methodologies. By adhering to the previously described steps, you can eradicate manual deployment mistakes, standardize your deployment process, and fully version control your Logic App infrastructure.
Furthermore, you can adjust various parameters and connection settings dynamically by utilizing PowerShell scripts in the pipeline, as shown in this blog. This method offers enhanced flexibility for deployments in diverse environments or for making real-time updates to configuration values.
If you have any questions you can reach out our SharePoint Consulting team here.
No comments:
Post a Comment