1

我已将Redis ElastiCache部分添加到我的s-resource-cf.json(CloudFormation模板)中,并将其主机名选为输出。如何在Lambda函数中使用CloudFormation资源?

"Resources": { 
    ...snip... 
    "Redis": { 
     "Type": "AWS::ElastiCache::CacheCluster", 
     "Properties": { 
      "AutoMinorVersionUpgrade": "true", 
      "AZMode": "single-az", 
      "CacheNodeType": "cache.t2.micro", 
      "Engine": "redis", 
      "EngineVersion": "2.8.24", 
      "NumCacheNodes": "1", 
      "PreferredAvailabilityZone": "eu-west-1a", 
      "PreferredMaintenanceWindow": "tue:00:30-tue:01:30", 
      "CacheSubnetGroupName": { 
       "Ref": "cachesubnetdefault" 
      }, 
      "VpcSecurityGroupIds": [ 
       { 
        "Fn::GetAtt": [ 
         "sgdefault", 
         "GroupId" 
        ] 
       } 
      ] 
     } 
    } 
}, 
"Outputs": { 
    "IamRoleArnLambda": { 
     "Description": "ARN of the lambda IAM role", 
     "Value": { 
      "Fn::GetAtt": [ 
       "IamRoleLambda", 
       "Arn" 
      ] 
     } 
    }, 
    "RedisEndpointAddress": { 
     "Description": "Redis server host", 
     "Value": { 
      "Fn::GetAtt": [ 
       "Redis", 
       "Address" 
      ] 
     } 
    } 
} 

运行sls resources deploy时,我能得到CloudFormation输出Redis的服务器主机,但我怎么能访问从一个lambda函数内的输出?

此入门项目模板中没有任何内容参考示例项目附带的IamRoleArnLambda。按照docs,模板只为项目配置使用,它们无法访问从lambda函数:

模板&变量是配置只

模板和变量被用于该项目的配置只要。这些信息在您的lambda函数中不可用。要设置可由lambda函数使用的变量,请使用环境变量。

那么,在创建ElastiCache服务器后,如何将环境变量设置为ElastiCache服务器的主机名呢?

回答

1

更新

自从评论发布在问题跟踪器中后,CloudFormation的用法有所改进。我已将文档更新提交到http://docs.serverless.com/docs/templates-variables,并在gist中发布了我的配置的缩短版本。

可以在s-function.json Lambda配置文件中引用CloudFormation输出,以便使这些输出可用作环境变量。

s-resource-cf.json输出部:

"Outputs": { 
    "redisHost": { 
     "Description": "Redis host URI", 
     "Value": { 
      "Fn::GetAtt": [ 
       "RedisCluster", 
       "RedisEndpoint.Address" 
      ] 
     } 
    } 
} 

s-function.json环境部分:

"environment": { 
    "REDIS_HOST": "${redisHost}" 
}, 

用法在一个lambda函数:

exports.handler = function(event, context) { 
    console.log("Redis host: ", process.env.REDIS_HOST); 
}; 

旧回答

看起来像在无服务器问题跟踪器(link)中找到/实现的解决方案。引述HyperBrain


CF输出变量

为了使您的拉姆达访问你必须给它在lambda IAM角色cloudformation:describeStacks访问权限的CF输出变量。

CF.loadVars()承诺会将所有CF输出变量添加到过程' 环境中作为SERVERLESS_CF_OutVar名称。它会为您的lambda的启动时间添加几个ms到 。

更改您的拉姆达处理程序如下:

// Require Serverless ENV vars 
var ServerlessHelpers = require('serverless-helpers-js'); 
ServerlessHelpers.loadEnv(); 

// Require Logic 
var lib = require('../lib'); 

// Lambda Handler 
module.exports.handler = function(event, context) { 
    ServerlessHelpers.CF.loadVars() 
    .then(function() { 
    lib.respond(event, function(error, response) { 
     return context.done(error, response); 
    }); 
    }) 
}; 
1

您可以在函数的s-function.json文件的environment部分中设置环境变量。此外,如果您想阻止这些变量进入版本控制(例如,如果您的代码将发布到公共GitHub仓库中),则可以将它们放入_meta/variables目录中的相应文件中,然后引用您的代码s-function.json文件。只要确保您将_meta行添加到您的.gitignore文件。

例如,在我最新的项目中,我需要连接到Redis Cloud服务器,但不想将连接详细信息提交到版本控制。我把变量到我_meta/variables/s-variables-[stage]-[region].json文件,像这样:

{ 
    "redisUrl": "...", 
    "redisPort": "...", 
    "redisPass": "..." 
} 

...和引用的连接设置变量在该函数的s-function.json文件:

"environment": { 
    "REDIS_URL": "${redisUrl}", 
    "REDIS_PORT": "${redisPort}", 
    "REDIS_PASS": "${redisPass}" 
} 

然后我把这个redis.js文件在我functions/lib目录:

module.exports =() => { 
    const redis = require('redis') 
    const jsonify = require('redis-jsonify') 
    const redisOptions = { 
    host: process.env.REDIS_URL, 
    port: process.env.REDIS_PORT, 
    password: process.env.REDIS_PASS 
    } 

    return jsonify(redis.createClient(redisOptions)) 
} 

然后,在需要连接到该Redis数据库的任何函数中,我导入了redis.js

redis = require('../lib/redis')() 

(关于我无服务器/ Redis的设置更多的细节和一些我面临的得到它的工作所面临的挑战,看到this question我昨天公布。)

+0

这应该只是正常工作对我来说,只要我手动创建Elasticache集群,并与无服务器堆栈名称前缀键名。每个项目一次性手动操作不是问题,我可能还会为生产创建一个单独的实例。令人惊讶的是,虽然使用CloudFormation非常困难。这是我两天来第三次尝试使用它来简化基础结构初始化,只放弃并回退到手动创建资源,并将它们记录在自述文件和专用配置文件中。 –

相关问题