“DirectDeploy” with Epinova DXP deployment
Epinova DXP Deployment has now been updated to support EpiClouds new feature “DirectDeploy” with an updated Deploy NuGet Package task that now supports this feature.
The new feature skips the slot swap and deploys the code directly to the environments production slot. At this point this “DirectDeploy” feature only works with the Integration environment but this could be changed in the feature.
For more detailed information about the Direct Deploy functionality, you can read Anders Wahlqvist blog post “Introducing "Direct Deploy", a quicker way to deploy to integration using the deployment API!”
What has been updated in the Epinova DXP Deployment extension?
We have updated the DeployNuGetPackage task to support “DirectDeploy”. And since this change the deployment flow, we have also updated the sample YAML files for the pipeline used to deploy to the Integration environment.
DeployNuGetPackage
A new parameter is added to the task so you can simply configure if you want to use “DirectDeploy” or not. The task is validating that you only use “DirectDeploy” when deploying to the Integration environment. If you try or accidentally set this param to true and try to deploy to the Preproduction or the Production environments, the task will give you a note in the log and just ignore the “DirectDeploy” parameter.
YAML example
- task: DxpDeployNuGetPackage@1
inputs:
ClientKey: '$(Integration.ClientKey)'
ClientSecret: '$(Integration.ClientSecret)'
ProjectId: '$(DXP.ProjectId)'
DropPath: '$(System.DefaultWorkingDirectory)\drop'
TargetEnvironment: 'Integration'
UseMaintenancePage: false
DirectDeploy: true
Timeout: 1800
Classic mode example
If you are using Azure release pipeline that is setup in “Classic mode”. You need to make some changes in the tasks.
As mentioned before, when you use “DirectDeploy” it will deploy directly to the Integration production slot. That means that the deployment can not use “Smoke test if fail reset” or “Complete deploy” tasks. In the example above you can see that I have disabled them. But a Warmup is always needed I would say.
Result log
In the result log we have added the input “Use Direct Deploy” so you can see what value that is sent to the task. You will also see a Warning message in the form of: ”Warnings: No automatic warmup configuration will be applied for this deployment (not available for Direct Deploy) (yyxxxzz012znb5inte/Production)”. That’s because the “DirectDeploy” deploy directly to the “production slot” for the Integration environment and will not use the slot or other warmup etc. You will not be able to use the “Smoke Test if fail reset” or “Complete deploy” tasks. That is because the status of the deployment in PAAS is “Succeeded” after deploying and not “AwaitingVerification” as it is when you are not using “DirectDeploy”.
Example YAML files
For those that has used our example YAML pipelines, we have updated two of the YAML files. “Develop-Inte.yml” and “Master-IntePrepProd.yml”. Both these YAML pipelines are using the task “DeployNuGetPackage” and we have added the new “DirectDeploy”. We have also added a parameter that you can set in Azure DevOps when you start the build/release pipeline.
If you check the “DirectDeploy” parameter when you start the build/release pipeline it will use the following YAML:
- task: DxpDeployNuGetPackage@1
inputs:
ClientKey: '$(Integration.ClientKey)'
ClientSecret: '$(Integration.ClientSecret)'
ProjectId: '$(DXP.ProjectId)'
DropPath: '$(System.DefaultWorkingDirectory)\drop'
TargetEnvironment: 'Integration'
UseMaintenancePage: false
DirectDeploy: ${{ parameters.DirectDeploy }}
Timeout: 1800
It will set the value depending of what you select from the start of the build/release. You can of course change that to just set “true” instead of “${{ parameters.DirectDeploy }}”. But you will then miss the nice condition that we also set up on the following tasks. That is because we have added a condition with the following statement:
- task: DxpSmokeTestIfFailReset@1
condition: and(succeeded(), eq('${{ parameters.DirectDeploy }}', false))
....
- task: DxpCompleteDeploy@1
condition: and(succeeded(), eq('${{ parameters.DirectDeploy }}', false))
.....
This will make the DxpSmokeTestIfFailReset and DxpCompleteDeploy only run if you are not using the “DirectDeploy”.
The updated example YAML pipelines can be found on the following URLs:
https://github.com/Epinova/epinova-dxp-deployment/blob/master/Pipelines/Develop-Inte.yml
https://github.com/Epinova/epinova-dxp-deployment/blob/master/Pipelines/Master-IntePrepProd.yml
Performance
We were interested of knowing how big the performance difference between the methods of deploying to Integration. We did some testing with the following three types of deployment:
- Deploy WebPackage with AzureRmWebAppDeployment@4. Will be called “WebPackDeploy”.
- Deploy NuGet with DxpDeployNuGetPackage@1 (DirectDeploy = true). Will be called “DirectDeploy”. Use EpiCloud: Start-EpiDeployment @startEpiDeploymentSplat -DirectDeploy
- Deploy NuGet with DxpDeployNuGetPackage@1 (DirectDeploy = false). Will be called “SlotDeploy”. Use EpiCloud: Start-EpiDeployment @startEpiDeploymentSplat
These tests are done with the same code, without any code updates between these different deployment tests. Note that your project maybe quicker or slower to deploy depending on a number of different factors, but this should give you a hint how long time the different deploys may take.
This is not a scientific approved test. It is just me done some deployments and it gives you a hint of how long time it takes.
Project |
WebPackDeploy |
DirectDeploy |
SlotDeploy |
Project X |
~ 1 min |
~ 8 min 30 sec |
~ 25 min |
Project Y |
~ 30 sec |
~ 6 min |
~ 18 min |
The time taken does not include build or warmup time or other things done during the build/release, just the step that deploy the code to the Integration environment in DXP. One good thing to notice is that if you use the “SlotDeploy” strategy, you need to use at least the “CompleteDeploy” task to move the code from the deployment slot to the environment production slot which is included in the time specified above.
Findings
Obviously, the WebPackage deployment with Azure web app deployment is still the fastest. But if you don´t need to have a superfast CI pipeline to DXP Integration environment, I would have used “DirectDeploy” since that enables you to have one single build pipeline that builds the NuGet package(s), and you can then use that to deploy to any of the environments in DXP. It also includes validation of the code package, config transform and handling web job gracefully like Application Insight etc. If you use WebPackage approach you could end up putting a ham in the fruit basket. 😊
I have had discussion with Episerver/Optimizely about the times specified in the performance section and they have seen that my projects have had problems with the Application Insight job that has slowed down the “DirectDeploy” time with around 3 minutes. For most of the projects it should take around 4-5 minutes to do a “DirectDeploy”. I also got information that they have found some performance issues that are going to be fixed ASAP. Hopefully we will see even faster deployments with “DirectDeploy” in near time.
Outro
I´m glad that Episerver/Optimizely continue update and working with the EpiCloud module and I’m looking forward to new features in near future (hint to Epi 😊).
For the latest documentation and guides please visit the repo on GitHub. Where all code, documentation and YAML files etc. exist.
https://github.com/Epinova/epinova-dxp-deployment
If you have not tested Epinova DXP Deployment Azure DevOps tasks yet, it is free to download and install from Microsoft marketplace.
https://marketplace.visualstudio.com/items?itemName=epinova-sweden.epinova-dxp-deploy-extension
Happy deploying everyone!