localstack / serverless-localstack

⚡ Serverless plugin for running against LocalStack
524 stars 85 forks source link

Cannot deploy application against localstack #82

Closed dblencowe closed 4 years ago

dblencowe commented 4 years ago

I've started trying to use localstack with serverless using this plugin but am unable to successfully deploy to the local environment.

I've tried updating my localstack docker container to the latest build.

serverless.yml

service: my-app
plugins:
  - serverless-localstack
app: my-app

custom:
  defaultStage: local
  tableName: 'rooms-table-${self:provider.stage}'
  filesBucketName: 'my-app-${self:provider.stage}-files'
  localstack:
    debug: true
    stages: [local]
    host: http://localhost
    autostart: false

provider:
  name: aws
  runtime: nodejs12.x
  stage: ${opt:stage, self:custom.defaultStage}
  iamRoleStatements:
    - Effect: Allow
      Action:
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource:
        - { "Fn::GetAtt": ["RoomsDynamoDBTable", "Arn" ] }
    - Effect: "Allow"
      Action:
        - "s3:ListBucket"
      Resource:
        - { "Fn::GetAtt": ["FileBucket", "Arn" ] }
    - Effect: "Allow"
      Action:
        - "s3:PutObject"
      Resource:
        - { "Fn::GetAtt": ["FileBucket", "Arn" ] }
  environment:
    ROOM_TABLE: ${self:custom.tableName}
    FILE_BUCKET_NAME: ${self:custom.filesBucketName}

functions:
  app:
    handler: index.handler
    events:
      - http:
          path: /
          method: ANY
          private: false
          cors:
            origin: '*' # <-- Specify allowed origin
            headers: # <-- Specify allowed headers
              - Content-Type
              - X-Amz-Date
              - Authorization
              - X-Api-Key
              - X-Amz-Security-Token
              - X-Amz-User-Agent
            allowCredentials: false
      - http:
          path: "{proxy+}"
          method: ANY
          private: false
          cors:
            origin: '*' # <-- Specify allowed origin
            headers: # <-- Specify allowed headers
              - Content-Type
              - X-Amz-Date
              - Authorization
              - X-Api-Key
              - X-Amz-Security-Token
              - X-Amz-User-Agent
            allowCredentials: false
      - websocket:
          route: $default

resources:
  Resources:
    FileBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:custom.filesBucketName}
    RoomsDynamoDBTable:
      Type: 'AWS::DynamoDB::Table'
      Properties:
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: ${self:custom.tableName}

sls deploy command:

