Infrastructure configuration often becomes difficult to maintain as an application grows. A small service may begin with a handful of deployment settings, but eventually the repository can contain Kubernetes manifests, environment-specific YAML files, Helm values, container configuration, secrets configuration, and CI/CD scripts.

.NET Aspire takes a different approach by allowing application infrastructure to be described in C# through the AppHost.

Aspire 13.5 extends this approach with improvements around deployment and infrastructure modeling, making it possible to describe more of the application's deployment topology from the AppHost rather than maintaining separate configuration for every environment.

The important question is not whether C# is universally better than YAML. It is whether keeping application resources and their relationships in one strongly typed model can reduce duplication, configuration drift, and deployment complexity.

What Is an Aspire AppHost?

The AppHost is the orchestration project in a .NET Aspire application.

A simplified application might look like this:

Aspire AppHost
     |
     +-- API
     |
     +-- PostgreSQL
     |
     +-- Redis
     |
     +-- Worker

The AppHost describes how these resources relate to each other.

For example:

var builder = DistributedApplication.CreateBuilder(args);

var postgres = builder.AddPostgres("postgres")
    .AddDatabase("appdb");

var cache = builder.AddRedis("cache");

builder.AddProject<Projects.Api>("api")
    .WithReference(postgres)
    .WithReference(cache);

builder.Build().Run();

The code expresses the application topology directly.

Instead of manually documenting that the API depends on PostgreSQL and Redis, those relationships are represented in the application model.

Why Replace Deployment YAML?

YAML itself is not the problem.

Kubernetes manifests, Helm charts, and other declarative configuration formats remain useful and widely adopted.

The problem appears when the same infrastructure relationship has to be represented in multiple places.

For example:

C# AppHost
     |
     +-- API
     +-- Database
     +-- Cache

Kubernetes YAML
     |
     +-- API
     +-- Database
     +-- Cache

Helm Values
     |
     +-- API
     +-- Database
     +-- Cache

CI/CD
     |
     +-- Environment
     +-- Secrets

The more copies of the same infrastructure intent exist, the more opportunities there are for them to become inconsistent.

Infrastructure as Code in C#

The major benefit of an AppHost-based model is that infrastructure becomes part of a programming language with:

Consider:

var api = builder.AddProject<Projects.Api>("api");

var database = builder.AddPostgres("postgres")
    .AddDatabase("orders");

api.WithReference(database);

The relationship is explicit.

A developer reading the code can immediately see that the API consumes the database.

Strong Typing vs Text Configuration

Compare the two approaches conceptually.

AreaC# AppHostYAML
Type checkingStrongLimited
IDE supportStrongTool-dependent
RefactoringStrongMore manual
Reusable logicNaturalUsually templates/anchors/tools
Syntax errorsCompiler feedbackParser feedback
Application relationship modelingDirectIndirect
Kubernetes ecosystemRequires generated/deployment integrationNative
Familiarity.NET developersBroad DevOps familiarity

Neither approach is universally superior.

The choice depends on the team and the infrastructure being managed.

AppHost as an Application Topology

One of the strongest concepts in Aspire is that the AppHost can represent application topology rather than merely deployment settings.

For example:

                  AppHost
                     |
        +------------+------------+
        |            |            |
        v            v            v
       API         Worker       Gateway
        |            |
        v            v
   PostgreSQL      Queue
        |
        v
      Storage

The graph communicates dependencies.

This becomes useful when the application contains multiple services.

Environment-Specific Configuration

Real applications rarely have identical infrastructure in every environment.

For example:

Development
  |
  +-- Local PostgreSQL
  +-- Local Redis

Staging
  |
  +-- Managed PostgreSQL
  +-- Managed Redis

Production
  |
  +-- Managed PostgreSQL
  +-- Managed Redis

The infrastructure model should make those differences explicit.

However, environment-specific branching should be used carefully.

Avoid turning the AppHost into a large collection of nested conditions:

if (environment == "production")
{
    // 500 lines of infrastructure
}
else if (environment == "staging")
{
    // another 500 lines
}

When the differences become substantial, reusable infrastructure components and separate deployment policies may be easier to maintain.

Deployment YAML Still Has a Role

Replacing YAML should not become a goal by itself.

There are cases where Kubernetes YAML remains appropriate.

For example:

Aspire should therefore complement existing infrastructure practices where necessary rather than forcing every deployment concern into C#.

The Hybrid Approach

A practical architecture can use both.

Aspire AppHost
     |
     +-- Application Resources
     +-- Service Relationships
     +-- Environment Configuration
     |
     v
Deployment / Infrastructure Layer
     |
     +-- Kubernetes
     +-- Azure
     +-- CI/CD
     +-- Platform Policies

This keeps application topology close to the application while leaving platform-level concerns to the platform layer.

Resource Relationships

One of the biggest benefits of AppHost-based infrastructure is explicit resource relationships.

For example:

