CI/CD & Test Automation for Dynamics 365 in Azure DevOps/VSTS- Part 3 – Release Definition

In my previous blog, I wrote about how to set up a VSTS build definition. This blog will continue on that by setting up a VSTS release pipeline in Azure DevOps/VSTS. I will assume you got a QA, UAT and a production environment. The package(CRM solutions) from the build automation blog will be deployed to these environments. It will be set up in a very basic way. After that I will elaborate on different other options you can use in Azure DevOps to include in your pipeline.

Dynamics CRM CICD process

The below diagram illustrates the basic flow of the Dynamics 365 CE Workflow process.

In this part, we are going to see the above-highlighted one in detail.

Pre-requisites

  • Visual Studio Team Services (VSTS)/ Azure DevOps
  • Dynamics 365 Build Tools by Wael Hamze

Setting up the variables for the connection to CRM

You can create variable groups in VSTS. This is useful for variables who are related. You will use this to create a group for credentials for your development environment. Later if you implement the automated deployment, you can store the credentials to other environments there too.

In VSTS go to “Build and Release” and select “Library”. Here you can create variable groups.

Next click on “+ Variable Group”. This will take you to a form where you can create a variable group.

Now you give your variable group a name. I will assume you got a test, UAT and a production environment. The package from the build automation blog will be deployed to these environments.So, we will create three connection string for the test, UAT and production environments.

  • Connection string – AuthType=$(AuthType);Username=$(Username);Password=$(Password);Url=$(Url)
  • URL- Enter your instance URL.
  • Username – Enter the username of your instance
  • Password – Enter the password of your instance
  • Authtype – Office365

Below is the sample connection string details for your reference

AuthType=Office365;Username=jsmith@contoso.onmicrosoft.com; Password=passcode;Url=https://contoso.crm.dynamics.com

Reference Link https://docs.microsoft.com/en-us/previous-versions/dynamicscrm-2016/developers-guide/mt608573(v=crm.8)?redirectedfrom=MSDN

VSTS Release Definition

This release definition will import our packed solution file and then publish the customizations to our Dynamics 365 CE Online sandbox instance(QA, UAT & Production environment).

Once the build definition gets succeded VSTS release definition will trigger automatically and perform the following steps:

You can create a release definition directly from Visual Studio Online(VSTS/Azure-DevOps). To create a new pipeline, you go to Pipelines and then Releases. After that, you click on new and then new release pipeline.

You will get asked to select a template. Those templates are really useful for setting up deployments for azure. For Dynamics CRM deployments there is no template, so you select an empty job.

Next, you will get asked to provide a stage name and stage owner. A stage is an environment, so in our case, we name it “QA”. The owner can be left at default (your account). After you did that you can press the ‘X’ on the top right of the stage tab to close it.

Now you will see the pipeline as below.

  1.  You can edit the name of the pipeline and provide the name of your choice. Below that we can see a navigation bar with different tabs.
  2. Artifacts: An artifact is usually the output of a VSTS build definition, but it also has other options like an Azure Container Repository. If you click on “Add an artifact” you can see all options available. In this blog, we will only use the default, which is a build output.
  3.  Next is the stages. Here you can copy and add new stages for QA, UAT and production environment.

Adding an artifact

To add an artifact. Click on the “Add an artifact’ button. Now select all the correct details. For Project select your current team project. For source select the build pipeline you made based on the previous blog. Set default version to ‘Default’. Finally, provide the source alias name and click ‘Add’ to finish.

Now, we need to add the task for stage QA. Click on stage “QA”. It will navigate you to the task page as follows:

Now you will be in the task editor. Here you can add tasks similar to the VSTS build definition task editor.

To add a Task click on the + icon next to “Agent Job”. You will get a list of tasks. Search for the “MSCRM Tool installer” and add the task.

Next, add the MSCRM Import solution task and click on the task and add the details like below:

