Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 29 additions & 13 deletions src/frontend/src/content/docs/deployment/kubernetes/clusters.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -325,11 +325,25 @@ Use [external parameters](/fundamentals/external-parameters/) to configure value

### Parameters inside environment expressions

Parameters embedded inside environment expressions are emitted as their own Helm values. For example, when a URL contains a host parameter, you can override that parameter at deployment time without reconstructing the entire URL. The publisher declares both the composed environment value and the nested parameter in `values.yaml`; deployment resolves the expression using the parameter's effective value.
When a parameter is embedded inside a larger environment variable expression — for example, a URL that contains a host parameter — the publisher declares the parameter as its own entry in `values.yaml`. The embedded parameter doesn't become an extra environment variable; instead, the generated ConfigMap or Secret references it directly, so you can override just that value at deployment time without reconstructing the entire URL.

Use an Aspire reference expression for composition, not a TypeScript string interpolation of a resource handle:

<Tabs syncKey='aspire-lang'>
<TabItem id='csharp' label='C#'>

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);
builder.AddKubernetesEnvironment("k8s");
var host = builder.AddParameter("host", "localhost");

builder.AddContainer("myapp", "nginx")
.WithEnvironment("SOME_URL", $"http://{host}/test");

builder.Build().Run();
```

</TabItem>
<TabItem id='typescript' label='TypeScript'>

```typescript title="apphost.mts" twoslash
Expand All @@ -338,28 +352,30 @@ import { createBuilder, refExpr } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
await builder.addKubernetesEnvironment('k8s');
const host = await builder.addParameter('host', { value: 'localhost' });
const app = await builder.addContainer('app', 'nginx');
await app.withEnvironment('SOME_URL', refExpr`http://${host}/test`);
const myapp = await builder.addContainer('myapp', 'nginx');
await myapp.withEnvironment('SOME_URL', refExpr`http://${host}/test`);

await builder.build().run();
```

</TabItem>
<TabItem id='csharp' label='C#'>
</Tabs>

```csharp title="AppHost.cs"
var builder = DistributedApplication.CreateBuilder(args);
builder.AddKubernetesEnvironment("k8s");
var host = builder.AddParameter("host", "localhost");
The generated `values.yaml` declares both the composed environment value and the nested `host` parameter under the resource's `config` section, and the ConfigMap template references the nested value:

builder.AddContainer("app", "nginx")
.WithEnvironment("SOME_URL", $"http://{host}/test");
```yaml title="values.yaml"
config:
myapp:
SOME_URL: ""
host: ""
```

builder.Build().Run();
```yaml title="templates/myapp/config.yaml"
data:
SOME_URL: "http://{{ .Values.config.myapp.host }}/test"
```

</TabItem>
</Tabs>
When you deploy with `aspire deploy`, Aspire resolves each nested parameter and the composed expression using the parameter's effective value — for example, `SOME_URL` becomes `http://localhost/test`. If you install the chart yourself, override the nested entry, such as `--set config.myapp.host=example.com`. Secret parameters are declared under `secrets.<resource>` instead, and any environment variable that embeds a secret parameter is emitted in the resource's Secret rather than its ConfigMap.

Conflicting Helm value paths, including names that collide after normalization, fail publishing rather than overwriting another entry.

Expand Down
Loading