serverless-tag-resources
Version:
Datamart: Tag all AWS resources with dual legacy + datamart:* tag support
108 lines (91 loc) • 3.15 kB
JavaScript
"use strict";
const { tagResources } = require("./src/template-tagger");
const { updateTagsPostDeploy } = require("./src/post-deploy-tagger");
const { removeUnwantedTags } = require("./src/post-deploy/untag");
const { validateTags } = require("./src/validation");
const { configFromProvider } = require("./src/aws-clients");
const { TAGS_TO_REMOVE } = require("./src/tags");
class TagResourcesServerlessPlugin {
constructor(serverless, options) {
this.serverless = serverless;
this.options = options;
const awsProvider = this.serverless.getProvider("aws");
this.stage = awsProvider.getStage();
this.region = awsProvider.getRegion();
this.partition = awsProvider.partition || "aws";
this.awsConfig = configFromProvider(awsProvider);
// Plugin config from custom.datamart
this.pluginConfig = (this.serverless.service.custom || {}).datamart || {};
this.hooks = {
"before:package:finalize": this.onBeforePackageFinalize.bind(this),
"after:deploy:deploy": this.onAfterDeploy.bind(this),
};
}
_log(message) {
this.serverless.cli.log(message);
}
_getStackTags() {
return this.serverless.service.provider.stackTags || {};
}
onBeforePackageFinalize() {
const stackTags = this._getStackTags();
// Validation (optional)
if (this.pluginConfig.validation) {
this._log("TAGGING: Validating tags...");
const result = validateTags(stackTags, this.stage);
if (!result.valid) {
const msg = `Tag validation failed:\n ${result.errors.join("\n ")}`;
throw new this.serverless.classes.Error(msg);
}
this._log("TAGGING: Validation passed");
}
// Tag compiled CloudFormation template
this._log("TAGGING: Updating tags in CloudFormation template...");
const cfTemplate =
this.serverless.service.provider.compiledCloudFormationTemplate;
if (cfTemplate && cfTemplate.Resources) {
tagResources(
cfTemplate.Resources,
stackTags,
this.stage,
this._log.bind(this)
);
}
// Tag custom resources section
const awsResources = this.serverless.service.resources;
if (awsResources && awsResources.Resources) {
tagResources(
awsResources.Resources,
stackTags,
this.stage,
this._log.bind(this)
);
}
}
async onAfterDeploy() {
this._log("TAGGING: Updating tags post-deploy...");
const awsProvider = this.serverless.getProvider("aws");
const stackName = awsProvider.naming.getStackName();
// Phase 1: Tag resources that CF doesn't cover natively
await updateTagsPostDeploy(
this.awsConfig,
stackName,
this._getStackTags(),
this.stage,
this.partition,
this.region,
this._log.bind(this)
);
// Phase 2: Remove unwanted tags (STAGE injected by SFW)
if (TAGS_TO_REMOVE.length > 0) {
await removeUnwantedTags(
this.awsConfig,
stackName,
TAGS_TO_REMOVE,
this._log.bind(this)
);
}
this._log("TAGGING: Post-deploy tagging complete");
}
}
module.exports = TagResourcesServerlessPlugin;