Creating a Serverless Variable Precedence with aws SSM and files

I had searched for an answer to create some sort of variable precedence that would follow something like:

Highest Precedence

  • Local config.yml
  • AWS SSM Param Store /<stage_name>/app-name
  • default: AWS SSM Param Store /dev/app-name

Lowest Precedence

All the things I tried seemed to error out with issues of Invalid variable (it was trying to use the string value that my ssm lookup substituted as a path for a variable), Valid Service Attribute... could not be found (incorrect referencing of paths), or Trying to populate nonString for variable

To make sure other people have an easier time with this solution, here is what I came up with:’
One of the biggest issues I had was using other variables for my SSM Path so I didn’t have to modify it in multiple places if we changed the hierachy.
To avoid region parameter duplication, I used the serverless-plugin-cloudformation-cross-region-variables plugin.

  envFile: $[{file(./config.yml),"none"}}
  ssmStagePath: ssmcr:us-west-1:/${{opt:stage}}/app-1
  ssmDefaultPath: ssmcr:us-west-1:/dev/app-1
  idServer: ${{self:custom.envFile.idServer, '${{${{self:custom.ssmStagePath}}/idServer, ${{self:custom.ssmDefaultPath}}/idServer}}'}}
  accessMgmtServer: ${{self:custom.envFile.accessMgmtServer, '${{${{self:custom.ssmStagePath}}/accessMgmtServer,${{self:custom.ssmDefaultPath}}/accessMgmtServer}}'}}
  apiDomainName: ${{self:custom.envFile.apiDomainName, '${{${{self:custom.ssmStagePath}}/apiDomainName,${{self:custom.ssmDefaultPath}}/apiDomainName}}'}} 

I used a nested overwrite to achieve my precedence that I wanted.

I used string values to declare my ssmStagePath and ssmDefaultPath to be reused in accessing multiple variables.My biggest issue was extracting the value from this path along with the necessary variable. (This is where I got a lot of invalid variable errors, as it would lookup the value). To fix this, I placed quotes around the inside overwrite structure to make sure the value was declared as a string.

For my file, I loaded the entire file in and simply accessed values with the . (dot) notation.