Display Name: Provide the name of your choice(Example: Import Solution to QA)
CRM Connection String: Provide the QA connection string variable which we have created earlier.
Solution File: Use the three dots at the right corner to select the correct solution (it will show the artifacts of the last successful build, so make sure your solution is there).
Checkboxes: According to your needs you can select the below checkboxes

Then next add the MSCRM Publish Customization task as follows:

Setting up the environments

Now that we have set up the QA environment, we need to set up the same for the UAT and production environment as well. Click on “Pipeline” on the navigation bar to go back to the overview. The UAT environment is the same as the QA environment, just different variables (remember we added those in the library). An easy way to create that environment is to clone the QA environment. To do that, hover over the QA test environment and click the icon with the 2 papers as shown below:

It will create a “Copy of QA” stage and you see it connected to the QA stage.  Click on it, change the name to “UAT ” and close the tab by pressing the ‘X’ button. Now you have the UAT stage too. The fact that the 2 environments are connected, means that the UAT deployment will automatically start when the QA stage is successfully deployed. Similarly, we need to clone and update the values for the production environment too.

Connecting variables

One more thing we need to do is to connect the variables we created at the start of the stages. You do that by clicking ‘Variables’ in the navigation bar and then “Variable Groups”

After that click on the “Link variable group”. Select the variable group and click on Link button as shown below:

VSTS release definition setup is done. Now, we will quickly explore the advanced options in the VSTS release definition.

Advanced Options

Triggers

Triggers define when a stage will be deployed. You can open it by clicking the lightning icon next to a stage.

There are 3 options you can select:

After Release

This means the stage will be deployed right after the release is created. This is used to automatically start the first stage in the pipeline after a release is created. In build pipelines, you can set to automatically create a release when the build is completed. If your pipeline has these options enabled, then a successful build will automatically deploy to the first stage.

After Stage

This means your stage will deploy whenever 1 or more stages successfully deployed. If you select multiple stages, then every stage needs to complete successfully in order to start this stage. Optionally you can select the checkbox to also deploy if the previous stages are “partially succeeded” instead of just “succeeded”

Manual Only

This means the deployment of the stage has to be manually started.

Approvals

In addition to triggers, you can set approvals. You can configure them by clicking the person icon next to a stage. There are 2 types.

Pre-deployment approvals

Somebody needs to approve that a stage will be deployed. This approval will trigger when the deployment of a stage is about to start. Either via an automatic trigger or a manual start. Approving the deployment results in the start of the deployment of that stage. Rejecting sets the status of the stage to “not deployed”.

Post-deployment approvals

Somebody needs to approve that the deployment of a stage is successful. This approval will trigger after the last deployment task is successfully completed. Approving this results in a succeeded deployment and rejecting it in a failed deployment.

For both options, you can select the approvers and a timeout before it automatically rejects. Also, you can set that if a user manually starts deployment of a stage, that user will not be able to approve the stage. Finally, you can select that approval is skipped when the previous stage was approved by somebody who is an approver of this stage.

Scheduling

Sometimes you may want to start releases on a specific day/time. For that, you can set a schedule. There are 2 options for scheduling resulting in different behavior.

Release Trigger Scheduling

You can set this schedule by clicking the scheduling button below the artifacts. A new release will be created at specific times that are configured. To also deploy to the first stage, make sure that at least one stage has the trigger “After Release”, otherwise it will create a new release but it won’t deploy anything. Also keep in mind a new release will be created, even if there is no new artifact available.

Stage Schedules

You can set this schedule by selecting the pre-deployment conditions and enabling the ‘Schedule’ option. Here you can define 1 schedule of when to deploy this stage.

I hope now you could have got clear information on how to create the VSTS release definition.

In my next blog, we will see how to enable the gated check-in.

If you are interested in this topic and would like to do some further self-study I encourage you to check out my blog on this.

 

CI/CD & Test Automation for Dynamics 365 in Azure DevOps/VSTS – Part 2- Build Definition

In the previous post, I showed you how you can export and extract the solution from Dynamics 365 CE instance and commit to VSTS.

