Merging maps in serverless.yml (with external files)

I was trying to load an external file and some additional map key/values into custom

custom:
  dotenv:
    ${file(...)}
    OTHER_KEY: 'THEVALUE'

That doesn’t work. (bad indentation of a mapping entry)

If I try to use the merge thing of YAML (<<:) it works for normal anchors and maps:

custom:
  dotenv:
     ORIGINALKEY: VALUE
     <<: { NEWKEY: NEWVALUE }

and

custom:
  other: &other
    NEWKEY: NEWVALUE
  dotenv:
     ORIGINALKEY: VALUE
     <<: *other

but not when using the ${file( syntax:

custom:
  dotenv:
    ORIGINALKEY: VALUE
    <<: ${file(...)}

cannot merge mappings; the provided source object is unacceptable
If I use an anchor I just get an empty map:

custom:
  external: &external
    ${file(...)}
  dotenv:
    - *external
    - ORIGINALKEY: VALUE

gives:

{ external: 
   {NEWKEY: NEWVALUE},
  dotenv: 
   [ {},
     { ORIGINALKEY: VALUE} ] }

As far as I can tell it’s because the file expansion is done after yaml parsing.

The whole reason I’m doing this is to both have those “external” values written to my .env as well as being able to somewhat reliably depend on the values inside of serverless.yml. For example:

 70       Properties:                                                                
 71         Description: Allowing access to read and write buckets                   
 72         Roles:                                                                   
 73           - {"Ref" : "IamRoleLambdaExecution"}                                   
 74         PolicyDocument:                                                          
 75           Version: '2012-10-17'                                                  
 76           Statement:                                                             
 77             -                                                                    
 78               Effect: Allow                                                      
 79               Action:                                                            
 80                 - s3:*                                                           
 81               Resource:                                                          
 82                 - "arn:aws:s3:::${self:custom.dotenv.IMAGES_BUCKET}" 

But I guess I can live with loading the file twice

custom:
   external:
     ${file(...)}
   dotenv:
    - ${file(...)}
    - ORIGINALKEY: VALUE

as the dotenv plugin I’m using supports both arrays and objects (and I’m not really fond of $(self:custom.dotenv.0.IMAGES_BUCKET) but that might just be me being weird)

I’m running version 1.1.0

2 Likes

Unfortunately I don’t have a solution for your mapping merge; I just wanted to point out with the recently announced environment variable support your implementation might be able to change.

See:
https://github.com/serverless/serverless/pull/2748
and
https://github.com/serverless/serverless/issues/2673