From 771f8c065991ba6fbc675b3d170644b73b1e2f0a Mon Sep 17 00:00:00 2001 From: knziiy Date: Thu, 16 Oct 2025 16:20:37 +0900 Subject: [PATCH 1/2] feat: Add support for customizing tag keys --- docs/en/DEPLOY_OPTION.md | 4 +- docs/ja/DEPLOY_OPTION.md | 4 +- docs/ko/DEPLOY_OPTION.md | 4 +- packages/cdk/bin/generative-ai-use-cases.ts | 3 +- packages/cdk/lib/rag-knowledge-base-stack.ts | 3 +- packages/cdk/lib/stack-input.ts | 1 + .../cdk/test/generative-ai-use-cases.test.ts | 48 +++++++++++++++++++ 7 files changed, 62 insertions(+), 5 deletions(-) diff --git a/docs/en/DEPLOY_OPTION.md b/docs/en/DEPLOY_OPTION.md index e6a0dfd6c..98be2a6a7 100644 --- a/docs/en/DEPLOY_OPTION.md +++ b/docs/en/DEPLOY_OPTION.md @@ -1808,7 +1808,7 @@ EventBridge rules are used for scheduling, and Step Functions for process contro ### How to Set Tags -GenU supports tags for cost management and other purposes. The key name of the tag is automatically set to `GenU` `. Here are examples of how to set them: +GenU supports tags for cost management and other purposes. By default, the key name of the tag is set to `GenU`, but you can use a custom tag key by specifying `tagKey`. Here are examples of how to set them: Setting in `cdk.json`: @@ -1816,6 +1816,7 @@ Setting in `cdk.json`: // cdk.json ... "context": { + "tagKey": "MyProject", // Custom tag key (optional, default is "GenU") "tagValue": "dev", ... ``` @@ -1824,6 +1825,7 @@ Setting in `parameter.ts`: ```typescript ... + tagKey: "MyProject", // Custom tag key (optional, default is "GenU") tagValue: "dev", ... ``` diff --git a/docs/ja/DEPLOY_OPTION.md b/docs/ja/DEPLOY_OPTION.md index 1dbf61c45..bb965fe83 100644 --- a/docs/ja/DEPLOY_OPTION.md +++ b/docs/ja/DEPLOY_OPTION.md @@ -1815,7 +1815,7 @@ Kendraのインデックスが削除されても、RAG機能はオンのまま ### タグを設定する方法 -GenU ではコスト管理等に使うためのタグをサポートしています。タグのキー名には、自動で `GenU` `が設定されます。 +GenU ではコスト管理等に使うためのタグをサポートしています。デフォルトでは、タグのキー名に `GenU` が設定されますが、`tagKey` を指定することでカスタムのタグキーを使用できます。 以下に設定例を示します。 `cdk.json` での設定方法 @@ -1824,6 +1824,7 @@ GenU ではコスト管理等に使うためのタグをサポートしていま // cdk.json ... "context": { + "tagKey": "MyProject", // カスタムのタグキー(省略可能、デフォルトは "GenU") "tagValue": "dev", ... ``` @@ -1832,6 +1833,7 @@ GenU ではコスト管理等に使うためのタグをサポートしていま ```typescript ... + tagKey: "MyProject", // カスタムのタグキー(省略可能、デフォルトは "GenU") tagValue: "dev", ... ``` diff --git a/docs/ko/DEPLOY_OPTION.md b/docs/ko/DEPLOY_OPTION.md index 29592272e..06caa0b54 100644 --- a/docs/ko/DEPLOY_OPTION.md +++ b/docs/ko/DEPLOY_OPTION.md @@ -1817,7 +1817,7 @@ Kendra 인덱스가 삭제되어도 RAG 기능은 계속 켜져 있습니다. ### 태그 설정 방법 -GenU는 비용 관리 및 기타 목적을 위한 태그를 지원합니다. 태그의 키 이름은 자동으로 `GenU`로 설정됩니다. 설정 방법의 예시는 다음과 같습니다: +GenU는 비용 관리 및 기타 목적을 위한 태그를 지원합니다. 기본적으로 태그의 키 이름은 `GenU`로 설정되지만, `tagKey`를 지정하여 사용자 정의 태그 키를 사용할 수 있습니다. 설정 방법의 예시는 다음과 같습니다: `cdk.json`에서 설정: @@ -1825,6 +1825,7 @@ GenU는 비용 관리 및 기타 목적을 위한 태그를 지원합니다. 태 // cdk.json ... "context": { + "tagKey": "MyProject", // 사용자 정의 태그 키 (선택사항, 기본값은 "GenU") "tagValue": "dev", ... ``` @@ -1833,6 +1834,7 @@ GenU는 비용 관리 및 기타 목적을 위한 태그를 지원합니다. 태 ```typescript ... + tagKey: "MyProject", // 사용자 정의 태그 키 (선택사항, 기본값은 "GenU") tagValue: "dev", ... ``` diff --git a/packages/cdk/bin/generative-ai-use-cases.ts b/packages/cdk/bin/generative-ai-use-cases.ts index 3cb3149e3..54e312949 100644 --- a/packages/cdk/bin/generative-ai-use-cases.ts +++ b/packages/cdk/bin/generative-ai-use-cases.ts @@ -8,7 +8,8 @@ import { TAG_KEY } from '../consts'; const app = new cdk.App(); const params = getParams(app); if (params.tagValue) { - cdk.Tags.of(app).add(TAG_KEY, params.tagValue, { + const tagKey = params.tagKey || TAG_KEY; + cdk.Tags.of(app).add(tagKey, params.tagValue, { // Exclude OpenSearchServerless Collection from tagging excludeResourceTypes: ['AWS::OpenSearchServerless::Collection'], }); diff --git a/packages/cdk/lib/rag-knowledge-base-stack.ts b/packages/cdk/lib/rag-knowledge-base-stack.ts index c39c2396b..d90d15ef7 100644 --- a/packages/cdk/lib/rag-knowledge-base-stack.ts +++ b/packages/cdk/lib/rag-knowledge-base-stack.ts @@ -145,6 +145,7 @@ export class RagKnowledgeBaseStack extends Stack { ragKnowledgeBaseAdvancedParsingModelId, ragKnowledgeBaseBinaryVector, crossAccountBedrockRoleArn, + tagKey, tagValue, } = props.params; @@ -312,7 +313,7 @@ export class RagKnowledgeBaseStack extends Stack { resourceType: 'Custom::ApplyTags', properties: { tag: { - key: TAG_KEY, + key: tagKey || TAG_KEY, value: tagValue || '', // Pass empty string when tagValue is unset }, collectionId: collection.ref, diff --git a/packages/cdk/lib/stack-input.ts b/packages/cdk/lib/stack-input.ts index e47ccd7fd..169c02531 100644 --- a/packages/cdk/lib/stack-input.ts +++ b/packages/cdk/lib/stack-input.ts @@ -185,6 +185,7 @@ const baseStackInputSchema = z.object({ // Dashboard dashboard: z.boolean().default(false), // Tag + tagKey: z.string().nullish(), tagValue: z.string().nullish(), // Closed network closedNetworkMode: z.boolean().default(false), diff --git a/packages/cdk/test/generative-ai-use-cases.test.ts b/packages/cdk/test/generative-ai-use-cases.test.ts index b68cb0ab9..4defb45ef 100644 --- a/packages/cdk/test/generative-ai-use-cases.test.ts +++ b/packages/cdk/test/generative-ai-use-cases.test.ts @@ -62,6 +62,8 @@ describe('GenerativeAiUseCases', () => { guardrailEnabled: true, crossAccountBedrockRoleArn: '', useCaseBuilderEnabled: true, + tagKey: null, + tagValue: null, }; test('matches the snapshot', () => { @@ -160,4 +162,50 @@ describe('GenerativeAiUseCases', () => { expect(generativeAiUseCasesTemplate.toJSON()).toMatchSnapshot(); expect(dashboardTemplate.toJSON()).toMatchSnapshot(); }); + + test('tagKey functionality', () => { + // Test with custom tagKey + const appWithCustomTag = new cdk.App(); + const paramsWithCustomTag = processedStackInputSchema.parse({ + ...stackInput, + tagKey: 'CustomTag', + tagValue: 'custom-value', + }); + + const stacksWithCustomTag = createStacks( + appWithCustomTag, + paramsWithCustomTag + ); + + // Test without tagKey (should use default) + const appWithoutTagKey = new cdk.App(); + const paramsWithoutTagKey = processedStackInputSchema.parse({ + ...stackInput, + tagKey: null, + tagValue: 'default-value', + }); + + const stacksWithoutTagKey = createStacks( + appWithoutTagKey, + paramsWithoutTagKey + ); + + // Assert that both scenarios create stacks successfully + expect(stacksWithCustomTag.generativeAiUseCasesStack).toBeDefined(); + expect(stacksWithoutTagKey.generativeAiUseCasesStack).toBeDefined(); + + // Test that RagKnowledgeBaseStack is created properly with custom tagKey + if (stacksWithCustomTag.ragKnowledgeBaseStack) { + const customTagTemplate = Template.fromStack( + stacksWithCustomTag.ragKnowledgeBaseStack + ); + // Check that custom resource uses the custom tag key + customTagTemplate.hasResourceProperties('Custom::ApplyTags', { + tag: { + key: 'CustomTag', + value: 'custom-value', + }, + }); + } + }); }); From f1629643c431e0df494e84a00ca4b7fd54e46c8e Mon Sep 17 00:00:00 2001 From: knziiy Date: Thu, 23 Oct 2025 10:39:44 +0900 Subject: [PATCH 2/2] added tagKey to cdk.json --- packages/cdk/cdk.json | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cdk/cdk.json b/packages/cdk/cdk.json index 317bed793..9438dfa84 100644 --- a/packages/cdk/cdk.json +++ b/packages/cdk/cdk.json @@ -16,6 +16,7 @@ }, "context": { "env": "", + "tagKey": null, "tagValue": null, "ragEnabled": false, "kendraIndexArn": null,