In this blog post, I will tell you how to create the VSTS build definition.

Dynamics CRM CICD process

The below diagram illustrates the basic flow of the Dynamics 365 CE Workflow process.

In this part, we are going to see how to create a build definition in VSTS.

Pre-requisites

Install Dynamics 365 Build Tools by Wael Hamze in VSTS

To set up your tooling there is only one thing to do. You need to install an extension from the Visual Studio Marketplace within VSTS. Go to this link to add this extension to your VSTS account. You need to be an administrator to do this.

Setting up the variables for the connection to CRM

You can create variable groups in VSTS. This is useful for variables who are related. You will use this to create a group for credentials for your development environment. Later if you implement the automated deployment, you can store the credentials to other environments there too.

In VSTS go to “Build and Release” and select “Library”. Here you can create variable groups.

https://www.dynamichands.nl/wp-content/uploads/2018/07/LibraryLink.png

Next click on ‘+ Variable Group’. This will take you to a form where you can create a variable group.

https://www.dynamichands.nl/wp-content/uploads/2018/07/AddVariableGroup.png

Now you give your variable group a name. For our demo purpose, I am giving the example as a Development environment. Next, add the below variables

Connection string – AuthType=$(AuthType);Username=$(Username);Password=$(Password);Url=$(Url)

URL- Enter your instance URL.

Username – Enter the username of your instance

Password – Enter the password of your instance

Authtype – Office365

Below is the sample connection string details for your reference

AuthType=Office365;Username=jsmith@contoso.onmicrosoft.com; Password=passcode;Url=https://contoso.crm.dynamics.com

Reference Link https://docs.microsoft.com/en-us/previous-versions/dynamicscrm-2016/developers-guide/mt608573(v=crm.8)?redirectedfrom=MSDN

VSTS Build Definition

Once the developer checks-in the changes into BuildAutomation.Solutions project we have a Build Definition in VSTS which will trigger automatically and perform the following steps:

In Build Pipeline, we will be packing the CRM solution and store the solution file in Artifacts. You can create a build definition directly from Visual Studio Online(VSTS/Azure-DevOps) or from within Visual Studio. Firstly, I will show you how to create a build definition from within Visual Studio, navigate to the Builds tab in the Team Explorer:

https://www.insight.com/content/dam/insight-web/sitesections/knowledgebase/Cardinal/Images/BuildDefinitions-1.png
https://www.insight.com/content/dam/insight-web/sitesections/knowledgebase/Cardinal/Images/BuildDefinitions-2.png

Once there, you can click New Build Definition to be taken directly to Visual Studio Online. This is where you would start if you had decided to create the build definition directly from Visual Studio Online instead of starting in Visual Studio.

On the dialog box that pops up in the browser, we’ll select Visual Studio as our build template, but you can see there are other templates for use, such as Xamarin for Android or iOS and the Universal Windows Platform. The default settings for your build definition should be correct for the most part, but you’ll need to check the Continuous Integration checkbox. Here’s what they look like for this example:

https://www.insight.com/content/dam/insight-web/sitesections/knowledgebase/Cardinal/Images/BuildDefinitions-3.png

Because this is a simple example and we don’t need the additional flexibility the Default queue provides, we can leave the default Hosted option selected in the Default agent queue field. For more information on the restrictions on the Hosted pool.

 
You can see the checkbox for CI at the bottom of the dialog. This is enabled so that Visual Studio Online will execute the defined build definition for each check-in. The build definition will define whether or not this build code is published to an environment. Since we want to continually build and deploy to our web environment, we’ll check this box.

We can create the build definition from Azure Dev Ops too by following the below steps.

Navigate to Pipelines -> Builds -> Click New Pipeline

image003
image005

Click the Visual Designer, which will allow you to perform using GUI.

Select the Team Project, Repository, Branch and click on the continue button. For Demo purpose, I have given the name of the build definition as D365 CI

image007

