簡體   English   中英

CloudFormation 為現有 s3 存儲桶添加觸發器

[英]CloudFormation add trigger for existing s3 bucket

我的目標是將在每個圖像上傳到存儲桶時調用的 lambda 代碼打包到 CloudFormation 模板中。 到目前為止,我已經實現了創建新資源並從頭開始觸發,但是我有現有的存儲桶,我需要在其中添加觸發器並在 2 種情況下得到錯誤:

  1. 當我創建 lambda 並在一個模板中觸發配置並嘗試將堆棧創建為新資源時 - 它說存儲桶已經存在
  2. 當我將觸發器移動到新文件時 - 首先像 1. 一樣創建新資源,然后將現有資源導入堆棧 - 我得到:

創建此更改集時出錯

您修改了模板中未導入的資源 [ScaleImages, ScaleImagesRole]。 在導入操作期間不能執行更新、創建或刪除操作。

我的模板看起來像:

  • lambda 創建 - 新 lambda 和角色 - 使用新資源創建堆棧
    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Resources": {
        "ScaleImages": {
          "Type": "AWS::Lambda::Function",
          "DeletionPolicy": "Retain",
          "Properties": {
            "FunctionName": "ScaleImages",
            "Handler": "index.handler",
            "Role": {
              "Fn::GetAtt": [
                "ScaleImagesRole",
                "Arn"
              ]
            },
            "Code": {
              "S3Bucket": "example-test",
              "S3Key": "example-resize.zip"
            },
            "Runtime": "nodejs12.x",
            "MemorySize": 1024,
            "Timeout": 300
          }
        },
        "ScaleImagesRole": {
          "Type": "AWS::IAM::Role",
          "DeletionPolicy": "Retain",
          "Properties": {
            "RoleName": "ScaleImagesRole",
            "AssumeRolePolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Principal": {
                    "Service": [
                      "lambda.amazonaws.com"
                    ]
                  },
                  "Action": [
                    "sts:AssumeRole"
                  ]
                }
              ]
            },
            "Path": "/",
            "Policies": [
              {
                "PolicyName": "AWSLambdaBasicExecutionRole",
                "PolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                    {
                      "Effect": "Allow",
                      "Action": [
                        "logs:CreateLogGroup",
                        "logs:CreateLogStream",
                        "logs:PutLogEvents"
                      ],
                      "Resource": "*"
                    }
                  ]
                }
              },
              {
                "PolicyName": "AmazonS3FullAccess",
                "PolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                    {
                      "Effect": "Allow",
                      "Action": "s3:*",
                      "Resource": [
                        "arn:aws:s3:::example-test",
                        "arn:aws:s3:::example-test/*",
                        "arn:aws:s3:::example-test-output",
                        "arn:aws:s3:::example-test-output/*"
                      ]
                    }
                  ]
                }
              }
            ]
          }
        }
      }
    }
  • 添加觸發器 - 存儲桶存在 - 導入資源
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "PutOriginalImage": {
      "Type": "AWS::S3::Bucket",
      "DeletionPolicy": "Retain",
      "Properties": {
        "BucketName": "example-test",
        "NotificationConfiguration": {
          "LambdaConfigurations": [
            {
              "Event": "s3:ObjectCreated:Put",
              "Filter": {
                "S3Key": {
                  "Rules": [
                    {
                      "Name": "prefix",
                      "Value": "original2/"
                    }
                  ]
                }
              },
              "Function": {
                "Fn::GetAtt": [
                  "ScaleImages",
                  "Arn"
                ]
              }
            }
          ]
        }
      }
    }
  }
}

在最后一個我也試過"Function": "ScaleImages" ,但在這兩種情況下我都有同樣的錯誤:

修改模板中的資源 [ScaleImages, ScaleImagesRole]

有人可以闡明我做錯了什么嗎?

您必須分階段進行

1.創建新堆棧

