Before Resource Runs Logic App
  • 30 Jan 2026
  • 13 Minutes to read
  • Dark
    Light
  • PDF

Before Resource Runs Logic App

  • Dark
    Light
  • PDF

Article summary

In this scenario we want to implement a Logic App that will be triggered by the schedule Before it takes an action on a resource such as turn it on/off or scale it up/down.  In this example case I would like to use the Run Command feature on the Azure Management API to log a message to the event log on the VM.  You could use this for many other such interactions which might involve running code on your VM.

The steps to achieve this are:

  • Create an action on the resource within the schedule

  • The schedule will trigger a logic app in my case which will call the Azure management API and use the Run Command operation to execute some Powershell on the VM.

Note you will need the appropriate RBAC access control for this.

HTTP Headers sent from Scheduler

The scheduler automation will pass some key HTTP headers to your Logic App. These include things like the name of the schedule and the group in cost analyzer. It will also include the below headers which are probably ones you will use to drive your workflow logic:

Header

Use

Values

Execution-Type

This is used to indicate if its an event from the validate button or if the schedule has generally ran

Test = The validate button was clicked in the scheduler

Actual = The scheduler actually ran

Schedule-Operation

Used to indicate the state that the schedule is transferring resources to.

Start = We are going to the green state (scale up / turn on)

Stop = We are going to the red state (scale down / turn off)

AzureResourceId

Used to pass the resource id of the resource the scheduler is about to action

Logic App Example

In the below picture you can see an example Logic App which will be used to handle the scenario of an extensibility before the overall schedule runs.

In the implementation I need to handle the following conditional Logic:

  • If the Execution-Type header is Test then just return an ACK that all is good with an HTTP 200 response

  • If Schedule-Operation is Start then do some action because the schedule is about to run and move resources to the started state

  • If Schedule-Operation is Stop then do some action because the schedule is about to run and move resources to the stopped state

The below picture shows my sample workflow which you could easily replicate then add your own custom extensibility.

Sample Logic App Template

The below json is a sample Logic App which you can paste into a logic app consumption logic app and use this to get up and running quickly.

{
    "definition": {
        "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "contentVersion": "1.0.0.0",
        "triggers": {
            "When_an_HTTP_request_is_received": {
                "type": "Request",
                "kind": "Http"
            }
        },
        "actions": {
            "Response": {
                "type": "Response",
                "kind": "Http",
                "inputs": {
                    "statusCode": 200
                },
                "runAfter": {
                    "Switch_-_Schedule_Operation": [
                        "Succeeded"
                    ]
                }
            },
            "Initialize_variables": {
                "type": "InitializeVariable",
                "inputs": {
                    "variables": [
                        {
                            "name": "executionType",
                            "type": "string",
                            "value": "@{triggerOutputs()?['headers']?['Execution-Type']}"
                        },
                        {
                            "name": "scheduleOperation",
                            "type": "string",
                            "value": "@{triggerOutputs()?['headers']?['Schedule-Operation']}"
                        },
                        {
                            "name": "resourceId",
                            "type": "string",
                            "value": "@{triggerOutputs()?['headers']?['AzureResourceId']}"
                        }
                    ]
                },
                "runAfter": {}
            },
            "Condition_-_Is_Test_Event": {
                "type": "If",
                "expression": {
                    "and": [
                        {
                            "equals": [
                                "@variables('executionType')",
                                "Test"
                            ]
                        }
                    ]
                },
                "actions": {
                    "Response_-_Ack_-_Test": {
                        "type": "Response",
                        "kind": "Http",
                        "inputs": {
                            "statusCode": 200
                        }
                    },
                    "Terminate_-_Ack": {
                        "type": "Terminate",
                        "inputs": {
                            "runStatus": "Succeeded"
                        },
                        "runAfter": {
                            "Response_-_Ack_-_Test": [
                                "Succeeded"
                            ]
                        }
                    }
                },
                "else": {
                    "actions": {}
                },
                "runAfter": {
                    "Initialize_variables": [
                        "Succeeded"
                    ]
                }
            },
            "Switch_-_Schedule_Operation": {
                "type": "Switch",
                "expression": "@variables('scheduleOperation')",
                "default": {
                    "actions": {
                        "Compose_-_Do_nothing": {
                            "type": "Compose",
                            "inputs": "You would do nothing here because the schedule is not going to the start or stop state"
                        }
                    }
                },
                "cases": {
                    "Case_-_Start": {
                        "actions": {
                            "Compose_-_Do_Something_Start_State": {
                                "type": "Compose",
                                "inputs": "The schedule is about to run to move the resources to the start state.  Do something here before the resources are acted upon"
                            }
                        },
                        "case": "Start"
                    },
                    "Case_-_Stop": {
                        "actions": {
                            "Compose_-_Do_something_Stop_State": {
                                "type": "Compose",
                                "inputs": "The schedule is going to the stopped or scaled down state.\n\nYou can do something here to before the schedule is actioned"
                            },
                            "HTTP_-_Log_Stop_Event": {
                                "type": "Http",
                                "inputs": {
                                    "uri": "https://management.azure.com/@{variables('resourceId')}/runCommand?api-version=2025-04-01",
                                    "method": "POST",
                                    "headers": {
                                        "Content-Type": "application/json"
                                    },
                                    "body": {
                                        "commandId": "RunPowerShellScript",
                                        "script": [
                                            "$logName = 'Application'",
                                            "$source  = 'Turbo360-FinOps'",
                                            "$eventId = 3001",
                                            "$message = 'Turbo360 scheduler is about to shut down this VM'",
                                            "",
                                            "if (-not [System.Diagnostics.EventLog]::SourceExists($source)) {",
                                            "  New-EventLog -LogName $logName -Source $source",
                                            "}",
                                            "",
                                            "Write-EventLog -LogName $logName -Source $source -EventId $eventId -EntryType Information -Message $message"
                                        ]
                                    },
                                    "authentication": {
                                        "type": "ManagedServiceIdentity",
                                        "identity": "/subscriptions/{your subscription id here}/resourceGroups/T360-Scheduler-VM-Demo-Actions/providers/Microsoft.ManagedIdentity/userAssignedIdentities/T360-Scheduler-VM-Demo-Actions",
                                        "audience": "https://management.azure.com/"
                                    },
                                    "retryPolicy": {
                                        "type": "none"
                                    }
                                },
                                "runAfter": {
                                    "Compose_-_Do_something_Stop_State": [
                                        "Succeeded"
                                    ]
                                },
                                "runtimeConfiguration": {
                                    "contentTransfer": {
                                        "transferMode": "Chunked"
                                    }
                                }
                            }
                        },
                        "case": "Stop"
                    }
                },
                "runAfter": {
                    "Condition_-_Is_Test_Event": [
                        "Succeeded"
                    ]
                }
            }
        },
        "outputs": {},
        "parameters": {
            "$connections": {
                "type": "Object",
                "defaultValue": {}
            }
        }
    },
    "parameters": {
        "$connections": {
            "type": "Object",
            "value": {}
        }
    }
}


Was this article helpful?