Hardcoded URLs and credentials are how production deployments go wrong. This lesson teaches you to design, implement, and enforce a complete environment variable strategy in Power Automate — covering naming conventions, deployment settings files, feature flags, and secrets management across dev, test, and production environments.

Imagine you've just finished building a Power Automate flow that calls your company's internal CRM API, sends emails through a custom SMTP relay, and writes records to a SharePoint site. It works perfectly in your development environment. Then your manager asks you to promote it to production — and you realize the API URL, the SMTP server address, and the SharePoint site URL are all hardcoded directly inside the flow. Changing them means opening every affected action, editing values by hand, and hoping you didn't miss anything. One slip and production is calling the dev API.
This is a problem every Power Automate practitioner eventually runs into, and the solution is environment variables. Environment variables are configuration containers that live inside a Power Platform solution and whose values can differ from one environment to the next without touching the flow itself. They're the mechanism that turns "it works on my machine" into a repeatable, auditable deployment process.
By the end of this lesson you'll be able to design a complete environment variable strategy — deciding what belongs in a variable, how to type and name variables correctly, how to set environment-specific values during deployment, and how to enforce that strategy across your team. You'll also understand how environment variables interact with secrets management and feature flags, giving you a foundation for production-grade solution lifecycle management.
What you'll learn:
You should be comfortable creating basic cloud flows and working inside Power Platform solutions. If you haven't worked with solutions before, read Deploying and Managing Power Automate Solutions Across Environments: ALM Pipelines, Solution-Aware Flows, and Environment Variables for Enterprise-Scale Delivery first — it will ground you in the solution export/import lifecycle that environment variables are built around. Some familiarity with the concept of dev/test/production environments is helpful; Environment Strategy for Power Platform: Separating Dev, Test, and Production covers that foundation if you need it.
Before touching the UI, let's build a mental model that will make everything else click.
A solution in Power Platform is a container — like a zip file — that holds flows, tables, connection references, and configuration. When you export a solution from dev and import it into test, you want the flows to behave identically in structure but differently in configuration. The API URL in test points to a staging server; in production it points to the live server. The flow itself hasn't changed — only its inputs have.
Environment variables are the mechanism that bridges this gap. Each environment variable consists of two parts:
Think of the definition as a labeled, typed slot, and the current value as whatever you've placed in that slot for this particular environment. When you promote the solution, the slot travels with it; you fill it with environment-appropriate content on arrival.
Key insight
The definition and the current value are intentionally decoupled. This is what makes the system work across environments — you ship the structure, not the data. Confusing these two layers is the most common source of "why didn't my value carry over" questions.
Power Platform supports four data types for environment variables:
| Type | Use case |
|---|---|
| Text | API endpoints, email addresses, SharePoint URLs, feature flag values |
| Number | Timeout thresholds, retry counts, batch sizes |
| Boolean | Feature flags, toggles |
| Data source | Dataverse table or SharePoint list references |
| Secret | Passwords, API keys — backed by Azure Key Vault |
The Secret type is special and deserves its own treatment later in this lesson. For now, focus on Text, Number, and Boolean — these cover the vast majority of real-world use cases.
Poor naming is the silent killer of maintainability. When a team has dozens of environment variables with names like URL1, Flag_New, or TestMode, nobody knows what anything does six months later.
A production-quality naming convention follows this pattern:
{Publisher Prefix}_{Domain}_{VariableName}
For example, if your publisher prefix is Contoso and you're building an integration with your ERP system:
Contoso_ERP_ApiBaseUrl
Contoso_ERP_ApiKey
Contoso_ERP_RequestTimeoutSeconds
Contoso_ERP_EnableDetailedLogging
Contoso_ERP_NotificationEmailAddress
This convention gives you:
Tip
Write the Description field for every environment variable, not just the important ones. Future you (and your colleagues) will thank you when someone needs to understand what Contoso_ERP_RequestTimeoutSeconds controls without having to trace it through ten flows.
If your organization uses multiple solutions — one for HR integrations, one for Finance, one for Operations — keep their variables separate. Don't put Finance variables inside the HR solution just because you're editing it at the moment. Solution boundaries are also variable boundaries.
Let's walk through actually creating an environment variable. All environment variables must be created inside a solution — you cannot create them from outside, and a flow that uses them must be in the same solution.
Step 1: Open your solution
Go to make.powerapps.com, confirm you're in your development environment (top-right corner shows the environment name), and open the solution you're working in.
Step 2: Add a new environment variable
Inside the solution, click the + New button in the top toolbar, then navigate to More → Environment variable. This opens the creation panel.
Step 3: Fill in the definition
ERP API Base URL (this is the human-readable label)contoso_ERP_ApiBaseUrl.Click Save.
Repeat this for each variable in your domain. A realistic ERP integration might have:
contoso_ERP_ApiBaseUrl (Text)
contoso_ERP_ApiVersion (Text)
contoso_ERP_RequestTimeoutSecs (Number)
contoso_ERP_EnableRetryOnFail (Boolean)
contoso_ERP_NotifyOnError (Text)
Warning
Don't put credentials like API keys directly in a Text-type environment variable. Text values are visible to anyone with solution-level access and appear in audit logs in plaintext. For secrets, use the Secret type backed by Azure Key Vault, covered in Integrating Power Automate with Azure Key Vault and Managed Identities: Complete Guide to Secrets Management and Zero-Trust Authentication.
Now that the variables exist, you need to use them inside your flows. Power Automate exposes environment variables through the dynamic content picker — there's no special syntax to memorize.
In an HTTP action:
Open an HTTP action's URI field. Click in the field, then open Dynamic content. At the bottom of the dynamic content panel, you'll see an Environment variables section. Your variables appear there by display name. Select ERP API Base URL and it populates the field with the appropriate reference token.
Behind the scenes, Power Automate resolves this to something like:
@parameters('$connections')
But you don't write that manually — the dynamic content picker handles it.
Composing a full URL:
Say your base URL is https://erp.contoso.com/api/v2 and you need to call /orders. In the HTTP action URI field you'd build:
@{variables('baseUrl')}/orders
But with environment variables, you reference them directly rather than first loading them into a flow variable:
In the URI field, using the expression editor:
concat(parameters('contoso_ERP_ApiBaseUrl'), '/orders')
Or simply use the dynamic content picker to insert the environment variable reference, then type /orders after it directly in the field.
Tip
If you find yourself writing the same environment variable reference in ten different actions across a flow, consider initializing it once into a flow-level variable at the top of your flow. This makes the flow easier to read and means the environment variable lookup happens once rather than repeatedly. This pattern pairs well with the scoped execution concepts in Orchestrating Child Flows and Scoped Execution in Power Automate for Scalable, Reusable Automation Architecture.
In a condition or expression:
Boolean environment variables are particularly useful in conditions. Say you have contoso_ERP_EnableRetryOnFail as a Boolean variable. In a condition action, use the expression:
parameters('contoso_ERP_EnableRetryOnFail')
And compare it to true. The condition branch will behave differently based on what that variable is set to in the current environment — without any code changes.
Here's where most people get confused: how do you actually assign different values per environment?
There are two approaches: manual import configuration and automated pipeline configuration.
When you import a solution (via Solutions → Import solution in Power Apps), the import wizard detects any environment variables in the solution that don't have a current value set in this environment. It presents you with a form where you can enter values before completing the import.
This is fine for occasional manual promotions, but it has problems at scale: it's manual, error-prone, and undocumented. You're relying on whoever runs the import to know the correct values.
The production-quality approach is to use a deployment settings file — a JSON file that maps environment variable names to their values for a specific environment. When you use Power Platform Build Tools with Azure DevOps or GitHub Actions, you pass this file to the import step.
A deployment settings file looks like this:
{
"EnvironmentVariables": [
{
"SchemaName": "contoso_ERP_ApiBaseUrl",
"Value": "https://erp-prod.contoso.com/api/v2"
},
{
"SchemaName": "contoso_ERP_ApiVersion",
"Value": "v2"
},
{
"SchemaName": "contoso_ERP_RequestTimeoutSecs",
"Value": "30"
},
{
"SchemaName": "contoso_ERP_EnableRetryOnFail",
"Value": "true"
},
{
"SchemaName": "contoso_ERP_NotifyOnError",
"Value": "ops-team@contoso.com"
}
],
"ConnectionReferences": []
}
You maintain one of these files per environment — settings.dev.json, settings.test.json, settings.prod.json — and store them in your source repository. Your pipeline selects the correct file based on the target environment and injects it during import.
Key insight
The deployment settings file is your single source of truth for per-environment configuration. It lives in version control alongside your solution, it's reviewed in pull requests, and it's auditable. Anyone on the team can see exactly what values are deployed where — no hunting through environment UIs.
This approach integrates naturally with CI/CD pipelines. If you're building those pipelines, see Building CI/CD for Power Automate with Azure DevOps and the Power Platform Build Tools for the mechanics of wiring up the import task with a settings file.
Feature flags are a powerful pattern borrowed from software engineering. A feature flag is a boolean (or text) value that enables or disables behavior at runtime without requiring a code change or redeployment.
In Power Automate, environment variable-backed feature flags let you:
Example: Verbose logging flag
Create a Boolean environment variable: contoso_ERP_EnableVerboseLogging
In your flow, after each major step, add a condition:
parameters('contoso_ERP_EnableVerboseLogging') is equal to true
Inside the true branch, add a Compose action that captures the current state of all key variables (input payload, response body, timestamps) and appends it to a logging SharePoint list or sends it to Application Insights.
In dev, EnableVerboseLogging is true — you see everything. In production, it's false — the logging branch is skipped entirely, saving on API calls and execution time.
Example: New feature rollout flag
You've built a new duplicate-detection algorithm for your ERP sync. Create a Text variable: contoso_ERP_DuplicateStrategy with possible values legacy or enhanced.
In your flow:
if(equals(parameters('contoso_ERP_DuplicateStrategy'), 'enhanced'),
... call new logic ...,
... call old logic ...)
Deploy to production with the flag set to legacy. When you're confident in the new logic after testing, update the environment variable value in the production environment (directly in the environment, no solution re-import needed) and the behavior changes immediately.
Note
Changing the current value of an environment variable in an environment does not require re-importing the solution. You go to the environment, open Solutions, find the environment variable, and edit its current value directly. The change takes effect on the next flow run. This is what makes feature flags powerful — you can toggle behavior in production without a deployment event.
For credentials, API keys, and connection strings, the Secret data type stores the environment variable's value in Azure Key Vault rather than in Dataverse. The environment variable definition references a Key Vault secret by its URI; Power Automate retrieves the actual value at runtime using a managed identity.
Setting this up requires:
Key Vault Secrets User role on that vaultThe result is that your deployment settings file can reference the Key Vault URI — which is not itself sensitive — while the actual credential never touches Dataverse or your flow definition. This satisfies compliance requirements like ISO 27001 and SOC 2 that prohibit credentials in configuration files.
The full setup walkthrough is covered in depth in Integrating Power Automate with Azure Key Vault and Managed Identities: Complete Guide to Secrets Management and Zero-Trust Authentication. For this lesson, the key architectural point is: your environment variable strategy should separate secret from non-secret variables from day one, even if you're not using Key Vault yet. That separation makes future hardening straightforward.
Having a strategy is worthless if nobody follows it. Here's how you enforce it.
1. Mandate solution-aware flows
Any flow that uses configuration of any kind must live inside a solution. Unmanaged, "My Flows"-style flows cannot use environment variables at all. Make this a team policy. Governance tooling in the CoE Toolkit can report on flows outside solutions.
2. Review deployment settings files in pull requests
When a developer adds a new environment variable, they must add entries to all three settings files (dev, test, prod) in the same PR. Reviewers check that no sensitive values appear in text-type variables and that production values are appropriate.
3. Use managed solutions in test and production
Import solutions as managed into test and production. Managed solutions prevent makers from manually editing flow actions or adding hardcoded values inside those environments. They also prevent direct editing of environment variable definitions — only the current value can be changed. This enforces the principle that configuration changes go through the pipeline.
4. Document the variable catalog
Maintain a table — in your team wiki, your README, wherever your team actually looks — listing every environment variable, its type, its purpose, and the expected value format. Treat it like an API contract.
5. Use DLP to prevent credential bypass
Even with environment variables enforced, a developer could still hardcode an API key directly in an HTTP action. Configuring Data Loss Prevention Policies for Enterprise Cloud Flows describes how DLP policies can constrain which connectors and endpoints are reachable, reducing the blast radius of credential mishandling.
Warning
Default values on environment variable definitions travel with the solution. If you set a default value of https://erp-dev.contoso.com/api/v2, that default will be used in any environment where no current value is set — including production, if someone forgets to provide one. Either leave defaults empty and require explicit values in every environment, or set a deliberately invalid default (like REPLACE_ME) that will cause obvious failures rather than silent misconfiguration.
Work through this in your own development environment. You'll need a Power Platform environment with a solution already created.
Scenario: You're building a flow that sends a daily digest email about new orders from your ERP. The email recipient and the ERP API URL differ between dev and production.
Steps:
Open your solution in make.powerapps.com.
Create three environment variables:
{YourPrefix}_Orders_ApiBaseUrl (Text) — Description: "Base URL of the Orders API endpoint"{YourPrefix}_Orders_DigestRecipient (Text) — Description: "Email address for the daily digest report"{YourPrefix}_Orders_EnableSummaryOnly (Boolean) — Description: "When true, sends a count-only summary; when false, sends full order list"Set current values directly in dev: click each variable, choose Edit, and enter values appropriate for your dev environment (a fake URL, your own email address, and true for the Boolean).
Create a new cloud flow inside the same solution. Add a Recurrence trigger (set to daily, or any interval for testing).
Add a Compose action. In its Inputs field, build an expression using your API URL variable:
concat(parameters('{YourPrefix}_Orders_ApiBaseUrl'), '/orders?status=new')
Add a Condition action. In the expression, reference {YourPrefix}_Orders_EnableSummaryOnly. In the true branch, add a Compose that outputs "Summary mode: on". In the false branch, output "Full detail mode: on".
Save and run the flow. Confirm the Compose output shows your dev URL and the condition branch executes correctly.
Create a settings.json file on your local machine with the structure shown earlier in this lesson. Fill in production-appropriate (or test-appropriate) values for your three variables.
(Optional, if you have a second environment) Import your solution into the second environment manually, using the import wizard's environment variable form to supply test values. Confirm the flow runs with the new values without any flow edits.
"My environment variable isn't showing up in dynamic content"
The flow must be inside the same solution as the environment variable. If you added the variable after the flow was created, close and reopen the flow designer — the dynamic content list refreshes on load. Also confirm the variable's data type: Secret-type variables do not appear in dynamic content and must be accessed differently.
"The flow is still using the old value after I updated the environment variable"
Environment variable current values are resolved at flow execution time, not at save time. If you updated the value and the flow immediately ran again with the old value, check whether you updated the current value or the default value. They are separate fields. Also confirm you edited the variable in the correct environment — it's easy to be logged into the wrong one.
"My deployment settings file isn't being picked up during import"
The SchemaName field in the JSON must match the variable's internal name exactly, including capitalization and the publisher prefix. The display name will not work. Find the schema name by opening the environment variable in the solution and looking at the Name field (not Display name).
"After promoting to production, all environment variable values are blank"
This happens when the production import finds no current value and no default value. Flows will fail with an expression evaluation error that mentions the parameter name. The fix is to set current values in production — either through the import wizard, through a deployment settings file, or by editing them directly in the environment after import.
"A team member hardcoded the API URL directly in the flow instead of using the variable"
This is a governance problem, not a technical one. Enforce code review of solution changes before promotion. The solution history in managed environments records changes, and the CoE Toolkit can flag flows where HTTP action URIs contain static URLs that look like API endpoints.
Environment variables are the cornerstone of any maintainable Power Automate deployment strategy. You've learned that the definition and current value are intentionally separate — one travels with the solution, one stays in the environment. You've seen how to create variables with proper naming conventions, reference them inside flows, supply environment-specific values through deployment settings files, use Boolean variables as feature flags, and enforce the pattern across your team through managed solutions and review processes.
The four things to take away: name your variables consistently with a prefix-domain-name pattern, write descriptions for every variable, never put secrets in Text-type variables, and always maintain deployment settings files in version control.
From here, the natural next steps are:
A well-governed environment variable strategy isn't glamorous, but it's what separates flows you can promote with confidence from flows you promote with your fingers crossed.