使用 cloudformation 模板的 AWS Lambda 的动态环境变量
Posted
技术标签:
【中文标题】使用 cloudformation 模板的 AWS Lambda 的动态环境变量【英文标题】:Dynamic environment variables for AWS Lambda using cloudformation template 【发布时间】:2018-04-30 02:43:05 【问题描述】:我必须在我的应用程序的各种堆栈中使用 AWS lambda,因此我创建了一个通用的云形成模板来创建一个 lambda 函数。此模板可以包含在另一个云形成模板中,以进一步用作nested stack。
# Basics
AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation Template to create a lambda function for java 8 or nodejs
# Parameters
Parameters:
FunctionName:
Type: String
Description: Funciton Name
HandlerName:
Type: String
Description: Handler Name
FunctionCodeS3Bucket:
Type: String
Description: Name of s3 bucket where the function code is present
Default: my-deployment-bucket
FunctionCodeS3Key:
Type: String
Description: Function code present in s3 bucket
MemorySize:
Type: Number
Description: Memory size between 128 MB - 1536 MB and multiple of 64
MinValue: '128'
MaxValue: '1536'
Default: '128'
RoleARN:
Type: String
Description: Role ARN for this function
Runtime:
Type: String
Description: Runtime Environment name e.g nodejs, java8
AllowedPattern: ^(nodejs6.10|nodejs4.3|java8)$
ConstraintDescription: must be a valid environment (nodejs6.10|nodejs4.3|java8) name.
Timeout:
Type: Number
Description: Timeout in seconds
Default: '3'
Env1:
Type: String
Description: Environment Variable with format Key|value
Default: ''
Env2:
Type: String
Description: Environment Variable with format Key|value
Default: ''
Env3:
Type: String
Description: Environment Variable with format Key|value
Default: ''
Env4:
Type: String
Description: Environment Variable with format Key|value
Default: ''
# Conditions
Conditions:
Env1Exist: !Not [ !Equals [!Ref Env1, '']]
Env2Exist: !Not [ !Equals [!Ref Env2, '']]
Env3Exist: !Not [ !Equals [!Ref Env3, '']]
Env4Exist: !Not [ !Equals [!Ref Env4, '']]
# Resources
Resources:
LambdaFunction:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref 'FunctionCodeS3Bucket'
S3Key: !Ref 'FunctionCodeS3Key'
Description: !Sub 'Lambda function for: $FunctionName'
Environment:
Variables:
'Fn::If':
- Env1Exist
-
- !Select [0, !Split ["|", !Ref Env1]]: !Select [1, !Split ["|", !Ref Env1]]
- 'Fn::If':
- Env2Exist
- !Select [0, !Split ["|", !Ref Env2]]: !Select [1, !Split ["|", !Ref Env2]]
- !Ref "AWS::NoValue"
- 'Fn::If':
- Env3Exist
- !Select [0, !Split ["|", !Ref Env3]]: !Select [1, !Split ["|", !Ref Env3]]
- !Ref "AWS::NoValue"
- 'Fn::If':
- Env4Exist
- !Select [0, !Split ["|", !Ref Env4]]: !Select [1, !Split ["|", !Ref Env4]]
- !Ref "AWS::NoValue"
- !Ref "AWS::NoValue"
FunctionName: !Ref 'FunctionName'
Handler: !Ref 'HandlerName'
MemorySize: !Ref 'MemorySize'
Role: !Ref 'RoleARN'
Runtime: !Ref 'Runtime'
Timeout: !Ref 'Timeout'
Outputs:
LambdaFunctionARN:
Value: !GetAtt 'LambdaFunction.Arn'
我想将环境变量注入到函数中,并将其从父堆栈传递,如下所示:
# Resouces
Resources:
# Lambda for search Function
ChildStackLambdaFunction:
Type: AWS::CloudFormation::Stack
Properties:
TemplateURL: <<REF_TO_ABOVE_LAMBDA_STACK.yml>>
Parameters:
FunctionName: test
HandlerName: 'index.handler'
FunctionCodeS3Bucket: <<BUCKET_NAME>>
FunctionCodeS3Key: <<FUNCTION_DEPLOYMENT_NAME>>
MemorySize: '256'
RoleARN: <<ROLE_ARN>>
Runtime: nodejs6.10
Timeout: '60'
Env1: !Sub 'AWS_REGION|$AWS::Region'
当我部署这个堆栈时,我遇到了错误。谁能帮我解决这个问题?
模板格式错误:[/Resources/LambdaFunction/Type/Environment/Variables/Fn::If/1/0] 映射键必须是字符串;而是收到了一张地图
传递key-value参数来自here
【问题讨论】:
【参考方案1】:所以,我尝试了很多方法来实现这一点,但我们无法将动态键值对从父堆栈传递给嵌套的 lambda 堆栈。我得到了 AWS 支持的确认,目前这是不可能的。
他们提出了另一种我喜欢并实施的方法,如下所述:
将 key:value 对作为 JSON 字符串传递,并在 lambda 函数中对其进行适当解析。
Environment:
Variables:
Env1: '"REGION": "REGION_VALUE", "ENDPOINT": "http://SOME_ENDPOINT"'
这个建议对解析 JSON 字符串的编程有一点开销,但现在我会推荐这个作为上述问题的解决方案。
【讨论】:
你有更好的吗? 不。希望有人能想出它;) 你有这种 lambda 的例子吗? 你能分享你的 lambda 栈的全部代码吗?【参考方案2】:我通过 PyPlate 宏实现了这一点。 以逗号分隔的环境变量列表
Parameters:
EnvVars:
Type: CommaDelimitedList
Description: Comma separated list of Env vars key=value pairs (key1=value1,key2=value2)
并在 Lambda 资源中使用它:
Environment:
Variables: |
#!PyPlate
output = dict()
for envVar in params['EnvVars']:
key, value = envVar.split('=')
output.update(key: value)
【讨论】:
以上是关于使用 cloudformation 模板的 AWS Lambda 的动态环境变量的主要内容,如果未能解决你的问题,请参考以下文章
AWS::ElasticBeanstalk::ConfigurationTemplate 的 AWS CloudFormation 模板失败
使用 PyYAML 库解析 AWS CloudFormation 模板
使用CloudFormation模板更新AWS Athena工作组
AWS cloudformation:一个大模板文件还是许多小模板文件?