In the next step, Select an empty job as shown below:

image010

After selecting an empty job, you can see the empty Agent Job and Select the Agent Pool as Hosted

image012

Once the above step is done, we need to associate the variable group which we have created in the previous step to the build definition variables. In the “Variables” tab, you can set up the variables which are connected to this definition. The first part is the process variables. These are variables specific and available only to this build definition. Just leave the default variables like they are.

The other part is that you can link variable groups. Earlier in the blog, you set up your credentials as a variable group. Here you click link variable group and select your variable group to link it to this build definition. After linking you can use these variables like they are process variables.

If you ever add your own variables, make sure that a variable in the process variable and a variable in the linked group(s) don’t have the same name. This can lead to unpredictable results.

https://www.dynamichands.nl/wp-content/uploads/2018/07/BuildLinkVariableGroup.png

System.Debug process variable

A good fact to know is the use of the ‘system.debug’ variable. If you set this to true, then verbose logging will be enabled on all build tasks. If you are stuck on some error in the process, this may help to get more information. It will create a massive amount of logging.

Next step is we need to configure the VSTS build definition as shown in the below diagram.

  1. UseNuGet4.4.1 & Nuget restore – The NuGet tasks are required to process the NuGet package references in the
  2. Build Solution – Then we use the Visual Studio Build task to build the complete solution
  3. Copy files – The Copy task copies all files in **\bin\$(BuildConfiguration)\** to the $(Build.ArtifactStagingDirectory).
  4. MSCRM Tool Installer – We are using the MSCRM tool installer. It will install the necessary files (Installs the Dynamics 365 tools required by all the tasks).
  5. MSCRM Set Solution Version – Then we are setting the solution version in the source environment using MSCRM set solution version component.

Note: We need to provide the connection string in the below format to establish the connection with Dynamics 365 CE instance which we have created initially.

  • MSCRM Pack Solution task creates an Unmanaged and managed solution from the files in Solution/.. within that project and we output the Zip file in the respective folder of the project.  The Copy task copies all files in **\bin\$(BuildConfiguration)\** to the $(Build.ArtifactStagingDirectory), we then Publish the Artifact.

In the MSCRM Set Version task, we must specify the Build Number Format under Options in the Build Definition. Here is an example of my build number $(Build.BuildNumber).

In my next blog, we will see how to create the VSTS Release definition(It will pick the CRM solution from artifacts and deploy it in the Dynamics 365 CE target instance).

If you are interested in this topic and would like to do some further self-study I encourage you to check out my blog on this.

CI/CD & Test Automation for Dynamics 365 in Azure DevOps/VSTS – Part 1

In this blog series, we will explore building out DevOps processes and practices for Dynamics 365 Customer Engagement (CE) by utilizing Wael Hamez MSCRM Build tools. In this first blog, we will cover the version control for Solutions.

What is DevOps?

DevOps is a new term emerging from the collision of two major related trends. The first was also called “agile infrastructure” or “agile operations”; it sprang from applying Agile and Lean approaches to operations work.  The second is a much-expanded understanding of the value of collaboration between development and operations staff throughout all stages of the development lifecycle when creating and operating a service, and how important operations has become in our increasingly service-oriented world (cf. Operations: The New Secret Sauce).

Problem Statement

I have started working on CI/CD when I was assigned as a Platform Engineer for a Dynamics 365 CE implementation project. At that time, I had a few key challenges with Dynamics 365 CE. I have listed those below:

  • Solution files were manually extracted and imported to target as a deployment process
  • No Unit testing or validation for deployed solution
  • Multiple deployment process is followed between release environments. For example, in Dev and Sit environment, the solution was migrated manually, and in UAT, Pre-Prod and Prod environment DB compare was applied to promote changes
  • Master data were mutually entered in each environment
  • Multiple developers working in the same organizations overwriting the changes.

