You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AWS CDK部署.NET 8 Lambda时是否可移除serverless.template?

.NET 8 Lambda + TypeScript CDK 替代 Serverless Template 方案

问题

我有一个.NET 8 Core Minimal API,通过在Program.cs的Main方法中添加builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi);将其转为Lambda函数。目前使用TypeScript CDK将基础设施部署到LocalStack(替代真实AWS环境),但部署必须依赖serverless.template文件。想确认:

  1. 是否可以完全通过TypeScript CDK定义所有基础设施,不再需要serverless.template?
  2. 如果可以,如何将serverless.template中的配置映射为CDK代码?

当前CDK代码

\lib*cdk-stack.ts

import * as cdk from 'aws-cdk-lib';
import { Lambda } from 'aws-cdk-lib/aws-ses-actions';
import * as lambda from "aws-cdk-lib/aws-lambda";
import { Construct } from 'constructs';

export class MyFunctionCdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

      const functionProps: lambda.FunctionProps = {
          runtime: lambda.Runtime.DOTNET_8,
          code: lambda.Code.fromAsset('../MyFunctionAssemblyName/bin/Release/net8.0/publish'),
          handler: 'MyFunctionAssemblyName',
          timeout: cdk.Duration.seconds(600)
      };

      new lambda.Function(this, "MyFunction", functionProps);
  }
}

\bin*cdk.ts

#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyFunctionCdkStack } from '../lib/my-app-name.cdk-stack';

const app = new cdk.App();
new MyFunctionCdkStack(app, 'MyFunctionCdkStack', {
  /* If you don't specify 'env', this stack will be environment-agnostic.
   * Account/Region-dependent features and context lookups will not work,
   * but a single synthesized template can be deployed anywhere. */

  /* Uncomment the next line to specialize this stack for the AWS Account
   * and Region that are implied by the current CLI configuration. */
  // env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION },

  /* Uncomment the next line if you know exactly what Account and Region you
   * want to deploy the stack to. */
  // env: { account: '123456789012', region: 'us-east-1' },

  /* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */
});

参考的serverless.template内容

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Transform": "AWS::Serverless-2016-10-31",
  "Description": "An AWS Serverless Application. This template is partially managed by Amazon.Lambda.Annotations (v1.2.0.0).",
  "Resources": {
    "MyFunction": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Handler": "MyFunctionAssemblyName",
        "Runtime": "dotnet8",
        "MemorySize": 256,
        "Timeout": 600,
        "Role": null,
        "Policies": [
          "AWSLambda_FullAccess"
        ],
        "Environment": {
          "Variables": {
            "POWERTOOLS_SERVICE_NAME": "MyService",
            "POWERTOOLS_LOG_LEVEL": "Info",
            "POWERTOOLS_LOGGER_CASE": "PascalCase",
            "POWERTOOLS_TRACER_CAPTURE_RESPONSE": true,
            "POWERTOOLS_TRACER_CAPTURE_ERROR": true,
            "POWERTOOLS_METRICS_NAMESPACE": "MyServiceFunction"
          }
        },
        "Events": {
          "ProxyResource": {
              "Type": "Api",
              "Properties": {
                  "Path": "/{proxy+}/path",
                  "Method": "ANY"
              }
          },              
          "RootResource": {
            "Type": "Api",
            "Properties": {
              "Path": "/path",
              "Method": "GET"
            }
          }
        }
      }
    }
  },
  "Outputs": {
    "ApiURL": {
      "Description": "API endpoint URL for Prod environment",
      "Value": {
        "Fn::Sub": "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
      }
    }
  }
}

解决方案

核心结论

完全可以移除serverless.template,所有基础设施配置都能通过TypeScript CDK实现,无需依赖该模板文件。

改造后的完整CDK栈代码

替换你原来的\lib\*cdk-stack.ts内容,以下代码完全覆盖serverless.template中的所有配置:

import * as cdk from 'aws-cdk-lib';
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as apigateway from "aws-cdk-lib/aws-apigateway";
import * as iam from "aws-cdk-lib/aws-iam";
import { Construct } from 'constructs';

export class MyFunctionCdkStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // 创建Lambda执行角色,附加AWSLambda_FullAccess权限
    const lambdaRole = new iam.Role(this, "MyFunctionRole", {
      assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"),
      managedPolicies: [
        iam.ManagedPolicy.fromAwsManagedPolicyName("AWSLambda_FullAccess")
      ]
    });

    // Lambda函数配置,对应template中的Function属性
    const myFunction = new lambda.Function(this, "MyFunction", {
      runtime: lambda.Runtime.DOTNET_8,
      code: lambda.Code.fromAsset('../MyFunctionAssemblyName/bin/Release/net8.0/publish'),
      handler: 'MyFunctionAssemblyName',
      timeout: cdk.Duration.seconds(600),
      memorySize: 256, // 对应template中的MemorySize
      role: lambdaRole, // 绑定执行角色
      environment: { // 对应template中的Environment.Variables
        POWERTOOLS_SERVICE_NAME: "MyService",
        POWERTOOLS_LOG_LEVEL: "Info",
        POWERTOOLS_LOGGER_CASE: "PascalCase",
        POWERTOOLS_TRACER_CAPTURE_RESPONSE: "true",
        POWERTOOLS_TRACER_CAPTURE_ERROR: "true",
        POWERTOOLS_METRICS_NAMESPACE: "MyServiceFunction"
      }
    });

    // 创建API网关,对应template中的Api事件
    const api = new apigateway.RestApi(this, "MyServiceApi", {
      restApiName: "My Service API",
      deployOptions: {
        stageName: "Prod" // 对应template中的Prod阶段
      }
    });

    // 绑定Lambda到API网关作为集成
    const lambdaIntegration = new apigateway.LambdaIntegration(myFunction);

    // 配置/path GET路由(对应RootResource)
    const pathResource = api.root.addResource("path");
    pathResource.addMethod("GET", lambdaIntegration);

    // 配置/{proxy+}/path ANY路由(对应ProxyResource)
    const proxyPathResource = api.root.addResource("{proxy+}").addResource("path");
    proxyPathResource.addMethod("ANY", lambdaIntegration);

    // 输出API URL,对应template中的Outputs
    new cdk.CfnOutput(this, "ApiURL", {
      description: "API endpoint URL for Prod environment",
      value: `${api.url}Prod/`
    });
  }
}

关键配置映射说明

  • 内存大小:在lambda.FunctionProps中添加memorySize: 256,对应模板中的MemorySize
  • 环境变量:通过environment属性直接定义键值对,注意布尔值需转为字符串(Lambda环境变量仅支持字符串类型)
  • 权限策略:创建IAM角色并附加AWSLambda_FullAccess托管策略,替代模板中的Policies配置
  • API网关触发器:通过aws-apigateway模块创建RestApi,添加资源和方法后绑定Lambda集成,对应模板中的Events部分
  • 输出API地址:用cdk.CfnOutput生成输出,直接拼接API网关的URL和阶段名

部署验证

修改完成后,直接运行CDK部署命令(针对LocalStack需确保已配置对应环境变量),无需再保留serverless.template文件,即可完成基础设施部署。

内容的提问来源于stack exchange,提问作者CB_at_Sw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:44:53