Skip to content

Instantly share code, notes, and snippets.

@peter
Created December 17, 2020 11:30
Show Gist options
  • Select an option

  • Save peter/8ae69d0236a8d276c1021cdea6417a53 to your computer and use it in GitHub Desktop.

Select an option

Save peter/8ae69d0236a8d276c1021cdea6417a53 to your computer and use it in GitHub Desktop.

Revisions

  1. peter created this gist Dec 17, 2020.
    54 changes: 54 additions & 0 deletions terraform-util.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,54 @@
    const fs = require('fs')

    module.exports = {
    writeTerraform,
    generateMain,
    }

    // Templates are just terraform (.tf files) with the following kinds of interpolations:
    // 1. Variables embedded in a string: "terraform-states-<id>"
    // 2. Variables occupying an entire string: "<apiId>".
    // If the value is a string then double quotes are preserved and for most other data types they are not (for say a number).
    // If value is an object then quotes are preserved if quotes === true, example object value without quotes:
    // { value: `aws_api_gateway_deployment.${api}.stage_name`, quotes: false }
    // 2. As a comment on its own line for a block of code: #<lambdas>
    function template (name, variables) {
    const code = fs.readFileSync(`_terraform/templates/${name}.tf`).toString()
    return code.replace(/#?"?<([a-z0-9]+)>"?/gi, (m, key) => {
    const value = variables[key]
    if (m.startsWith('"') && m.endsWith('"')) {
    if (typeof value === 'string') {
    return `"${value}"`
    } else if (typeof value === 'object' && value.value) {
    return value.quotes ? `"${value.value}"` : value.value
    } else {
    return value
    }
    } else if (m.startsWith('"') && !m.endsWith('"')) {
    return `"${value}`
    } else if (!m.startsWith('"') && m.endsWith('"')) {
    return `${value}"`
    } else {
    return value
    }
    })
    }

    function writeTerraform (code, options = {}) {
    if (Array.isArray(code)) code = code.join('\n')
    const tfPath = (options.path || process.argv[1] || 'main.js').replace(/\.js$/, '.tf')
    fs.writeFileSync(tfPath, code)
    }

    // Example Terraform generation from a main.tf template
    function generateMain () {
    const variables = {
    api,
    name,
    body: { value: `data.template_file.openapi_${api}.rendered`, quotes: false },
    restApiId: { value: `aws_api_gateway_rest_api.${api}.id`, quotes: false },
    apiId: { value: `aws_api_gateway_rest_api.${api}.id`, quotes: false },
    stageName: { value: `aws_api_gateway_deployment.${api}.stage_name`, quotes: false }
    }
    return template('main', variables)
    }