2

我想在我的無服務器項目中使用多個dynamodb表。如何正確定義iamrolestatements中的多個資源?如何在無服務器框架中爲多個dynamodb表定義iamrolestatements的資源?

我有一個例子serverless.yml

service: serverless-expense-tracker 
frameworkVersion: ">=1.1.0 <2.0.0" 

provider: 
    name: aws 
    runtime: nodejs6.10 
    environment: 
    EXPENSES_TABLE: "${self:service}-${opt:stage, self:provider.stage}-expenses" 
    BUDGETS_TABLE: "${self:service}-${opt:stage, self:provider.stage}-budgets" 

    iamRoleStatements: 
    - Effect: Allow 
     Action: 
     - dynamodb:Query 
     - dynamodb:Scan 
     - dynamodb:GetItem 
     - dynamodb:PutItem 
     - dynamodb:UpdateItem 
     - dynamodb:DeleteItem 
     Resource: "arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.EXPENSES_TABLE}" 
     # what is the best way to add the other DB as a resource 

functions: 
    create: 
    handler: expenseTracker/create.create 
    events: 
     - http: 
      path: expenses 
      method: post 
      cors: true 

    list: 
    handler: expenseTracker/list.list 
    events: 
     - http: 
      path: expenses 
      method: get 
      cors: true 

    get: 
    handler: expenseTracker/get.get 
    events: 
     - http: 
      path: expenses/{id} 
      method: get 
      cors: true 

    update: 
    handler: expenseTracker/update.update 
    events: 
     - http: 
      path: expenses/{id} 
      method: put 
      cors: true 

    delete: 
    handler: expenseTracker/delete.delete 
    events: 
     - http: 
      path: expenses/{id} 
      method: delete 
      cors: true 

resources: 
    Resources: 
    DynamoDbExpenses: 
     Type: 'AWS::DynamoDB::Table' 
     DeletionPolicy: Retain 
     Properties: 
     AttributeDefinitions: 
      - 
      AttributeName: id 
      AttributeType: S 
     KeySchema: 
      - 
      AttributeName: id 
      KeyType: HASH 
     ProvisionedThroughput: 
      ReadCapacityUnits: 1 
      WriteCapacityUnits: 1 
     TableName: ${self:provider.environment.EXPENSES_TABLE} 

    DynamoDbBudgets: 
     Type: 'AWS::DynamoDB::Table' 
     DeletionPolicy: Retain 
     Properties: 
     AttributeDefinitions: 
      - 
      AttributeName: id 
      AttributeType: S 
     KeySchema: 
      - 
      AttributeName: id 
      KeyType: HASH 
     ProvisionedThroughput: 
      ReadCapacityUnits: 1 
      WriteCapacityUnits: 1 
     TableName: ${self:provider.environment.BUDGETS_TABLE} 

你可以看到在那裏的說明有問題的區域。

+0

如果你有一個具體的問題(如何正確定義IAM角色聲明多個資源),那麼請仔細示例顯示你已經嘗試過,從它的任何錯誤不工作,並解釋你的意圖 – Vorsprung

+0

謝謝@Vorsprung。我沒有任何錯誤,但獲得上述鏈接的serverless.yml的唯一方法是使用通配符定義iam資源。這看起來像我們工程師稱之爲「不好的想法」。你能幫我以更呃封裝的方式定義iamrolestatements中的多個資源嗎? – jasongonzales

+0

或者你的意思是我不應該鏈接到yml作爲一個要點,而是直接在這裏發佈? – jasongonzales

回答

3

我明白了!

關鍵僅僅是在關鍵字- Resource下添加了一個列表,但我還了解到,只需使用您在配置表時使用的邏輯ID即可。完整的示例如下:

service: serverless-expense-tracker 

frameworkVersion: ">=1.1.0 <2.0.0" 

