- 示例工程
- 教程
- 后端
【免费下载链接】aws-doc-sdk-examples
Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.
导读
Photo Asset Manager(PAM,照片资产管理器)是 AWS Code Examples 仓库中的一个跨服务示例应用:它以 React 网站为前端,支持将摄影图片上传至 Amazon S3、通过 Amazon Rekognition 自动完成图片分类,并支持按类别打包下载 ZIP 压缩包。本指南以 cdk/README.md 为核心,结合仓库中applications/photo-asset-manager/cdk/的完整 CDK 源码,讲解如何使用 AWS CDK 将 PAM 全栈应用部署到 AWS 云环境。读完本文,你将掌握 PAM 的三大 CDK 堆栈结构、环境变量配置、按语言选择 Lambda 运行时的策略机制,以及从合成(synth)、部署(deploy)到销毁(destroy)的完整生命周期操作。
PAM 应用与 CDK 工程概览
PAM 的核心业务流程是一条完整的媒体处理流水线:
- React 前端接收用户上传的图片;
- 图片进入 Amazon S3 存储桶;
- S3 对象创建事件触发 AWS Lambda 函数;
- Lambda 调用 Amazon Rekognition 的
DetectLabels完成图片自动分类; - 分类标签写入 DynamoDB;
- 用户按类别发起下载请求,后端打包匹配图片为 ZIP 文件,并通过 SNS 发送通知。
整个基础设施由 cdk 目录 下的 TypeScript CDK 工程定义,包含:
- IAM 用户与用户组:创建并管理部署所需的身份与权限;
- Amazon S3 存储桶:存放上传图片(storage)与临时打包文件(working);
- Amazon DynamoDB 表:存储图片分类标签;
- AWS Lambda 函数:四个函数分别负责图片分类、标签查询、上传与下载打包;
- Amazon API Gateway:为 Lambda 函数提供 REST 路由;
- Amazon Cognito:用户池与 App Client,提供身份认证;
- Amazon CloudFront + S3:托管 React 静态网站;
- Amazon SNS:下载任务完成后的邮件通知;
- 角色与策略:为上述资源授予最小必要权限。
该工程支持使用任意一种 AWS SDK 语言实现来部署,相关语言实现列表可参考仓库根目录 README.md。
环境准备与依赖安装
前置要求
| 依赖 | 用途 |
|---|---|
| git | 获取本仓库代码 |
| npm(Node.js) | 安装 CDK 工程依赖 |
| docker | CDK 的 Docker 镜像打包(bundling)构建 Lambda 代码 |
| AWS 访问密钥与秘密访问密钥 | IAM 用户需具备创建上述资源的权限,配置方式参见 AWS CLI 快速配置文档 |
安装依赖并检查 CDK 版本
进入applications/photo-asset-manager/cdk/目录后安装依赖:
npm install验证 AWS CDK Toolkit 版本:
cdk --version从 package.json 可以看到,工程将aws-cdk2.67.0 作为开发依赖固定,aws-cdk-lib为 ^2.189.1、constructs为 ^10.0.0,app入口为npx ts-node --prefer-ts-exts bin/app.ts(见 cdk.json)。
配置环境变量:PAM_NAME / PAM_EMAIL / PAM_LANG
部署前必须导出三个环境变量,它们是工程命名与运行时选择的核心输入:
| 变量名 | 用途 |
|---|---|
| PAM_NAME | 标识该堆栈的短单词名称(如pam、demo) |
| PAM_EMAIL | 预置默认用户账户的邮箱地址(用于 Cognito 用户创建与 SNS 订阅通知) |
| PAM_LANG | 本部署中 Lambda 函数使用的编程语言 |
README 声明当前支持的 Lambda 语言为Java、Python、Dotnet。结合源码 strategies.ts 中的STRATEGIES注册表,实际可选的键更丰富:java、javascript、python、dotnet、dotnetla(.NET Lambda 注解版)、rust、cpp、php,以及占位用的empty。getStrategy()会对输入做小写化匹配,未知语言回退到EMPTY_LAMBDAS_STRATEGY(空实现,仅用于占位)。
各平台导出语法
bash/zsh:
export PAM_NAME= export PAM_EMAIL= export PAM_LANG=Windows cmd:
set PAM_NAME= set PAM_EMAIL= set PAM_LANG=Windows PowerShell:
$Env:PAM_NAME = $Env:PAM_EMAIL = $Env:PAM_LANG =环境变量的源码级约束
在 common.ts 中,PAM_NAME与PAM_EMAIL通过assert.ok()强制非空,缺失会直接中断程序;PAM_LANG缺省值为"Java"。命名规则如下:
PAM_STACK_NAME = ${PAM_NAME}-${PAM_LANG}-PAM PAM_FE_INFRA_STACK_NAME = ${PAM_NAME}-FE-Infra-PAM PAM_FE_ASSET_STACK_NAME = ${PAM_NAME}-FE-Assets-PAMCognito 用户池域前缀取自PAM_STACK_NAME的小写形式(见 auth.ts),因此PAM_NAME建议使用简短、无特殊字符的单词,避免用户池域名超长或非法。
三个 CDK 堆栈与部署顺序
工程共定义三个堆栈,必须按顺序部署:
| 顺序 | 堆栈名 | 逻辑 ID | 职责 |
|---|---|---|---|
| 1 | PamFrontEndInfraStack | {PAM_NAME}-FE-Infra-PAM | CloudFront 分发与托管静态网站的 S3 桶 |
| 2 | PamStack | {PAM_NAME}-{PAM_LANG}-PAM | 后端资源:Rekognition、Lambda、S3、Cognito、API Gateway、DynamoDB、SNS |
| 3 | PamFrontEndAssetStack | {PAM_NAME}-FE-Assets-PAM | 构建并部署 React 静态网站资源 |
堆栈之间的依赖与数据交换由 bin/app.ts 驱动:应用启动时通过 CloudFormationListExportsCommand拉取已部署堆栈的导出值(CloudFront 域名、Cognito 用户池 ID、App Client ID、API Gateway URL 等)。只有当上一堆栈的导出值存在时,才会实例化下一个堆栈:
- 先无条件创建
PamFrontEndInfraStack; - 拿到
CLOUDFRONT_DISTRIBUTION_NAME导出后,才创建PamStack(后端); - 拿到 Cognito 与 API Gateway 全部导出后,才创建
PamFrontEndAssetStack(前端资源)。
这就是为什么 README 要求严格按 1→2→3 的顺序部署。
合成与部署
列出并合成堆栈
cdk ls会基于你的PAM_NAME与PAM_LANG列出三个堆栈。合成(synth)首个堆栈的 CloudFormation 模板:
cdk synth {PAM_NAME}-FE-Infra-PAM以PAM_NAME=pam为例,实际命令为cdk synth pam-FE-Infra-PAM。
部署
确认模板无误后执行部署。此步骤会真实修改你的 AWS 云环境:
cdk bootstrap # 每个账户只需执行一次 cdk deploy {STACK_NAME} # 按顺序依次部署上述三个堆栈cdk bootstrap用于为当前账户/区域准备部署所需的 S3 桶与角色等引导资源,仅在账户生命周期内需要一次。
前端基础设施堆栈源码要点
infra-stack.ts 中,网站桶设置RemovalPolicy.DESTROY与autoDeleteObjects: true(便于销毁时自动清理),CloudFront 分发将 S3 桶作为默认来源,根对象为index.html。为遵循现代 S3 私有桶最佳实践,该堆栈通过CfnOriginAccessControl创建 OAC(Origin Access Control),并写入s3:GetObject桶策略,StringEquals条件限定为当前 CloudFront 分发的AWS:SourceArn。堆栈最终以CfnOutput导出 CloudFront 域名,供后续堆栈消费。
后端堆栈(PamStack)深入解析
stack.ts 中的PamStack依次组装五个核心构件:PamTables、PamBuckets、SNSTopic(PamNotifier,并通过EmailSubscription订阅PAM_EMAIL)、PamLambda(四函数)与PamApi,最后统一授予权限并导出输出。
存储资源:S3 桶与 DynamoDB 表
resources.ts 定义了:
- storage 桶:开放 CORS 的
PUT方法(allowedOrigins: ["*"]),允许前端直接上传;1 天后转入INTELLIGENT_TIERING智能分层存储; - working 桶:打包工作区,1 天后过期删除(
expiration: Duration.days(1)); - LabelsTable(DynamoDB):分区键
Label(字符串类型),存放标签聚合数据。
两个桶均设置RemovalPolicy.DESTROY与autoDeleteObjects: true,销毁堆栈时自动清空删除。
Lambda 函数与语言策略
lambdas.ts 定义了四个函数,并通过PamLambdasStrategy抽象出“语言无关”的构建方式:
| 函数名 | 职责 | 环境变量 |
|---|---|---|
| DetectLabelsFn | S3 上传触发,调用 Rekognition 分类图片 | LABELS_TABLE_NAME、STORAGE_BUCKET_NAME、WORKING_BUCKET_NAME、NOTIFICATION_TOPIC |
| LabelsFn | 返回标签列表(GET) | 同上 |
| UploadFn | 为前端生成预签名上传 URL(PUT) | 同上 |
| PrepareDownloadFn | 按标签打包 ZIP(POST) | 同上 |
每种语言的策略(strategies.ts)不仅指定运行时与处理器,还通过 CDK 的bundling(容器内打包)能力决定代码资产如何构建:
- Java:
Runtime.JAVA_11,1024 MB 内存 / 90 秒超时;容器内执行mvn install并导出PhotoAssetRestSDK-1.0-SNAPSHOT.jar,源码来自 javav2/usecases/pam_source_files; - Python:
Runtime.PYTHON_3_9,512 MB 内存 / 60 秒超时;直接使用 cdk/rekognition_photo_analyzer 目录作为代码资产; - Dotnet:
Runtime.DOTNET_6,1024 MB / 90 秒;容器内安装Amazon.Lambda.Tools并执行dotnet lambda package,源码来自 dotnetv3/cross-service/PhotoAssetManager; - Dotnet(注解版 dotnetla):同 Dotnet,但打包
PamApiAnnotations项目,使用Functions_GetLabels_Generated等注解生成的处理器; - JavaScript:
Runtime.NODEJS_18_X,256 MB / 5 分钟;容器内npm i && npm run build,源码来自 javascriptv3/example_code/cross-services/photo-asset-manager; - Rust:
Runtime.PROVIDED_AL2+Architecture.ARM_64;通过宿主机cargo lambda build --release --arm64 --output-format Zip交叉编译,引用 rustv1/cross_service/photo_asset_management; - C++:
Runtime.PROVIDED_AL2+Architecture.ARM_64;使用Code.fromDockerBuild从 cpp/example_code/cross-service/photo_asset_manager 构建; - PHP:
Runtime.PROVIDED_AL2+X86_64;直接引用 php/applications/photo_asset_manager 下预构建的bootstrap.zip。
权限授予与事件触发
PamStack.permissions()(stack.ts)集中处理权限与触发:
- DetectLabelsFn 通过
LambdaDestination订阅 storage 桶的.jpg与.jpeg后缀对象创建事件;授予rekognition:DetectLabels、LabelsTable 读写、storage 桶读写权限; - LabelsFn 授予 LabelsTable 读权限;
- UploadFn 授予 storage 桶
PutObject(grantPut)权限; - PrepareDownloadFn 授予 LabelsTable 读、storage 读、working 读写、SNS 发布及
sns:subscribe权限。
四个堆栈输出(Cognito 用户池 ID、App Client ID、用户池 Base URL、API Gateway URL)通过CfnOutput以exportName导出。
认证与 API:Cognito + API Gateway
auth.ts 创建 Cognito 用户池:最小密码策略(6 位、无强制复杂度)、关闭 MFA、关闭自助注册、RemovalPolicy.DESTROY;用户池域前缀取PAM_STACK_NAME小写。App Client 配置 OAuth 隐式授权流(implicitCodeGrant),回调与登出 URL 均指向 CloudFront 域名,Scope 为profile与openid。同时通过CfnUserPoolUser预置一个默认用户,用户名即PAM_EMAIL。
api.ts 构建 API Gateway REST API,使用CognitoUserPoolsAuthorizer对全部路由启用AuthorizationType.COGNITO,并开启全源 CORS 预检。路由与 Lambda 的映射关系:
| 路由 | 方法 | 后端 Lambda | 说明 |
|---|---|---|---|
/labels | GET | LabelsFn | 返回标签聚合列表 |
/upload | PUT | UploadFn | 请求体含file_name,返回预签名上传url |
/download | POST | PrepareDownloadFn | 请求体为labels数组,以异步事件方式调用 |
/download使用非代理集成并注入X-Amz-Invocation-Type: 'Event'头,使 API Gateway 以异步事件方式触发 Lambda,避免客户端长时间等待打包过程。请求/响应模型定义在 api_models.ts(JSON Schema Draft4):LabelsResponseModel的labels为标签到count的映射、UploadRequestModel含file_name、UploadResponseModel返回url、DownloadRequestModel的labels为字符串数组。
以 Python 为例的图片分类 Lambda
rekognition_photo_analyzer/rekfunction.py 展示了 DetectLabelsFn 的完整逻辑:从 S3 事件取对象 key,调用rekognition.detect_labels(Image=..., MaxLabels=10, MinConfidence=70),将标签 JSON 写入 storage 桶的results/目录,并把image_name → labels写入 DynamoDB。该文件是理解“S3 事件 → Rekognition 分类 → 结果持久化”链路的最小可读样本。
前端资源堆栈(PamFrontEndAssetStack)
asset-stack.ts 做两件事:
- 生成前端
.env:根据上一堆栈的导出值写入 elros-pam 目录下的.env文件:
VITE_COGNITO_USER_POOL_ID=... VITE_COGNITO_USER_POOL_CLIENT_ID=... VITE_API_GATEWAY_BASE_URL=... VITE_COGNITO_SIGN_IN_URL=${userPoolBaseUrl}/oauth2/authorize?response_type=token&client_id=...&redirect_uri=https://${cloudfrontUrl} VITE_COGNITO_SIGN_OUT_URL=${userPoolBaseUrl}/logout?client_id=...&logout_uri=https://${cloudfrontUrl}- 构建并部署静态资源:通过
BucketDeployment+ Docker 容器(node:18)执行npm i && npm run build,将构建产物(dist/*)同步到前端基础设施堆栈创建的 S3 桶,由 CloudFront 对外提供。
测试与验证
完成PamFrontEndInfraStack部署后,终端会输出 CloudFront 分发 URL。直接访问该 URL 即可看到部署后的 PAM Web 应用;登录账号即PAM_EMAIL对应的预置默认用户。测试路径可参考应用整体说明 applications/photo-asset-manager/README.md。
清理资源
按创建顺序的逆序销毁三个堆栈,逐个执行:
cdk destroy {STACK_NAME}即依次销毁PamFrontEndAssetStack→PamStack→PamFrontEndInfraStack。由于桶与用户池均设置了RemovalPolicy.DESTROY与autoDeleteObjects,销毁时会自动清空对象,避免残留计费资源。
常用 CDK 命令速查
| 命令 | 作用 |
|---|---|
cdk ls | 基于你的名称与编程语言列出堆栈 |
cdk deploy | 将堆栈部署到默认 AWS 账户/区域 |
cdk diff | 对比已部署堆栈与当前状态的差异 |
cdk synth | 生成(emit)合成的 CloudFormation 模板 |
cdk bootstrap | 首次部署前为账户初始化引导资源 |
cdk destroy | 销毁指定堆栈 |
小结
PAM 的 CDK 工程是一个典型的“前后端分离 + 事件驱动”全栈示例:前端由 CloudFront + S3 托管,后端由 S3 事件触发 Lambda + Rekognition 分类 + DynamoDB 索引 + API Gateway 鉴权 + SNS 通知组成。三个堆栈通过 CloudFormation 导出值顺序衔接,Lambda 实现则通过策略模式(PamLambdasStrategy)解耦为 Java、Python、.NET、JavaScript、Rust、C++、PHP 等多种语言,直观演示了同一套基础设施定义如何对接不同 SDK 语言实现。如果你希望深入扩展,可以继续阅读 SPECIFICATION.md、DESIGN.md 与 DEVELOPMENT.md 了解该应用的设计与开发细节。
- 示例工程
- 教程
- 后端
【免费下载链接】aws-doc-sdk-examples
Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.
相关推荐
MaaAssistantArknights 库存保持(Depot Maintain)全指南:从计划配置到智能理智判定的源码级解读
MaaAssistantArknights 库存保持(Depot Maintain)全指南:从计划配置到智能理智判定的源码级解读 库存保持是《明日方舟》小助手
示例工程教程后端使用 AWS CDK 部署 Chalice 应用:构建 REST API + DynamoDB 完整实战指南
使用 AWS CDK 部署 Chalice 应用:构建 REST API + DynamoDB 完整实战指南 导读 本文以 Chalice 官方 CDK 教程为
后端云原生为 Photo Asset Manager(PAM)新增语言实现:AWS CDK 部署策略与 Lambda 开发指南
为 Photo Asset Manager(PAM)新增语言实现:AWS CDK 部署策略与 Lambda 开发指南 Photo Asset Managemen
示例工程教程后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考