web-dev-qa-db-fra.com

Variables d'environnement dynamique pour AWS Lambda à l'aide d'un modèle de cloudformation

Je dois utiliser AWS lambda dans diverses piles de mon application, j'ai donc créé un modèle générique de formation de nuages ​​pour créer une fonction lambda. Ce modèle peut être inclus dans un autre modèle de formation de nuages ​​pour une utilisation ultérieure en tant que pile imbriquée .

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

Je veux injecter les variables d'environnement à la fonction et qui seront passées de la pile parent comme ci-dessous:

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

Lorsque je déploie cette pile, j'obtiens en dessous de l'erreur. Quelqu'un peut-il m'aider à résoudre celui-ci?

Erreur de format du modèle: [/ Resources/LambdaFunction/Type/Environment/Variables/Fn :: If/1/0] les clés de mappage doivent être des chaînes; a reçu une carte à la place

Le passage du paramètre de valeur-clé est référencé par ici

12

J'ai donc essayé tant de façons d'y parvenir, mais nous ne pouvons pas transmettre la paire clé-valeur dynamique à la pile lambda imbriquée à partir de la pile parent. J'ai eu une confirmation du support AWS que ce n'est pas possible en ce moment.

Ils ont suggéré une autre manière que j'ai aimée et mise en œuvre et qui est mentionnée ci-dessous:

Passez la paire clé: valeur en tant que chaîne JSON et analysez-la de manière appropriée dans la fonction lambda.

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

Cette suggestion a un peu de temps sur la programmation pour analyser la chaîne JSON, mais pour le moment je vais recommander ceci comme solution au problème ci-dessus.

8