{"id":1018,"date":"2024-08-16T11:39:00","date_gmt":"2024-08-16T16:39:00","guid":{"rendered":"https:\/\/automatethemundane.com\/index.php\/2024\/08\/16\/power-pipelines-and-enhanced-alm-part-8a-solution-watcher\/"},"modified":"2024-08-16T11:39:00","modified_gmt":"2024-08-16T16:39:00","slug":"power-pipelines-and-enhanced-alm-part-8a-solution-watcher","status":"publish","type":"post","link":"https:\/\/automatethemundane.com\/index.php\/2024\/08\/16\/power-pipelines-and-enhanced-alm-part-8a-solution-watcher\/","title":{"rendered":"Power Pipelines and Enhanced ALM Part 8a &#8211; Solution Watcher"},"content":{"rendered":"\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">With the solution register in place, we still face the risk of people (with the correct permissions) importing solutions that are not being tracked. This could be everything from PCF controls to solutions from developer\/sandbox environments. This does not mean there is something nefarious happening, but to be a good steward of governance we need to monitor what solutions are being installed. <\/p>\n\n\n<h1 class=\"wp-block-heading\">Diagram<\/h1>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-1024x634.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">This diagram is the core of what is going to be happening with the project. In the next post we will break it down further. <\/p>\n\n\n<h1 class=\"wp-block-heading\">Create new table for current PPM<\/h1>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The first step is to create a new Dataverse table that will be used to store approved solutions. It will consist of the following<\/p>\n\n\n<ul class=\"wp-block-list\">\n<li>Solution ID<\/li>\n\n\n\n<li>Name (string)<\/li>\n\n\n\n<li>If the solution is tracked (boolean)<\/li>\n\n\n\n<li>Environment Name (String)<\/li>\n\n\n\n<li>Environment ID (string)<\/li>\n\n\n\n<li>Purpose (text area)<\/li>\n\n\n\n<li>ALM Solution (boolean)<\/li>\n\n\n\n<li>Who created the solution (email)<\/li>\n\n\n\n<li>When it was created (date time)<\/li>\n\n\n\n<li>Who approved the solution (email)<\/li>\n\n\n\n<li>When it was approved (date time)<\/li>\n<\/ul>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\"> The Environment Name and ID will only be used if the solution is added manually to an Environment. <\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-1.png\" alt=\"\"\/><\/figure>\n\n\n<h2 class=\"wp-block-heading\">View<\/h2>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The main view will be as follows<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-2.png\" alt=\"\"\/><\/figure>\n\n\n<h2 class=\"wp-block-heading\">Form<\/h2>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The Main form will be as follows. Each of the fields will be set to read only. This is being done because at no time should people be adding or updating the data in the form itself. <\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-3-1024x681.png\" alt=\"\"\/><\/figure>\n\n\n<h2 class=\"wp-block-heading\">Business Rules<\/h2>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Since the Environment ID and Name will not be used if the solution is apart of the ALM pipeline, we will want to hide them. The easiest way to do this is to create a business rule. <\/p>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The properties of the first condition will be if ALM solution is Yes<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-4.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Then components to set the visibility to No for the Environment ID, the Environment Name, Solution Created By, Solution Created on, Solution Approved by, and Solution Approved on.<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-5-1024x96.png\" alt=\"\"\/><\/figure>\n\n\n<h2 class=\"wp-block-heading\">Security Role Updates<\/h2>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">For both security roles (Admin and Developers), we will set the Tracking&#039;s table to Read Only. Updates will be coming via the Power Automate flows. The Form view is simply to see what is going on. <\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-6-1024x159.png\" alt=\"\"\/><\/figure>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-7-1024x184.png\" alt=\"\"\/><\/figure>\n\n\n<h2 class=\"wp-block-heading\">Ribbon Updates<\/h2>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">In addition to the security role updates, we will remove the Add button from the ribbon of the Tracking&#039;s table. <\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-8.png\" alt=\"\"\/><\/figure>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-9.png\" alt=\"\"\/><\/figure>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-10-1024x176.png\" alt=\"\"\/><\/figure>\n\n\n<h1 class=\"wp-block-heading\">Update current flows<\/h1>\n\n\n<h2 class=\"wp-block-heading\">1.1 Flow<\/h2>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The 1.1 flow needs to be updated to add the row to the tracking table if it is coming via the pipeline. We will use the same output of the solution name as seen in LINK, mark the solution as tracked and set the purpose to, \u201cFrom Pipeline\u201d, then set the ALM Solution to Yes. <\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-11.png\" alt=\"\"\/><\/figure>\n\n\n<h1 class=\"wp-block-heading\">Update MDA<\/h1>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Within the PPPM MDA, we will add the table to the Backend area.<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-12-1024x547.png\" alt=\"\"\/><\/figure>\n\n\n<h2 class=\"wp-block-heading\">Update Project Table<\/h2>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The last portion to update will be the project table. We will create a relationship between the watcher table and the Projects table.<\/p>\n\n\n<h3 class=\"wp-block-heading\">Relationships<\/h3>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-13.png\" alt=\"\"\/><\/figure>\n\n\n<h3 class=\"wp-block-heading\">Form<\/h3>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Within the Main form of the Projects table, we will add the subgrid of the Solutions Watcher Table<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-14-1024x653.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">With all these updates in order, we can push them all to Production to update the orchestrator flow. <\/p>\n\n\n<h1 class=\"wp-block-heading\">Updating the orchestrator flow<\/h1>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">This should be done after all other updates are in production and watcher table has been updated.<\/p>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">First, we need to search against the new solutions tracking table<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-15-1024x444.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Then, we need to look up the associated project<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-16.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Finally, update the get customer and lead info with the proper values<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-17-1024x417.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The pipeline will now be able to run as it did before with the updated table<\/p>\n\n\n<h1 class=\"wp-block-heading\">Building Watcher Solution<\/h1>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Since the purpose of this solution is to live in each of our Environments as a managed solution, we can not add this to our current solution or build it in our current Environment. We will need to build the solution in a separate development environment then export it as a managed solution. <\/p>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">In our personal dev Environment, we will create a solution called Solution Watcher and Environment Variable called Production Environment then create a flow called SW - 1.1 - When a new solution is created in the Environment <\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-18-1024x212.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The SW - 1.1 - When a new solution is created in the Environment it will be built as follows<\/p>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The trigger will be when a solution is added to the environment solutions table.<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-19.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">The first step is to filter out if the solution is coming in via Microsoft as part a built in feature. To do this, find the GUID of the user \u201cSYSTEM\u201d in the user table. If that matches the user that created the solution, we will terminate the flow.<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-20.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Using a FetchXML to find the user \u201cSYSTEM\u201d<\/p>\n\n\n<pre class=\"wp-block-code\"><code>&lt;fetch top=&quot;1&quot;&gt;\n  &lt;entity name=&quot;systemuser&quot;&gt;\n    &lt;filter&gt;\n      &lt;condition attribute=&quot;fullname&quot; operator=&quot;eq&quot; value=&quot;SYSTEM&quot; \/&gt;\n    &lt;\/filter&gt;\n  &lt;\/entity&gt;\n&lt;\/fetch&gt;<\/code><\/pre>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">If the created by equals the \u201cSYSTEM\u201d user then we will stop the flow<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-21-1024x353.png\" alt=\"\"\/><\/figure>\n\n\n<pre class=\"wp-block-code\"><code>outputs(&#039;List_rows_-_Users_Table&#039;)?[&#039;body\/value&#039;]?[0]?[&#039;systemuserid&#039;]<\/code><\/pre>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Now, we will look up who created the solution and write it to a compose<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-22.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Then, to get the current Environments Name and ID, we will need to run the workflow() expression (<a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/logic-apps\/workflow-definition-language-functions-reference#workflow\">Reference guide for expression functions - Azure Logic Apps | Microsoft Learn<\/a>), then parse the JSON of the output, use the Power Apps for Makers Environments Action then filter it by the output of the workflow().<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-23.png\" alt=\"\"\/><\/figure>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-24.png\" alt=\"\"\/><\/figure>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-25.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">Next, we will list all rows in the Solutions tracking table in the Production Environment and filter it based on the Name<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-26.png\" alt=\"\"\/><\/figure>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">We will now add a condition that if no record is found, it will add a row to the Tracking table in Production<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-27.png\" alt=\"\"\/><\/figure>\n\n\n<pre class=\"wp-block-code\"><code>length(outputs(&#039;List_rows_from_selected_environment_-_Tracking_Table&#039;)?[&#039;body\/value&#039;])<\/code><\/pre>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">If it does not match, we need to add it to the production table Solutions Tracking<\/p>\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/Untitled-28.png\" alt=\"\"\/><\/figure>\n\n\n<h1 class=\"wp-block-heading\">Closeout<\/h1>\n\n\n<p class=\"has-text-color\" style=\"color: rgb(0, 0, 0)\">We will end here at the risk of exercising too much new information. In the next post, we will go over how to install the solutions and the actions that happens when a solution is added. <\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>With the solution register in place, we still face the risk of people (with the correct permissions) importing solutions that are not being tracked. This could be everything from PCF controls to solutions from developer\/sandbox environments. This does not mean there is something nefarious happening, but to be a good steward of governance we need [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1016,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,43,6,30,42,45,37,35],"tags":[],"class_list":["post-1018","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dataverse","category-environments","category-model-driven-app","category-power-automate","category-power-pipelines","category-pppm","category-security","category-tables","entry","has-media"],"jetpack_featured_media_url":"https:\/\/automatethemundane.com\/wp-content\/uploads\/2024\/08\/photo-1495125175509-8fddf00e56cd-1-scaled.jpg","_links":{"self":[{"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/posts\/1018","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/comments?post=1018"}],"version-history":[{"count":0,"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/posts\/1018\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/media\/1016"}],"wp:attachment":[{"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/media?parent=1018"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/categories?post=1018"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/automatethemundane.com\/index.php\/wp-json\/wp\/v2\/tags?post=1018"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}