Cloud Formation并未创建现有的AWS S3存储桶,而是尝试创建存储桶

时间:2020-09-13 11:16:57

标签: amazon-web-services amazon-s3 aws-lambda amazon-cloudformation

我陷入了一个奇怪的问题。我使用以下云形成模板创建了一个AWS S3存储桶:-

AWSTemplateFormatVersion: '2010-09-09'
Metadata: 
  License: Unlicensed
Description: >
  This template creates a global unique S3 bucket in a specific region which is unique. 
  The bucket name is formed by the environment, account id and region

Parameters:
  # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html
  Environment:
    Description: This paramenter will accept the environment details from the user
    Type: String
    Default: sbx
    AllowedValues:
      - sbx
      - dev
      - qa
      - e2e
      - prod
    ConstraintDescription: Invalid environment. Please select one of the given environments only

Resources:
  # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html
  MyS3Bucket:
      Type: AWS::S3::Bucket
      DeletionPolicy: Retain
      Properties: 
        BucketName: !Sub 'global-bucket-${Environment}-${AWS::Region}-${AWS::AccountId}' # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html
        AccessControl: Private                
        LoggingConfiguration:
          DestinationBucketName: !Ref 'LoggingBucket'
          LogFilePrefix:  'access-logs'
        Tags:
          - Key: name
            Value: globalbucket
          - Key: department
            Value: engineering
  LoggingBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Retain
    Properties:
      BucketName: !Sub 'global-loggings-${Environment}-${AWS::Region}-${AWS::AccountId}'
      AccessControl: LogDeliveryWrite      

Outputs:
  GlobalS3Bucket:
    Description: A private S3 bucket with deletion policy as retain and logging configuration
    Value: !Ref MyS3Bucket
    Export:
      Name: global-bucket            

如果您在上面的模板中注明,那么我将在“输出”部分中以名为 global-bucket 的名称导出此S3存储桶。

现在,我的意图是在任何新资源(例如Lambda等)想要一个S3存储桶时,在我的AWS账户中引用此现有存储桶。这是一个使用AWS SAM(无服务器应用程序模型)的示例,我试图创建一个AWS Lambda,并尝试使用属性!ImportValue和导出名称作为global-bucket来引用此现有S3存储桶,如下所示:-

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  hellolambda

  Sample SAM Template for hellolambda
  
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello-world/
      Handler: app.lambdaHandler
      Runtime: nodejs12.x
      Events:
        HelloLambdaEvent:
         Type: S3
         Properties:
            Bucket: !Ref SrcBucket
            Events: s3:ObjectCreated:*
  SrcBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !ImportValue global-bucket

现在,问题是当我执行sam build之类的命令,然后执行sam deploy --guided并选择同一区域(存在我以前的CloudFormation堆栈输出的区域)时,出现以下错误:-

global-bucket-sbx-ap-southeast-1-088853283839已存在于堆栈中arn:aws:cloudformation:ap-southeast-1:088853283839:stack / my-s3-global-bucket / aabd20e0-f57d -11ea-80bf-06f1487f6a64

以下屏幕截图:-

enter image description here

问题在于AWS CloudFormation试图创建S3存储桶,而不是引用现有的存储桶。

但是,如果我尝试更新此SAM模板,然后执行sam deploy,则会出现以下错误:-

正在等待创建变更集。 错误:无法为堆栈创建更改集:my-lambda-stack,例如:Waiter ChangeSetCreateComplete失败:Waiter遇到终端故障状态:FAILED。原因:转换AWS :: Serverless-2016-10-31失败,原因:无效的无服务器应用程序规范文档。发现的错误数量:1. ID为[HelloWorldFunction]的资源无效。 ID为[HelloLambdaEvent]的事件无效。 S3事件必须引用同一模板中的S3存储桶。

我被两端挡住了。如果有人可以协助指导我在Lambda中正确编写SAM模板,以便我可以正确地引用现有存储桶而不是创建新存储桶,我将不胜感激。

谢谢

1 个答案:

答案 0 :(得分:1)

(change)="onisFavoriteChange($event,value)" 下列出的所有项目均指代堆栈负责维护的资源。

当您列出Resources时,您正在要求CloudFormation创建一个新的S3存储桶,其名称为SrcBucket的值,这是您已经创建的S3存储桶的名称。

假设这是存储桶名称,您只需在模板中引用它即可,如下所示。

!ImportValue global-bucket