➜ sls deploy --stage local
Serverless: config.options_stage: local
Serverless: serverless.service.custom.stage: undefined
Serverless: serverless.service.provider.stage: ${opt:stage, self:custom.defaultStage}
Serverless: config.stage: local
Serverless: Using serverless-localstack
Serverless: Reconfiguring service apigateway to use http://localhost:4567
Serverless: Reconfiguring service cloudformation to use http://localhost:4581
Serverless: Reconfiguring service cloudwatch to use http://localhost:4582
Serverless: Reconfiguring service lambda to use http://localhost:4574
Serverless: Reconfiguring service dynamodb to use http://localhost:4569
Serverless: Reconfiguring service kinesis to use http://localhost:4568
Serverless: Reconfiguring service route53 to use http://localhost:4580
Serverless: Reconfiguring service firehose to use http://localhost:4573
Serverless: Reconfiguring service stepfunctions to use http://localhost:4585
Serverless: Reconfiguring service es to use http://localhost:4578
Serverless: Reconfiguring service s3 to use http://localhost:4572
Serverless: Reconfiguring service ses to use http://localhost:4579
Serverless: Reconfiguring service sns to use http://localhost:4575
Serverless: Reconfiguring service sqs to use http://localhost:4576
Serverless: Reconfiguring service sts to use http://localhost:4592
Serverless: Reconfiguring service iam to use http://localhost:4593
Serverless: Reconfiguring service ssm to use http://localhost:4583
Serverless: Reconfiguring service rds to use http://localhost:4594
Serverless: Reconfiguring service ec2 to use http://localhost:4597
Serverless: Reconfiguring service elasticache to use http://localhost:4598
Serverless: Reconfiguring service kms to use http://localhost:4599
Serverless: Reconfiguring service secretsmanager to use http://localhost:4584
Serverless: Reconfiguring service logs to use http://localhost:4586
Serverless: Reconfiguring service cloudwatchlogs to use http://localhost:4586
Serverless: Reconfiguring service iot to use http://localhost:4589
Serverless: Reconfiguring service cognito-idp to use http://localhost:4590
Serverless: Reconfiguring service cognito-identity to use http://localhost:4591
Serverless: Reconfiguring service ecs to use http://localhost:4601
Serverless: Reconfiguring service eks to use http://localhost:4602
Serverless: Reconfiguring service xray to use http://localhost:4603
Serverless: Reconfiguring service appsync to use http://localhost:4605
Serverless: Reconfiguring service cloudfront to use http://localhost:4606
Serverless: Reconfiguring service athena to use http://localhost:4607
Serverless: Warning: Unable to find plugin named: TypeScriptPlugin
Serverless: config.options_stage: local
Serverless: serverless.service.custom.stage: undefined
Serverless: serverless.service.provider.stage: local
Serverless: config.stage: local
Serverless: config.options_stage: local
Serverless: serverless.service.custom.stage: undefined
Serverless: serverless.service.provider.stage: local
Serverless: config.stage: local
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Installing dependencies for custom CloudFormation resources...
Serverless: Safeguards Processing...
Serverless: Safeguards Results:

   Summary --------------------------------------------------

   passed - no-secret-env-vars
   passed - allowed-regions
   passed - framework-version
   passed - no-wild-iam-role-statements
   warned - allowed-stages
   passed - require-dlq
   warned - allowed-runtimes
   warned - require-cfn-role

   Details --------------------------------------------------

   1) Warned - Stage name "local" not in list of permitted names: ["dev","qa","prod"]
      details: http://slss.io/sg-allowed-stages
      Limit the stages that can be used.

   2) Warned - Runtime of function app not in list of permitted runtimes: ["nodejs8.10","nodejs10.x","python3.7","python3.6","ruby2.5","java-1.8.0-openjdk","go1.x","dotnetcore2.1","dotnetcore2.0"]
      details: http://slss.io/sg-allowed-runtimes
      Limit the runtimes that can be used.

   3) Warned - no cfnRole set
      details: http://slss.io/sg-require-cfn-role
      Require the cfnRole option, which specifies a particular role for CloudFormation to assume while deploying.

Serverless: Safeguards Summary: 5 passed, 3 warnings, 0 errors
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service my-app.zip file to S3 (32.36 MB)...
Serverless: Uploading custom CloudFormation resources...
Serverless: Validating template...
Serverless: Skipping template validation: Unsupported in Localstack
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
.
Serverless: Operation failed!
Serverless: View the full error output: https://us-east-1.console.aws.amazon.com/cloudformation/home?region=us-east-1#/stack/detail?stackId=arn%3Aaws%3Acloudformation%3Aus-east-1%3A000000000000%3Astack%2Fmy-app-local%2Ff39403a8-aedd-4cb4-b765-22e136d87b75
Serverless: Publishing service to the Serverless Dashboard...
Serverless: Successfully published your service to the Serverless Dashboard: https://dashboard.serverless.com/tenants/dblencowe/applications/my-app/services/my-app/stage/local/region/us-east-1

  Serverless Error ---------------------------------------

  An error occurred: my-app-local - undefined.

  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Issues:        forum.serverless.com

  Your Environment Information ---------------------------
     Operating System:          darwin
     Node Version:              12.12.0
     Framework Version:         1.67.0
     Plugin Version:            3.5.0
     SDK Version:               2.3.0
     Components Version:        2.22.3

localstack docker container output:

