Skip to content

Instantly share code, notes, and snippets.

@PopeFelix
Created May 20, 2020 16:21
Show Gist options
  • Save PopeFelix/56b485871c672a2292fe546057810f0e to your computer and use it in GitHub Desktop.
Save PopeFelix/56b485871c672a2292fe546057810f0e to your computer and use it in GitHub Desktop.
Interpolate custom vars in serverless.yml
/*
This came about because I needed to get a VPC name that was a function of the deployment stage
(e.g. 'my-vpc-dev', 'my-vpc-qa', etc.). I could have just hardcoded the VPC name in serverless.yml and edited it for
each deploy, but where's the fun in that?
What this does is to take a value from serverless.yml like "my-vpc-${self:custom.stage}" and interpolate the variable
"${self:custom.stage}" embedded therein. This variable could resolve to another variable, so it gets called recursively.
Note that the construction "${opt:stage, self:provider.stage}" should be interpreted as
${opt:stage} || ${self:provider.stage}
*/
const fillVars = (string, serverless) => {
const sourceMap = {
self: serverless.variables.service,
opt: serverless.variables.options,
}
const match = string.match(/\${.+?}/g)
if (match) {
console.debug(`Interpolating "${string}"`)
match.forEach((matched) => {
// matched: '${SRC:PATH}'
const paths = matched.replace(/\${(.+)}/, '$1').split(/,\s*/)
console.debug({ paths: paths })
let val = paths.reduce((ret, pathspec) => {
if (ret) return ret
const [src, path] = pathspec.split(':')
console.debug({ src: src, path: path })
const target = sourceMap[src]
if (!target) {
console.warn(`Unsupported variable ${pathspec}`)
}
ret = jmespath.search(target, path)
console.debug(`Value for path "${path}" is "${ret}"`)
return ret
}, null)
// const [src, path] = matched.match(/\${(\w+):(.+?)}/).slice(1, 3)
if (val.match(/\${.+?}/)) {
console.debug(`Recursively interpolating ${val}`)
val = fillVars(val, serverless)
}
string = string.replace(matched, val)
})
}
return string
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment