Asana to Microsoft Planner Two-Way Sync
Bidirectionally syncs an Asana project with a Microsoft Planner plan: Asana tasks create/update Planner tasks in the matching bucket and Planner status changes write back to Asana, keyed on a stored ID map with a source flag to prevent loops. Lets Asana users and Teams/Planner users share one task list.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
Bidirectionally syncs an Asana project with a Microsoft Planner plan. Asana is authoritative for task content (title, due date) and pushes create/update into Planner; completion status is bidirectional. A Dataverse ID-map table links each Asana task to its mirrored Planner task and carries a last-source flag plus per-side completion flags so completions never ping-pong between the two systems.
Why it matters: Some team members live in Asana, others in Teams/Planner. A loop-safe two-way sync means neither side has to switch tools, and both see the same task list and completion state.
Built as one solution with two cloud flows + one Dataverse table (Asana Planner Task Map). Both flows ship Off.
Use Case
A team split across Asana and Planner wants tasks and completion mirrored across both tools, without duplicate tasks or infinite update loops.
Flow Architecture
Flow 1 — Recurrence Poll Asana
Recurrence (15 min)Outbound Sync: poll the Asana project.
Initialize correlation + config variables
Initialize VariableMint a run correlation guid, then bind Workspace/Project GID, Plan/Group/Bucket, BucketMap, Teams group/channel and resolve the target bucket; init created/updated counters.
List Asana Tasks
Asana — ListTasksRead project tasks (source of truth).
Apply To Each Asana Task
Foreach (Sequential)Per-task upsert.
Lookup Map Row
Microsoft Dataverse — ListRecordsFind existing mapping for the Asana task.
Condition Task Already Mapped
Condition (If length(value) > 0)Create vs update branch.
Update Planner Task + Map Row
Microsoft Planner — UpdateTask_V2 / Microsoft Dataverse — UpdateRecordMapped branch: sync title/due/%complete; stamp source = Asana; increment Updated.
Create Planner Task + Map Row
Microsoft Planner — CreateTask_V3 / Microsoft Dataverse — CreateRecordUnmapped branch: create task in the target bucket; create map row; increment Created.
Post Teams Summary
Microsoft Teams — PostMessageToConversationCreated/updated counts + correlationId.
Flow 2 — Recurrence Poll Planner
Recurrence (15 min)Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_AsanaWorkspaceGid | String | <configure> | Asana workspace to read tasks from. |
| flowlibs_AsanaProjectGid | String | <configure> | Asana project mirrored into Planner. |
| flowlibs_PlannerPlanID | String | <configure> | Planner plan that mirrors the project. |
| flowlibs_PlannerGroupID | String | <configure> | M365 Group that owns the plan. |
| flowlibs_PlannerBucketId | String | <configure> | Default bucket for new tasks. |
| flowlibs_BucketMap | String | {"default":"BUCKET_ID_PLACEHOLDER"} | JSON Asana-section to Planner-bucket map; default key is the fallback bucket. |
| flowlibs_TeamsGroupId | String | <your-team-id> | Teams group for summary posts. |
| flowlibs_TeamsChannelId | String | <your-channel-id> | Teams channel for summary posts. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Asana | shared_asana | ListTasks CompleteTaskV2 AddComment |
| Microsoft Planner | shared_planner | CreateTask_V3 UpdateTask_V2 ListTasks_V3 |
| Microsoft Dataverse | shared_commondataserviceforapps | ListRecords CreateRecord UpdateRecord |
| Microsoft Teams |
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Section to bucket routing
- Extend flowlibs_BucketMap with one key per Asana section to route tasks into matching Planner buckets (Asana ListTasks doesn't return section, so resolving section requires an Asana REST call).
- Assignee map
- Map Asana people to Planner/AAD users (Planner CreateTask_V3 accepts body/assignments).
- Sync cadence
- Adjust the Recurrence interval on both flows (default 15 min). Keep both equal to minimise drift.
- Richer content writeback
- To push Planner title/notes/due back to Asana, add a built-in HTTP PUT https://app.asana.com/api/1.0/tasks/{id} (Asana connector has no general update op) with a Key Vault-backed PAT.
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Bucket resolve
Resolve the target Planner bucket from the map or default.
EXPR.02Desired Planner %
Map Asana completion to Planner percentComplete.
EXPR.03Map lookup (Flow 1)
OData filter to find the existing map row.
EXPR.04Loop guard (Flow 2 condition)
Only write back to Asana when the completion originated in Planner.
EXPR.05Correlation ID
Minted in each flow's first action, stamped on every map row.
Customize & download
Generate a ready-to-import copy of this solution with your environment-variable values baked in — available on Base, Pro, or Team.
Upgrade to customize
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.