我能够使用cloudformation创建一个S3存储桶,但想在S3存储桶中创建一个文件夹。比如
<mybucket>--><myfolder>
请告诉我用于在存储桶中创建文件夹的模板......两者都应该在同一时间创建...
我使用AWS lambda如下
stackname = 'myStack'
client = boto3.client('cloudformation')
response = client.create_stack(
StackName= (stackname),
TemplateURL= 'https://s3.amazonaws.com/<myS3bucket>/<myfolder>/nestedstack.json',
Parameters=<params>
)
答案 0 :(得分:17)
AWS未提供正式的CloudFormation资源来在S3存储桶中创建对象。但是,您可以使用AWS SDK创建Lambda-backed Custom Resource来执行此功能,实际上gilt/cloudformation-helpers GitHub存储库提供了现成的自定义资源。
与任何自定义资源设置一样有点冗长,因为您需要首先部署Lambda函数和IAM权限,然后将其作为堆栈模板中的自定义资源引用。
首先,将Lambda::Function
和关联的IAM::Role
资源添加到您的堆栈模板中:
"S3PutObjectFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Version" : "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [ "lambda.amazonaws.com" ]
},
"Action": [ "sts:AssumeRole" ]
}
]
},
"ManagedPolicyArns": [
{ "Ref": "RoleBasePolicy" }
],
"Policies": [
{
"PolicyName": "S3Writer",
"PolicyDocument": {
"Version" : "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:DeleteObject",
"s3:ListBucket",
"s3:PutObject"
],
"Resource": "*"
}
]
}
}
]
}
},
"S3PutObjectFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "com.gilt.public.backoffice",
"S3Key": "lambda_functions/cloudformation-helpers.zip"
},
"Description": "Used to put objects into S3.",
"Handler": "aws/s3.putObject",
"Role": {"Fn::GetAtt" : [ "S3PutObjectFunctionRole", "Arn" ] },
"Runtime": "nodejs",
"Timeout": 30
},
"DependsOn": [
"S3PutObjectFunctionRole"
]
},
然后,您可以使用Lambda函数作为自定义资源来创建S3对象:
"MyFolder": {
"Type": "Custom::S3PutObject",
"Properties": {
"ServiceToken": { "Fn::GetAtt" : ["S3PutObjectFunction", "Arn"] },
"Bucket": "mybucket",
"Key": "myfolder/"
}
},
除了Body
和Bucket
之外,您还可以通过添加Key
参数来使用相同的自定义资源来编写基于字符串的S3对象(请参阅docs )。
答案 1 :(得分:11)
使用AWS CloudFormation模板无法做到这一点。
应该提到的是,文件夹在Amazon S3中实际上并不存在。而是将对象的路径添加到对象的名称(key
)之前。
因此,存储在名为bar.txt
的文件夹中的文件foo
实际上存储的密钥为:foo/bar.txt
您还可以将文件复制到不存在的文件夹,并自动创建文件夹(实际上并非如此,因为文件夹本身不存在)。但是,管理控制台将提供此类文件夹的外观,并且路径将建议将其存储在此类文件夹中。
底线:无需预先创建文件夹。只要使用就好像它已经存在一样。
答案 2 :(得分:0)
我们(至少到目前为止)无法在s3存储桶中创建子文件夹。
您可以尝试使用以下命令:
aws s3 mb s3://yavdhesh-bucket/inside-folder
然后尝试使用命令列出存储桶中的所有文件夹:
aws s3 ls s3://yavdhesh-bucket
您会发现未创建子文件夹。
只有一种创建子文件夹的方法,即通过在不存在的子文件夹或子目录(相对于存储桶)中创建/复制文件
例如,
aws s3 cp demo.txt s3://yavdhesh-bucket/inside-folder/
现在,如果您列出子文件夹中的文件,它应该可以工作。
aws s3 ls s3://yavdhesh-bucket/inside-folder/
它应该列出该子文件夹中存在的所有文件。
希望有帮助。
答案 3 :(得分:0)
我最终得到了一个小的python脚本。它应该手动运行,但是会自动同步。适用于不想创建Lambda支持的自定义资源的懒惰人。
import subprocess
import json
STACK_NAME = ...
S3_RESOURCE = <name of your s3 resource, as in CloudFormation template file>
LOCAL_DIR = <path of your local dir>
res = subprocess.run(
['aws', 'cloudformation', 'describe-stack-resource', '--stack-name', STACK_NAME, '--logical-resource-id', S3_RESOURCE],
capture_output=True,
)
out = res.stdout.decode('utf-8')
resource_details = json.loads(out)
resource_id = resource_details['StackResourceDetail']['PhysicalResourceId']
res = subprocess.run(
['aws', 's3', 'sync', LOCAL_DIR, f's3://{resource_id}/', '--acl', 'public-read']
)