Closed Palkess closed 10 months ago
does IIS consider anything else than a web.config file? like, would it even look at a web.prod.config file? it is also possible i might not understand your usecase fully.
No, when the site is up and running in IIS it only cares about web.config. The transformation usually happens during the deployment of the built package, in my case when I trigger my releases in Azure Devops.
I'll try to give some context by sharing some screenshots:
This is how my release looks like in Azure Devops
And here are the steps it takes to deploy my artifact. During my deploy-step I can choose to transform my *.config-files a few different ways, from what I've seen working with other .NET projects running XML Transformations are the most common. So after I've run my deploy, the actual web.config on my server has the prod values in the appSettings keys instead of my local values. The IIS doesn't interact at all with the transformation files.
Hopefully it made a bit more sense with some context!
it wouldn't be that hard to add, i guess do you want to explicitly define the env files considered, or just do all .env* files?
I think checking for any .env.{stage} files and writing a web.{stage}.config with transforms for each would be straight forward and follows a common pattern when defining stage specific .env/.config-files. Something I haven't considered here is if there could be any values outside of \<appSettings> that could be stage specific, I guess that's a discussion for when someone has a use-case for it.
i'm working on a pr
@Palkess
if you want to, add documentation for this, because i forgot plus you can probably better explain why it's useful
Excellent, that was very fast! 😄 There's a few more things that's needed, the transformation web.{stage}.config should only contain the key/values that is going to change and has some more attributes on \<configuration> and \web.config.js
. It's described in https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/transform-webconfig?view=aspnetcore-8.0#build-configuration
I'm currently at work, I can write some documentation on it later.
in the link you sent, it looks like it's using <environmentVariables>
, but this adapter uses <appSettings>
to pass env vars to IISnode, so which one snould be used?
can you send a full xml transformation file for sveltekit&iis? i'll adjust it accordingly
@KraXen72 I'm sorry, I gave a bad example in a rush. From my example above, here's what the complete web.prod.config-file would look like in that scenario:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="https://schemas.microsoft.com/XML-Document-Transform">
<appSettings>
<add key="DATABASE_CONNECTIONSTRING" value="prod-connection" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
<add key="SMTP_HOST" value="prod-smtp-host" xdt:Transform="SetAttributes" xdt:Locator="Match(key)" />
</appSettings>
</configuration>
So the xdt:Locator
attribute matches the element based on the key value and then the xdt:Transform
is set to replaces all attributes on that element, in this case value
.
Here's a link to an online XML transform tester, it's a bit sensitive to tabs between attributes though in case you run in to any trouble with it. https://elmah.io/tools/webconfig-transformation-tester/
i see. thanks for the example. i am now thinking if it would be possible to have staging like this even outside of .NET/AWS environments, because i too usually do 2 build types.
while the XML transforms are a good thing to implement and i'll continue my work on the pr, i'm open to ideas on how this could be achieved, for example with cli flags for using different ENV variables & setting passed to the adapter.
it's getting quite annoying changing it by hand every time, and i don't use an AWS platform for deplyment, i just copy the build over ftp :P
How I think this could be implemented fairly easily would be
import { vitePreprocess } from '@sveltejs/kit/vite'
import IISAdapter from 'sveltekit-adapter-iis'
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: vitePreprocess(),
kit: {
version: {
pollInterval: 300000,
},
adapter: IISAdapter({
// the hostname/port that the site will be hosted on in IIS.
// can be changed later in web.config
origin: 'http://localhost:80XX',
// ... other options
transforms: [
{
environment: 'production',
origin: 'https://productionurl.com'
},
{
environment: 'staging',
origin: 'https://stagingurl.com'
}
]
}),
},
}
export default config
The transforms
property would be an array of type AdapterOptions
where we just ignore the transforms
property on them (since we cant have nested transforms). Then that would enable us to just reuse the same bit of code to generate each web.*.config
file. What are your thoughts?
not necessarily my usecase. probably confusing of me that i brought it up in this issue, but for my usecase i don't care about creating multiple web.config files, just a different one preferrably based on a cli flag, that would select different adapter options (so i can create npm scripts like build:prod, build:test etc.) i'll try finishing up this xml transform pr sooner or later and we can take a look at this in a different issue/pr.
i finished up the pr
This has been merged and published as v1.2.0
In one of my projects where I'm using this adapter I have several staging environments: local, dev, test, pre-prod, prod. Currently when deploying via Azure Pipelines I apply changes to environment variables in \<appSettings> through XML variable substitution so I set up corresponding variables with matching names on each stage release.
Maybe this is correct and should be the way to do stage specific settings but in my other .NET projects we create stage specific transformation files, like web.prod.config, that lives next to the default web.config in the repos making the source of truth closer to the code base instead of separating them in the CI/CD flows.
There's a few different solutions to this that could be implemented but I think checking for stage specific .env files and creating transformation files based on the variables would be a good way to do it.
Example of I would imagine it could work:
Assume I have the following .env files:
After building the project the following .config files would be created:
Would a feature like this be a good addition to the project or should stage specific .env variables be handled in a different way?