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

如何在CDK中当源文件变更时强制触发BucketDeployment部署?

解决S3 BucketDeployment源文件变更不触发部署的问题

方法1:利用源对象ETag触发更新

CDK的BucketDeployment默认不会主动跟踪S3源对象的内容变化,我们可以通过获取源文件的ETag(文件哈希标识),将其作为部署资源的元数据,让CDK在合成模板时检测到变化,从而触发重新部署。

代码示例:

import boto3
from aws_cdk import aws_s3_deployment as s3_deploy

# 假设src_bucket和dest_bucket已提前定义
s3_client = boto3.client('s3')
# 获取dist.zip的ETag,去除返回结果自带的引号
src_obj_info = s3_client.head_object(Bucket=src_bucket.bucket_name, Key="dist.zip")
source_etag = src_obj_info['ETag'].strip('"')

# 创建BucketDeployment
deployment = s3_deploy.BucketDeployment(
    self,
    "UploadFrontendFromMainBucket",
    sources=[
        s3_deploy.Source.bucket(
            src_bucket,
            zip_object_key="dist.zip",
        )
    ],
    destination_bucket=dest_bucket,
    destination_key_prefix="/",
    extract=True,
    retain_on_delete=self._deployto != "tst",
    prune=False,
)

# 添加ETag作为元数据,让CDK感知源文件变化
deployment.node.add_metadata("source-dist-zip-etag", source_etag)
deployment.node.add_dependency(api, dest_bucket)

当源dist.zip更新时,ETag会随之改变,CDK合成模板时会检测到元数据的差异,自动触发重新部署。

方法2:启用源桶版本控制并使用版本ID

如果源存储桶开启了版本控制,可以获取dist.zip的最新版本ID,将其传入Source.bucket的object_version参数。每次文件更新都会生成新的版本ID,CDK会自动识别并触发部署。

代码示例:

import boto3
from aws_cdk import aws_s3_deployment as s3_deploy

# 假设源桶已开启版本控制
s3_client = boto3.client('s3')
src_obj_info = s3_client.head_object(Bucket=src_bucket.bucket_name, Key="dist.zip")
latest_version_id = src_obj_info['VersionId']

deployment = s3_deploy.BucketDeployment(
    self,
    "UploadFrontendFromMainBucket",
    sources=[
        s3_deploy.Source.bucket(
            src_bucket,
            zip_object_key="dist.zip",
            object_version=latest_version_id  # 指定最新版本ID
        )
    ],
    destination_bucket=dest_bucket,
    destination_key_prefix="/",
    extract=True,
    retain_on_delete=self._deployto != "tst",
    prune=False,
)
deployment.node.add_dependency(api, dest_bucket)

方法3:用自定义资源动态检测变化

如果不想在CDK合成阶段提前获取ETag(比如担心权限或需要动态检测),可以通过自定义资源(CustomResource)在部署阶段检查源文件ETag,让BucketDeployment依赖该资源。当ETag变化时,自定义资源更新,触发部署重新运行。

核心逻辑:

  1. 编写一个Lambda函数,负责调用S3 API获取dist.zip的ETag
  2. 创建CDK自定义资源,关联该Lambda函数
  3. 让BucketDeployment依赖这个自定义资源

代码示例(简化版):

from aws_cdk import custom_resources as cr

# 创建自定义资源的Lambda提供者(需提前定义Lambda函数实现ETag获取逻辑)
etag_provider = cr.Provider(
    self,
    "SourceETagProvider",
    on_event_handler=get_etag_lambda  # get_etag_lambda是已定义的Lambda函数
)

# 创建自定义资源获取ETag
source_etag_resource = cr.CustomResource(
    self,
    "SourceDistZipETag",
    service_token=etag_provider.service_token,
    properties={
        "BucketName": src_bucket.bucket_name,
        "Key": "dist.zip"
    }
)

# 让部署任务依赖自定义资源
deployment.node.add_dependency(source_etag_resource)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 13:55:17