還沒有存儲桶,只需堆疊您缺少的 function 和lambda 權限即可。

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Resources": {
        "ScaleImages": {
          "Type": "AWS::Lambda::Function",
          "Properties": {
            "FunctionName": "ScaleImages",
            "Handler": "index.handler",
            "Role": {
              "Fn::GetAtt": [
                "ScaleImagesRole",
                "Arn"
              ]
            },
            "Code": {
              "S3Bucket": "example-test",
              "S3Key": "example-resize.zip"
            },
            "Runtime": "nodejs12.x",
            "MemorySize": 1024,
            "Timeout": 300
          }
        },
        "ScaleImagesRole": {
          "Type": "AWS::IAM::Role",
          "Properties": {
            "RoleName": "ScaleImagesRole",
            "AssumeRolePolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Principal": {
                    "Service": [
                      "lambda.amazonaws.com"
                    ]
                  },
                  "Action": [
                    "sts:AssumeRole"
                  ]
                }
              ]
            },
            "Path": "/",
            "Policies": [
              {
                "PolicyName": "AWSLambdaBasicExecutionRole",
                "PolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                    {
                      "Effect": "Allow",
                      "Action": [
                        "logs:CreateLogGroup",
                        "logs:CreateLogStream",
                        "logs:PutLogEvents"
                      ],
                      "Resource": [
                        "arn:aws:s3:::example-test",
                        "arn:aws:s3:::example-test/*",
                        "arn:aws:s3:::example-test-output",
                        "arn:aws:s3:::example-test-output/*"
                      ]
                    }
                  ]
                }
              },
              {
                "PolicyName": "AmazonS3FullAccess",
                "PolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                    {
                      "Effect": "Allow",
                      "Action": "s3:*",
                      "Resource": "*"
                    }
                  ]
                }
              }
            ]
          }
        },


"s3Permission": {
    "Type": "AWS::Lambda::Permission",
    "Properties": {
        "FunctionName": {
            "Fn::GetAtt": [
                "ScaleImages",
                "Arn"
            ]
        },
        "Action": "lambda:InvokeFunction",
        "Principal": "s3.amazonaws.com",
        "SourceAccount": {
            "Ref": "AWS::AccountId"
        }
    }
}



      }
    }

2. 將bucket導入現有stack

使用將Import resources into stack選項並使用此模板上傳堆棧。 它添加了存儲桶,但還沒有通知

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Resources": {
        "ScaleImages": {
          "Type": "AWS::Lambda::Function",
          "Properties": {
            "FunctionName": "ScaleImages",
            "Handler": "index.handler",
            "Role": {
              "Fn::GetAtt": [
                "ScaleImagesRole",
                "Arn"
              ]
            },
            "Code": {
              "S3Bucket": "example-test",
              "S3Key": "example-resize.zip"
            },
            "Runtime": "nodejs12.x",
            "MemorySize": 1024,
            "Timeout": 300
          }
        },
        "ScaleImagesRole": {
          "Type": "AWS::IAM::Role",
          "Properties": {
            "RoleName": "ScaleImagesRole",
            "AssumeRolePolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Principal": {
                    "Service": [
                      "lambda.amazonaws.com"
                    ]
                  },
                  "Action": [
                    "sts:AssumeRole"
                  ]
                }
              ]
            },
            "Path": "/",
            "Policies": [
              {
                "PolicyName": "AWSLambdaBasicExecutionRole",
                "PolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                    {
                      "Effect": "Allow",
                      "Action": [
                        "logs:CreateLogGroup",
                        "logs:CreateLogStream",
                        "logs:PutLogEvents"
                      ],
                      "Resource": [
                        "arn:aws:s3:::example-test",
                        "arn:aws:s3:::example-test/*",
                        "arn:aws:s3:::example-test-output",
                        "arn:aws:s3:::example-test-output/*"
                      ]
                    }
                  ]
                }
              },
              {
                "PolicyName": "AmazonS3FullAccess",
                "PolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                    {
                      "Effect": "Allow",
                      "Action": "s3:*",
                      "Resource": "*"
                    }
                  ]
                }
              }
            ]
          }
        },


"s3Permission": {
    "Type": "AWS::Lambda::Permission",
    "Properties": {
        "FunctionName": {
            "Fn::GetAtt": [
                "ScaleImages",
                "Arn"
            ]
        },
        "Action": "lambda:InvokeFunction",
        "Principal": "s3.amazonaws.com",
        "SourceAccount": {
            "Ref": "AWS::AccountId"
        }
    }
}
,
    "PutOriginalImage": {
      "Type": "AWS::S3::Bucket",
      "DeletionPolicy": "Retain",
      "Properties": {
        "BucketName": "example-test"
      }
    }

      }
    }

3.更新堆棧

通過向存儲桶添加通知來更新堆棧。 使用以下模板:

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Resources": {
        "ScaleImages": {
          "Type": "AWS::Lambda::Function",
          "Properties": {
            "FunctionName": "ScaleImages",
            "Handler": "index.handler",
            "Role": {
              "Fn::GetAtt": [
                "ScaleImagesRole",
                "Arn"
              ]
            },
            "Code": {
              "S3Bucket": "example-test",
              "S3Key": "example-resize.zip"
            },
            "Runtime": "nodejs12.x",
            "MemorySize": 1024,
            "Timeout": 300
          }
        },
        "ScaleImagesRole": {
          "Type": "AWS::IAM::Role",
          "Properties": {
            "RoleName": "ScaleImagesRole",
            "AssumeRolePolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Principal": {
                    "Service": [
                      "lambda.amazonaws.com"
                    ]
                  },
                  "Action": [
                    "sts:AssumeRole"
                  ]
                }
              ]
            },
            "Path": "/",
            "Policies": [
              {
                "PolicyName": "AWSLambdaBasicExecutionRole",
                "PolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                    {
                      "Effect": "Allow",
                      "Action": [
                        "logs:CreateLogGroup",
                        "logs:CreateLogStream",
                        "logs:PutLogEvents"
                      ],
                      "Resource": [
                        "arn:aws:s3:::example-test",
                        "arn:aws:s3:::example-test/*",
                        "arn:aws:s3:::example-test-output",
                        "arn:aws:s3:::example-test-output/*"
                      ]
                    }
                  ]
                }
              },
              {
                "PolicyName": "AmazonS3FullAccess",
                "PolicyDocument": {
                  "Version": "2012-10-17",
                  "Statement": [
                    {
                      "Effect": "Allow",
                      "Action": "s3:*",
                      "Resource": "*"
                    }
                  ]
                }
              }
            ]
          }
        }

,

"s3Permission": {
    "Type": "AWS::Lambda::Permission",
    "Properties": {
        "FunctionName": {
            "Fn::GetAtt": [
                "ScaleImages",
                "Arn"
            ]
        },
        "Action": "lambda:InvokeFunction",
        "Principal": "s3.amazonaws.com",
        "SourceAccount": {
            "Ref": "AWS::AccountId"
        }
    }
},



            "PutOriginalImage": {
      "Type": "AWS::S3::Bucket",
      "DeletionPolicy": "Retain",
      "Properties": {
        "BucketName": "example-test",

        "NotificationConfiguration": {
          "LambdaConfigurations": [
            {
              "Event": "s3:ObjectCreated:Put",
              "Filter": {
                "S3Key": {
                  "Rules": [
                    {
                      "Name": "prefix",
                      "Value": "original2/"
                    }
                  ]
                }
              },
              "Function": {
                "Fn::GetAtt": [
                  "ScaleImages",
                  "Arn"
                ]
              }
            }
          ]
        }


      }
    }



      }
    }

一種稍微不同的方法,無需遵循 3 個步驟即可讓您一次性完成。 在 Cloudformation 中導入現有資源時,我經歷了一些艱難時期,我將通過自定義資源處理 lambda 中的復雜性

                s3 = boto3.resource('s3')
                
                def lambda_handler(event, context):
                    print("Received event: " + json.dumps(event, indent=2))
                    responseData={}
                    try:
                        if event['RequestType'] == 'Delete':
                            print("Request Type:",event['RequestType'])
                            Bucket=event['ResourceProperties']['Bucket']
                            delete_notification(Bucket)
                            print("Sending response to custom resource after Delete")
                        elif event['RequestType'] == 'Create' or event['RequestType'] == 'Update':
                            print("Request Type:",event['RequestType'])
                            LambdaArn=event['ResourceProperties']['LambdaArn']
                            Bucket=event['ResourceProperties']['Bucket']
                            add_notification(LambdaArn, Bucket)
                            responseData={'Bucket':Bucket}
                            print("Sending response to custom resource")
                        responseStatus = 'SUCCESS'
                    except Exception as e:
                        print('Failed to process:', e)
                        responseStatus = 'FAILURE'
                        responseData = {'Failure': 'Something bad happened.'}
                    cfnresponse.send(event, context, responseStatus, responseData)
    
                def add_notification(LambdaArn, Bucket):
                    bucket_notification = s3.BucketNotification(Bucket)
                    response = bucket_notification.put(
                      NotificationConfiguration={
                        'LambdaFunctionConfigurations': [
                          {
                              'LambdaFunctionArn': LambdaArn,
                              'Events': [
                                  's3:ObjectCreated:*'
                              ]
                          }
                        ]
                      }
                    )
                    print("Put request completed....")
                  
                def delete_notification(Bucket):
                    bucket_notification = s3.BucketNotification(Bucket)
                    response = bucket_notification.put(
                        NotificationConfiguration={}
                    )
                    print("Delete request completed....")

完整的模板和解決方案可以在這里找到

注意:在 github 上的 AWS CloudFormation Repo 上已經存在一個未解決的問題。 最初來自無服務器的人

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM