I’m looking for some advice on how to model a deployment process for one of my team’s product.
We have a need to deploy more than one copy of the product based on different build configurations. It’s not a .NET based product, but it is as if we had to deploy one copy built on .NET Framework and another copy based on .NET Core. The deployment process is identical for both configurations except for a few variables. The code is the same, it’s just built differently. Whenever I deploy a version for one configuration I also need to deploy the same version for the other config.
Right now I’m trying to use Channels for this and scoping some variables to the channel. The build server (TeamCity) builds different packages with similar names (Product.ConfigA.1.0.0.zip / Product.ConfigB.1.0.0.zip) and the deploy package step selects the package according to the channel being deployed to.
It’s kinda working but it feels like I’m abusing the system. For one thing I have to deploy do production twice. My understanding is that channels is focused more on “the last deployment is the live product” scenario, rather than each channel being an active release pipeline and all of them active at once.
Can you suggest any improvements based on the needs? What I’ve considered so far:
- continue using channels despite them feeling a little weird on this scenario;
- duplicate the project once for each build configuration and keeping them completely separate. I don’t expect the process to change often so this might be OK;
- have one project and one default channel but duplicate some steps in the deployment process, so that when the deployment runs it actually deploys more than one package.
- use the multi-tenant feature. Is this just me trying to abuse the system again?
On the TeamCity side of things I’m using a Build Configuration Template and then creating the actual build configurations based on those templates. Some kind of deployment template might also work for me if there is something similar in Octopus.
Hi Marcos - thanks for reaching out!
Can you tell me a little bit more about your scenario?
How many steps are used to deploy the app?
How many of those steps are shared between the app?
Are both of the apps deployed to the same targets or different targets?
Are there any variables that are different between the two versions of the app?
Hi Ryan, sure,
The whole thing is a bit confusing since the process involves repacking part of the extracted package in different ways to interact with another systems.
Right now there are seven steps: 1 deploy package with a post-deployment script, 5 run scripts, 1 manual intervention. Two of the steps only run when deploying to Prod. It goes like:
- script: validation and defining some runtime variables;
- deploy package: dynamic select the package based on the channel, the post deployment script does some selective 7z repacking and moving files around;
- 2 script steps: interacts with external systems, mostly SQL stuff;
- manual intervention with some validation instructions;
- 2 script steps: interacts again with the external systems, mostly SQL stuff.
The lifecycle is the default one (Test -> Prod, for my case) and both channels use the default lifecycle. All of the steps run exactly the same (except for some variables) for both configurations. The targets are also the same.
There are about a dozen variables for the project, most of them having different values depending on the environment. About five of them are also scoped on the channel. The variables that change between channels have to do with some IDs related to the external systems and some file paths for the “moving files around” stuff.
Thanks for your time in helping me out and if you feel more details are needed I can provide them,
Thanks for that information.
It is definitely an interesting scenario.
If you were deploying to two different targets, I would suggest using two different roles and updating your steps to deploy to both roles. Unfortunately, with one target, it will result with deploying one configuration. You could potentially work around this by installing a second tentacle instance on the target and using a different port. In that way, you could scope the different variable values to the different roles.
Beyond that, I think either duplicating the steps or using multi-tenancy would be the best approach. Using multi-tenancy is a much more complicated solution, but then you don’t have to create separate releases for each channel.
If you don’t expect the process to change very often, duplicating the steps could be the simplest approach.
I hope that helps. Let me know if you have any follow questions on those options.
I took some time to peruse the multi-tenancy docs and it looks a bit more complicated than I had first expected but it might work well for my needs. I’ll give it a try and report back with my experience.
If it starts to get too complicated I’ll probably go with duplicating a few steps in the process.
Thanks again for the help,
Sounds good - thanks for the update, Marcos.
I did some tests and experiments with multi-tenancy and in the end decided not to use it. One of the issues I had was dynamically selecting the package to deploy at runtime depending on some tenant variables and it was proving difficult. Since my tenant really represented a build configuration, I had to choose the package accordingly and hadn’t managed to do so.
After a few more experiments and thinking through the requirements, I ended up duplicating the project. It means I have to deploy twice but the project complexity is kept low which looks like a net win for us.
Thanks a lot for the insights,
Sounds good, Marcos - glad you found a solution that works for you.
This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.