AWS Lambda的動態環境變量,使用cloudformation模板

[英]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. This template can be included in another cloud-formation template for further use as a nested stack.

我必須在我的應用程序的各種堆棧中使用AWS lambda,因此我創建了一個通用的雲形成模板來創建lambda函數。此模板可以包含在另一個雲形成模板中,以進一步用作嵌套堆棧。

    # 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:

我想將環境變量注入到函數中,並將從父堆棧傳遞,如下所示:

# 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; received a map instead

模板格式錯誤:[/ Resources / LambdaFunction / Type / Environment / Variables / Fn :: If / 1/0]映射鍵必須是字符串;收到地圖而不是

Passing key-value parameter is referred from here

傳遞鍵值參數在這里引用

1 个解决方案

#1


5  

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. I had a confirmation from the AWS support that this is not possible as this moment.

所以,我嘗試了很多方法來實現這一點,但我們無法將動態鍵值對從父堆棧傳遞給嵌套的lambda堆棧。我從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函數中適當地解析它。

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字符串的編程上有一點開銷,但是此時我會推薦這個作為上述問題的解決方案。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2017/11/16/7255a208af412d5ea5357d07946e37d4.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com