Skip to content

Instantly share code, notes, and snippets.

@igrek8
Created February 17, 2022 18:21
Show Gist options
  • Save igrek8/0234147af864c614064395f2166d6139 to your computer and use it in GitHub Desktop.
Save igrek8/0234147af864c614064395f2166d6139 to your computer and use it in GitHub Desktop.
Composes a AWS CloudFormation template from multiple sources using deep-merge
#!/usr/bin/env node
const glob = require("glob");
const yargs = require("yargs");
const { hideBin } = require("yargs/helpers");
const path = require("path");
const fs = require("fs");
const yaml = require("yaml");
const lodash = require("lodash");
const argv = yargs(hideBin(process.argv))
.option("folder", { type: "string", alias: "f", default: ".aws/template" })
.option("output", { type: "string", alias: "o", default: "template.yml" })
.demandOption("folder")
.demandOption("output")
.parse();
const parts = [];
const tags = {
"!Base64": "Fn::Base64",
"!Cidr": "Fn::Cidr",
"!FindInMap": "Fn::FindInMap",
"!GetAtt": "Fn::GetAtt",
"!GetAZs": "Fn::GetAZs",
"!ImportValue": "Fn::ImportValue",
"!Join": "Fn::Join",
"!Select": "Fn::Select",
"!Split": "Fn::Split",
"!Sub": "Fn::Sub",
"!Transform": "Fn::Transform",
"!Ref": "Ref",
"!Condition": "Condition",
"!And": "Fn::And",
"!Equals": "Fn::Equals",
"!If": "Fn::If",
"!Not": "Fn::Not",
"!Or": "Fn::Or",
};
const customTags = [];
for (const key in tags) {
if (tags.hasOwnProperty(key)) {
const value = tags[key];
customTags.push({
tag: key,
identity: () => true,
resolve: (_, cst) => {
return {
[value]: yaml.parse(cst.rawValue, {
customTags,
}),
};
},
});
}
}
for (const filePath of glob.sync(path.join(argv.folder, "**/*.{yml,yaml}"))) {
let fileContent = fs.readFileSync(filePath, { encoding: "utf-8" });
let data = yaml.parse(fileContent, { customTags });
parts.push(data);
}
if (parts.length > 0) {
fs.writeFileSync(
argv.output,
yaml.stringify(lodash.merge(...parts), { customTags }),
{ encoding: "utf-8" }
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment