Menu
InfoQ Cloud·July 27, 2026

Clean Architecture for Portable Serverless Business Logic

This article explores how to achieve cloud-agnostic business logic in serverless applications, mitigating vendor lock-in while still leveraging native cloud capabilities. It demonstrates structuring FaaS applications using Clean Architecture, Spring Cloud Function, and Gradle modules to isolate core business logic from infrastructure concerns. The presentation includes a live demo of deploying portable Kotlin services across AWS Lambda and Azure Functions using Terraform CDK.

Read original on InfoQ Cloud

The Challenge of Serverless Vendor Lock-in

Serverless architectures, particularly Function-as-a-Service (FaaS), offer benefits like automatic scaling, pay-per-use billing, and reduced operational overhead. However, a significant concern for architects and developers is vendor lock-in, as specific cloud provider SDKs and deployment models can tightly couple business logic to a single platform. This presentation addresses this by proposing an architectural approach that enables business logic portability across different cloud providers.

Architectural Pillars for Cloud Agnostic FaaS

  • Clean Architecture: Provides a framework to separate business rules from technical details, making the core logic independent of frameworks, UI, and infrastructure.
  • Spring Cloud Function: Acts as an abstraction layer, allowing Spring applications to run as FaaS functions across various cloud providers (AWS Lambda, Azure Functions, Google Cloud Functions).
  • Gradle Modules: Used to logically separate cloud-specific adapters and infrastructure code from the core business logic module.
💡

Key Principle

The core idea is to encapsulate the pure business logic in a module that has no direct dependencies on any cloud SDKs or FaaS runtime specifics. Cloud-specific integration details are handled by separate adapter modules.

Separating Concerns with Clean Architecture and Spring Cloud Function

The approach demonstrates how, even with Spring Cloud Function, some cloud-specific dependencies for triggers and entry points are often unavoidable. The solution is to use Gradle modules to isolate these dependencies. For instance, an Azure-specific module would contain the Azure Spring Cloud adapter and the Azure Function entry point, while an AWS-specific module would handle the AWS Lambda adapter and its entry point. The crucial business logic remains in a shared, independent module.

Infrastructure as Code for Multi-Cloud Deployment

To deploy these portable services, Terraform CDK (Cloud Development Kit) is utilized. Terraform CDK allows developers to define infrastructure using familiar programming languages (like Kotlin in this case), which then synthesizes into Terraform configuration files. This enables a unified approach to provisioning the necessary FaaS resources (Lambda functions, API Gateways, Azure Function Apps) across different cloud environments, pointing to the same core business logic artifact.

kotlin
// Example of a cloud-agnostic business logic interface (Kotlin)
interface DocumentProcessingService {
    fun processDocument(document: Document): ProcessedDocument
}

// Cloud-specific adapter for AWS Lambda
class AwsDocumentProcessorHandler : SpringBootRequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent>() {
    // Delegates to DocumentProcessingService
}

// Cloud-specific adapter for Azure Functions
class AzureDocumentProcessorFunction(@Autowired val service: DocumentProcessingService) {
    @FunctionName("uploadDocument")
    fun uploadDocument(@HttpTrigger(name = "req", methods = [HttpMethod.POST], authLevel = AuthorizationLevel.FUNCTION) request: HttpRequestMessage<Optional<String>>): HttpResponseMessage {
        // Delegates to DocumentProcessingService
    }
}
ServerlessFaaSClean ArchitectureSpring Cloud FunctionMulti-cloudVendor Lock-inInfrastructure as CodeTerraform CDK

Comments

Loading comments...