如何配置Serverless为所有部署资源添加aws:cloudformation:stack-name标签
解决方案:为Serverless部署的所有AWS资源添加统一标签并实现成本过滤
一、通过Serverless Framework配置全局标签,覆盖所有资源
Serverless默认仅为Lambda、CloudWatch等核心资源自动添加aws:cloudformation:stack-name标签,要让API Gateway、ElastiCache、X-Ray等资源也带上该标签,需要手动在serverless.yml中配置全局标签,并针对自定义资源单独补充标签逻辑。
1. 配置全局Provider标签
在provider节点下添加tags字段,将栈名作为全局标签,让Serverless自动为支持的资源(如API Gateway)打上标签:
service: your-service-name provider: name: aws runtime: nodejs18.x stage: ${opt:stage, 'dev'} # 全局标签配置 tags: aws:cloudformation:stack-name: ${self:service}-${self:provider.stage} # 可额外添加自定义标签,方便后续过滤 ServiceName: ${self:service}
2. 为自定义资源补充标签
对于通过resources节点定义的ElastiCache等自定义资源,需要手动在资源属性中添加标签:
resources: Resources: # ElastiCache集群示例 MyCacheCluster: Type: AWS::ElastiCache::CacheCluster Properties: CacheNodeType: cache.t3.micro Engine: redis NumCacheNodes: 1 # 手动添加栈名标签 Tags: - Key: aws:cloudformation:stack-name Value: ${self:service}-${self:provider.stage} # X-Ray分组示例(用于标记X-Ray资源) MyServiceXRayGroup: Type: AWS::XRay::Group Properties: GroupName: ${self:service}-${self:provider.stage}-xray FilterExpression: "service(\"${self:service}-${self:provider.stage}\")" Tags: - Key: aws:cloudformation:stack-name Value: ${self:service}-${self:provider.stage}
3. 针对API Gateway的特殊配置
如果使用的是HTTP API,可在provider.apiGateway下单独指定标签,确保API Gateway资源继承栈名标签:
provider: apiGateway: tags: aws:cloudformation:stack-name: ${self:service}-${self:provider.stage}
二、功能受限情况下的替代方案
如果部分资源无法通过Serverless自动打标签,可采用以下方案实现成本过滤:
1. 批量补打标签(AWS Tag Editor)
- 登录AWS控制台,打开Tag Editor,选择需要补标签的资源类型(API Gateway、ElastiCache等);
- 通过资源名称筛选(通常Serverless部署的资源名称会包含服务名/栈名),选中目标资源;
- 批量添加
aws:cloudformation:stack-name标签,值设置为对应服务的栈名。
2. 基于资源名称的Cost Explorer过滤
在Cost Explorer中,除了标签过滤,还可以结合资源名称维度筛选:
- 添加过滤条件:
资源名称包含 ${self:service}-${self:provider.stage}; - 结合标签过滤(针对已打标签的Lambda/CloudWatch),实现全资源范围的成本隔离。
3. 部署后自动打标签脚本
编写脚本通过AWS SDK批量为栈内资源打标签,通过Serverless的post-deploy钩子自动执行:
- 安装
serverless-plugin-scripts插件:
npm install serverless-plugin-scripts --save-dev
- 在
serverless.yml中配置钩子:
plugins: - serverless-plugin-scripts custom: scripts: hooks: after:deploy:deploy: node ./tag-stack-resources.js
- 编写
tag-stack-resources.js(使用AWS SDK v3示例):
import { CloudFormationClient, ListStackResourcesCommand } from "@aws-sdk/client-cloudformation"; import { ResourceGroupsTaggingAPIClient, TagResourcesCommand } from "@aws-sdk/client-resource-groups-tagging-api"; const client = new CloudFormationClient({ region: process.env.AWS_REGION }); const tagClient = new ResourceGroupsTaggingAPIClient({ region: process.env.AWS_REGION }); const stackName = `${process.env.SERVICE_NAME}-${process.env.STAGE}`; async function tagStackResources() { // 获取栈内所有资源 const listCommand = new ListStackResourcesCommand({ StackName: stackName }); const stackResources = await client.send(listCommand); // 提取资源ARN列表 const resourceArns = stackResources.StackResourceSummaries.map(res => res.PhysicalResourceId); // 批量添加标签 const tagCommand = new TagResourcesCommand({ ResourceARNList: resourceArns, Tags: { "aws:cloudformation:stack-name": stackName } }); await tagClient.send(tagCommand); console.log(`Successfully tagged all resources in stack: ${stackName}`); } tagStackResources().catch(err => console.error(err));
4. X-Ray成本的特殊处理
X-Ray的费用通常与产生跟踪数据的Lambda关联,可通过以下方式过滤:
- 在Cost Explorer中先筛选带有
aws:cloudformation:stack-name标签的Lambda; - 查看该Lambda对应的X-Ray关联费用(Cost Explorer的“相关成本”功能);
- 结合自定义X-Ray分组的标签,直接筛选X-Ray资源成本。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

