简体   繁体   English

使用 cloudformation 模板的 AWS Lambda 的动态环境变量

[英]Dynamic environment variables for AWS Lambda using cloudformation template

I have to use AWS lambda in various stack of my application, thus I have created a generic cloud-formation template to create a lambda function.我必须在我的应用程序的各种堆栈中使用 AWS lambda,因此我创建了一个通用的云形成模板来创建 lambda function。 This template can be included in another cloud-formation template for further use as a 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'

I want to inject the environment variables to the the function and that will be passed from parent stack as below:我想将环境变量注入 function 并将从父堆栈传递,如下所示:

# 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}'

When I deploy this stack, I am getting below error.当我部署这个堆栈时,我遇到了错误。 Can anybody help me to resolve this one?有人可以帮我解决这个问题吗?

Template format error: [/Resources/LambdaFunction/Type/Environment/Variables/Fn::If/1/0] map keys must be strings;模板格式错误:[/Resources/LambdaFunction/Type/Environment/Variables/Fn::If/1/0] map 键必须是字符串; received a map instead收到了 map

Passing key-value parameter is referred from here传递键值参数是从这里引用的

So, I tried so many ways to achieve this, but we can not pass the dynamic key-value pair to nested lambda stack from the parent stack.所以,我尝试了很多方法来实现这一点,但我们无法将动态键值对从父堆栈传递给嵌套的 lambda 堆栈。 I had a confirmation from the AWS support that this is not possible as this moment.我得到了 AWS 支持的确认,目前这是不可能的。

They suggested a another way which I liked and implemented and its mentioned as below:他们提出了另一种我喜欢并实施的方法,如下所述:

Pass the key: value pair as a JSON string and parse it appropriately in the lambda function.将 key: value 对作为 JSON 字符串传递,并在 lambda function 中对其进行适当解析。

Environment:
  Variables:
    Env1: '{"REGION": "REGION_VALUE", "ENDPOINT": "http://SOME_ENDPOINT"}'  

This suggestion has a little overhead on programming to parse the JSON string, but at this moment I will recommend this as solution for above problem.这个建议对解析 JSON 字符串的编程有一点开销,但此时我会推荐这个作为上述问题的解决方案。

I achieved this with the PyPlate macro.我通过 PyPlate 宏实现了这一点。 Take environment variables list in a commalimited以逗号分隔的环境变量列表

Parameters:
  EnvVars:
    Type: CommaDelimitedList
    Description: Comma separated list of Env vars key=value pairs (key1=value1,key2=value2)

and use it in the Lambda Resource:并在 Lambda 资源中使用它:

  Environment:
    Variables: |
      #!PyPlate
      output = dict()
      for envVar in params['EnvVars']:
        key, value = envVar.split('=')
        output.update({key: value})

You can try to orchestrate creation of specific resources using AWS::NoValue您可以尝试使用 AWS::NoValue 来编排特定资源的创建

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html

Below is taken from variables creation for LambdaFunction以下摘自 LambdaFunction 的变量创建

Conditions:
   IsProd: !Equals [!Ref Env, "production"]

Environment:
   Variables:
     USER: !If [IsProd, !GetAtt ...., Ref: AWS::NoValue]

This is the right way to use global variables.这是使用全局变量的正确方法。

Globals:
  Function:
    Timeout: 60
    Runtime: nodejs10.x
    Environment:
      Variables:
        STAGE: !Ref Stage
        DatabaseName: !Ref DatabaseName
        DatabaseUsername: !Ref DatabaseUsername
        DatabasePassword: !Ref DatabasePassword
        DatabaseHostname: !Ref DatabaseHostname
        AuthyAPIKey: !Ref AuthyApiKey

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在CloudFormation模板中为不同的AWS Lambda别名配置环境变量 - Configuration of environment variables for different AWS Lambda aliases in CloudFormation template 如何使用CloudFormation加密AWS Lambda环境变量 - How to encrypt AWS Lambda environment variables using CloudFormation AWS CloudFormation 的全局环境变量 - Global environment variables for AWS CloudFormation 如何为使用 CloudFormation 模板创建的 AWS Lambda function 添加触发器? - How to add triggers for a AWS Lambda function created using a CloudFormation template? 我可以使用 CloudFormation 模板更新 AWS Lambda function 吗? - Can I update AWS Lambda function using CloudFormation template? 如何使用 CloudFormation 模板更新 AWS Lambda function - How do I update AWS Lambda function using CloudFormation template 在存储库的cloudformation模板中使用AWS :: CodeBuild :: Project环境变量 - Using AWS::CodeBuild::Project Environment variable in cloudformation template of repository Cloudformation模板Lambda环境变量错误-属性值变量必须是带有String的对象 - Cloudformation template Lambda environment variable error - Value of property Variables must be an object with String 通过Cloudformation模板将Lambda目标与AWS ALB - AWS ALB with lambda target through Cloudformation Template 如何将 AWS Lambda 转换回 CloudFormation 模板 - How to convert AWS Lambda back into CloudFormation template
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM