资讯动态

用 AWS CDK 与 Java 实现自定义资源(Custom Resource):从构建、部署到源码拆解

发布时间:2026/10/15 7:03:27 来源:尧图企业网站定制
【免费下载链接】aws-cdk-examplesExample projects using the AWS CDK项目地址https://gitcode.com/gh_mirrors/aw/aws-cdk-examples点击查看免费下载AWS CDK 的自定义资源Custom Resource是在 CloudFormation 原生资源之外将任意业务逻辑如外部系统调用、托管 API 操作、参数校验接入 IaC 编排的关键手段。本文以本仓库aws-cdk-examples中的 java/custom-resource 示例为完整骨架讲解如何用 Java 编写 CDK 应用、用 Lambda 实现自定义资源处理逻辑并覆盖从mvn compile构建、CDK Toolkit 合成/部署到 Lambda 代码更新的完整工作流。读完本文你将掌握在 Java 工程中拆分构造Construct、注册自定义资源 Provider、读取资源返回属性并输出到 CloudFormation 输出的完整实战方案。为什么需要自定义资源把架构拆成可复用组件CloudFormation 原生的资源类型覆盖了绝大多数 AWS 服务但总有“官方资源覆盖不到”的场景比如在部署时调用第三方 API、初始化外部系统数据、或者编排多个服务之间的依赖关系。自定义资源正是为这类场景设计的——你可以把一段 Lambda 函数注册成资源 Provider然后在 CDK 应用里像使用普通资源一样声明它CloudFormation 会在资源创建、更新、删除的生命周期内自动调用你的处理器。示例 README 明确指出这个示例的价值在于构造Construct的设计与架构组件拆分This example shows adding a custom resource to a CDK app in Java. This custom resource is useful when considering design of constructs, or separating your architecture into components.也就是说自定义资源不仅是一种“补位”技术更是把“有状态的外部逻辑”封装成可复用、可组合的 CDK 构造单元的一种工程实践。本示例属于 Stable 稳定性等级仅依赖 CDK 核心库没有任何基础设施前置条件不需要预先创建 VPC、密钥等开箱即可构建。工程结构与多模块 Maven 布局示例采用标准的 Maven 多模块工程共三个模块各自职责清晰java/custom-resource/ ├── asset/ │ └── lambda-1.0.0-jar-with-dependencies.jar # Lambda 处理器 jar已构建产物 ├── cdk/ # CDK 应用模块 │ ├── cdk.json │ ├── pom.xml │ └── src/main/java/software/amazon/awscdk/examples/ │ ├── CustomResourceApp.java # 应用入口 │ ├── CustomResourceStack.java # Stack 定义 │ └── MyCustomResource.java # 自定义构造核心 ├── lambda/ # Lambda 处理器模块 │ ├── cdk.json │ ├── pom.xml │ └── src/main/java/software/amazon/awscdk/examples/ │ ├── CustomResourceHandler.java # 资源生命周期处理器 │ └── CustomResourceIsCompleteHandler.java # 完成轮询处理器 ├── cdk.json ├── pom.xml # 聚合父 POM └── README.md根目录的 pom.xml 是聚合父工程声明了lambda与cdk两个子模块并配置了maven-compiler-pluginsource/target 1.8与maven-assembly-plugin产出jar-with-dependencies形式的可运行 jar。cdk模块的 cdk/pom.xml 声明了 CDK 核心依赖版本区间是工程当前实际使用的software.amazon.awscdk:aws-cdk-lib[2.262.0, 3.0.0)software.constructs:constructs[10.5.0, 11.0.0)junit:junit4.13.1test 作用域供编写单元测试lambda模块的 lambda/pom.xml 则使用maven-shade-plugin打 fat jar依赖aws-lambda-java-core1.2.1 与aws-lambda-java-events3.10.0同时通过dependencyManagement引入 AWS SDK v2 BOM。构建一条命令拉起整个工程README 给出的构建命令只有一条$ mvn compile这条命令会在根工程执行Maven 会自动解析lambda、cdk两个子模块并按依赖顺序编译同时下载所需的全部依赖。编译之后工程结构就已就绪可以进入下一步——用 CDK Toolkit 合成与部署。提示你也可以用 IDE 编写代码和单元测试但合成synthesize与部署deploy必须通过 CDK Toolkit完成IDE 无法替代这一环节。CDK Toolkit 集成cdk.json 与入口配置CDK Toolkit 如何知道“该怎样执行你的 Java 程序”答案在 cdk.json{ app: mvn exec:java -pl cdk -Dexec.mainClasssoftware.amazon.awscdk.examples.CustomResourceApp }app字段指示 Toolkit 使用mvn exec:java作为应用入口命令主类是software.amazon.awscdk.examples.CustomResourceApp。-pl cdk指定只在cdk模块内执行。这意味着修改 Java 代码后无需手动重新编译——CDK Toolkit 每次执行时 Maven 会按需自动重编译随后即可照常运行所有 Toolkit 命令$ cdk ls list all stacks in this program $ cdk synth cloudformation template $ cdk deploy deploy stack to your account $ cdk diff diff against deployed stackcdk ls列出本程序包含的所有 Stackcdk synth把 CDK 应用合成成 CloudFormation 模板cdk deploy将 Stack 部署到你的账号cdk diff对比当前代码与已部署 Stack 的差异。结合 java/README.md 中 Java 示例的统一运行方式首次部署前的全局准备是安装 CDK CLI$ npm install -g aws-cdk $ cd java/custom-resource $ cdk deployStack 使用完毕后用cdk destroy即可清理全部资源。源码拆解三层结构如何协作整个示例由“应用入口 → Stack → 自定义构造 → Lambda 处理器”四个层次构成下面逐层剖析。1. 应用入口CustomResourceAppCustomResourceApp.java 是所有 CDK 应用的入口负责创建App、注入资源属性、注册 Stack 并触发合成public class CustomResourceApp { private static MapString, Object props new HashMapString, Object(); public static void main(final String args[]) { App app new App(); props.put(Message, AWS CDK); new CustomResourceStack(app, cdk-custom-resource-example2, props); app.synth(); } }这里的关键设计是把业务参数Message: AWS CDK以MapString, Object形式从入口传入后续会一路透传到自定义资源构造与 Lambda 处理器。Stack 的 id 为cdk-custom-resource-example2app.synth()最终生成 CloudFormation 模板。2. Stack 层CustomResourceStackCustomResourceStack.java 的职责很单纯实例化自定义构造并把构造暴露出来的返回属性输出为 CloudFormation 输出public class CustomResourceStack extends Stack { public String response ; public CustomResourceStack(final Construct scope, final String id, final MapString, ? extends Object props) { super(scope, id); try { MyCustomResource resource new MyCustomResource(this, DemoResource, props); CfnOutput.Builder.create(this, ResponseMessage) .description(The message that came back from the Custom Resource) .value((resource.response)) .build(); } catch (Exception e) { e.printStackTrace(); } } }Stack 里有一个公开字段response它接收MyCustomResource从自定义资源返回的Response属性值随后CfnOutput逻辑 idResponseMessage把它暴露为 CloudFormation 输出部署后可以在控制台或 CLI 中直接看到“自定义资源回传的消息”。3. 核心构造MyCustomResourceMyCustomResource.java 是本例的“灵魂”它继承software.constructs.Construct把“Provider 自定义资源”整体封装成一个可复用组件。整个构造按三步搭建第一步创建事件处理 LambdaonEventfinal SingletonFunction onEvent SingletonFunction.Builder.create(this, Singleton1) .uuid(UUID.randomUUID().toString()) .code(Code.fromAsset(./asset/lambda-1.0.0-jar-with-dependencies.jar)) .handler(software.amazon.awscdk.examples.CustomResourceHandler) .runtime(Runtime.JAVA_21).memorySize(1024) .timeout(Duration.minutes(5)) .build();要点使用SingletonFunction复用同一个 jar./asset/lambda-1.0.0-jar-with-dependencies.jar并配一个随机uuid保证函数资源唯一处理器入口是CustomResourceHandler运行时JAVA_21、内存 1024 MB、超时 5 分钟——这些参数保证即使onEvent逻辑较重也不会被超时打断。第二步创建完成轮询 LambdaisCompletefinal SingletonFunction isComplete SingletonFunction.Builder.create(this, Singleton2) .uuid(UUID.randomUUID().toString()) .code(Code.fromAsset(./asset/lambda-1.0.0-jar-with-dependencies.jar)) .handler(software.amazon.awscdk.examples.CustomResourceIsCompleteHandler) .runtime(Runtime.JAVA_21).memorySize(1024) .timeout(Duration.minutes(5)) .build();它复用同一个 jar但入口换成了CustomResourceIsCompleteHandler——这是 AWS CDKcustom-resources模块的“异步 Provider”模式CDK 框架会先用onEvent触发业务逻辑再反复调用isComplete轮询直到返回IsComplete: true才认为资源就绪。第三步组装 Provider 并声明自定义资源final Provider myProvider Provider.Builder.create(this, MyProvider) .onEventHandler(onEvent) .isCompleteHandler(isComplete) .logRetention(RetentionDays.ONE_DAY) .build(); final CustomResource resource CustomResource.Builder.create(this, Resource1) .serviceToken(myProvider.getServiceToken()) .properties(props) .build(); response resource.getAttString(Response);Provider是software.amazon.awscdk.customresources包提供的框架构造负责封装响应上报、完成轮询等底层机制logRetention设为ONE_DAY控制 Provider 框架 Lambda 的 CloudWatch 日志保留时间CustomResource通过serviceToken指向 Provider并把入口传入的props含Message作为资源属性下发最后用resource.getAttString(Response)读取自定义资源返回的Response属性——这个值会在合成期被解析最终进入 Stack 的CfnOutput。从源码结构看MyCustomResource对外只暴露一个response字段内部细节两个 Lambda、Provider、资源声明全部被封装起来——这正是 README 强调的“构造设计”与“组件化拆分”的直观体现使用方Stack完全不需要关心自定义资源内部的 Lambda 与轮询机制。4. 生命周期处理器CustomResourceHandlerCustomResourceHandler.java 实现了RequestHandlerMapString, Object, MapString, Object按 CloudFormation 事件中的RequestType分发到三种生命周期操作Override public MapString, Object handleRequest(MapString, Object event, Context context) { String requestType (String) event.get(RequestType); switch (requestType) { case Create: return onCreate(event); case Update: return onUpdate(event); case Delete: return onDelete(event); default: throw new RuntimeException(Invalid request type: requestType); } }Create 分支是业务核心从ResourceProperties里取出Message构造一个Data属性Response返回private MapString, Object onCreate(MapString, Object event) { MapString, Object props (MapString, Object) event.get(ResourceProperties); String message (String) props.get(Message); MapString, String attributes new HashMapString, String(); attributes.put(Response, String.format(Resource message %s, message)); MapString, Object response new HashMapString, Object(); response.put(Data, attributes); return response; }这个返回 Map 会被 CDK 的 Provider 框架转换成标准 CloudFormation 自定义资源响应Data.Response正是前面getAttString(Response)读到的那个值。当入口传入Message AWS CDK时最终输出就是Resource message AWS CDK。Update / Delete 分支则相对轻量从事件中读取PhysicalResourceId并原样返回确保 CloudFormation 能正确标识资源、完成响应上报private MapString, Object onUpdate(MapString, Object event) { String physicalId (String) event.get(PhysicalResourceId); MapString, Object response new HashMapString, Object(); response.put(PhysicalResourceId, physicalId); return response; } private MapString, Object onDelete(MapString, Object event) { String physicalId (String) event.get(PhysicalResourceId); MapString, Object response new HashMapString, Object(); response.put(PhysicalResourceId, physicalId); return response; }真实项目中onDelete通常需要执行清理逻辑如删除外部系统数据本示例保持最简只做物理 ID 的回传。5. 完成轮询处理器CustomResourceIsCompleteHandlerCustomResourceIsCompleteHandler.java 是整个链路的“收尾哨兵”逻辑极简public class CustomResourceIsCompleteHandler implements RequestHandlerMapString, Object, MapString, Object { Override public MapString, Object handleRequest(MapString, Object event, Context context) { MapString, Object response new HashMapString, Object(); response.put(IsComplete, true); return response; } }它永远返回IsComplete: true即“onEvent 一执行完就算完成”。对于需要异步等待外部系统就绪的真实场景可以在这里检查实际状态未就绪时返回falseCDK 的 Provider 框架会持续轮询直至返回true或超时。Lambda 代码更新流程改完怎么生效README 特别强调了 Lambda 处理器的部署更新流程。由于 CDK 构造引用的是asset/目录下预构建的 jar因此每当你修改了 Lambda 处理器代码都必须重新打包并拷贝 jar才能让下一次cdk deploy携带最新代码$ mvn package -f lambda/pom.xml generates jar with lambda handler code $ cp lambda/target/lambda-1.0.0-jar-with-dependencies.jar asset/ copies lambda handler jar to asset dir第一步用-f lambda/pom.xml只对lambda模块执行packagemaven-shade-plugin会生成包含全部依赖的 fat jarlambda-1.0.0-jar-with-dependencies.jar第二步把生成的 jar 覆盖拷贝到asset/目录——这正是MyCustomResource中Code.fromAsset(./asset/...)引用的位置注意该相对路径以java/custom-resource/cdk为基准解析。完成这两步后再执行cdk deploy即可把新的处理器代码部署到 Lambda。运行与清理完整实操闭环综合 README 与 java/README.md完整实操闭环如下# 1. 安装 CDK CLI如未安装 $ npm install -g aws-cdk # 2. 进入示例目录 $ cd java/custom-resource # 3. 编译工程下载依赖 $ mvn compile # 4. 查看 Stack $ cdk ls # 5. 部署 $ cdk deploy # 6. 部署后在输出中查看 ResponseMessage值为 Resource message AWS CDK # 7. 清理资源 $ cdk destroy若需要提前查看将要生成的 CloudFormation 模板或与线上对比可随时执行cdk synth与cdk diff。小结通过这个 Java 示例可以提炼出自定义资源在 CDK 工程中的完整落地模式入口层CustomResourceApp负责组装参数并触发合成Stack 层CustomResourceStack把自定义构造的输出暴露为 CloudFormation 输出构造层MyCustomResource用SingletonFunctionProviderCustomResource封装完整机制对外只暴露业务字段——这是构造化设计、组件化拆分的最佳示范处理器层CustomResourceHandler、CustomResourceIsCompleteHandler按Create/Update/Delete处理生命周期并以Data属性向 CDK 回传业务结果。当你需要把“CloudFormation 覆盖不到的业务逻辑”接入 IaC 编排或想把一段有状态的外部操作封装成可复用组件时可以直接套用本示例的三层骨架。相关代码全部可在仓库中继续研读CustomResourceApp.java、CustomResourceStack.java、MyCustomResource.java以及两个 Lambda 处理器 CustomResourceHandler.java 与 CustomResourceIsCompleteHandler.java。赞分享【免费下载链接】aws-cdk-examplesExample projects using the AWS CDK项目地址https://gitcode.com/gh_mirrors/aw/aws-cdk-examples点击查看免费下载相关推荐QGroundControl 资源覆盖Resource Overrides机制全解析从 URL 拦截器到 Custom 前缀的自定义构建实践QGroundControl 资源覆盖Resource Overrides机制全解析从 URL 拦截器到 Custom 前缀的自定义构建实践 导读 本文面无人机智能硬件TensorFlow Serving 自定义算子Custom Op接入实战从源码链接到模型部署TensorFlow Serving 自定义算子Custom Op接入实战从源码链接到模型部署 本文面向需要在 TensorFlow Serving 中部模型推理服务人工智能后端aws-doc-sdk-examples使用 AWS CDK 与 CloudFormation 部署 DynamoDB Item Tracker 资源aws doc sdk examples使用 AWS CDK 与 CloudFormation 部署 DynamoDB Item Tracker 资源 本指南示例工程教程后端上一篇Jellium Desktop命令行使用教程掌握高效管理Jellyfin客户端的终极指南下一篇微信小程序图片拖拽排序组件完整开发指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