Search code examples
amazon-web-servicesamazon-dynamodbaws-cloudformationaws-samaws-sam-cli

AWS sam deploy failed : Waiter ChangeSetCreateComplete failed: Max attempts exceeded


Just added a DynamoDB table to my template.yaml for my stack. Running aws deploy freezes for some time with message Waiting for changeset to be created.. And after a few minutes fails with

File "/usr/local/Cellar/aws-sam-cli/1.26.0/libexec/lib/python3.8/site-packages/samcli/lib/deploy/deployer.py", line 295, in wait_for_changeset reason = resp["StatusReason"] KeyError: 'StatusReason'

I'm not sure what I am missing, I believe the IAM for this user has all required permissions as well. I'm very new to AWS so any help would be appreciated.

My template.yaml is

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  bibbl.io

  Sample SAM Template for bibbl.io

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3
    Environment:
      Variables:
        TABLE_NAME: my-table


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.lambda_handler
      Runtime: python3.8
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get
  MyTable:
    Type: AWS::DynamoDB:Table
    Properties:
      TableName: my-table
      AttributeDefinitions:
        - AttributeName: note_id
          AttributeType: S
        - AttributeName: upload_uri
          AttributeType: S
      KeySchema:
        - AttributeName: note_id
          KeyType: HASH
      GlobalSecondaryIndexes:
        IndexName: "upload_uri"
        KeySchema:
          - AttributeName: "upload_uri"
            KeyType: "HASH"
        Projection:
          ProjectionType: "ALL"
        ProvisionedThroughput: 
          ReadCapacityUnits: 5
          WriteCapacityUnits: 5
      ProvisionedThroughput: 
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref MyTable


Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn
  TableName:
    Value: !Ref MyTable
    Description: Table name of the newly created DynamoDB table


Solution

  • There were several mistakes in your template.yml.

    AWSTemplateFormatVersion: '2010-09-09'
    Transform: AWS::Serverless-2016-10-31
    Description: >
      bibbl.io
    
      Sample SAM Template for bibbl.io
    
    # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
    Globals:
      Function:
        Timeout: 3
        Environment:
          Variables:
            TABLE_NAME: my-table
    
    
    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.lambda_handler
          Runtime: python3.8
          Events:
            HelloWorld:
              Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
              Properties:
                Path: /hello
                Method: get
          Policies:
            - DynamoDBCrudPolicy:
                TableName: !Ref MyTable
    
      MyTable:
        Type: AWS::DynamoDB::Table
        Properties:
          TableName: my-table
          AttributeDefinitions:
            - AttributeName: note_id
              AttributeType: S
            - AttributeName: upload_uri
              AttributeType: S
          KeySchema:
            - AttributeName: note_id
              KeyType: HASH
          GlobalSecondaryIndexes:
           -
              IndexName: "upload_uri"
              KeySchema:
                - AttributeName: "upload_uri"
                  KeyType: "HASH"
              Projection:
                ProjectionType: "ALL"
              ProvisionedThroughput:
                ReadCapacityUnits: 5
                WriteCapacityUnits: 5
          ProvisionedThroughput:
            ReadCapacityUnits: 5
            WriteCapacityUnits: 5
    
    
    Outputs:
      # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
      # Find out more about other implicit resources you can reference within SAM
      # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
      HelloWorldApi:
        Description: "API Gateway endpoint URL for Prod stage for Hello World function"
        Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
      HelloWorldFunction:
        Description: "Hello World Lambda Fun ction ARN"
        Value: !GetAtt HelloWorldFunction.Arn
      HelloWorldFunctionIamRole:
        Description: "Implicit IAM Role created for Hello World function"
        Value: !GetAtt HelloWorldFunctionRole.Arn
      TableName:
        Value: !Ref MyTable
        Description: Table name of the newly created DynamoDB table
    
    1. The type for your Dynamo Table is missing a second colon after the Dynamo.

    2. The Policy attribute needs to be on your Lambda, not on your table. You want to give the Lambda function access to you table and not your table to itself, which does not make sense.

    3. GlobalSecondaryIndexes is a list of objects. You were missing the dash to indicate the start of a list.