localstack_1  | 2020-03-22T09:07:15:WARNING:moto: No Moto CloudFormation support for AWS::S3::BucketPolicy
localstack_1  | 2020-03-22T09:07:20:WARNING:localstack.services.awslambda.lambda_api: Function not found: arn:aws:lambda:us-east-1:000000000000:function:lecturn-local-app
localstack_1  | 2020-03-22T09:07:21:WARNING:moto: No Moto CloudFormation support for AWS::ApiGatewayV2::Deployment
localstack_1  | 2020-03-22T09:07:21:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to determine physical_resource_id for resource <class 'moto.dynamodb2.models.Table'>
localstack_1  | 2020-03-22T09:07:22:WARNING:localstack.services.awslambda.lambda_api: Function not found: arn:aws:lambda:us-east-1:000000000000:function:lecturn-local-app
localstack_1  | 2020-03-22T09:07:47:WARNING:moto: No Moto CloudFormation support for AWS::ApiGatewayV2::Integration
localstack_1  | 2020-03-22T09:07:47:WARNING:moto: No Moto CloudFormation support for AWS::Logs::SubscriptionFilter
localstack_1  | 2020-03-22T09:07:47:WARNING:moto: No Moto CloudFormation support for AWS::Logs::SubscriptionFilter
localstack_1  | 2020-03-22T09:07:47:INFO:localstack.services.cloudformation.cloudformation_starter: Error on moto CF resource creation. Ignoring, as should_be_created=False: 400 Bad Request: {
localstack_1  |     "message": "The specified log group already exists",
localstack_1  |     "__type": "ResourceAlreadyExistsException"
localstack_1  | }
localstack_1  | 2020-03-22T09:07:47:WARNING:moto: No Moto CloudFormation support for AWS::ApiGatewayV2::Route
localstack_1  | 2020-03-22T09:07:47:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to extract id for resource IamRoleCustomResourcesLambdaExecution: {'Role': {'Path': '/', 'RoleName': 'IamRoleCustomResourcesLambdaExecution', 'RoleId': '6jemco19dzixgupuz1e3', 'Arn': 'arn:aws:iam::000000000000:role/IamRoleCustomResourcesLambdaExecution', 'CreateDate': datetime.datetime(2020, 3, 22, 9, 7, 47, 174000, tzinfo=tzlocal()), 'AssumeRolePolicyDocument': {'Version': '2012-10-17', 'Statement': [{'Effect': 'Allow', 'Principal': {'Service': ['lambda.amazonaws.com']}, 'Action': ['sts:AssumeRole']}]}, 'MaxSessionDuration': 3600}, 'ResponseMetadata': {'RequestId': '4a93ceee-9966-11e1-b624-b1aEXAMPLE7c', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'BaseHTTP/0.6 Python/3.8.2', 'date': 'Sun, 22 Mar 2020 09:07:47 GMT', 'content-type': 'text/html; charset=utf-8', 'content-length': '715', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'HEAD,GET,PUT,POST,DELETE,OPTIONS,PATCH', 'access-control-allow-headers': 'authorization,content-type,content-md5,cache-control,x-amz-content-sha256,x-amz-date,x-amz-security-token,x-amz-user-agent,x-amz-target,x-amz-acl,x-amz-version-id,x-localstack-target,x-amz-tagging', 'access-control-expose-headers': 'x-amz-version-id'}, 'RetryAttempts': 0}}
localstack_1  | 2020-03-22T09:07:47:INFO:localstack.services.cloudformation.cloudformation_starter: Updating resource ID from 73221304 to 4nfj5aqifz (us-east-1)
localstack_1  | 2020-03-22T09:07:47:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to determine physical_resource_id for resource <class 'moto.apigateway.models.RestAPI'>
localstack_1  | 2020-03-22T09:07:47:WARNING:moto: No Moto CloudFormation support for AWS::S3::BucketPolicy
localstack_1  | 2020-03-22T09:07:47:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to extract id for resource EnterpriseLogAccessIamRole: {'Role': {'Path': '/', 'RoleName': 'EnterpriseLogAccessIamRole', 'RoleId': 'b4mm8g4bkzyaerlkz0f5', 'Arn': 'arn:aws:iam::000000000000:role/EnterpriseLogAccessIamRole', 'CreateDate': datetime.datetime(2020, 3, 22, 9, 7, 47, 468000, tzinfo=tzlocal()), 'AssumeRolePolicyDocument': {'Version': '2012-10-17', 'Statement': [{'Effect': 'Allow', 'Principal': {'AWS': 'arn:aws:iam::802587217904:root'}, 'Action': 'sts:AssumeRole', 'Condition': {'StringEquals': {'sts:ExternalId': 'ServerlessEnterprise-hZxWthzcJBqg95N8Dy'}}}]}, 'MaxSessionDuration': 3600}, 'ResponseMetadata': {'RequestId': '4a93ceee-9966-11e1-b624-b1aEXAMPLE7c', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'BaseHTTP/0.6 Python/3.8.2', 'date': 'Sun, 22 Mar 2020 09:07:47 GMT', 'content-type': 'text/html; charset=utf-8', 'content-length': '789', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'HEAD,GET,PUT,POST,DELETE,OPTIONS,PATCH', 'access-control-allow-headers': 'authorization,content-type,content-md5,cache-control,x-amz-content-sha256,x-amz-date,x-amz-security-token,x-amz-user-agent,x-amz-target,x-amz-acl,x-amz-version-id,x-localstack-target,x-amz-tagging', 'access-control-expose-headers': 'x-amz-version-id'}, 'RetryAttempts': 0}}
localstack_1  | 2020-03-22T09:07:47:WARNING:moto: No Moto CloudFormation support for AWS::S3::BucketPolicy
localstack_1  | 2020-03-22T09:07:47:WARNING:moto: No Moto CloudFormation support for AWS::S3::BucketPolicy
localstack_1  | 2020-03-22T09:07:47:WARNING:moto: No Moto CloudFormation support for AWS::S3::BucketPolicy
localstack_1  | 2020-03-22T09:07:48:INFO:localstack.services.cloudformation.cloudformation_starter: Resource ApiGatewayDeployment1584868019205 cannot be deployed, found unsatisfied dependencies. {'Type': 'AWS::ApiGateway::Deployment', 'Properties': {'RestApiId': '4nfj5aqifz', 'StageName': 'local'}, 'DependsOn': ['ApiGatewayMethodOptions', 'ApiGatewayMethodProxyVarOptions', 'ApiGatewayMethodAny', 'ApiGatewayMethodProxyVarAny']}
localstack_1  | 2020-03-22T09:07:48:INFO:localstack.services.cloudformation.cloudformation_starter: Updating resource ID from 4fa881b1 to gj3pzr0gfi (us-east-1)
localstack_1  | 2020-03-22T09:07:48:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to determine physical_resource_id for resource <class 'moto.apigateway.models.Resource'>
localstack_1  | 2020-03-22T09:07:48:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to determine physical_resource_id for resource <class 'moto.apigateway.models.Method'>
localstack_1  | 2020-03-22T09:07:48:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to determine physical_resource_id for resource <class 'moto.apigateway.models.Method'>
localstack_1  | 2020-03-22T09:07:48:WARNING:moto: No Moto CloudFormation support for AWS::ApiGatewayV2::Api
localstack_1  | 2020-03-22T09:07:48:WARNING:localstack.utils.cloudformation.template_deployer: Unknown resource type "ApiGatewayV2::Api": {'Type': 'AWS::ApiGatewayV2::Api', 'Properties': {'Name': 'local-lecturn-websockets', 'RouteSelectionExpression': '$request.body.action', 'Description': 'Serverless Websockets', 'ProtocolType': 'WEBSOCKET'}}
localstack_1  | 2020-03-22T09:07:48:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to determine physical_resource_id for resource <class 'moto.apigateway.models.Method'>
localstack_1  | 2020-03-22T09:07:48:WARNING:localstack.services.awslambda.lambda_api: Function not found: arn:aws:lambda:us-east-1:000000000000:function:lecturn-local-custom-resource-apigw-cw-role
localstack_1  | 2020-03-22T09:07:55:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to determine physical_resource_id for resource <class 'moto.apigateway.models.Method'>
localstack_1  | 2020-03-22T09:07:55:WARNING:moto: No Moto CloudFormation support for Custom::ApiGatewayAccountRole
localstack_1  | 2020-03-22T09:07:55:WARNING:moto: No Moto CloudFormation support for AWS::ApiGatewayV2::Stage
localstack_1  | 2020-03-22T09:07:55:WARNING:localstack.services.cloudformation.cloudformation_starter: Unable to resolve "Ref" attribute for: {'Ref': 'AppLambdaVersiony0cDtpkn8rzPhUXUAIeZWEg4AW1zUg9oNeBn2gZpd8'} - AppLambdaVersiony0cDtpkn8rzPhUXUAIeZWEg4AW1zUg9oNeBn2gZpd8 - <class 'moto.awslambda.models.LambdaVersion'>
localstack_1  | 2020-03-22T09:07:55:WARNING:moto: No Moto CloudFormation support for AWS::S3::BucketPolicy
localstack_1  | 2020-03-22T09:07:55:WARNING:moto: No Moto CloudFormation support for AWS::S3::BucketPolicy
localstack_1  | 2020-03-22T09:07:55:WARNING:moto: No Moto CloudFormation support for AWS::S3::BucketPolicy
localstack_1  | 2020-03-22T09:07:55:WARNING:moto: No Moto CloudFormation support for AWS::S3::BucketPolicy
localstack_1  | 2020-03-22T09:07:55:INFO:localstack.services.cloudformation.cloudformation_starter: Resource ApiGatewayDeployment1584868019205 cannot be deployed, found unsatisfied dependencies. {'Type': 'AWS::ApiGateway::Deployment', 'Properties': {'RestApiId': '4nfj5aqifz', 'StageName': 'local'}, 'DependsOn': ['ApiGatewayMethodOptions', 'ApiGatewayMethodProxyVarOptions', 'ApiGatewayMethodAny', 'ApiGatewayMethodProxyVarAny']}
localstack_1  | 2020-03-22T09:07:55:WARNING:localstack.services.cloudformation.cloudformation_starter: Unresolvable dependencies, there may be undeployed stack resources: {'ApiGatewayDeployment1584868019205': ['ApiGatewayDeployment1584868019205', {'Type': 'AWS::ApiGateway::Deployment', 'Properties': {'RestApiId': '4nfj5aqifz', 'StageName': 'local'}, 'DependsOn': ['ApiGatewayMethodOptions', 'ApiGatewayMethodProxyVarOptions', 'ApiGatewayMethodAny', 'ApiGatewayMethodProxyVarAny']}, <moto.cloudformation.parsing.ResourceMap object at 0x7fc374e0ae20>, 'us-east-1']}
localstack_1  | 2020-03-22T09:07:55:WARNING:bootstrap.py: Thread run method <function apply_patches.<locals>.run_dependencies_deployment_loop.<locals>.run_loop at 0x7fc37479de50>(None) failed: Traceback (most recent call last):
localstack_1  |   File "/opt/code/localstack/localstack/utils/bootstrap.py", line 442, in run
localstack_1  |     self.func(self.params)
localstack_1  |   File "/opt/code/localstack/localstack/services/cloudformation/cloudformation_starter.py", line 738, in run_loop
localstack_1  |     raise Exception('Unable to resolve all CloudFormation resources after traversing ' +
localstack_1  | Exception: Unable to resolve all CloudFormation resources after traversing dependency tree (maximum depth 40 reached): dict_keys(['ApiGatewayDeployment1584868019205'])
localstack_1  |
dblencowe commented 4 years ago

. Further investigation seems to be lack of support for the CORS definition on the http event

          cors:
            origin: '*' # <-- Specify allowed origin
            headers: # <-- Specify allowed headers
              - Content-Type
              - X-Amz-Date
              - Authorization
              - X-Api-Key
              - X-Amz-Security-Token
              - X-Amz-User-Agent
            allowCredentials: fals
whummer commented 4 years ago

Thanks for reporting @dblencowe . This should be - at least partially - fixed in https://github.com/localstack/localstack/pull/2186 . Can you please do a docker pull localstack/localstack once the image has been pushed by our CI system, and then give it another try?

Please note that API Gateway and WebSocket APIs are not supported in the community version of LocalStack - you may have to comment out these two lines to get it working:

#      - websocket:
#          route: $default

Thanks