Homeβ€Ί Blogβ€Ί Azure Architecture Series #57 β€” Lifecycle Workflows: Automation Is Only As Good As the Date…
Azure Architecture Azure Architecture Series

Azure Architecture Series #57 β€” Lifecycle Workflows: Automation Is Only As Good As the Date

Verified against current vendor documentation on 9 October 2026. Pricing, limits and API behaviour were checked against the official docs on that date. Cloud services change fast — if you are reading this much later, treat the specifics as a starting point and re-check the linked sources.

Business Challenge

#56 gave access a lifecycle but left the trigger human: somebody requests, somebody approves. Lifecycle workflows remove the human from the predictable parts. The three phases are the familiar ones — “Joiner: When an individual enters the scope of needing access… Mover: When an individual moves between boundaries within an organization… Leaver: When an individual leaves the scope of needing access” — and the structure is pleasingly small.

A workflow is “tasks and execution conditions”, and an execution condition is just two questions: “the scope of who's affected and the trigger of when a workflow will be performed.” The documentation’s own example is the whole feature in three lines: send a manager an email “seven days before the value in the employeeHireDate attribute of new employees” — task, scope, trigger.

Which is also the dependency nobody mentions in the pitch. The trigger is an attribute on a user object. If employeeHireDate is empty, wrong, or arrives from HR after the date it describes, the automation does not misfire — it does nothing, silently, for that person.

The sentence that defines what you must get right first

“For reliable workflow execution, the user account must be configured with all relevant details (e.g., trigger and scoping attributes) in advance of the scheduled workflow execution.”

There is a grace period, and it is short and specific: if setup is late, “Lifecycle Workflows will still attempt to process the user—provided the necessary setup is completed within three days of the original processing time.” Miss that window and the run for that user is simply gone.

And the catch-up is not universal: it “doesn't apply when you select Time based attribute V2 (Preview)” — so the newer trigger is less forgiving than the one it replaces.

So this is not really a workflow-authoring exercise. It is a data-quality project with a workflow engine attached, and the order of work is: fix the HR feed, then automate.

Architecture

Four triggers, a scheduler you must switch on separately, and a limits table that shapes the design more than the templates do.

Diagram: Microsoft Entra lifecycle workflows structure, triggers, scheduling and limits. A workflow has three parts: general information, tasks, and execution conditions, where an execution condition combines a scope defining who is affected and a trigger defining when the workflow runs. The four supported scheduled triggers are attribute changes, group membership change, time based attribute, and sign-in inactivity. Time based triggers fire relative to a date attribute such as employeeHireDate, with an offsetInDays range of 180 days, or minus 180 to plus 180 via the API where negative means before the attribute date and positive means after. Newly created workflows are enabled by default but scheduling must be enabled manually, and once enabled the workflow is evaluated on an interval set in workflow settings with a default of three hours, configurable from 1 to 24 hours. If a user account or workflow is configured after the intended processing time, lifecycle workflows still attempt to process the user provided setup completes within three days of the original processing time, but this catch-up does not apply to the Time based attribute V2 preview trigger. Running a workflow on demand does not evaluate execution conditions at all and applies the tasks regardless, and on-demand selection is limited to 10 users, making it a testing tool rather than a bulk remediation tool. Service limits are 100 workflows per tenant, 25 tasks per workflow, 100 custom task extensions per tenant, 5 administrative scopes per workflow, and a custom task extension timeout between 30 minutes and 3 hours. Lifecycle workflows differ from dynamic groups by managing static groups with no dynamic group rule needed, needing no rule per group because the rule scopes users rather than groups, supporting attributes dynamic groups cannot such as a number of days before a hire date, and being able to act on the group itself rather than only its membership. Workflows can disable and remove user accounts, assign and remove access packages, and extend into Logic Apps. Versioning creates separate workflows reported differently in logs, and history can be viewed by users, runs or tasks. Licensing requires Microsoft Entra ID Governance or Microsoft Entra Suite, and the delegated role is Lifecycle Workflows Administrator.
Tasks plus a scope plus a trigger. The trigger is a date on a user object, which is where the risk lives.

Four triggers, and only one of them is about time

“The supported scheduled triggers are: Attribute changes · Group membership change · Time based · Sign-in inactivity.” The mental model that helps is that each answers a different question about when a fact became true:

Trigger Fires when Natural use
Time based attribute A date attribute reaches a configured offset Joiner and leaver, relative to hire or leave date
Attribute changes “the attribute you defined is changed for a user” Mover — department, job title, cost centre
Group membership change “if a user is added or removed from a specific group” Access-driven rather than HR-driven events
Sign-in inactivity “a user has not signed in over a specific time period” Dormant accounts — the leaver nobody told you about

That last one deserves attention because it is the only trigger that does not depend on anyone telling the truth. Every other trigger needs HR, or an administrator, to record something. Sign-in inactivity is observed by the platform itself, which makes it the backstop for the case this series has met repeatedly: the person who left and whose account nobody disabled. It is the lifecycle equivalent of #46’s access review — a control that works when the process has already failed.

