← Back to Tutorials
Intermediate⏱️ 30 min

Variables, Loops, and Conditional Logic

Variables, Loops, and Conditional Logic

Learn how to use variables, iterate over data with loops, and implement branching logic in Azure Logic Apps workflows.

Initialize Variable Action

The Initialize Variable action creates a variable at the workflow level. You must initialize variables at the top level of your workflow (not inside loops or conditions).

Supported variable types:

TypeExample Value
String"Hello World"
Integer42
Booleantrue
Array["item1", "item2"]
Object{"key": "value"}

To add an Initialize Variable action:

  1. Click + New step and search for "Initialize variable"
  2. Provide a Name for the variable
  3. Select the Type from the dropdown
  4. Optionally set an initial Value

Screenshot: Initialize Variable action with type selection

Set Variable and Append to Array

Set Variable

Use the Set Variable action to update the value of an existing variable at any point in your workflow.

  • The variable must already be initialized
  • The new value must match the variable's declared type

Append to Array Variable

Use Append to array variable to add an item to an array variable:

  1. Select the target array variable
  2. Provide the value to append (can be a dynamic expression)

Screenshot: Set Variable and Append to Array actions

For Each Loop

The For Each loop iterates over an array and executes actions for each item.

Parallel vs Sequential Execution

By default, For Each iterations run in parallel (up to 20 concurrent iterations).

To configure concurrency:

  1. Click the ... menu on the For Each action
  2. Select Settings
  3. Toggle Concurrency Control on
  4. Set the Degree of Parallelism (1 = sequential, up to 50)

Setting concurrency to 1 forces sequential execution, which is necessary when:

  • Iterations depend on each other's results
  • You need to preserve processing order
  • You're calling a rate-limited API

Screenshot: For Each loop concurrency settings

Until Loop

The Until loop repeats actions until a specified condition is met or a limit is reached.

Exit Conditions

An Until loop exits when:

  • The specified expression evaluates to true
  • The count limit is reached (default: 60 iterations)
  • The timeout is reached (default: PT1H / 1 hour)

Configure exit conditions:

  1. Add an Until action
  2. Set the condition expression (e.g., @equals(variables('status'), 'Complete'))
  3. Click Change limits to adjust count and timeout

Screenshot: Until loop with exit condition configuration

Condition Action (If/Else Branching)

The Condition action evaluates an expression and branches into True or False paths.

  1. Add a Condition action
  2. Select a value (dynamic content or expression)
  3. Choose an operator (is equal to, contains, is greater than, etc.)
  4. Provide the comparison value

Each branch (True/False) can contain multiple actions, including nested conditions.

Screenshot: Condition action with True and False branches

Switch Action (Multiple Branches)

The Switch action evaluates an expression and routes to one of multiple Case branches or a Default branch.

  1. Add a Switch action
  2. Set the On value (the expression to evaluate)
  3. Add Case blocks with specific values to match
  4. Add actions inside each Case
  5. The Default case handles unmatched values

Screenshot: Switch action with multiple case branches

Nested Conditions and Loops

You can nest conditions inside loops and loops inside conditions to build complex logic:

  • Condition inside For Each — filter or route items during iteration
  • For Each inside Condition — iterate only when a condition is met
  • Until inside For Each — retry logic per item
  • Nested conditions — multi-level decision trees

Tip: Keep nesting to 3 levels or fewer for readability. Consider splitting deeply nested logic into child workflows.

Screenshot: Nested condition inside a For Each loop

Step-by-Step: Process Orders, Filter by Amount, and Count Results

Build a workflow that receives an array of orders, filters orders above a threshold amount, and counts the results.

Step 1: Initialize Variables

  1. Add Initialize Variable — Name: OrdersArray, Type: Array, Value: (leave empty, will be set by trigger)
  2. Add Initialize Variable — Name: FilteredCount, Type: Integer, Value: 0
  3. Add Initialize Variable — Name: HighValueOrders, Type: Array, Value: []

Screenshot: Three initialized variables for the order processing workflow

Step 2: Set the Orders Array

Use a When a HTTP request is received trigger or a Compose action with sample data:

[
  {"orderId": "A001", "amount": 150, "customer": "Contoso"},
  {"orderId": "A002", "amount": 45, "customer": "Fabrikam"},
  {"orderId": "A003", "amount": 320, "customer": "Northwind"},
  {"orderId": "A004", "amount": 80, "customer": "AdventureWorks"}
]

Set the OrdersArray variable to the trigger body or Compose output.

Step 3: Add a For Each Loop

  1. Add a For Each action
  2. Set the input to variables('OrdersArray')
  3. Set concurrency to 1 (sequential) since we're updating a counter

Step 4: Add a Condition Inside the Loop

  1. Inside the For Each, add a Condition
  2. Set the condition: items('For_each')?['amount'] is greater than 100

Step 5: True Branch — Append and Increment

In the True branch:

  1. Add Append to array variable — Name: HighValueOrders, Value: items('For_each')
  2. Add Increment variable — Name: FilteredCount, Value: 1

Step 6: Return the Results

After the For Each loop, add a Response action:

{
  "highValueOrderCount": "@variables('FilteredCount')",
  "highValueOrders": "@variables('HighValueOrders')"
}

Screenshot: Complete order processing workflow in designer view

Expected Output

{
  "highValueOrderCount": 2,
  "highValueOrders": [
    {"orderId": "A001", "amount": 150, "customer": "Contoso"},
    {"orderId": "A003", "amount": 320, "customer": "Northwind"}
  ]
}

Performance Tips for Loops

  • Use parallel execution when iterations are independent — it dramatically reduces total run time
  • Avoid unnecessary variables inside loops; use expressions inline where possible
  • Limit array sizes — For Each supports up to 100,000 items, but performance degrades beyond a few thousand
  • Use chunking — break large arrays into batches with take() and skip() expressions
  • Offload heavy processing — call child workflows or Azure Functions for complex per-item logic
  • Set appropriate timeouts on Until loops to prevent runaway executions
  • Monitor with Run History — check individual iteration durations to identify bottlenecks
  • Consider Durable Functions for fan-out/fan-in patterns that exceed Logic Apps loop capabilities

← Previous: Data Operations | Next: Error Handling →