Decoding .NET 5+ Deployment Options for a CI/CD World
by The Inedo Team, on Nov 19, 2020 12:30:07 PM
Finally! After waiting almost 20 years in some cases, Microsoft’s .NET 5+ gives us highly demanded features like self-contained applications. These “new deployment options” are exciting and long-awaited.
These represent increased .NET functionality (and they’re genuinely impressive feats of coding). But as excited as we are, we’re also practical.
We (Inedo) make Continuous Delivery and Continuous Delivery (CI/CD) tools, advocate for CI/CD use in modern organizations, and use CI/CD internally. Obviously, we’ve been thinking about these new deployment options and assessing them from a CI/CD standpoint.
We’ve discovered that, when it comes to these new deployment options, “just because you can doesn’t mean you should.” Practically, almost all of these new deployment options will have not home in companies using CI/CD for internal applications.
Again: The advice in this article is for organizations using CI/CD. CI/CD processes make these “deployment options” impractical, but organizations not using CI/CD should investigate these options further to make the best decision.
How to use these methods are unclear; WHY to use them in a CI/CD world is even less clear. Therefore, we’ve scoured Microsoft’s documentation to bring you a clear primer on what each of these is (and isn’t) and why you should (or shouldn’t) use them.
What AREN'T ".NET 5+ Deployment Options"?
Back in the 1950s and 60s, a computer was a person. But (to quote The Matrix), “Then man made the machine in his own likeness.” The term “computer” didn’t change, but its definition changed over time.
In a similar way, terms like “deployment” existed before Continuous Integration and Continuous Delivery (CI/CD) and were later picked up and redefined by CI/CD. This can lead to some serious confusion, especially for this topic.
Just like “publishing” in this case doesn’t mean “publishing to the NuGet Gallery” or similar, “deployment” in the CI/CD sense means something different that Microsoft means in these “new deployment options.”
What is a CI/CD "Deployment"?
In CI/CD, deployment is a common term that involves taking a packaged/published application file (i.e., an artifact, package, or installer) and copying it from the accessible location (a CI/CD tool like BuildMaster or repository like ProGet) to a server. And then usually, running some commands like stopping and starting services as well.
What is a "Deployment" in .NET Core/5+?
Keeping with the “extremely complicated documentation” theme, this term is NOT clearly defined in Microsoft’s documentation. They use this word synonymously with “publishing,” which both seem to mean the same thing: ‘following of the things under this part of the documentation.’ (In fact, don’t be surprised if these same “deployment” options later are called “publishing” options. The documentation history seems to indicate this is possible.)
Now that you understand this, you may realize that these new “deployment options” are NOT worth serious consideration for you because they’re not reasonably applicable to organizations using CI/CD.
But since you’ve read this far… let’s decode the mystery.
Interpreting Microsoft's New Deployment Options for CI/CD Users
Most of these new deployment options from Microsoft have been long-anticipated and often-requested. But their documentation is exceptionally complex. Here, we simply explain each one and include concerns that organizations using CI/CD should consider.
The CLI (dotnet)
Microsoft included the dotnet CLI in the documentation for the new deployment options. Even though it isn’t a deployment option at all, we included it here for that reason.
The .NET Framework build CLI tool was MSBuild; its .NET Core/5+ replacement is dotnet.exe. Unlike the deployment options discussed below, this is just a tool. In CI/CD, everything in this automated process will use dotnet.exe, the CLI tool.
If you’re already familiar with MSBuild, then you’ll have no problem learning dotnet.exe. Not only are the arguments substantially similar, but dotnet.exe uses MSBuild behind the scenes for many commands, including dotnet build. (If you aren’t yet familiar with using CLI tools to build your .NET applications, it’s important to learn, because this is how you integrate into a CI/CD process.)
Visual Studio Deployment
.NET 5+ brings with it the option to deploy using Visual Studio.
The concern? Visual Studio is a desktop tool, intended for a developer workstation to use to code. Thus, when you use Visual Studio for deployment, it involves a person clicking through options in the tool to deploy code on that workstation.
This might be suitable for hobbyists or prototyping, but having a human manually creating and deploying builds on a workstation is not appropriate within a CI/CD process.
Publish Framework-dependent versus Self-contained
Applications require a framework of some kind to run. Think of trying to open a Microsoft Word document (.doc) on a computer that doesn’t have Microsoft Word installed; it won’t work. Microsoft has tried to eliminate this problem by allowing self-contained deployment.
The concerns? In almost all CI/CD cases, you shouldn’t publish as self-contained for a few reasons.
- While self-contained applications might be useful if you need to distribute your application to external customers or consumers, you'd likely be sending those consumers a software installer program to install your application. The installer could install the correct .NET or could verify that it’s already installed.
- When distributing your application to internal customers/consumers within your organization, you're already defining the required configuration for your application. Internal customers/consumers having .NET installed is a very reasonable requirement compared with other configurations (especially given the complications of self-contained).
- This type of application adds complexity to the deployment process and more training requirements or someone who needs to use or modify it—not to mention how much “heavier” the application becomes when the framework is included.
- It also spawns a series of other questions:
- What operating system/hardware will it be run on? You’ll have to know what operating system and chipset (64 or 32 bit) your application will run on and specify that using the .NET Core Runtime Identifier (RID) Catalog.
- How will you trim the application? Your self-contained application will be quite large, as it includes the entire .NET runtime framework. The trim reduces the file size, but you must carefully select the correct options to make sure you don’t trim what you need.
- How will you use Runtime Rollforward? Too often, your self-contained application may bundle a different version of the .NET Framework than you expect and may not include the security patches. Runtime rollforward helps control this, but it is quite complicated.
- Should you consider Ready-To-Run? Because you’re shipping the entire framework, it might be a bit slow. This option helps speed it up.
There’s nothing wrong with publishing framework-dependent applications. If your organization controls the deployment/installation of your applications as part of a CI/CD process, you should just keep doing it that way.
This allows you to distribute the entire application as a single .exe file. As an example, if you navigate to C: > Program Files > Internet Explorer, you can see that this one program contains a ton of individual files and folders. “Single file” deployment would reduce these files to one. Microsoft’s engineers call this an “attractive option to deploy and distribute the application as a single file.” But that doesn’t make it the right option for CI/CD.
The concerns? This may be considered a “pennywise, pound foolish” choice for CI/CD. Your engineers will likely end up doing a lot of extra work just to have a cleaner-looking end result. But cleaner-looking to whom? Someone who’s manually browsing files?
In a CI/CD organization you are already putting your files in an artifact, package, or installer. There are several practical disadvantages (such as losing some APIs related to assembly locations), as well as the theoretical disadvantage of creating and using opaque applications that are difficult to see inside for diagnostic purposes.
There is no need to complicate a CI/CD process just because single files are an “attractive option.”
Runtime Package Store
Runtime package store offers “faster deployments, lower disk space usage, and improved startup performance in some cases” by packaging and deploying applications “against a known set of packages that exist in the target environment.”
The concerns? If single file deployments can be considered “pennywise, pound-foolish” in CI/CD organizations, runtime package stores would be “pennywise, megaton foolish.”
If Microsoft had been able to create this program years ago, when disk space was expensive, this may have been a fabulous option. But in 2020, disk space doesn’t break the bank.
And the small savings to disk space and slight increases in deployment speeds introduce massive risk. This is because runtime package store seems to change the way you code, which means developers doing day-to-day coding will have to master this extremely complex topic.
Furthermore, runtime package stores assume that packages are going to be on the server when you deploy your application. If they’re not, your application won’t work. This process creates an unnecessary new dependency—and therefore unnecessary risk.
In a CI/CD situation, keep using packages as you already are. They’re small enough that the tiny savings from this complicated process are simply not worth making the switch.
What does this all mean?
If you’re not using CI/CD at your organization, definitely investigate these new deployment options further, because they may be a great option for your organization.
But for organizations already using CI/CD, the benefits of these new deployment options are minimal and add risk. From our perspective, organizations using CI/CD don’t even need to consider using these options.
New Deployment Options Flowchart
Use the simple instructions below to simplify your decision-making process. Click the flowchart to open it in a separate window for easier viewing and sharing.
Are you using a Docker container?
All the new deployment options do not apply. You’re all set!
What operating system will you use?
This determines what you’ll compile.
- Windows-only may create an executable or a cross-platform binary.
- Linux or cross-platform must create a cross-platform binary.
Will you bundle your framework?
You can create a framework-dependent application or a self-contained one.
If you choose self-contained, you must:
- know which specific platform(s) you will be targeting;
- make sure you know your runtime identifier (RID) and runtime package store;
- choose Ready-to-Run images.
Will you use single-file deployment?
Whether you choose this option or not, this is the last step.
Got CI/CD? .NET 5+ is Still the Future
Just because these new deployment methods aren’t useful to CI/CD organizations doesn’t mean .NET 5+ is too. Microsoft has made it clear that .NET 5+ is the only path forward for .NET development.
Learn more about the challenges of migrating and contribute your questions and advice to our forthcoming guide.