From 59c94c16687cbab3cd901d54d5b84b4ed9986122 Mon Sep 17 00:00:00 2001 From: Hemal Shah Date: Sun, 9 Mar 2025 20:15:17 +0000 Subject: [PATCH 1/2] feat(azure): add azure resources default tagging --- src/lib/azure/common/index.ts | 1 + .../azure/common/resource-name-formatter.ts | 4 +++- src/lib/azure/common/stack.ts | 6 +++-- src/lib/azure/common/tagging.ts | 24 +++++++++++++++++++ src/lib/azure/common/types.ts | 1 + .../common/cdkConfig/api-management.json | 2 +- .../services/api-management-manager.test.ts | 2 +- 7 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 src/lib/azure/common/tagging.ts diff --git a/src/lib/azure/common/index.ts b/src/lib/azure/common/index.ts index f3b00b2b..0f16b3fa 100644 --- a/src/lib/azure/common/index.ts +++ b/src/lib/azure/common/index.ts @@ -2,4 +2,5 @@ export * from './constants' export * from './construct' export * from './resource-name-formatter' export * from './stack' +export * from './tagging' export * from './types' diff --git a/src/lib/azure/common/resource-name-formatter.ts b/src/lib/azure/common/resource-name-formatter.ts index 496feeb2..1102f716 100644 --- a/src/lib/azure/common/resource-name-formatter.ts +++ b/src/lib/azure/common/resource-name-formatter.ts @@ -33,6 +33,8 @@ export class AzureResourceNameFormatter extends Construct { azureResourceNameElements.push(this.props.stage) - return azureResourceNameElements.filter(Boolean).join('-') + return azureResourceNameElements + .filter(azureResourceNameElements => azureResourceNameElements != undefined) + .join('-') } } diff --git a/src/lib/azure/common/stack.ts b/src/lib/azure/common/stack.ts index 3ac0606f..14476b36 100644 --- a/src/lib/azure/common/stack.ts +++ b/src/lib/azure/common/stack.ts @@ -1,9 +1,9 @@ import fs from 'fs' import { CommonAzureConstruct } from './construct' import { CommonAzureStackProps } from './types' - +import { TagsAddingAspect } from './tagging' import appRoot from 'app-root-path' -import { TerraformStack } from 'cdktf' +import { Aspects, TerraformStack } from 'cdktf' import { Construct } from 'constructs' import _ from 'lodash' import { isDevStage } from '../../common' @@ -35,6 +35,8 @@ export class CommonAzureStack extends TerraformStack { this.determineStageContexts() this.props = this.determineConstructProps(props) + + Aspects.of(this).add(new TagsAddingAspect(this.props.defaultTags || {})) } /** diff --git a/src/lib/azure/common/tagging.ts b/src/lib/azure/common/tagging.ts new file mode 100644 index 00000000..315f6dfd --- /dev/null +++ b/src/lib/azure/common/tagging.ts @@ -0,0 +1,24 @@ +import { IAspect } from 'cdktf' +import { IConstruct } from 'constructs' + +type TaggableConstruct = IConstruct & { + tags?: { [key: string]: string } + tagsInput?: { [key: string]: string } +} + +function isTaggableConstruct(defaultTags: IConstruct): defaultTags is TaggableConstruct { + return 'tags' in defaultTags && 'tagsInput' in defaultTags +} + +export class TagsAddingAspect implements IAspect { + constructor(private tagsToAdd: Record) {} + + // This method is called on every Construct within the specified scope (resources, data sources, etc.). + visit(node: IConstruct) { + if (isTaggableConstruct(node)) { + // We need to take the input value to not create a circular reference + const currentTags = node.tagsInput || {} + node.tags = { ...this.tagsToAdd, ...currentTags } + } + } +} diff --git a/src/lib/azure/common/types.ts b/src/lib/azure/common/types.ts index ea8cb984..deda6291 100644 --- a/src/lib/azure/common/types.ts +++ b/src/lib/azure/common/types.ts @@ -14,6 +14,7 @@ export interface CommonAzureStackProps extends BaseProps, AzurermProviderConfig resourceSuffix?: string resourceNameOptions?: { [key: string]: AzureResourceNameFormatterProps } location?: string + defaultTags?: { [key: string]: string } } export interface AzureRemoteBackendProps extends AzurermBackendConfig { diff --git a/src/test/azure/common/cdkConfig/api-management.json b/src/test/azure/common/cdkConfig/api-management.json index a6a575d4..e57076bb 100644 --- a/src/test/azure/common/cdkConfig/api-management.json +++ b/src/test/azure/common/cdkConfig/api-management.json @@ -16,7 +16,7 @@ { "displayName": "test", "method": "post", - "urlTemplate": "/test/{path}", + "urlTemplate": "/test/{*path}", "templateParameter": [ { "name": "path", diff --git a/src/test/azure/services/api-management-manager.test.ts b/src/test/azure/services/api-management-manager.test.ts index cb0eb6fe..5c88b57d 100644 --- a/src/test/azure/services/api-management-manager.test.ts +++ b/src/test/azure/services/api-management-manager.test.ts @@ -255,7 +255,7 @@ describe('TestAzureApiManagementConstruct', () => { type: '', }, ], - url_template: '/test/{path}', + url_template: '/test/{*path}', }) }) }) From e4495bdda00370083ebab0158584138083f9f76a Mon Sep 17 00:00:00 2001 From: sathish-palanivelu Date: Mon, 10 Mar 2025 11:26:38 +0000 Subject: [PATCH 2/2] fix(azure): add exclusion list for tags --- src/lib/azure/common/constants.ts | 5 +++++ src/lib/azure/common/tagging.ts | 25 +++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/lib/azure/common/constants.ts b/src/lib/azure/common/constants.ts index c54cf35e..2087e693 100644 --- a/src/lib/azure/common/constants.ts +++ b/src/lib/azure/common/constants.ts @@ -2,3 +2,8 @@ export enum AzureRemoteBackend { local = 'local', azurerm = 'azurerm', } + +/** + * List of Azure resources that excludes tags + */ +export const RESOURCES_TO_EXCLUDE_TAGS = new Set(['ApiManagementNamedValue']) diff --git a/src/lib/azure/common/tagging.ts b/src/lib/azure/common/tagging.ts index 315f6dfd..c5bddb14 100644 --- a/src/lib/azure/common/tagging.ts +++ b/src/lib/azure/common/tagging.ts @@ -1,13 +1,14 @@ import { IAspect } from 'cdktf' import { IConstruct } from 'constructs' +import { RESOURCES_TO_EXCLUDE_TAGS } from './constants' type TaggableConstruct = IConstruct & { - tags?: { [key: string]: string } - tagsInput?: { [key: string]: string } + tags?: { [key: string]: string } | string[] + tagsInput?: { [key: string]: string } | string[] } -function isTaggableConstruct(defaultTags: IConstruct): defaultTags is TaggableConstruct { - return 'tags' in defaultTags && 'tagsInput' in defaultTags +function isTaggableConstruct(node: IConstruct): node is TaggableConstruct { + return 'tags' in node && 'tagsInput' in node } export class TagsAddingAspect implements IAspect { @@ -15,10 +16,18 @@ export class TagsAddingAspect implements IAspect { // This method is called on every Construct within the specified scope (resources, data sources, etc.). visit(node: IConstruct) { - if (isTaggableConstruct(node)) { - // We need to take the input value to not create a circular reference - const currentTags = node.tagsInput || {} - node.tags = { ...this.tagsToAdd, ...currentTags } + // We need to take the input value to not create a circular reference + if (!isTaggableConstruct(node)) { + return } + + // Determine if the resource excludes `tags` + if (RESOURCES_TO_EXCLUDE_TAGS.has(node.constructor.name)) { + node.tags = undefined // Completely remove tags for this resource + return + } + + const currentTags = node.tagsInput || {} + node.tags = { ...this.tagsToAdd, ...currentTags } } }