您能否通过数据库名称而不是Lambda函数中的主机名连接到Amazon RDS实例?

时间:2018-01-15 23:47:10

标签: node.js aws-lambda amazon-dynamodb amazon-rds serverless-framework

我喜欢DynamoDB的一个方面就是你可以像这样连接它。

const params = {
      TableName: process.env.TWILIO_TABLE,
      Item: {
        callId: obj.CallSid,
        to: obj.To,
        from: obj.From,
        callerName: obj.CallerName,
        callerCity: obj.CallerCity,
        callStatus: obj.CallStatus,
        direction: obj.Direction,
        createdAt: new Date().getTime()
      }
    };

请注意,您只需要TableName,并从您的AWS凭据中了解您所引用的DynamoDB表。

我想以相同的方式连接到RDS。

我正在使用无服务器框架来创建如下所示的资源。

resources:
  Resources:
    uploadBucket:
       Type: AWS::S3::Bucket
       Properties:
         BucketName: ${self:custom.uploadBucket}
    RDSDatabase:
      Type: AWS::RDS::DBInstance
      Properties:
        Engine : mysql
        DBInstanceIdentifier: ${self:custom.databaseName}
        MasterUsername: Test123
        MasterUserPassword: TestPass123
        DBInstanceClass : db.m1.small
        AllocatedStorage: '5'
        PubliclyAccessible: true
      DeletionPolicy: Snapshot

反过来,它使用云形成为我创建数据库实例。特别是我动态创建数据库名称及其标识符DBInstanceIdentifier: ${self:custom.databaseName}

该名称根据我通过无服务器部署时使用的阶段参数(dev,beta,alpha,prod等)而更改。

这个想法是,如果需要,开发人员可以自动为他创建一个数据库,以便根据阶段进行测试。假设他们创建了一个自定义阶段,比如'joe',他们可以在推送到'staging'之前使用真实资源进行测试。

这样做的好处是真正的测试,并且很容易使用sls remove --stage joe删除资源,例如删除该阶段的所有相关资源。

问题是要连接到RDS,您需要拥有用户名,密码和主机。这些资源在创建资源后位于控制台中,但我需要在无服务器脚本中以某种方式访问​​这些内容,因此我可以将它们设置为环境变量,以便轻松连接到我所有脚本的正确数据库。

简而言之,DynamoDB的工作方式非常完美,因为我只引用了tableName,而且我不必担心主机名,用户名,密码等,而且它知道哪些表是什么。 如果可能,我需要为RDS做同样的事情或解决方法类型解决方案。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

答案并不完全正确,但只要您可以公开访问数据库,我就创建了一个非常好的解决方法。

将您的资源文件修改为类似的内容......

resources:
  Resources:
    uploadBucket:
       Type: AWS::S3::Bucket
       Properties:
         BucketName: ${self:custom.uploadBucket}
    RDSDatabase:
      Type: AWS::RDS::DBInstance
      Properties:
        Engine : mysql
        MasterUsername: ${env:RDS_USERNAME}
        MasterUserPassword: ${env:RDS_PASSWORD}
        DBInstanceClass : db.t2.micro
        AllocatedStorage: '5'
        PubliclyAccessible: true
        #TODO: The Value of Stage is also available as a TAG automatically which I may use to replace this manually being put here..
        Tags:
          -
            Key: "Name"
            Value: ${self:custom.databaseName}
      DeletionPolicy: Snapshot
    DNSRecordSet:
      Type: AWS::Route53::RecordSet
      Properties:
        HostedZoneName: yourdomain.com.
        Name: database-${self:custom.stage}.yourdomain.com
        Type: CNAME
        TTL: '300'
        ResourceRecords:
        - {"Fn::GetAtt": ["RDSDatabase","Endpoint.Address"]}
      DependsOn: RDSDatabase

我的策略是连接Route53记录,该记录采用无法预测的唯一端点ID,并使其成为您将理解的域名。在我的情况下,我使用阶段名称创建它,以便我的函数以后将始终知道数据库位于database-dev.yourdomain.com

使用它你现在基本上可以知道所有lambda和/或nodejs函数的HOST:)。

对此有任何更好的解决方案当然是受欢迎的,这正是我现在想出来的。