Migrating a .NET Console App from IaaS to PaaS Using WebJobs and Blob Storage

How I moved a server-bound console process into PaaS without carrying a VM just to keep one job alive.

What I Needed to Solve

I had a .NET console application that was originally running on a server. When the target moved to PaaS, that model no longer fit because there was no server to host the process in the old way.

Why the Server Model Failed

The console app expected a server, local disk, and a place where it could run on demand or on a schedule. In PaaS, that assumption breaks quickly because the platform is not meant for you to manage a machine directly.

Old model vs new model
Why the original server assumptions stopped fitting PaaS
Old model PaaS shift Replacement
Old IaaS ExpectationWhy It Failed in PaaSWhat I Needed Instead
Long-running server processPaaS abstracts the hostHosted job runner
Local file system for work filesLocal disk is not durableBlob Storage
Manual machine accessNot the PaaS operating modelPlatform-managed execution

Easy Migration Steps

I broke the migration into small pieces so I could prove each step before I changed the runtime model.

  1. Identify what the console app actually does: input, processing, file output, and downstream handoff.
  2. Remove local disk assumptions and move persistent files to Blob Storage.
  3. Host the app in a WebJob so it runs inside App Service instead of a VM.
  4. Move configuration into App Service settings and connection strings.
  5. Validate the output in Blob Storage before replacing the old server-based run path.

Why I Chose WebJobs

Azure Functions was available, but for this workload it was not the best fit. The app behaved like a background job, and WebJobs matched that shape without making the cost or runtime model more complicated than it needed to be.

Target Architecture

The migration path is simple: the platform hosts the job, the job runs the console logic, Blob Storage holds the durable state, and the downstream process reads the result.

Blob Storage Replaced Local Disk

Local files were the first thing I moved out of the app. Anything that needed to survive beyond the runtime had to go to Blob Storage instead of local disk.

  1. The console app writes its working files to Blob Storage.
  2. The WebJob picks up the files or creates them directly in Blob.
  3. Any downstream consumer reads from Blob instead of the old server path.

Implementation

The code did not need a rewrite. What changed was the host, the storage path, and the way the job was triggered.

public static async Task Main(string[] args)
{
    var blobService = new BlobServiceClient(Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING"));
    var container = blobService.GetBlobContainerClient("work-items");
    await container.CreateIfNotExistsAsync();

    // Read input, process it, and write results to Blob Storage
    var result = ProcessWork();
    var blob = container.GetBlobClient($"output/{DateTime.UtcNow:yyyyMMddHHmmss}.json");
    await blob.UploadAsync(BinaryData.FromString(result), overwrite: true);
}

Runtime Model

The job was hosted as a WebJob in App Service, which gave me a managed execution environment without maintaining the underlying server.

Runtime pieces
What the platform is doing behind the scenes
Host Storage Config
PartRole
WebJobRuns the console app in PaaS
Blob StorageStores files and job output
App ServiceHosts the job without a VM
ConfigurationConnection strings and runtime settings

Execution Flow

The app was scheduled or started in the way the business needed, but the important part was that the execution no longer depended on a server I had to manage.

What I Verified

CheckWhat It Proved
Blob output existsThe job completed and wrote results.
WebJob status is healthyThe platform is running the job.
Downstream consumer reads from BlobThe old server dependency is gone.
No local disk dependency remainsThe app is suitable for PaaS.

What Happened In Practice

The hardest part was not the code. It was removing the assumption that the app needed a server sitting there waiting for it. Once the job moved into WebJobs and the files moved into Blob Storage, the application behaved like a managed cloud workload instead of a server-bound process.

Delivery Lessons