如何使用AWS CDK编写单元测试校验栈内所有资源是否正确打标签
实现方法
CDK 官方断言库没有内置你示例中的toHaveAllResourcesAPI,你可以通过以下两种方案实现全栈资源标签校验需求:
方案1:直接遍历合成后的模板资源
你可以先将CDK栈合成CloudFormation模板,再遍历所有资源逐一校验标签,示例代码如下:
import * as cdk from 'aws-cdk-lib'; import { Template } from 'aws-cdk-lib/assertions'; import { YourStack } from '../lib/your-stack'; test('栈内所有资源都带有ou=ds标签', () => { const app = new cdk.App(); const stack = new YourStack(app, 'TestStack'); const template = Template.fromStack(stack); const allResources = template.toJSON().Resources; Object.entries(allResources).forEach(([resourceId, resource]: [string, any]) => { // 跳过CDK内置的元数据资源,可根据需求调整过滤规则 if (resource.Type === 'AWS::CDK::Metadata') return; // 断言标签数组包含目标键值对 expect(resource.Tags).toEqual( expect.arrayContaining([ { Key: 'ou', Value: 'ds' } ]) ); }); });
方案2:封装自定义断言复用逻辑
如果需要频繁使用全栈标签校验能力,可以把遍历逻辑封装为自定义断言,直接实现你示例中的调用风格:
import * as cdk from 'aws-cdk-lib'; import { Template } from 'aws-cdk-lib/assertions'; import { YourStack } from '../lib/your-stack'; // 注册自定义断言 expect.extend({ toHaveAllResourcesTagged(stack: cdk.Stack, expectedTag: { Key: string; Value: string }) { const template = Template.fromStack(stack); const allResources = template.toJSON().Resources; const invalidResources: string[] = []; Object.entries(allResources).forEach(([resourceId, resource]: [string, any]) => { if (resource.Type === 'AWS::CDK::Metadata') return; const hasValidTag = resource.Tags?.some( (tag: any) => tag.Key === expectedTag.Key && tag.Value === expectedTag.Value ); if (!hasValidTag) invalidResources.push(`${resource.Type}(${resourceId})`); }); return invalidResources.length === 0 ? { pass: true, message: () => `所有资源都已配置标签${expectedTag.Key}=${expectedTag.Value}`, } : { pass: false, message: () => `以下资源未配置要求标签:${invalidResources.join('、')}`, }; }, }); // 调用方式和你示例中的写法完全一致 test('栈内所有资源都带有ou=ds标签', () => { const app = new cdk.App(); const stack = new YourStack(app, 'TestStack'); expect(stack).toHaveAllResourcesTagged({ Key: 'ou', Value: 'ds' }); });
内容的提问来源于stack exchange,提问作者Christian Bonzelet
相关产品推荐
相关产品推荐

