Ссылка имени корзины в качестве переменной на ресурс в событии s3 в файле serverless.yml

#amazon-web-services #amazon-s3 #lambda #serverless

Вопрос:

У меня есть следующая конфигурация в serverless.yml, которая хорошо работает:

 service: fx-crawler-av
frameworkVersion: '2'

provider:
  name: aws
  runtime: python3.8
  lambdaHashingVersion: 20201221
  region: eu-west-1

  environment:
    S3BucketName: !Ref 'S3BucketFXDataStorage'
    AlphaVantageAPIKey: ${ssm:AlphaVantageAPIKey}

package:
  exclude:
    - requirements.txt
    - package.json
    - package-lock.json
    - node_modules/**
    - .serverless/**
    - .env/**

functions:
  fetch_api:
    handler: handler.fetch_api
    iamRoleStatements:
      - Effect: "Allow"        
        Action:
          - "s3:PutObject"
        Resource:
          Fn::Join:
            - ""
            - - "arn:aws:s3:::"
              - "Ref": "S3BucketFXDataStorage"
              - "/*"
  set_ccy_pair_scope:
    handler: handler.set_ccy_pair_scope
    iamRoleStatements:
      - Effect: "Allow"        
        Action:
          - "s3:GetObject"
        Resource:
          Fn::Join:
            - ""
            - - "arn:aws:s3:::"
              - "Ref": "S3BucketFXDataStorage"
              - "/*"
      - Effect: "Allow"        
        Action:
          - "s3:ListBucket"
        Resource:
          Fn::Join:
            - ""
            - - "arn:aws:s3:::"
              - "Ref": "S3BucketFXDataStorage"
  get_ccy_list:
    handler: handler.get_ccy_list
    iamRoleStatements:
      - Effect: "Allow"        
        Action:
          - "s3:GetObject"
        Resource:
          Fn::Join:
            - ""
            - - "arn:aws:s3:::"
              - "Ref": "S3BucketFXDataStorage"
              - "/*"
  append_parquet_file:
    handler: handler.append_parquet_file
    iamRoleStatements:
      - Effect: "Allow"        
        Action:
          - "s3:GetObject"
          - "s3:PutObject"
        Resource:
          Fn::Join:
            - ""
            - - "arn:aws:s3:::"
              - "Ref": "S3BucketFXDataStorage"
              - "/*"
      - Effect: "Allow"        
        Action:
          - "s3:ListBucket"
        Resource:
          Fn::Join:
            - ""
            - - "arn:aws:s3:::"
              - "Ref": "S3BucketFXDataStorage"

resources:
  Resources:
    S3BucketFXDataStorage:
      Type: 'AWS::S3::Bucket'
      Properties:
        BucketName: !Join
          - ''
          - - !Ref 'AWS::AccountId'
            - '-fx-data-storage'

stepFunctions:
  stateMachines:
    FXCrawler:
      events:
        - schedule: cron(35 21 * * ? *)
      definition:
        Comment: "State machine for crawling AlphaVantage API for FX rates"
        StartAt: GetCurrencyList
        States:
          GetCurrencyList:
            Type: Task
            Resource: 
              Fn::GetAtt: [get_ccy_list, Arn]
            Next: SetCurrencyPairScope
          SetCurrencyPairScope:
            Type: Task
            Resource:
              Fn::GetAtt: [set_ccy_pair_scope, Arn]
            Next: mapped_task
          mapped_task:
            Type: Map
            ItemsPath: '$.ccy_pair_scope'
            MaxConcurrency: 1
            Iterator:
              StartAt: FetchAPI
              States:
                FetchAPI:
                  Type: Task
                  Resource:
                    Fn::GetAtt: [fetch_api, Arn]
                  Next: WaitForAPI
                WaitForAPI:
                  Type: Wait
                  Seconds: 60
                  End: true
            End: true

plugins:
  - serverless-python-requirements
  - serverless-iam-roles-per-function
  - serverless-step-functions

custom:
  pythonRequirements:
    slim: true
    dockerizePip: true
    useDownloadCache: true
 

Теперь я хотел бы добавить триггер события S3 в свою append_parquet_file функцию, например:

   append_parquet_file:
    handler: handler.append_parquet_file
    events:
      - s3:
          bucket: !Ref 'S3BucketFXDataStorage'
          event: s3:ObjectCreated:*
          rules:
            - suffix: .json
 

Но, к сожалению, это, похоже, не работает..

  1. Я получаю предупреждение во время развертывания Serverless: Configuration warning at 'functions.append_parquet_file.events[0].s3.bucket': should be string
  2. Сбой развертывания:
 Serverless Error ---------------------------------------
 
  [object Object] - Bucket name must conform to pattern (?!^(d{1,3}.){3}d{1,3}$)(^(([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9]).)*([a-z0-9]|[a-z0-9][a-z0-9-]*[a-z0-9])$). Please check provider.s3.[object Object] and/or s3 events of function "append_parquet_file".
 

Я перепробовал несколько способов создания и ввода имени ведра в качестве переменной, но не преуспел. Есть идеи, что может пойти не так?

Ответ №1:

Вы должны ссылаться на свое ведро следующим образом:

 bucket: ${self:resources.Resources.S3BucketFXDataStorage.Properties.BucketName}
 

Комментарии:

1. Спасибо, Марчин, но я тоже получаю одинаковые ошибки при этом подходе.

2. @ati Является ли это частью одного и того же шаблона? Можете ли вы предоставить полный, воспроизводимый код, демонстрирующий проблему?

3. включен в мой полный бессерверный файл.yml как есть

Ответ №2:

Все, что вам нужно, это: (удалите двойные кавычки)

     Resource: !Ref S3BucketFXDataStorage
    event: s3:ObjectCreated:*
    existing: true
 

и у вас есть еще одна проблема в политиках, попробуйте вместо этого сослаться на ваше ведро в политиках:

 Resource: !Join ["", [!GetAtt S3BucketFXDataStorage.Arn, "/*" ]]