I’m looking at the options available for using Octopus to configure ASP.Net applications running in containers. I’d like to fit with the container philosophy as much as possible so I want the container itself to contain the application code and as much run-time configuration as possible.
One method I’ve thought about is to have Octopus server run the transforms etc that would normally happen as part of deployment on the application server. The resulting web.config file would be environment specific - containing connection strings etc, as it normally would by the time the application is executed.
That compiled configuration could be inserted into a Kubernetes ConfigMap or Secret allowing the orchestrator to place the configuration on ‘disk’ within the application container without the application container having to do additional work. This helps align with the Docker best practices of having the container itself be agnostic to the environment it is operating within supporting consistent desktop development experiences etc.
Essentially, this means packaging the configuration and the application as two independent entities - the application is packaged in the Docker image while the configuration is packaged by Octopus into some secure location like Kubernete or an encrypted file in S3 etc. Octopus is so good at managing .Net configuration it seems ideal to continue with it managing that task.
Is it possible to generate the end-state web.config on the Octopus server? Is there any documentation I’ve missed that would help me get that up and running?
Your use case for the Octopus transforms is an interesting one, and we don’t have a perfect solution today. You can however achieve what you are looking for with some customization of the Deploy a Package step.
The Deploy a Package step allows you to enable features (see https://octopus.com/docs/deployment-process/configuration-features for documentation on the features), and those features include config file and general XML transformations against variables in Octopus, along with custom scripts that can be run post deployment. So you can achieve the outcome you are looking for with something like this:
Create a package with the config files and upload it to Octopus.
Create a target that the package can be deployed to. This target will serve as a kind of worker in that we don’t really want to deploy a package to it, but we need somewhere that can accept the package, transform it and then upload it again to Kubernetes. Workers are coming as a first-class concept in Octopus in the next few releases, but today a single target can be used as a pseudo-worker. You may want to install a tentacle on the Octopus server to serve as the pseudo-worker.
Ensure kubectl is installed, configured and available to the pseudo-worker.
Create a deployment project in Octopus with the Deploy a Package step. Enable the desired transformation features to modify the config files.
Enable the Custom Deployment Scripts feature, which will allow you to write scripts that can be run after the package has been deployed to the target and transformed.
Enable the Custom Installation Directory feature, so you know where the transformed package will be saved.
In the Post-deployment script extract the package and use kubectl to upload the transform config file as a Kubernetes ConfigMap.
We are currently working on native Kubernetes integration, and you can review the specifications at https://github.com/OctopusDeploy/Specs/blob/master/Kubernetes/index.md. And feedback you may have is welcome, as there is plenty of opportunity to streamline these kinds of processes.