What for? #
Basically, automation. Right now the API only allows the refresh from one Microsoft Dynamics 365 for Finance and Operations environment to another, so the idea is having fresh data from production in our UAT environments daily. I don’t know which new operations the API will support in the future but another idea could be adding the DB export operation (creating a bacpac) to the pipeline and having a copy of prod ready to be restored in a Dev environment. Don’t forget that the API has a limit of 3 refresh operations per environment per 24 hours. Don’t do this on a CI build! (it makes no sense either). Probably the best idea is to run this nightly with all your tests, once a day.Calling the API #
I’ll use PowerShell to call the API from a pipeline. PowerShell has a command called Invoke-RestMethod that makes HTTP/HTTPS requests. It’s really easy and we just need to do the same we did to call the API in my post.Getting the token #
$projectId = "1234567" $tokenUrl = "https://login.microsoftonline.com/common/oauth2/token" $clientId = "12345678-abcd-432a-0666-22de4c4321aa" $clientSecret = "superSeCrEt12345678" $username = "youruser@tenant.com" $password = "strongerThan123456" $tokenBody = @{ grant_type = "password" client_id = $clientId client_secret = $clientSecret resource = "https://lcsapi.lcs.dynamics.com" username = $username password = $password } $tokenResponse = Invoke-RestMethod -Method 'POST' -Uri $tokenUrl -Body $tokenBody $token = $tokenResponse.access_tokenTo get the token we’ll use this script. Just change the variables for the ones of your project, AAD App registration, user (remember it needs access to the preview) and password and run it. If everything is OK you’ll get the JSON response in the $tokenResponse variable and from there you can get the token’s value using dot notation.
Requesting the DB refresh #
$projectId = "1234567" $sourceEnvironmentId = "fad26410-03cd-4c3e-89b8-85d2bddc4933" $targetEnvironmentId = "cab68410-cd13-9e48-12a3-32d585aaa548" $refreshUrl = "https://lcsapi.lcs.dynamics.com/databasemovement/v1/databases/project/$projectId/source/$sourceEnvironmentId/target/$targetEnvironmentId" $refreshHeader = @{ Authorization = "Bearer $token" "x-ms-version" = '2017-09-15' "Content-Type" = "application/json" } $refreshResponse = Invoke-RestMethod $refreshUrl -Method 'POST' -Headers $refreshHeaderThis will be the call to trigger the refresh. We’ll need the token we’ve just obtained in the first step to use it in the header and the source and target environment Ids. If it’s successful the response will be a 200 OK.
Add it to your pipeline #
Adding this to an Azure DevOps pipeline is no mistery. Select and edit your pipeline, I’m doing it on a nigthly build (it’s called continuous but it’s not…) that runs after the environment has been updated with code, and add a new PowerShell task: Select the task and change it to “Inline”: Then just paste the script we’ve created in the Script field and done! You’ll get a refresh after the tests! You can also run this on your release pipeline BUT if you do it after the deploy step remember to mark the “Wait for Completion” option or the operation will fail because the environment will already be servicing! And even then it could fail if the servicing goes over the timeout time. So… don’t run this on your release pipeline! And that’s all. Let’s which new operations will be added to the API and what we can do with them.Use d365fo.tools in your Azure Pipeline #
Thanks to Mötz’s comment pointing me to how to add d365fo.tools to a hosted pipeline I’ve created a pipeline which will install the tools and run the commands. It’s even easier to do than with the Invoke-RestMethod.But first… #
Make sure that in your Azure Active Directory app registration you’ve selected “Treat application as a public client” under Authentication:The task #
First we need to install d365fo.tools and then we can use its commands to call the LCS API:Install-PackageProvider nuget -Scope CurrentUser -Force -Confirm:$false Install-Module -Name AZ -AllowClobber -Scope CurrentUser -Force -Confirm:$False -SkipPublisherCheck Install-Module -Name d365fo.tools -AllowClobber -Scope CurrentUser -Force -Confirm:$false Get-D365LcsApiToken -ClientId "{YOUR_APP_ID}" -Username "{USERNAME}" -Password "{PASSWORD}" -LcsApiUri "https://lcsapi.lcs.dynamics.com" -Verbose | Set-D365LcsApiConfig -ProjectId 1234567 Invoke-D365LcsDatabaseRefresh -SourceEnvironmentId "958ae597-f089-4811-abbd-c1190917eaae" -TargetEnvironmentId "13cc7700-c13b-4ea3-81cd-2d26fa72ec5e" -SkipInitialStatusFetchAs you can see it a bit easier to do the refresh using d365fo.tools. We get the token and pipeline the output to the Set-D365LcsApiConfig command which will store the token (and others). This also helps to not having to duplicate AppIds, users, etc. and as you can see to call the refresh operation we just need the source and target environment Ids!
2 Comments
Hi , can you help how can we achieve this when we have Multifactor authentication enabled with our tenant
Unfortunately it’s not possible, you’ll need a service account without MFA for that. There are no further investments in LCS as most of the functionality will be moved to PPAC, maybe in PPAC we’ll have a way to use service principals instead of user accounts.