Before we start solving the problem, let us take a moment to define some of the mandatory steps which we need to follow.

  • All the source code must be in source control. For example, Plugin Code, Custom workflows, actions, Warehouses (HTML, js, etc) Solution file, master Data, and user roles, etc.
  • Check-in regularly and every change should trigger the commit process
  • Commit process should be short and validates the committed component(Gated-Checkin)
  • Track changes and rollback as needed

Pre-Requisites

Here is a little bit of information regarding the environment.  We are using Dynamics 365 (Online) v9.0 and VSTS/Azure DevOps for version control, build and deployment.  I am using Visual Studio 2017 with the Microsoft Dynamics CRM SDK Templates extension installed.

I have also installed the Dynamics 365 Build Tools(By Wael Hamze) into our VSTS Organization so the tasks are available for all Build and Release Definitions.

Version control for solutions

Solutions in Dynamics 365 CE are in essence a package containing any customization we’ve done to our environment that we can export from one environment then import into various environments. When exported from an environment, solutions are in the form of a zip file. When that zip file is unzipped, the output directory contains folders for plugins, web resources, and any workflows we have made as well as XML files defining the schema of any customization we have done. In the zipped format, our schema definition is contained in one massive file. Consider this zip file as a binary, or in layman’s terms, a tidy package with a fancy bow, i.e. It may look nice but it’s not easy to see what’s inside and it’s a poor format for version control.

Solution packager is a tool that essentially takes our Dynamics 365 CE solution zip file and breaks it out into a logical folder structure by decomposing the contents. The resulting output shows a more granular view of our solution and is considerably more friendly for version control as you can see from the example screenshots below.

Dynamics 365 Instance Management

Below are the little regarding how we have managed the dynamics 365 instances for achieving this DevOps.

  1. Dev environment: It is the true source for all the customization and configuration changes.
  2. SIT: where you test all the functionality against different types of data by internal test users.
  3. UAT: where you test all the functionality against different types of data by business users.
  4. Production: Go Live Instance.

Dynamics CRM CICD process

The below diagram illustrates the basic flow of Dynamics 365 CE Workflow process.

In this part, we are going to see the highlighted one in detail.

The process followed by the developer is essentially these steps (pictured below), the two steps in the middle are handled by the SolutionExportDev.cmd script:

Items

It will export the solution from source instance and unpack the solutions into the folders in BuildAutomation.Solutions

  • Developers benefit using this process by making the solution deployment repeatable and predictable.
  • Developers can associate their work items with their check-ins
  • Very useful for tracking changes (traceability) and comparing solution files
  • SolutionExportDev.cmd – This PowerShell script connects to Dynamics where the developers are customizing their solution, downloads the zip file to the developer’s workspace and extracts the Unmanaged solution into the BuildAutomation.Solutions /BuildAutomation folder.  The Core Tools folder contains the Solution Packager tool from the Dynamics Core Tools NuGet package (pictured below)

Our solution consists of a CRM Deployment Packager project(BuildAutomation.SolutionPackager) and Solutions(BuildAutomation.Solutions) which is used as a container for the extracted files and folders of the solution. 

We added a Scripts(SolutionExportDev.cmd) folder to the project (BuildAutomation.SolutionPackager) which contains some below PowerShell scripts.

PowerShell Script:
set crmuserpwd=%3
set crmuser=%2
set crmserver=%4
set orgname=%1 
set crmuserdomain=%8%
set solution=%5
set folder=%6
set auth=%7
if "%solution%"=="" set solution=BuildAutomation
if "%folder%"=="" set folder=%solution%
if "%auth%"=="" set auth=ifd
set managed=false
set packagetype=unmanaged
set projectdir=BuildAutomation.Solutions
bin\Debug\BuildAutomation.SolutionPackager export managed=%managed% allowdelete=true crmuser=%crmuser% auth=%auth% crmuserpwd=%crmuserpwd% crmserver=%crmserver% orgname=%orgname% solution=%solution% solutionfile=..\%projectdir%\%folder%\%solution%.zip 
echo Exit Code is %errorlevel%
IF %ERRORLEVEL% EQU 0 Echo Solution export was SUCCESSFUL
IF %ERRORLEVEL% EQU 1 (
   echo Aborting the process, as solution export has FAILED with ErrorCode %errorlevel%
   exit /b %errorlevel%
)
tools\solutionpackager.exe /action:Extract /packagetype:%packagetype% /zipfile:..\%projectdir%\%folder%\%solution%.zip /folder:..\%projectdir%\%folder%\ /allowDelete:No
exit /b
:EXIT
@pause

