Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serverless Service update Dynamodb table created with DeletionPolicy retain

I'm encountering some problems using Serverless framework, since i accidentally used the same name of a service on another one.

An error occurred: tableX - TableX already exists.

Let's suppose that i have two "serverless.yml" files, both with the same name of service. One of them (let's call it, "test1") have resources (DynamoDB tables), the other hasn't ("test2"). Like the following snippets:

Test1

service: sandbox-core
provider:
  name: aws
  stage: core
  runtime: nodejs6.10
  region: sa-east-1
  memorySize: 128
  timeout: 300

resources:
  Resources:

    table3:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        TableName: SandboxTable3
        AttributeDefinitions:
          -
            AttributeName: provider
            AttributeType: S
          -
            AttributeName: appId
            AttributeType: S
        KeySchema:
          -
            AttributeName: provider
            KeyType: HASH
          -
            AttributeName: appId
            KeyType: RANGE

        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1

    table4:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        TableName: SandboxTable4
        AttributeDefinitions:
          -
            AttributeName: session
            AttributeType: S
        KeySchema:
          -
            AttributeName: session
            KeyType: HASH

        ProvisionedThroughput:
          ReadCapacityUnits: 5
          WriteCapacityUnits: 1

functions:
  auth:
    handler: handler.auth
    events:
      - http:
          path: auth/{session}/{provider}/{appId}
          method: get
          cors: true

Test2

service: sandbox-core

provider:
  name: aws
  stage: core
  runtime: nodejs6.10
  region: sa-east-1
  memorySize: 128
  timeout: 300

functions:
  createCustomData:
    handler: handler.createCustomData
    events:
      - http:
          path: teste2
          method: post
          cors: true

When i sls deploy the "test1", he creates the tables as i wanted, with DeletionPolicy: Retain, for the tables with very sensible data. Then i sls deploy "test2" that has other functions but doesn't have any resources (DynamoDB tables), he does what is expected: skip the deletion of the tables.

But, when i sls deploy "test1" again, he doesn't recognizes the tables, he starts to "create" existing tables rather than update them, and fails to deploy.

I need the tables that aren't deleted, and need the functions on the service. It looks like the Cloud Formation losted the track of the created tables from the first deploy.

I don't whant to separate the services (one only for the resources) like was said on this github thread. I need the tables that are running, it has a lot of data and it's too much expensive to backup and restore it to another one, a lot of users could be affected.

So, how do i tell to Cloud Formation Stack that i'm updating that table, and not trying to create it? How to keep track of a service on the Cloud Formation Stack? And, how do i prevent to deploy a service with resources without them?

What's the best solution for this case? Hope that my questions are clear enough to understand.

like image 859
Sergio Flores Avatar asked Jan 19 '26 15:01

Sergio Flores


1 Answers

There is no problem related to test2.

For test1, you are fine to sls deploy many times.

But if you run sls remove, when the dynamodb is set to Retain in serverless.yml, the dynamodb table isn't deleted. So you can't create it again with sls deploy, because the resource with same name is exist. This is the design in aws cloudformation.

You found the open ticket already for a new feature to skip resources. We have to wait for the feature to be developed and merged. I am waiting for the same solution as well. Go there to vote it up!

With current situation, you have to backup the dynamodb, destroy it, and run sls deploy, and restore it if it is really matter.

I normally manage with variable, such as

DeletionPolicy: ${self:custom.${self:custom.stage}.deletion_policy}

in custom for different environments:

custom
  dev:
    deletion_policy: Delete
  prod:
    deletion_policy: Retain
like image 64
BMW Avatar answered Jan 22 '26 07:01

BMW