This article explores how to achieve cloud-agnostic business logic in serverless Function-as-a-Service (FaaS) applications, mitigating vendor lock-in while leveraging native cloud capabilities. It demonstrates structuring FaaS applications using Clean Architecture, Spring Cloud Function, and Gradle modules to isolate core business logic. The approach enables deploying the same business logic across multiple cloud providers like AWS Lambda and Azure Functions using Terraform CDK for Infrastructure as Code.
Read original on InfoQ ArchitectureServerless architectures, particularly Function-as-a-Service (FaaS), offer significant benefits like automatic scaling, pay-per-use billing, and reduced operational overhead. However, they often introduce the challenge of vendor lock-in due to deep integrations with cloud-specific SDKs, event models, and deployment mechanisms. The core problem is how to leverage the advantages of FaaS without tightly coupling business logic to a single cloud provider, allowing for portability and multi-cloud strategies.
The article advocates for applying Clean Architecture principles to serverless applications. This involves structuring the application into concentric layers, with the innermost layer containing the pure business logic (entities and use cases) that is entirely independent of external frameworks, databases, or cloud providers. Outer layers handle framework, infrastructure, and cloud-specific details, acting as adapters to the core business logic. This separation ensures that the core domain remains portable.
Key Architectural Separation
The crucial insight is to separate: 1. Core Business Logic: Cloud-agnostic, framework-agnostic. 2. Cloud Adapters/Triggers: Cloud-specific (e.g., AWS Lambda handler, Azure Function entry point). 3. Infrastructure as Code (IaC): Defines cloud resources and triggers (e.g., API Gateway, Lambda configuration).
The presentation uses Spring Cloud Function as a framework to wrap business logic, making it executable within various FaaS environments (AWS Lambda, Azure Functions, Google Cloud Functions). Spring's dependency injection and ecosystem facilitate building modular applications. Gradle modules are employed to further enforce architectural separation, allowing different modules for core business logic, cloud-specific adapters, and deployment configurations.
To demonstrate portability, the article shows deploying the same business logic to both AWS Lambda and Azure Functions. Terraform CDK (Cloud Development Kit for Terraform) is used to define the Infrastructure as Code (IaC) in a programmatic language (e.g., Kotlin, TypeScript), which then synthesizes into standard Terraform HCL. This allows for defining cloud resources once and deploying consistently across different cloud providers, further reducing vendor-specific IaC lock-in.