Developers need to do below the configuration in visual studio(Run the command prompt from inside Visual Studio) to execute the SolutionExportDev.cmd

To make the tool available, add it to the external tools list. Here are the steps:

  1. Open Visual Studio.
  2. Select the Tools menu, and then choose External Tools.
  • On the External Tools dialog box, choose the Add button. A new entry appears.
  • Enter a Title for your new menu item such as Command Prompt.
  • In the Command field, specify the file you want to launch, such as SolutionExportDev.cmd
  • In the Arguments field, specify the organization name, CRM username, password, server name, and domain name
  • Choose a value for the Initial directory field, such as Project Directory.

Example:

Title – Name of the external tools to run

Command – Provide the physical path to the command file

Arguments – SolutionExportDev.cmd accepts 4 arguments

  • Organization Name
    1. Username
    2. Password
    3. CRM Server name
    4. Domain

Initial directory – Provide the directory path of the SolutionExportDev.cmd file.

Use Output Window – Enable

Prompt for Arguments ­– Disable

Close on exit–Enable

  • Choose the OK button.

The new menu item is added, and you can access the command prompt from the Tools menu as follows:

To run this, please click on ExportCrmSolution. It will export the solution from source instance and unpack the solutions into the folders in BuildAutomation. Solutions.

Once the above step is done, the developer now has some manual steps to perform depending on the files/changes that were extracted from the solution:

  1. Include any new file under the extracted folder Solutions\BuildAutomation (extracted) into the project- BuildAutomation. Solutions (so that they can be checked-in).
    NOTE: When doing the check-in, be sure to check the ‘Excluded Changes’ if additional files were detected and promote them to the ‘Included Changes’ as needed.
  2. For any .xaml file (under Solutions\BuildAutomation\Workflows or Solutions\BuildAutomation \Entities\xxxx\Formulas), make sure that Build Action is ‘None’ (not ‘Page’ or ‘XamlAppDef’). If this step is skipped, you may get one of this compilation error (s):
    – Project file must include the .NET Framework assembly ‘WindowsBase, PresentationCore, PresentationFramework’ in the reference list.
    – Assembly “System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ cannot be resolved”.
  • Ensure that DLL files under Solutions\..\PluginAssemblies are added to source control.
  • Undo all pending changes that do not specifically apply to your changes.
  • Associate the check-in with a work item(s), write a comment and check-in all required changes.

Note: Check-in to TFS will auto trigger the deployment process.

In my next blog, we will see how to pack the solution and deploy it in the Target instance using VSTS Build and Release definition.

If you are interested in this topic and would like to do some further self-study I encourage you to check out my blog on this.

Alternate Keys as an Alternative to Duplicate Detection Rules

Recently, I came across one scenario where I shouldn’t allow the duplicate record creation.

