Wie verwende ich benutzerdefinierte Ressourcen mit Amazon S3-Buckets in CloudFormation?
Ich möchte benutzerdefinierte Ressourcen mit Amazon Simple Storage Service (Amazon S3)-Buckets in AWS CloudFormation verwenden.
Lösung
CloudFormation-Vorlagen verwenden von AWS Lambda unterstützte benutzerdefinierte Ressourcen. Wenn Sie eine CloudFormation-Vorlage für benutzerdefinierte Ressourcen mit einem S3-Bucket verwenden, können Sie die folgenden Aktionen ausführen:
- Die Vorlage verwenden, um Ordner in S3-Buckets zu erstellen.
- Die Vorlage verwenden, um Inhalte in Buckets zu kopieren, hochzuladen oder zwischen zwei Buckets zu synchronisieren, nachdem Sie einen S3-Bucket erstellt haben.
- Die Vorlage mit Ihrem eigenen Code ändern.
Hinweis: In der folgenden Lösung löscht Amazon S3 den gesamten Inhalt des S3-Buckets, wenn Sie den CloudFormation-Stack löschen. Um dieses Verhalten zu ändern, müssen Sie den Lambda-Code ändern.
Abrufen der CloudFormation-Vorlage
Um benutzerdefinierte Ressourcen mit einem Amazon-S3-Bucket zu verwenden, speichern Sie die folgende JSON- oder YAML-Vorlage als Datei.
JSON:
{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Working with custom resources and S3", "Parameters": { "S3BucketName": { "Type": "String", "Description": "S3 bucket to create.", "AllowedPattern": "[a-zA-Z][a-zA-Z0-9_-]*" }, "DirsToCreate": { "Description": "Comma delimited list of directories to create.", "Type": "CommaDelimitedList" } }, "Resources": { "SampleS3Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "BucketName": {"Ref":"S3BucketName"} } }, "S3CustomResource": { "Type": "Custom::S3CustomResource", "DependsOn":"AWSLambdaExecutionRole", "Properties": { "ServiceToken": {"Fn::GetAtt": ["AWSLambdaFunction","Arn"]}, "the_bucket": {"Ref":"SampleS3Bucket"}, "dirs_to_create": {"Ref":"DirsToCreate"} } }, "AWSLambdaFunction": { "Type": "AWS::Lambda::Function", "Properties": { "Description": "Work with S3 Buckets!", "FunctionName": {"Fn::Sub":"${AWS::StackName}-${AWS::Region}-lambda"}, "Handler": "index.handler", "Role": {"Fn::GetAtt": ["AWSLambdaExecutionRole","Arn"]}, "Timeout": 360, "Runtime": "python3.9", "Code": { "ZipFile": "import boto3\r\nimport cfnresponse\r\ndef handler(event, context):\r\n # Init ...\r\n the_event = event['RequestType']\r\n print(\"The event is: \", str(the_event))\r\n response_data = {}\r\n s_3 = boto3.client('s3')\r\n # Retrieve parameters\r\n the_bucket = event['ResourceProperties']['the_bucket']\r\n dirs_to_create = event['ResourceProperties']['dirs_to_create']\r\n try:\r\n if the_event in ('Create', 'Update'):\r\n print(\"Requested folders: \", str(dirs_to_create))\r\n for dir_name in dirs_to_create:\r\n print(\"Creating: \", str(dir_name))\r\n s_3.put_object(Bucket=the_bucket,\r\n Key=(dir_name\r\n + '\/'))\r\n elif the_event == 'Delete':\r\n print(\"Deleting S3 content...\")\r\n b_operator = boto3.resource('s3')\r\n b_operator.Bucket(str(the_bucket)).objects.all().delete()\r\n # Everything OK... send the signal back\r\n print(\"Operation successful!\")\r\n cfnresponse.send(event,\r\n context,\r\n cfnresponse.SUCCESS,\r\n response_data)\r\n except Exception as e:\r\n print(\"Operation failed...\")\r\n print(str(e))\r\n response_data['Data'] = str(e)\r\n cfnresponse.send(event,\r\n context,\r\n cfnresponse.FAILED,\r\n response_data)" } } }, "AWSLambdaExecutionRole": { "Type": "AWS::IAM::Role", "Properties": { "AssumeRolePolicyDocument": { "Statement": [ { "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Principal": { "Service": [ "lambda.amazonaws.com" ] } } ], "Version": "2012-10-17" }, "Path": "/", "Policies": [ { "PolicyDocument": { "Statement": [ { "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Effect": "Allow", "Resource": "arn:aws:logs:*:*:*" } ], "Version": "2012-10-17" }, "PolicyName": {"Fn::Sub": "${AWS::StackName}-${AWS::Region}-AWSLambda-CW"} }, { "PolicyDocument": { "Statement": [ { "Action": [ "s3:PutObject", "s3:DeleteObject", "s3:List*" ], "Effect": "Allow", "Resource": [ {"Fn::Sub": "arn:aws:s3:::${SampleS3Bucket}/*"}, {"Fn::Sub": "arn:aws:s3:::${SampleS3Bucket}"} ] } ], "Version": "2012-10-17" }, "PolicyName": {"Fn::Sub":"${AWS::StackName}-${AWS::Region}-AWSLambda-S3"} } ], "RoleName": {"Fn::Sub":"${AWS::StackName}-${AWS::Region}-AWSLambdaExecutionRole"} } } } }
YAML:
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AWSTemplateFormatVersion: 2010-09-09 Description: Working with custom resources and S3 Parameters: S3BucketName: Type: String Description: "S3 bucket to create." AllowedPattern: "[a-zA-Z][a-zA-Z0-9_-]*" DirsToCreate: Description: "Comma delimited list of directories to create." Type: CommaDelimitedList Resources: SampleS3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref S3BucketName S3CustomResource: Type: Custom::S3CustomResource Properties: ServiceToken: !GetAtt AWSLambdaFunction.Arn the_bucket: !Ref SampleS3Bucket dirs_to_create: !Ref DirsToCreate AWSLambdaFunction: Type: "AWS::Lambda::Function" Properties: Description: "Work with S3 Buckets!" FunctionName: !Sub '${AWS::StackName}-${AWS::Region}-lambda' Handler: index.handler Role: !GetAtt AWSLambdaExecutionRole.Arn Timeout: 360 Runtime: python3.9 Code: ZipFile: | import boto3 import cfnresponse def handler(event, context): # Init ... the_event = event['RequestType'] print("The event is: ", str(the_event)) response_data = {} s_3 = boto3.client('s3') # Retrieve parameters the_bucket = event['ResourceProperties']['the_bucket'] dirs_to_create = event['ResourceProperties']['dirs_to_create'] try: if the_event in ('Create', 'Update'): print("Requested folders: ", str(dirs_to_create)) for dir_name in dirs_to_create: print("Creating: ", str(dir_name)) s_3.put_object(Bucket=the_bucket, Key=(dir_name + '/')) elif the_event == 'Delete': print("Deleting S3 content...") b_operator = boto3.resource('s3') b_operator.Bucket(str(the_bucket)).objects.all().delete() # Everything OK... send the signal back print("Operation successful!") cfnresponse.send(event, context, cfnresponse.SUCCESS, response_data) except Exception as e: print("Operation failed...") print(str(e)) response_data['Data'] = str(e) cfnresponse.send(event, context, cfnresponse.FAILED, response_data) AWSLambdaExecutionRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - lambda.amazonaws.com Version: '2012-10-17' Path: "/" Policies: - PolicyDocument: Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:PutLogEvents Effect: Allow Resource: arn:aws:logs:*:*:* Version: '2012-10-17' PolicyName: !Sub ${AWS::StackName}-${AWS::Region}-AWSLambda-CW - PolicyDocument: Statement: - Action: - s3:PutObject - s3:DeleteObject - s3:List* Effect: Allow Resource: - !Sub arn:aws:s3:::${SampleS3Bucket}/* - !Sub arn:aws:s3:::${SampleS3Bucket} Version: '2012-10-17' PolicyName: !Sub ${AWS::StackName}-${AWS::Region}-AWSLambda-S3 RoleName: !Sub ${AWS::StackName}-${AWS::Region}-AWSLambdaExecutionRole
Bereitstellen Ihrer CloudFormation-Vorlage
Verwenden Sie die CloudFormation-Konsole oder AWS Command Line Interface (AWS CLI), um Ihre CloudFormation-Vorlage bereitzustellen.
**Hinweis:**Wenn Sie beim Ausführen von Befehlen in AWS CLI Fehlermeldungen erhalten, finden Sie weitere Informationen unter Troubleshooting errors for the AWS CLI. Stellen Sie außerdem sicher, dass Sie die neueste Version von AWS CLI verwenden.
Gehen Sie wie folgt vor, um die CloudFormation-Konsole zu verwenden:
- Öffnen Sie die CloudFormation-Konsole.
- Wählen Sie Stack erstellen und dann Mit neuen Ressourcen (Standard) aus.
- Wählen Sie unter Vorlage angeben die Option Vorlagendatei hochladen aus.
- Klicken Sie auf Datei auswählen, wählen Sie die heruntergeladene Vorlage aus und klicken Sie dann auf Weiter.
- Geben Sie in Parameter für S3BucketName einen Namen für den neuen S3-Bucket an.
- Geben Sie für DirsToCreate eine durch Kommas getrennte Liste von Ordnern und Unterordnern ein, die Sie erstellen möchten.
Hinweis: Sie können beispielsweise dir_1,dir_2/sub_dir_2,dir_3 als Liste eingeben. - Führen Sie die verbleibenden Schritte im Einrichtungsassistenten aus und wählen Sie dann Stack erstellen.
Gehen Sie in AWS CLI wie folgt vor:
- Benennen Sie die heruntergeladene Vorlage in custom-resource-lambda-s3.template um.
- Öffnen Sie eine Befehlszeile in Ihrem Betriebssystem und navigieren Sie zu dem Ordner, in dem Sie die Vorlage gespeichert haben.
- Um die Vorlage bereitzustellen, führen Sie den Befehl create-stack aus:
Hinweis: Ersetzen Sie custom-resource-lambda-s3.template durch Ihre Vorlage, test-bucket-custom-resource durch den S3-Bucket-Namen und dir_1\,dir_2/sub_dir_2\,dir_3 durch die Liste der Ordner und Unterordner, die Sie erstellen möchten.aws cloudformation create-stack \ --timeout-in-minutes 10 \ --disable-rollback \ --stack-name testing-custom-resource-s3 \ --template-body file://custom-resource-lambda-s3.template \ --capabilities CAPABILITY_NAMED_IAM \ --parameters \ ParameterKey=DirsToCreate,ParameterValue="dir_1\,dir_2/sub_dir_2\,dir_3" \ ParameterKey=S3BucketName,ParameterValue="test-bucket-custom-resource"
Verwandte Informationen
Relevanter Inhalt
- AWS OFFICIALAktualisiert vor 2 Monaten
- AWS OFFICIALAktualisiert vor 2 Jahren