Power Automate - Environment Variables
Tags: powerplatform, powerautomate, lowcode, rpa
Published: 2023-11-06 07:40:36

If you want to do ALM (application Life-cycle Management), and you should, then you need environment variables.

ALM has 2 main benefits

1. Separation of duty
2. Protection of prod

Separation of duty means the person who created it can't deploy it. Why is that important, well we need checks and balances, apps and automation's can have a lot of power, power that can be misused. Just imagine if the flow had access to sensitive data, and the developer used that access to distribute the data. Often this is a legal requirement, it ensures critical company data that may impact share price cannot be tampered with (e.g in the US Sox).

Protection of prod is kind of obvious, but let me expand anyway. By stopping edits or deployments straight to prod we stop many unexpected system issues. Test is a gatekeeper to check that the new deployment works as expected. We would all want crashes in test rather than on our critical prod automation's/apps.

---

Sorry I digressed a little there, so environment variables. Well if we are deploying from dev to test to prod, then we need a quick and easy way to flip between those environments. The power of the Power Platform is its connections, so we need those variables to flip between environments.

An obvious example would be SharePoint, lets say you have a flow triggered by a file upload to a library, extracts data and saves to a list. We need a way to trigger, dev, test and prod, but not at the same time. We also need to make sure the extracted test data does not go into the prod list.

The key info we need to understand are the right strategy and right environment type.

## Strategy

There are a couple of approaches to your strategy, multiple versions/environments or sub environments.
The best example for this is our old friend SharePoint, do you go with:
Multiple sites, all duplicates with the same lists, libraries settings.

or

One site, multiple lists / libraries

This also works for other connections like Outlook (different Shared mailbox or same but different folders).

My preference is different versions/environments. As that is the most accurate and allows testing of updates the the version/environment settings.

## Types

There are 5 types of environment variables and using the right one is key

- Data source (SharePoint/Dataverse/SAP only)
- Text
- Decimal Number
- Yes/No
- JSON
- Secret


![environment variable selection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyf2k7gttl9qmbkrq5sg.png)


**Data source**
This is great for SharePoint sites and lists, it uses the SharePoint API to list all your available sites with a display name. You can then use the site environment variable for the list variable, again showing the available lists.

There are a couple of problems with this though, first the api isn't 100% perfect, so often sites and lists/libraries don't show up to be selected. The next is its limitations.

![data sources](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/izseq9iguqxi215p1kf6.png)

First its only good for the 3 connections above, I would love it for MS forms, planner and more. But the big one is it doesn't cover everything like you would think. Take SharePoint, if you use it to select a Excel action from a SharePoint list you get an error. You have to input the library id, same with the Word connector too.

For me the whole point of LowCode is ease of use, the data source environment variable is exactly what it should be, but its implementation is half baked.

**Text**
This one is an obvious one, it holds a string. As mentioned above this is great for library/drive ids, and a must for when you use any of the HTTP actions. This can also be used for date/times, but it should never be used for confidential data like passwords or secrets, as it is stored in plain text with the environment variable value Dataverse table. 

**Decimal Number**
Another obvious one, instead of going with an integer they use a float. Not sure how many decimal places, but never had an issue (also works fine with integers - whole numbers).

**Secret**
This one is a great idea but it's just out of preview so still not fully featured. As I said string variables are not right for passwords, so where do you put them, in a secret. The secret term is used for Azure spn's etc, and this is what this was originally designed for (though I don't see why you cant use it with any password). A simple approach would just be a string variable but masked, but that is not how this works and for good reason. Instead this links to a key vault (currently only Azure Key vault). So what is the main benefit of this approach, well its rotations. Passwords should be rotated, key vaults to this automatically. This means you don't have to manually update them and then go into the Power Platform environment and update them. Another benefit is security, as its now stored in industry leading locations rather then a Dataverse table (not to say that's not secure)

![secret settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l1vpv322hw8swomh23g7.png)

You need all the Kay vault information, so you will need support from your Azure team (if its a different team).

A good blog to read about Secret varaiables can be found here:
https://blog.yannickreekmans.be/environment-variable-secrets-azure-key-vault-improvement/

**Yes/No**
Another obvious one, this is a simple boolean (true/false) also known as a flag. If you select Yes then it returns true, no false. Great for a conditions (especially if() expressions as this can be used for the first input).

![yes no variable flow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gw184vf60li8fu04ncqt.png)


**JSON**
This one is my favourite as it's incredibly powerful but rarely used. The JSON allows you to create a fully body as an environment variable, why is this cool, 3 reasons.

1- Multi variable. I see lots of solutions with multiple environment variables, these are a pain to keep upto date. If they are all linked (so generally get updated at the same time), then they should all be replaced with one JSON varaible.

![simple object](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iiuuasmy6j49dqfoz3ox.png)

```
{
  "text": "hello world",
  "number": 1,
  "boolean": true
}
```

![flow run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xjyz816mr6nj00kipgv.png)

It takes a little more effort in the flow, as the quick select can't be used (instead an expression with the sub variable name)
```
parameters('testObject (wd_testObject)')['text']
```

2- Arrays, yep you can store whole arrays in there too. No more pulling in a SharePoint list for a config array, store it in a variable.

```
{
  "array": [
    {
      "text": "hello",
      "index": 1
    },
    {
      "text": "world",
      "index": 2
    }
  ]
}
```

![flow array](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/80exnog5mp8seby5kpu2.png)


To use them is the same as the multi variable, just add it to the loop and then use the items() expression.
```
parameters('testObject (wd_testObject)')['array']
```

```
items('Apply_to_each')?['text']
```

3- Test data, you can store an entire body return from an action and reuse for testing. By this I mean you can copy from something like a SharePoint get items the return body, paste it in the variable and then call it.

---

As you can see there are more then just text variables, and used correctly they can push your automatons to be enterprise ready