blog.atwork.at

news and know-how about microsoft, technology, cloud and more.

How to backup and restore a flow with another flow

Did you know that you can backup and restore a flow (or multiple flows) with another flow in Power Automate? This is very helpful for backing up and restoring important flows in the company. Well, I knew the mechanism. Now I've tested it myself and found that this process is undocumented and I've only found examples that didn't work. Reason enough to develop the process to work and describe it with all workarounds. Here is the guide for real world application.

It took some effort to get this to work. I would like to thank my colleague Christoph Wilfing for his support. We analyzed and developed this process together.

Scenario

We want to create an (automatic) backup of one or more Power Automate flows. If a flow is deleted, we can restore the flow (in the same environment). You can download the flows from my GitHub repo, see the end of the article. Here we try to explain how the process works.

Note: The restore flow requires that all connections in that environment are existing and functional. See also the following article.

Backup a flow

Let's keep it simple and start with the backup flow. We open make.powerautomate.com and change the environment to the desired one and get the id of the flow.

In this sample, we want to backup a flow with the name "VacationRequest". In the "more commands", we can open the Details, as here.

image


The browser navigates to the flow and it´s details. We get the the id of the flow from the URL, at the <flow-id> position:

https://make.powerautomate.com/environments/<env-id>/flows/<flow-id>/details

In my sample, the flow-id is e38d9103... (a GUID, simplified here). So, we can create a new flow with the name "Backup1flow". Here´s the complete flow.

image

Steps:

  • For testing we use a manual trigger.
  • In an "init variable" action, we set the flowname to the flow-id (it does not work with the flow´s display name, and flows can´t have parameters like Azure Logic Apps).
  • Get Flow is a method in the Power Automate Management connectors:
    image
  • In Get Flow, we select the environment and use the flowname variable to get the flow.
  • The next two operations are a Data Operation / Compose actiona. We need to get details from the flow.
  • First, we transform the flow definition in the ComposeFlowDefinition action. We select the GetFlow properties from the Dynamic content options: GetFlow / Flow definition (or, we can use the expression):
    outputs('GetFlow')?['body/properties/definition']
    image
  • In ComposeConnectionReferences, we use the GetFlow / connectionReferences, or the expression
    outputs('GetFlow')?['body/properties/connectionReferences']
  • Then, we write this data into two files stored in an SharePoint Online document library. The definition is written to a file with the flowname-Definition.json. Note, that the second file with the connections is written to a file named with the flowname-Connections.txt. There´s a reason for that.
    image
  • That´s the Backup1flow flow.

Pitfall 1-reading a json file from SharePoint

The SharePoint connector for reading a file has a feature named Infer Content Type with the settings Yes or No. This means, the connector finds out the file format by the file extension and tries to transform the file content into the correct object type. If set to yes (which is the default), the content type will be retrieved by flow from the document. Otherwise, we could get an octet-stream for text files (which is useless for our purposes).

The problem here is that the connections document is also a valid json document, but this is not working with the SharePoint connector that does not transform that content correctly. Here´s the VacationRequest-connections.txt file content:

image

We see, it´s an array containing one or more connections that are used in the flow.

If we write the connections to a file flowname-Connections.json (as here), and we try to read that file from SharePoint with Infer Content Type set to Yes (again, that usually makes sense), the Restore1flow flow (below) delivers an internal error!

image

"Encountered internal server error. The tracking Id is <some-id>."

While we have two reads, the first worked and the second failed. Helpful, isn´t it? Winking smile

It took me some time to figure out the differences and the behavior... BTW, the documentation of the Power Automate Management connector is absolutely useless. The description of the "Create Flow" action is it´s name "Create flow" with list of parameters with a type only. There is absolutely no description or hint how to use that action (or the other actions in the connector). However, the reason for the "internal error" is the SharePoint connector with the connections json content as described above.

So, we have to workaround for the connections file content. The first step is to save the connections with the .txt file extension instead of .json. In the Backup1flow, we write the file flowname-Connections.txt. The rest, we have to workaround with some actions below.

Note: The reason to create a flowname-Definition.json file and a flowname-Connections.txt file is that we can read it from SharePoint with the SharePoint connector only as described here.