The offset window is six months, and the sign carries the meaning

The time-based trigger is an offset from a date attribute, and the range is generous: “offsetInDays range of triggerAndScopeBasedConditions executionConditions: 180 days.” Through the API it is signed, which is the part worth knowing when scripting: “the offsetInDays range will be between -180 - 180 days. The negative value signals happening before the timeBasedAttribute, while the positive value signals happening afterwards.”

So one attribute and a signed integer express both halves of a lifecycle: −7 for “a week before they start”, +30 for “a month after they left”. Six months in either direction covers notice periods, probation and most retention obligations without a second mechanism.

Scheduling is a separate switch, and it is off

This is the first of the three operational details, and it is the one most likely to produce a workflow that looks live and is not: “While newly created workflows are enabled by default, scheduling is an option that must be enabled manually.”

Enabled and scheduled are different states. A workflow can be enabled, correct, templated, pass every review — and never run, because nothing is evaluating it. The documentation points at the column to check (Scheduled), which is a tell that people get this wrong.

Once it is on, the cadence is a tenant setting: evaluated “based on the interval that is set within your workflow settings (default of three hours)”, configurable across “1-24 hours”. That range is the real precision limit of the whole feature. A leaver task is not instant; it happens within an hour at best, three by default. If your requirement is “access gone at the moment of termination”, this is the wrong tool and #50’s immediate-disable path is the right one.

On demand ignores everything you configured

The second operational detail, and the one with real blast radius: “A workflow that is run on demand for a user does not take into account whether or not a user meets the workflow's execution conditions. It will apply the tasks regardless of whether the execution conditions are met by the user or not.”

Read that against a leaver workflow whose tasks are “the disabling and removal of user accounts”. Running it on demand against the wrong person does not get stopped by the scope you carefully defined — the scope is not consulted. The guardrail is a limit rather than a check: “Number of users per on-demand selection: 10.”

Which tells you what on-demand is for. Ten users, no condition evaluation: that is a testing affordance, not a bulk remediation tool. If you were planning to use it to catch up on a backlog of leavers, it is both the wrong size and the wrong semantics.

The limits shape the design

Limit Value What it implies
Workflows per tenant 100 Not one per department. Scope broadly, vary by attribute.
Tasks per workflow 25 Generous — an onboarding sequence fits comfortably.
Custom task extensions per tenant 100 The Logic Apps escape hatch is not rationed.
Administrative scopes per workflow 5 Delegation is per workflow, and narrow.
Custom extension timeout 30 minutes to 3 hours A Logic App can take hours. Design for async.

The hundred-workflow ceiling is the one that changes architecture. It pushes you towards the design the documentation already recommends for dynamic groups — “Lifecycle workflow rules determine the scope of users to execute workflows against, not which group” — so a single joiner workflow scoped by department beats forty department-specific ones. And all of these are soft: “Limits can be increased… you must contact Microsoft Support.”

Why This Architecture Holds Up

Because it is not a replacement for HR provisioning, and the boundary is precise

The division of labour is stated cleanly and is worth quoting at anyone who thinks this tool creates users: “HR provisioning manages the creation and attribute updates of user accounts, [while] lifecycle workflows provide additional automation of tasks.”

So the account and its employeeHireDate come from the HR system; the email to the manager, the temporary access pass, the group memberships and the access packages come from here. Lifecycle workflows sit downstream of the data they depend on, which is why the data-quality problem cannot be solved inside them. If HR enters a hire date the day someone starts, no offset can send a manager an email a week earlier.

Because it overlaps dynamic groups, and the documentation says when to prefer which

This is a genuinely useful comparison that rarely gets made explicitly. Four differences, each with a decision attached:

  • “Lifecycle workflows manage static groups, where you don't need a dynamic group rule.” So you can govern a group whose membership must be explicit and auditable.
  • “There's no need to have one rule per group” — the rule scopes users, not groups, so one workflow can touch many groups.
  • It reaches attributes dynamic groups cannot: “a certain number of days before the employeeHireDate attribute value.” No dynamic rule can express “seven days before”.
  • “Lifecycle workflows can perform actions on the group, not just the membership.”

The clean split: dynamic groups for “who is currently X”, lifecycle workflows for “what should happen N days either side of X becoming true”. Membership is a state; a lifecycle event is a moment, and only one of these tools has a clock.

Because versioning is how you avoid lying to your own audit trail

A quiet feature with a governance purpose: “Workflow versions are separate workflows built using the same information of an original workflow, but with either the tasks or scope updated, so that they're reported differently within logs.”

That last clause is the point. If you edit a leaver workflow’s tasks in place, every historical run is now attributed to a definition that did not exist when it ran — and the audit trail quietly misrepresents what happened to people who left last quarter. Versioning keeps the old definition addressable. For a feature whose outputs are “we disabled this account on this date for this reason”, that matters more than it sounds.

