My wife’s Power Platform solution for her business will have emails being sent for confirming, changing or cancelling an appointment. We’ll need the sender of emails to appear from different email addresses depending on what environment is being used. That’s this week’s topic sorted then – Environment Variables in the Power Platform.
Table of Contents
ToggleWhat are they?
Environment variables are dynamic values that can be used to store and manage settings or references. Rather than hard-coding values directly into your solutions (such as email addresses or connection strings), you can use environment variables as placeholders that will adapt to their respective environment. This makes our Power Platform solutions much easier to maintain, especially when you’re using multiple environments and full Application Lifecycle Management.
Environment variables are created & stored at the environment level, meaning they can be accessed by any app, flow, bot or solution within that environment. That’s great as you can reuse a variable across lots of solutions, but obviously be careful of impact for others if changing them.
Key benefits
There’s a couple of key benefits worth noting for using environment variables:
Secure configuration management: Environment variables provide a secure way to store sensitive information such as database credentials, API keys and authentication tokens. By storing these values in variables, you can easily update them without having to change your code or settings in apps, flows, bots etc. This minimizes the chances of sensitive data being accidentally exposed.
Decoupling logic: You can separate application and configuration logic. This decoupling allows you to focus on the business logic of your solution without being concerned about the specifics of each environment or having to constantly change code.
Flexibility: You can easily move your solutions between different environments. This simplifies your deployment processes and reduces risk of errors caused by hard-coded settings.
Variable types
There are various environment variable types you can select and configure:
Text
Stores plain text values, so can be used to store email addresses, API endpoints or any other text-based config. We’ll be using a couple of these for storing email addresses for my wife’s solution.
Decimal number
Stores numeric values, so can be used to store phone numbers, thresholds, a maximum or minimum range or any other numerical scenarios.
Yes/No
Stores a ‘yes’ or ‘no’ value. These are super useful if you want to configure settings that control behaviour of apps, flows or anything else within your solution. Please note that this isn’t a Boolean output of true or false, these are text value outputs of ‘yes’ and ‘no’.
JSON
Stores data objects or arrays in the form of JavaScript Object Notation – or JSON for short. You can use this variable type to store more intricate configurations, such as tables of data or connection properties that have multiple values.
Secure
These are purposefully designed for storing sensitive information such as usernames, passwords, secrets or API keys. The values stored in secure variables are encrypted and can only be accessed by authorized users or processes.
Not going to lie, never done a secret as an environment variable so can’t really chat much about my experience with them. Microsoft have them well documented here. According to that link they’re still in preview so not intended for any production usage yet.
Data source
These are used to manage connections to external datasources. Currently there are only 3 configurable data sources; Dataverse, SharePoint Online and SAP.
Where is the information stored?
Environment variable information is stored in 2 Dataverse tables.
The ‘Environment Variable Definitions’ table stores the information about the data you want to keep variable. This is where the Default value of your variable is stored.
The ‘Environment Variable Values’ table stores the actual value to be used. It’s in this table that the Current value is stored.
Create an environment variable
Typically, I start by navigating to my DEV environment, then the relevant solution. Alternatively, you can access the Default solution and add from there instead, but remember to add the environment variable to your solution afterwards.
In your chosen solution, select New > More > Environment variable:
Enter a display name. You may have an internal naming convention to follow, please check before committing to a choice. The ‘Name’ field will be prefixed with the Publisher of your solution. It’s here that you also select the type of environment variable you want:
For the Decimal number, JSON and Text types, you’ll then see an option to add a Current and/or Default value:
For the Data source type, you’ll see the 3 options currently available – each with their own required configuration. We’ll cover the SharePoint one later in this article:
For the Secret type, this involves setting up secrets in Azure before plugging the info into here:
Given that each type has options for both a Default and Current value, let’s cover that off before continuing with examples.
Current vs Default value
I must admit, this is an area that confuses me a bit. Googling around gives rise to lots of conflicting opinions, so I don’t think I’m alone. I’ll document what I do and why, but genuinely welcome anyone else’s take.
For me, I stick to using the Current value only. Here’s why:
The Default value, I believe, should be for when the value you’re using will be, or likely be the same in DEV, UAT and PRD. As such, on solution import you won’t be prompted for an updated value. it still eliminates hard coding and can be changed when needed.
The Current value is therefore more useful for updating with different values per environment. BUT, you have to remember to clear the value out before exporting your solution to import elsewhere. This will then provide a prompt in the destination environment that a variable needs updating.
So you could probably just do that with the Default value as well, then? Insert confused look here.
I resorted to looking at some of the environment variables in the CoE Starter Kit. They all seem to use Current Value so if it’s good enough for the Power CAT team, it’s good enough for me.
Referencing variables
In this section, we’ll go over setting up each environment type and then how to reference the values in Power Apps and Power Automate.
Please note – you’ll need to add 2 Dataverse tables to your Power App to retrieve data for environment variables. This will mean your app is now consuming a Premium feature, so ensure you have appropriate licensing.
OR – set up a Power Automate flow that can be called from your Power App. This method can retrieve environment variable values without needing to add the 2 Dataverse tables to your App. No license required!
Text, Decimal Number, Yes/No
Here, I’ve added an email address as the current value for the text variable:
Use in Power Automate
To use the environment variable values in the context of a flow, bring up the dynamic content box and find the relevant environment variable to add in:
Use in Power Apps - table method
If you’re using the 2 Dataverse tables and have the appropriate licensing, you’ll need to use the following formula:
LookUp(
'Environment Variable Values',
'Environment Variable Definition'.'Schema Name' = "NameOfYourVariable"
).Value
The Schema Name is the Name of your variable, not the Display Name. You can choose to use Display Name for the lookup, but you might have more than 1 with the same name. The uniqueness comes from the Schema Name, so more accurate to use that.
In my example, the Schema Name I need is ‘bsn_EmailSentFrom’:
Use the exact same methods for Decimal & Yes/No types. Please note that for the ‘Yes/No’ type, when setting the variable, the option is capitalized but the output isn’t. It may be of minimal consequence but worth knowing, just in case:
Use in Power Apps - flow method
We can build a Power Automate flow that can be triggered from our canvas app. We can then get the environment variable value and pass it back to our app. This avoids using the 2 Dataverse tables and therefore not license dependent.
For this to work, I believe the flow needs to be in the same solution as your canvas app.
To start, open your canvas app in edit mode, select the Power Automate option and click ‘Create new flow’:
Select ‘Create from blank’. This will show a popup with your Flow designer, with PowerApps as the trigger:
Click ‘New step’. Find and add the action for ‘Respond to a PowerApp or flow:
Select the relevant output type for your environment variable. I’ll pick ‘Text’ for this example:
Give your output a name. Use the ‘Add dynamic content’ option to find your relevant environment variable:
Save the flow by clicking the option in the top right. Once saved, the popup will disappear. Your app will then process the new flow and will appear once loaded;
We now need to call the flow to get the value returned, so we can store it.
Add a button to your app. In the OnSelect property, use the following Power Fx:
// Set global variable with output received from Flow
Set(
gvMyTextEnvVar,
Gettextenvvar.Run().mytextenvvar
)
Gettextenvvar is the name of our Flow we created. With that, we need to use ‘.Run()‘ to ask the flow to run which will send a value back.
The name of our value in the flow is myTextEnvVar, though this is shown as all being lower case in the Power Fx:
As a test, we can add a label control and set the text property to the name of the variable:
There you go – an easy and free way to get your environment variable values!
Data source
At time of writing, there’s 3 data sources you can configure as environment variables; Dataverse, SharePoint & SAP. This will be useful for those using SharePoint lists/libraries as a data source for canvas apps. SharePoint is the example covered below:
You need to set up a SharePoint Site environment variable first. It simply won’t get you set up a SharePoint List unless there’s at least 1 Site variable present:
With a Site variable defined, we can then reference any of the Lists in that Site to set as our List variable. Here, I’ve connected to a SharePoint site that contains information about Formula 1 drivers:
Use in Power Automate
We can access the dynamic content again within any SharePoint trigger or action:
Interestingly though, I noticed a bug (?) with the SharePoint trigger. When I selected an automated cloud flow & picked the trigger from the menu, there’s no options for dynamic content:
But if I click on ‘Skip’, I get the dynamic content options:
Nice one, Power Automate.
Use in Power Apps
In the Power Apps designer, we need to add SharePoint as a data source. This is free to use and consume, so no need to create or call a flow:
From the resulting pane, switch from ‘Recent sites’ to ‘Advanced’, then select the relevant SharePoint Site environment variable:
Select ‘Advanced’ again to choose the relevant SharePoint list URL:
You can now use the variable connection string as you normally would:
JSON
In a previous company, we used JSON environment variables to store a server and database name for SQL. We had dedicated DEV, UAT & PRD SQL instances to map to our respective Power Platform environments. We’ll use that as a basis for this example.
When setting up this variable type, make sure you enter a valid JSON string to the Current Value field. There are loads of tools out there to help validate, personally I love using JSON Crack.
Once validated, add the string to your Current Value:
Use in Power Automate
If we want to retrieve the rows and/or columns from our JSON variable, we’ll need to use the Parse JSON action. Bring up the dynamic content box and find the relevant environment variable to add in for the ‘Content’. Using the validated JSON string, select ‘Generate from sample’ to copy in the schema:
With that done, we can then access the values:
In our example of using the JSON environment variable to store SQL properties, our Flow would look something like this:
Use in Power Apps
There are currently 2 ways to retrieve JSON environment variables for your Power Apps.
Option 1: Power Automate
We can build a flow that we can call from the canvas app, much like what was explained earlier in this article. This time, we’ll need to include a ‘Parse JSON’ action to get the values to return:
We can embed the calling of the flow into other functions in Power Apps. In this example, I want to use the response to create a collection:
Please note – my example is of a single-row JSON string, so using the ‘Respond to a PowerApp’ action is fine. If you have multiple rows, your best bet is to use the ‘Response’ action though this is Premium, so needs a license.
There are free alternatives, including sending the raw output back as text then using various Substitute or MatchAll functions in Power Fx to convert the string. Thankfully and at last, there’s an easier way:
Option 2: ParseJSON function
Microsoft recently announced the ParseJSON function for Power Fx that’s currently in experimental stage. As per the documentation, ‘experimental features aren’t meant for production use’ so at time of writing probably best to use the Power Automate method for now.
That said, it’s definitely worth understanding this function as it’ll make lives easier when it moves to GA. As well as handling JSON environment variables, there’s some other cool stuff we can do with the ParseJSON function. That’s going to be the topic of my article next week, as we’re going to use this new function in the canvas app build for my wife’s business. We’ll cover the technique for retrieving environment variables values at the same time.
Current limitations
There are a couple of limitations for environment variables, as listed on Microsoft’s documentation. I had meant to include this part in my original article draft. Massive thanks to Stefan Jackmuth on LinkedIn for the reminder!
There’s one in particular that can really catch you out:
“When environment variable values are changed directly within an environment instead of through an ALM operation like solution import, flows will continue using the previous value until the flow is either saved or turned off and turned on again.“
Don’t forget to deactivate, then reactivate any flow that uses an environment value that’s had its value updated.
We now have a couple of environment variables set up. These will be handy for driving dynamic functionality in our solution, so will pick these up when we come to building our app & flows!
Thanks for this great article!!
Question regarding connection references (mainly used in powerautomate flows) :
What is the best strategy:
1. create seperate connection references (for every type of connection you use) for every solution
2. or re-use same connection references in all of your solutions (dependencies?)
Hi Rudi, that’s a great question and hoping to cover connection references in a future article. For me personally, I tend to create separate connection references per solution, I think more a fear of anything going wrong with a shared one. Whether that’s considered best practice I don’t know but will do some research.
Wow, love the detail! This blog is great! I especially love the screenshots as it makes it easy to follow along. Keep it coming!
Thanks Hunter, appreciate the feedback!
Noticed something today after banging my head on a PowerApp for a few hours…
Despite PowerAutomate being more than happy to use a default value, PowerApps insists on using the current value of an enviroment variable.
Hi Jimi, yes I’ve seen this before. In Power Apps you can target either or both values. The formula is slightly different to do so, which is a bit annoying and yes, would be great if Power Apps can auto determine which to use.
Example below, I’ve an environment variable called EnvVarTEST, which has a schema name of cre84_EnvVarTEST. Both the Default and Current values are populated.
This Power Fx formula can get the current value:
LookUp(‘Environment Variable Values’, ‘Environment Variable Definition’.’Schema Name’ = “cre84_EnvVarTEST”).Value
And this Power Fx formula can get the default value:
LookUp(‘Environment Variable Definitions’,’Display Name’=”EnvVarTEST”).’Default Value’
Hope that helps!