3

I'm very unclear on how references or variables work with CloudFormation.

Currently my iAmRole in my serverless.yml looks like:

  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      # Restrict our IAM role permissions to
      # the specific table for the stage
      Resource:
        - "Fn::GetAtt": [ ReportsTable, Arn ]

ReportsTable is a table created in another file that looks like:

Resources:
  ReportsTable:
    Type: AWS::DynamoDB::Table
    Properties:
    ...
    LocalSecondaryIndexes:
        - IndexName: typeId-accessToken-index
          KeySchema:
          - AttributeName: typeId
            KeyType: HASH
            ...etc

I understand that the second value in the Fn::GetAtt array is referencing an attributename, but I don't understand where Arn is coming from. It seems like a variable but it's not defined anywhere.

Ultimately I need to add another Effect, Action, Resource block referencing the local secondary index I have created, but I'm lost as to where to start.

Edit: Looks like Arn comes from dynamoDB tables return values (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html)

Edit2: Okay so I now have the format arn:aws:dynamodb:region:account-id:table/table-name/index/* from the permissions reference docs, testing now.

colemars
  • 979
  • 3
  • 12
  • 25
  • arn:aws:dynamodb:region:account-id:table/table-name/index/* is the correct reference. Now I need to figure out how to dynamically refer to the tablename like is being done above. And probably how to refer to my account id and region without hardcoding. – colemars Aug 01 '19 at 02:55

2 Answers2

6

You can use Cloudformation intrinsic function Sub to create index arn

!Sub '${ReportsTable.Arn}/index/*'
Igor Marcelo
  • 141
  • 4
0

After referring to these docs: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html)

and these: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/api-permissions-reference.html

I was able to figure out that the required format for referencing an index table is arn:aws:dynamodb:region:account-id:table/table-name/index/*.

Further, in order to not hard code all the values in (in my case because I have several staging environments) you can do a join like so:

        Fn::Join:
          - ''
          -
            - 'arn:aws:dynamodb:'
            - Ref: AWS::Region
            - ':'
            - Ref: AWS::AccountId
            - ':table/'
            - ${self:custom.tableName}/
            - 'index/*'

Where table name is defined in your custom block.

colemars
  • 979
  • 3
  • 12
  • 25
  • FYI, unless you're doing manipulation on the Join components, or importing them, you can generally use a Sub instead of a Join, which makes things easier to read: `!Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${self:custom.tableName}/index/*` – 404 Aug 01 '19 at 08:28