Duplicate detection has been around since the early versions of Dynamics CRM. In 2015, alternate keys were introduced to help identify a record based on a unique combination of attributes to perform an upsert request. An upsert is the action of inserting a record if it is new, or updating it if it already exists, based on the primary key identifier (https://msdn.microsoft.com/en-us/library/dn932135.aspx). Logically, this means whenever an alternate key is defined, any new records that are created with the same key combination will throw a duplicate exception.

Note: When using Alternate Keys in this manner, be sure that the combination of attributes selected truly represents a unique value.


Setting up an alternate key(Copy pasted from MS blog):

Please follow the below steps to create the alternate Key:

1. First, navigate to System -> Customizations -> Customize the System.

2. Expand the Entity.

3. Click Keys and then New.

4. Provide a Display Name.

5.Select multiple attributes to act as a Composite, Unique key.

6. Add the selected attributes. In this instance, we chose First Name, Last Name, and Mobile Phone to be the unique keys.

Note: Only the data types of Single Line of Text, Whole Number, and Decimal Number are available for use.

7. Click OK. An indexing System Job will now be created.

That’s it! Your Composite/Alternate Key has now been created!

Now, when you create a record with the same combination as another entry in the system, you will receive the following error message as below:

Note that alternate key creation can fail sometimes. Always check, after creating your key, whether the creation has been successful. If a duplicate already exists in your dataset, the key creation will fail. To check the status of a newly created key, in your solution, navigate to Entities | <entity> | Keys and ensure the Status column states Active. If the creation fails, it shows the status as Failed.

Dynamics 365 Set Parent Child relationship from Correct Sub grid (Relationship)

Let us consider we have two entities. Entity A (Parent entity) and Entity B (child entity). I have created two lookup of entity A in entity B. Now we will have two associated sub grids of Entity B in Entity A. Whenever I tried a new entity B record (child record) from entity A (parent record) using the associated sub grid add button, it’s auto populating both the lookup fields of entity A in entity B record.

For this scenario, the easiest way is just to remove the field mapping. But the problem is when you want to try to delete one of the mapping, CRM platform won’t allow us to do it. Error details are as follows:

Then the only way to achieve our scenario is by customization only and here are my steps to solve it:

It’s not always recommended to customize the OOB button. So, in this case we can achieve this scenario by adding a custom button.

Create a html resource using the below code:

<!DOCTYPE html>
  
 <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <meta charset="utf-8" />
 <title>Entity B Record</title>
 https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js
 http://../../ClientGlobalContext.js.aspx
 <style>
 .btnSubmit {
 background-color:rgba(0, 0, 0, 1) !important;
 height: 24px;
 font-family: Segoe UI;
 font-size: 12px;
 color: rgb(255,255,255);
 border: 1px solid rgba(0, 120, 215, 1.0);
 background-image: none;
 margin-top: 10px;
 width: auto !important;
 min-width: 80px;
 white-space: nowrap;
 }
 </style>
 
 function openEntityBRecord () {
 debugger;
 var recordId = window.parent.Xrm.Page.data.entity.getId();
 var fullName = window.parent.Xrm.Page.data.entity.attributes.get("fullname").getValue();
 var entityFormOptions = {};
 entityFormOptions["entityName"] = "plc_associatedpriorityservice";
 entityFormOptions["openInNewWindow"] = true;
 var formParameters = {};
 formParameters["EntityA1id"] = recordId;
 formParameters["EntityA1name"] = fullName;
 Xrm.Navigation.openForm(entityFormOptions, formParameters).then(
 function(success) {
 console.log(success);
 },
 function(error) {
 console.log(error);
 });
 }
 
 </head>
 <body>
 <input style="float:right;" type="button" class="btnSubmit" id="btnSubmit" name="btnSubmit" value="Add Entity B Record" onclick="openEntityBRecord();">
 </body>
 </html> 

Then go to form Editor of Entity A and insert a web resource just above the first associated sub grid. When finished, publish all customization and you can try the result.

Now the “Add Entity B Record” button will appear above the first associated sub grid in Entity A(parent) record.

Similar in the same way we need to do it for second associated sub grid.

Also, we need to hide the OOB Add button form both the sub grids by using the below code:

 var hideSubgridAddBtn = function(primaryEntityName) {
         if (primaryEntityName == “entityname”)
             return false;
         else
             return true
     }; 

Add the above method to the one JavaScript library and we need to add a enable rule to the OOB button and call the above method “hideSubgridAddBtn” from the above newly created JavaScript library.

Once done, publish all the customization and you can try the result. It will set only the first lookup of entity A in entity B record.