provider: 
    name: aws 
    runtime: nodejs6.10 
    environment: 
    EXPENSES_TABLE: { "Ref": "DynamoDbExpenses" } #DynamoDbExpenses is a logicalID also used when provisioning below 
    BUDGETS_TABLE: { "Ref": "DynamoDbBudgets" } 

    iamRoleStatements: 
    - Effect: Allow 
     Action: 
     - dynamodb:DescribeTable 
     - dynamodb:Query 
     - dynamodb:Scan 
     - dynamodb:GetItem 
     - dynamodb:PutItem 
     - dynamodb:UpdateItem 
     - dynamodb:DeleteItem 
     Resource: 
     - { "Fn::GetAtt": ["DynamoDbExpenses", "Arn"] } #you will also see the logical IDs below where they are provisioned 
     - { "Fn::GetAtt": ["DynamoDbBudgets", "Arn"] } 
functions: 
    create: 
    handler: expenseTracker/create.create 
    events: 
     - http: 
      path: expenses 
      method: post 
      cors: true 

    createBudget: 
    handler: expenseTracker/createBudget.createBudget 
    events: 
     - http: 
      path: budgets 
      method: post 
      cors: true 

    list: 
    handler: expenseTracker/list.list 
    events: 
     - http: 
      path: expenses 
      method: get 
      cors: true 

    listBudgets: 
    handler: expenseTracker/listBudgets.listBudgets 
    events: 
     - http: 
      path: budgets 
      method: get 
      cors: true 

    get: 
    handler: expenseTracker/get.get 
    events: 
     - http: 
      path: expenses/{id} 
      method: get 
      cors: true 

    update: 
    handler: expenseTracker/update.update 
    events: 
     - http: 
      path: expenses/{id} 
      method: put 
      cors: true 

    delete: 
    handler: expenseTracker/delete.delete 
    events: 
     - http: 
      path: expenses/{id} 
      method: delete 
      cors: true 

resources: 
    Resources: 
    DynamoDbExpenses: #this is where the logicalID is defined 
     Type: 'AWS::DynamoDB::Table' 
     DeletionPolicy: Retain 
     Properties: 
     AttributeDefinitions: 
      - 
      AttributeName: id 
      AttributeType: S 
     KeySchema: 
      - 
      AttributeName: id 
      KeyType: HASH 
     ProvisionedThroughput: 
      ReadCapacityUnits: 1 
      WriteCapacityUnits: 1 

    DynamoDbBudgets: #here too 
     Type: 'AWS::DynamoDB::Table' 
     DeletionPolicy: Retain 
     Properties: 
     AttributeDefinitions: 
      - 
      AttributeName: id 
      AttributeType: S 
     KeySchema: 
      - 
      AttributeName: id 
      KeyType: HASH 
     ProvisionedThroughput: 
      ReadCapacityUnits: 1 
      WriteCapacityUnits: 1 
+0

當您管理兩個DynamoDB表時,您如何讓每個函數知道需要連接哪個數據庫? – BMW

+0

在這種情況下,您會注意到我在provider.environment中定義了EXPENSES_TABLE和BUDGETS_TABLE。在你的lambda中,你只需引用它就像這樣:'TableName:process.env.EXPENSES_TABLE' – jasongonzales

+0

但lambda是在sls中自動創建的,我可以在哪裏設置TableName?你的意思是在強硬的腳本中? – BMW

2

我想把我的更新,因爲我花時間和從這個問題學到很多東西。目前接受的答案沒有充分發揮作用。

我說什麼:

1)確保在你的處理器,有一個環境TABLE_NAME(或其他名稱,則可以相應調整)如下,它指的lambda函數的環境變量

const params = { 
    TableName: process.env.TABLE_NAME, 
    Item: { 
     ... 
    } 
    } 

2)更新serverless.yml爲每個功能提名錶名。

environment: 
    TABLE_NAME: { "Ref": "DynamoDbExpenses" } 

environment: 
    TABLE_NAME: { "Ref": "DynamoDbBudgets" } 