Run the backup flow

When we run the Backup1flow, we should get two files per flow (here VacationRequest) in the SharePoint library:

image

We now have a backup of a flow in a specific environment saved to a SharePoint library.

Restore a flow

So let's imagine the flow has been deleted and we need to restore the saved flow (in the same environment). For that purpose, we create another flow named Restore1flow, that looks as here.

image

The screenshot shows the successful run of the Restore1Flow flow.

Steps:

  • For testing we use a manual trigger.
  • In an "init variable" action, we set the flowname to the name of the saved flow, here it´s VacationRequest.
    image
  • We read the two files with the SharePoint / Get file content using path actions. Note, the different Infer Content Type settings for the .json and for the .txt file.
    image
    Note: For reading the definition file, we could also set the Infer Content Type to Yes, and replace the json() function in the Create flow definition with a string() operation. Just pay attention to the settings.
  • Now we add a Data operation / Parse JSON action. As content, we use the output from the connections.txt:
    body('GetFileContentFlowConnections')
    For the Schema, we click on Generate from sample and paste the content from the flowname-Connections.txt file. This generates the schema, containing three keys: connectionName, displayName, and id.
    image
    We then have a json object with the connections.
  • Now comes the magic to make the restore process work as described in pitfall 2: We need to transform the connections into a new object the Create flow action requires. We do this with a Data operation / Select action, as here:
    image
  • To fill this action, we only need two keys: connectionName and id.
    From is the output of the ParseJSON action: body('ParseJSON')
    connectionName contains the expression item()?['connectionName']
    id contains the expression item()?['id']
    The Peek Code feature shows how this action should be filled:
    image
    This creates a new object with only these two properties.
  • As last step, we use the Power Automate Management / Create Flow action. We select the same environment, and add a new name Restored-flowname. We add the Flow definition from the SPO definition file output.
    Flow Display Name: Restored-...variables('flowname')
    We convert the definition content to a json object: json(outputs('GetFileContentFlowDefinition')?['body'])
    The Flow state can be Started or Stopped.
    The connectionReferences are set to the new object we created above: body('Select')
    image
  • This action works only if the parameters are in the correct format. Here´s the relevant PeekCode info:
    image
  • This is Restore1flow.

Pitfall 2-find out what data is required

We tested and stumbled multiple times how the Create Flow action expects the values. We figured out by trying, how the definition and the connections must look like. The definition of a flow (Get flow definition) can be passed 1:1 as a json object to the Create Flow action.  The connectionReference must be a json object as well and must include an array that only includes the connectionName and id. Therefore, we need to dump the displayName key from each connection. To accomplish this, we create a new json object with only these two parameters. Only this format works for the connectionReference.

This is how the connectionReference must be passed to the Create Flow action. Every connection is an object within the array, as in this sample.

[

  {
    "connectionName": "shared-office365-132cb39d-e17b-4d8b-99e9-ee473e73ad1c",
    "id": "/providers/Microsoft.PowerApps/apis/shared_office365"
  },
  { <next-connection...> }
]

With these data transformation workarounds, we can restore a flow to the same environment where it was previously saved.

Run the flow restore

When the Restore1flow runs successfully, we get the restored flow, as here: Restored-VacationRequest.

image

The run time usually is some seconds. The copy works in the same way as the original flow, but is stopped here because we decided so in the Create Flow action.

Notes on the recovery process

  • The restore works only, if the connections used in the flow are still existing in the environment. See the following article for fixing this if needed.
  • If we run the restore flow multiple times, the restored flows are numbered: Restored-VacationRequest, Restored-VacationRequest-2, etc.
  • The flow user must have the permissions to read the flow, and to create a new flow. A Power Platform Admin role helps. See more at Service administrator permission matrix.

Room for more

Now we have a mechanism for backing up and restoring a single flow. We can develop the flows in a Get all flows loop and do the backup for multiple flows. You can find the two flows to download and import into your own Flow environment in my PowerPlatformGovernance repository in GitHub. In the next article we will see how we can restore a saved flow in a different environment.

We hope this practical guide will help you easily backup and restore your own flows.

Pingbacks and trackbacks (1)+

Loading