The history is also built for the question you will actually ask, from three angles: “through the lens of its users, runs, and tasks”. One of those three answers “why did nothing happen to this person”, which is the hardest question to answer about any automation.

Because the failure mode is silence, and the dashboard names it

Every post in this phase has found a control that fails quietly. Here the platform at least counts the silence for you: the workflow overview reports “Total processed users… Processed users with failures… Failed tasks… Number of tasks… Current version”, plus the next target run.

The number to watch is not failures — it is total processed users against what you expected. A leaver workflow with zero failures and four processed users in a month when eleven people left is not healthy; it is scoped wrong, or seven hire-date fields were blank. Failures tell you the tasks broke. The processed count tells you the trigger never matched, which is the failure this feature is actually prone to.

Because the licence puts it in the same conversation as #56

Same gate as entitlement management: “Using this feature requires Microsoft Entra ID Governance or Microsoft Entra Suite licenses.” Above P2, and sold with the feature this post completes.

Which is the right way to buy them, because they compose. Lifecycle workflows can “automate assigning, and removing, access packages for users” — so #56’s bundles become the thing a joiner workflow hands out and a leaver workflow takes back. One licence, and the request-driven and date-driven halves of governance meet. The delegated role, for the record, is “Lifecycle Workflows Administrator”.

Worth keeping the matching limits in view while designing that pairing: 20,000 access packages and 300,000 assignments per tenant, but only 15,000 assignments from any single automatic assignment policy — which is the one most likely to bind, because an automatic policy is exactly what you reach for when a workflow drives the assignment.

Key Architecture Decisions

Situation Decision Why
Before building any workflow Audit employeeHireDate and employeeLeaveDateTime coverage A blank trigger attribute means silent no-op for that user.
HR enters dates late Know the catch-up window is three days Later than that and the run for that user is lost.
Using the V2 time-based trigger Expect no catch-up at all The three-day grace does not apply to the preview trigger.
Workflow built and reviewed Check the Scheduled column, not just Enabled Scheduling is a separate switch and defaults off.
Requirement is instant revocation Wrong tool — use direct disable Evaluation runs hourly at best, three-hourly by default.
Tightening the cadence 1 hour is the floor The interval is configurable only within 1–24 hours.
Tempted to use Run on demand for a backlog Don't It ignores execution conditions entirely and caps at 10 users.
Testing a destructive leaver workflow Treat on-demand as live fire Scope is not consulted; the tasks just run.
Designing for many departments One workflow scoped by attribute 100 workflows per tenant; rules scope users, not groups.
Catching leavers nobody reported Sign-in inactivity trigger The only trigger that needs nobody to tell the truth.
Mover scenarios Attribute-change trigger on department or title Fires on the change itself rather than a date.
Something a task cannot do Custom task extension to Logic Apps 100 per tenant, with a 30-minute to 3-hour timeout.
Changing a live workflow's tasks or scope Create a version Editing in place misattributes historical runs in logs.
Health-checking a workflow Watch total processed users, not failures A trigger that never matches produces zero of both.
Pairing with access packages Automate assignment and removal from the workflow Same licence; mind the 15,000-per-automatic-policy cap.
Delegating workflow administration Lifecycle Workflows Administrator, max 5 scopes per workflow Purpose-built role; administrative scopes are limited.

Closing Thought

The honest summary of lifecycle workflows is that they are a small, well-shaped engine bolted to a field in your HR system. The engine is good: four triggers that cover the real events, a signed six-month offset that expresses both ends of an employment relationship with one number, twenty-five tasks per workflow, and a Logic Apps escape hatch for everything else. None of that is where projects fail. They fail because employeeHireDate is populated for seventy per cent of starters, or because the HR feed lands two days late and nobody knew the catch-up window was three days, or because somebody built the workflow, enabled it, and never noticed that scheduling is a different switch.

So the useful sequencing is the opposite of the demo order. Measure attribute coverage first and fix the feed. Then build one broadly-scoped workflow per phase rather than one per department, because the ceiling is a hundred and the rules scope users anyway. Then watch processed users rather than failures, because the characteristic failure of this feature is a trigger that quietly matches nobody. And keep the sign-in inactivity trigger switched on regardless of how good the rest of it gets, since it is the only one that does not require a human to have done their part.

The one thing I would treat with genuine care is Run on demand. A feature whose leaver tasks disable and delete accounts, and whose on-demand path explicitly does not evaluate the scope you wrote, is a loaded tool with a ten-user magazine. It is there for testing. Using it for anything else means the only thing standing between a mistake and eleven disabled accounts is the person clicking.

Next in this series

#58 turns to the evidence for all of this: Entra’s logs — sign-ins, audit and provisioning — what each one records, how long it is kept, and which questions none of them can answer.

Comments

How was your experience?
Your feedback helps improve this site.
PoorExcellent