依靠其表的功能目標。

serverless.yml在這裏更新:

service: serverless-expense-tracker 

frameworkVersion: ">=1.1.0 <2.0.0" 

provider: 
    name: aws 
    runtime: nodejs6.10 
    environment: 
    EXPENSES_TABLE: { "Ref": "DynamoDbExpenses" } #DynamoDbExpenses is a logicalID also used when provisioning below 
    BUDGETS_TABLE: { "Ref": "DynamoDbBudgets" } 

    iamRoleStatements: 
    - Effect: Allow 
     Action: 
     - dynamodb:DescribeTable 
     - dynamodb:Query 
     - dynamodb:Scan 
     - dynamodb:GetItem 
     - dynamodb:PutItem 
     - dynamodb:UpdateItem 
     - dynamodb:DeleteItem 
     Resource: 
     - { "Fn::GetAtt": ["DynamoDbExpenses", "Arn"] } #you will also see the logical IDs below where they are provisioned 
     - { "Fn::GetAtt": ["DynamoDbBudgets", "Arn"] } 
functions: 
    create: 
    handler: expenseTracker/create.create 
    environment: 
     TABLE_NAME: { "Ref": "DynamoDbExpenses" } 
    events: 
     - http: 
      path: expenses 
      method: post 
      cors: true 

    createBudget: 
    handler: expenseTracker/createBudget.createBudget 
    environment: 
     TABLE_NAME: { "Ref": "DynamoDbBudgets" } 
    events: 
     - http: 
      path: budgets 
      method: post 
      cors: true 

    list: 
    handler: expenseTracker/list.list 
    environment: 
     TABLE_NAME: { "Ref": "DynamoDbExpenses" } 
    events: 
     - http: 
      path: expenses 
      method: get 
      cors: true 

    listBudgets: 
    handler: expenseTracker/listBudgets.listBudgets 
    environment: 
     TABLE_NAME: { "Ref": "DynamoDbBudgets" } 
    events: 
     - http: 
      path: budgets 
      method: get 
      cors: true 

    get: 
    handler: expenseTracker/get.get 
    environment: 
     TABLE_NAME: { "Ref": "DynamoDbExpenses" } 
    events: 
     - http: 
      path: expenses/{id} 
      method: get 
      cors: true 

    update: 
    handler: expenseTracker/update.update 
    environment: 
     TABLE_NAME: { "Ref": "DynamoDbExpenses" } 
    events: 
     - http: 
      path: expenses/{id} 
      method: put 
      cors: true 

    delete: 
    handler: expenseTracker/delete.delete 
    environment: 
     TABLE_NAME: { "Ref": "DynamoDbExpenses" } 
    events: 
     - http: 
      path: expenses/{id} 
      method: delete 
      cors: true 

resources: 
    Resources: 
    DynamoDbExpenses: #this is where the logicalID is defined 
     Type: 'AWS::DynamoDB::Table' 
     DeletionPolicy: Retain 
     Properties: 
     AttributeDefinitions: 
      - 
      AttributeName: id 
      AttributeType: S 
     KeySchema: 
      - 
      AttributeName: id 
      KeyType: HASH 
     ProvisionedThroughput: 
      ReadCapacityUnits: 1 
      WriteCapacityUnits: 1 
     TableName: ${self:service}-${opt:stage, self:provider.stage}-expenses 

    DynamoDbBudgets: #here too 
     Type: 'AWS::DynamoDB::Table' 
     DeletionPolicy: Retain 
     Properties: 
     AttributeDefinitions: 
      - 
      AttributeName: id 
      AttributeType: S 
     KeySchema: 
      - 
      AttributeName: id 
      KeyType: HASH 
     ProvisionedThroughput: 
      ReadCapacityUnits: 1 
      WriteCapacityUnits: 1 
     TableName: ${self:service}-${opt:stage, self:provider.stage}-budgets 

參見:

serverless environment variables

相關問題