我已将Redis ElastiCache部分添加到我的s-resource-cf.json(CloudFormation模板),并选择其主机名作为输出。
if (someObject.doSomething()) //So if your function returns true then the below statement will be executed
{
// print a statment
}
else //This will check for the false condition of your function
{
// print a different statement
}
我可以在运行"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"
]
}
}
}
时让CloudFormation输出Redis服务器主机,但是如何从Lambda函数中访问该输出呢?
此入门项目模板中没有任何内容引用示例项目附带的sls resources deploy
。根据{{3}},模板仅可用于项目配置,无法从Lambda函数访问它们:
模板&变量仅适用于配置
模板和变量仅用于配置项目。此信息在lambda函数中不可用。要设置lambda函数可以使用的变量,请使用环境变量。
那么,如何在创建ElastiCache服务器的主机名后设置环境变量?
答案 0 :(得分:2)
您可以在函数environment
文件的s-function.json
部分设置环境变量。此外,如果要阻止这些变量进入版本控制(例如,如果您的代码将发布到公共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。)
答案 1 :(得分:2)
更新
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:
要让lambda访问CF输出变量,必须在lambda IAM角色中为其赋予cloudformation:describeStacks
访问权限。
CF.loadVars()
承诺会将所有CF输出变量添加到流程'
环境为SERVERLESS_CF_OutVar
名称。它会增加几毫秒
你的lambda的启动时间。
按如下方式更改lambda处理程序:
// 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);
});
})
};