var database = builder.AddPostgres("postgres")
    .AddDatabase("orders");

builder.AddProject<Projects.OrderApi>("orders-api")
    .WithReference(database);

The API has an explicit dependency on the database.

This is more useful than simply storing a connection string because the infrastructure model understands that the database is a resource.

The application configuration can then be generated or supplied according to the deployment environment.

Avoid Hard-Coded Infrastructure Values

Even in a C# infrastructure model, avoid scattering environment-specific values throughout the code.

Instead of:

var endpoint =
    "https://production-storage.example.com";

prefer configuration or resource references.

This keeps the infrastructure model portable.

Reusable Infrastructure Components

As an application grows, repeated infrastructure patterns can be extracted into methods.

For example:

static IResourceBuilder<IResourceWithConnectionString>
    AddApplicationDatabase(
        IDistributedApplicationBuilder builder)
{
    return builder.AddPostgres("postgres")
        .AddDatabase("appdb");
}

The exact generic types depend on the resources being modeled, but the design principle is important.

Repeated infrastructure should have one definition where practical.

This reduces copy-and-paste configuration.

Infrastructure Validation

C# provides an additional advantage because infrastructure code can be tested.

For example, a test can verify that a resource exists or that expected relationships are represented.

The exact testing strategy depends on how the AppHost is structured, but the principle is useful:

Infrastructure Model
       |
       v
Validation
       |
       +-- Required Resource?
       +-- Dependency Present?
       +-- Configuration Valid?
       +-- Environment Rules?

This moves some infrastructure errors earlier in the development process.

CI/CD Integration

A C# AppHost does not eliminate CI/CD.

The pipeline still needs to:

  1. Restore dependencies.

  2. Build the application.

  3. Validate the AppHost.

  4. Produce deployment artifacts.

  5. Apply infrastructure.

  6. Deploy application services.

  7. Run post-deployment validation.

A simplified pipeline might look like:

Commit
  |
  v
Build
  |
  v
Test
  |
  v
AppHost Validation
  |
  v
Deployment Artifact
  |
  v
Environment
  |
  v
Smoke Tests

The important improvement is that application infrastructure intent is represented closer to the application source.

Common Mistakes

Trying to Eliminate YAML Everywhere

Not every YAML file is application infrastructure.

CI/CD pipelines and platform tooling may still use YAML for good reasons.

Putting Secrets in the AppHost

Infrastructure code is still source code.

Do not hard-code credentials or secrets.

Overusing Conditional Logic

Too many environment-specific branches can make the AppHost difficult to understand.

Ignoring Platform Ownership

A platform team may own cluster-level configuration.

Application teams should not necessarily duplicate or replace those controls.

Assuming C# Automatically Means Better Infrastructure

The language is not the deciding factor.

Good infrastructure design depends on clear ownership, repeatability, security, observability, and operational practices.

Troubleshooting

Deployment Works Locally but Fails in the Target Environment

Compare the generated deployment configuration and environment-specific settings.

Check:

Resource Dependency Is Missing

Inspect the AppHost relationship.

For example:

api.WithReference(database);

Without an explicit relationship, the application may not receive the expected resource configuration.

Configuration Differs Between Environments

Identify which values are environment-specific and move them into the appropriate configuration or deployment layer rather than duplicating entire resource definitions.

Best Practices

  1. Use the AppHost to describe application topology.

  2. Keep resource relationships explicit.

  3. Avoid duplicating infrastructure definitions.

  4. Keep secrets outside source code.

  5. Reuse common infrastructure patterns.

  6. Keep environment-specific differences deliberate.

  7. Use YAML where Kubernetes-native or platform-level configuration requires it.

  8. Validate infrastructure changes in CI.

  9. Keep platform and application ownership separate.

  10. Treat deployment artifacts as part of the application's release process.

  11. Avoid unnecessary environment-specific branching.

  12. Document exceptional infrastructure behavior.

Advantages and Disadvantages

Advantages

Disadvantages

When Should You Use AppHost Infrastructure?

AppHost-based infrastructure is particularly attractive when:

Traditional Kubernetes configuration may remain preferable when:

The right answer can also be a combination of both approaches.

Conclusion

.NET Aspire's AppHost provides a way to describe application infrastructure and resource relationships using C#. That can reduce duplication between application code and deployment configuration, particularly for .NET teams building distributed applications.

But replacing deployment YAML should not be treated as the objective. The real objective is to create a reliable infrastructure model with clear ownership, repeatable deployment, secure configuration, and minimal drift.

For many .NET applications, the most practical approach is a hybrid one: use Aspire to describe application topology and resource relationships while retaining Kubernetes, cloud-platform, and CI/CD tooling where those layers provide capabilities the AppHost should not own.

The strongest infrastructure model is not the one with the least YAML. It is the one where developers and operators can clearly understand what the application needs, how its resources are connected, and which layer is responsible for deploying and securing each part.