aws-cdk - 如何在 aws cdk 中使用自定义资源将文件上传到 s3 存储桶
问题描述
创建后,我需要将 zip 文件上传到 s3 存储桶。我知道 s3_deployment 包,但它不适合我的用例,因为我需要在堆栈创建时只上传一次文件。s3_deployment 包会在每次更新时上传 zip。
我定义了以下自定义资源,但是我不确定如何将文件主体传递给自定义资源。我尝试以二进制模式打开文件,但返回错误。
app_data_bootstrap = AwsCustomResource(self, "BootstrapData",
on_create={
"service": "S3",
"action": "putObject",
"parameters": {
"Body": open('app_data.zip', 'rb'),
"Bucket": f"my-app-data",
"Key": "app_data.zip",
},
"physical_resource_id": PhysicalResourceId.of("BootstrapDataBucket")
},
policy=AwsCustomResourcePolicy.from_sdk_calls(resources=AwsCustomResourcePolicy.ANY_RESOURCE)
)
解决方案
我认为这是不可能的,除非您编写自定义脚本并在cdk deploy
将本地文件上传到中间 S3 存储桶之前运行。然后,您可以编写一个自定义资源,将事件中的中间存储桶的内容复制on_create
到通过 CDK 创建的存储桶。
s3_deployment
从CDK 文档中阅读此段落:
这就是幕后发生的事情:
部署此堆栈时(通过 cdk deploy 或通过 CI/CD),本地 website-dist 目录的内容将被存档并上传到中间资产存储桶。如果有多个来源,它们将被单独上传。
BucketDeployment 构造将 Custom::CDKBucketDeployment 类型的自定义 CloudFormation 资源综合到模板中。源存储桶/键设置为指向资产存储桶。
自定义资源下载 .zip 存档,将其解压缩并针对目标存储桶(在本例中为 websiteBucket)发出 aws s3 sync --delete。如果有多个源,则将在此步骤下载源并在部署前合并。
因此,为了复制第 1 步,您必须编写一个小脚本来创建中间存储桶并将本地文件上传到其中。该脚本的示例可以是这样的:
#!/bin/sh
aws s3 mb <intermediary_bucket> --region <region_name>
aws s3 sync <intermediary_bucket> s3://<your_bucket_name>
然后你的自定义资源可以是这样的:
*请注意,这适用于复制一个对象,您可以更改代码以复制多个对象。
import json
import boto3
import cfnresponse
def lambda_handler(event, context):
print('Received request:\n%s' % json.dumps(event, indent=4))
resource_properties = event['ResourceProperties']
if event['RequestType'] in ['Create']: #What happens when resource is created
try:
s3 = boto3.resource('s3')
copy_source = {
'Bucket': 'intermediary_bucket',
'Key': 'path/to/filename.extension'
}
bucket = s3.Bucket('otherbucket')
obj = bucket.Object('otherkey')
obj.copy(copy_source)
except:
cfnresponse.send(event, context, cfnresponse.FAILED, {})
raise
else:
cfnresponse.send(event, context, cfnresponse.SUCCESS,
{'FileContent': response['fileContent'].decode('utf-8')})
elif event['RequestType'] == 'Delete': # What happens when resource is deleted
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
所有这一切的替代方法是在 AWS CDK 的Github 存储库中打开一个问题,并要求他们添加您的用例。
推荐阅读
- android - Xamarin.android 未从 Play 商店中的生产加载
- python - time.sleep、Flask 和 I/O 等待
- html - 我有两个重叠的 div
- angular - 在业力测试运行期间从编译中排除文件
- bash - 如何使用 cat 小写 bash 中的大文件?
- c# - SSIS 导入多个文件并创建表
- powershell - PowerShell Active Directory 导入脚本在 PS 3.0 或更高版本中失败
- django - 如何在 React App 中实现消息通知?
- react-native - React Native Button:适合文本布局
- scala - 使用 Spark collectionAccumulator 时出现 ConcurrentModificationException