1

我在我的 s-resource-cf.json(一个 CloudFormation 模板)中添加了一个 Redis ElastiCache 部分,并选择了它的主机名作为输出。

"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 服务器主机sls resources deploy,但是如何从 Lambda 函数中访问该输出?

此入门项目模板中没有任何内容引用IamRoleArnLambda示例项目附带的那个。根据文档,模板仅可用于项目配置,无法从 Lambda 函数访问:

模板和变量仅用于配置

模板和变量仅用于项目的配置。此信息在您的 lambda 函数中不可用。要设置 lambda 函数可以使用的变量,请使用环境变量。

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

4

2 回答 2

2

更新

自从问题跟踪器中发布了该评论以来,CloudFormation 的使用已经有所简化。我已向http://docs.serverless.com/docs/templates-variables提交了文档更新,并在gist中发布了我的配置的缩短版本。

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

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);
};

旧答案

看起来在无服务器问题跟踪器(链接)中找到/实施了解决方案。引用HyperBrain 的话


CF 输出变量

要让您的 lambda 访问 CF 输出变量,您必须为其授予cloudformation:describeStackslambda IAM 角色的访问权限。

PromiseCF.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);
    });
  })
};
于 2016-05-09T14:34:18.180 回答
2

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

例如,在我最新的项目中,我需要连接到 Redis 云服务器,但不想将连接详细信息提交给版本控制。我将变量放入我的_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 设置的更多详细信息以及我在使其工作时遇到的一些挑战,请参阅我昨天发布的这个问题。)

于 2016-05-09T05:59:37.063 回答