Aspire
Give each developer their own tunnel
Read the tunnel name and key from each developer’s user secrets, so a team shares one AppHost and each person runs their own tunnel.
Why each developer needs their own tunnel
#A tunnel serves one computer at a time. When a second computer connects with the same tunnel, it takes the tunnel over and the first one stops. Tunnel names are unique across the whole service, so each developer creates their own, for example my-tunnel-dev1 and my-tunnel-dev2.
Keep the tunnel name and the key out of the AppHost’s code, so the same code runs on every computer and each developer supplies their own 2 values.
Create your own tunnel
#Each developer needs to be a member of the workspace. Owners and admins can invite a teammate; members can create tunnels.
Create a tunnel with your own name, for example my-tunnel-dev1, with the Groundhog CLI as in the next section, or in the Groundhog dashboard. In the dashboard, choose Copy key: the key is shown once.
Create the tunnel and save its name and key with the Groundhog CLI
#The Groundhog CLI can create your tunnel and save both values in the AppHost’s user secrets in one step, so you never handle the key. Signed in with groundhog login, pass the AppHost’s project file with --project:
groundhog create my-tunnel-dev1 --project AppHost/AppHost.csprojIn the AppHost’s user secrets, Parameters:groundhog-tunnel-name is my-tunnel-dev1 and Parameters:groundhog-tunnel-key is the new connection key. The key is never printed.
For a tunnel you created earlier with the CLI on this computer, key copy writes the key the CLI saved then, without changing the tunnel:
groundhog key copy my-tunnel-dev1 --project AppHost/AppHost.csprojA tunnel created in the Groundhog dashboard or on another computer has no saved key here. groundhog key rotate my-tunnel-dev1 --project AppHost/AppHost.csproj makes a new key and saves both values; anything still using the old key disconnects. groundhog key add my-tunnel-dev1 --project AppHost/AppHost.csproj saves a second key instead, so anything using the old key stays connected until you revoke it.
These commands need CLI 0.4.0-preview.7 or later. The AppHost project needs a UserSecretsId; Aspire AppHost templates include one.
Set the tunnel name and key with the .NET CLI
#Without the Groundhog CLI, save your tunnel’s name and key in the AppHost project’s user secrets with dotnet user-secrets before you add the code that reads them. Run these from your AppHost project’s folder, with your own tunnel name. The key is read at a hidden prompt so it never appears in your shell history.
dotnet user-secrets set "Parameters:groundhog-tunnel-name" "my-tunnel-dev1"
$tunnelKey = Read-Host "Groundhog connection key" -MaskInput
dotnet user-secrets set "Parameters:groundhog-tunnel-key" $tunnelKey
Remove-Variable tunnelKeyThe PowerShell commands need PowerShell 7.1 or later, which added -MaskInput. If dotnet user-secrets says the project has no UserSecretsId, run dotnet user-secrets init first. Aspire AppHost templates already include one.
dotnet user-secrets listUser secrets are stored in your user profile, outside the repository, and are not encrypted.
Read the tunnel name and key with WithGroundhogTunnel()
#WithGroundhogTunnel() without a tunnel name reads the 2 values each developer saved, so the same code works on every computer:
var builder = DistributedApplication.CreateBuilder(args);
var web = builder.AddProject<Projects.Web>("web");
// Reads the tunnel name from Parameters:groundhog-tunnel-name and its key from Parameters:groundhog-tunnel-key.
web.WithGroundhogTunnel(configure: webTunnel =>
web.WithEnvironment("PublicOrigin", webTunnel.Resource.PublicAddress));
builder.Build().Run();On the computer of the developer who saved my-tunnel-dev1, the tunnel is my-tunnel-dev1 and web gets PublicOrigin set to https://my-tunnel-dev1.groundhog.unifinity.com.
Commit this code; each developer keeps the values on their own computer. When a value is missing, the Aspire dashboard asks for it. WithGroundhogTunnel() needs client 0.4.0-preview.7 or later.
For the gateway AppHost, add the tunnel to apiGateway the same way:
var apiGateway = builder.AddProject<Projects.ApiGateway>("api-gateway")
.WithReference(serviceA)
.WithReference(serviceB)
.WithGroundhogTunnel();
var apiGatewayTunnel = apiGateway.GetGroundhogTunnel();
serviceA.WithReference(apiGateway, apiGatewayTunnel);
serviceB.WithReference(apiGateway, apiGatewayTunnel);Enter the tunnel name and key in the Aspire dashboard
#Instead of saving the values with either CLI, you can start the AppHost without saving anything first. The Aspire dashboard asks for groundhog-tunnel-name and groundhog-tunnel-key. Turn on Save to user secrets before you submit, and the values are saved in the same place as the commands above.
Keep the tunnel name and key out of source control
#- Never put the key in appsettings.json, appsettings.Development.json or any committed file.
- Leave the tunnel name out of committed settings too: a name there makes every developer connect the same tunnel, and each takes it over from the last.
- Where user secrets are not available, for example in a dev container, set environment variables instead:
Parameters__groundhog-tunnel-nameandParameters__groundhog-tunnel-key.