Search code examples
aws-cloudformationserverless-frameworkaws-serverless

Serverless environment variable scope


We have one yaml file that has 1 service with several lambda function definitions. I'm trying to define an environment variable under one function, and was hoping that could be picked up in the iamrole statement, but I got Value not found at "env" source. But I need the variable to be defined at each function level. Is there a way we could achieve that. Our yml looks like

service: myService

frameworkVersion: "3"

provider:
  name: aws
  ...
  iamRoleStatements:
    - Fn::If:
        - myCondition
        - Effect: "Deny"
          Action:
            - ...
          Resources:
            - ...
resources:
  Conditions:
    myCondition: !Equals ["${env:MY_ENV_VARIABLE, false}", true]


functions:
  my_function:
    ...
    environment:
      MY_ENV_VARIABLE: true  

Thanks a lot!


Solution

  • You can simply define that value in custom section of yaml file and then pick it up from there:

    service: myService
    
    frameworkVersion: "3"
    
    custom:
      myEnvVariable: true
    
    provider:
      name: aws
      ...
      iamRoleStatements:
        - Fn::If:
            - myCondition
            - Effect: "Deny"
              Action:
                - ...
              Resources:
                - ...
    
    resources:
      Conditions:
        myCondition: !Equals ["${self:custom.myEnvVariable, false}", true]
    
    
    functions:
      my_function:
        ...
        environment:
          MY_ENV_VARIABLE: ${self:custom.myEnvVariable}  
    

    However I see that basing on this: ["${env:MY_ENV_VARIABLE, false}", true], your variable might be not set in some cases. If it depends on the stage, you can simply use params section:

    service: myService
    
    frameworkVersion: "3"
    
    params:
      default:
        MY_ENV_VARIABLE: true
      staging:
        MY_ENV_VARIABLE: true
      prod:
        MY_ENV_VARIABLE: false
    
    provider:
      name: aws
      ...
      iamRoleStatements:
        - Fn::If:
            - myCondition
            - Effect: "Deny"
              Action:
                - ...
              Resources:
                - ...
    
    resources:
      Conditions:
        myCondition: !Equals ["${param:MY_ENV_VARIABLE}", true]
    
    
    functions:
      my_function:
        ...
        environment:
          MY_ENV_VARIABLE: ${param:MY_ENV_VARIABLE}  
    
    

    Then basing on the stage name that you pass during deployment, a correct value will be picked. In that example for prod the value of MY_ENV_VARIABLE will be different. If non-standard stage will be provided, then it will fallback to default value.