【備忘録】CDKで作成したリソースにタグを付与する方法

# この記事について
本記事は、AWS CDKを利用する上でのTipsを紹介します。
cdkで作成したリソースにTagをつける方法について、備忘録がてら簡単にまとめます。

# 動作環境
この記事の内容は以下の環境で動作確認を行っています。
- Node.js 20.15.0
- TypeScript 5.5.2
- AWS CDK v2(2.150.0)

# 結論
`cdk.Tags`を使うことで、CDKで作成したリソースにタグを簡単に付与できます。

# 使い方
## Stack全体に同一のTagを付与したい場合
スタック全体にタグを付与するには、`cdk.Tags.of(stack).add('タグキー', 'タグ値')`の形式でタグを追加します。これにより、そのスタック内のすべてのリソースに同じタグが付与されます。例えば、リソースを作成した環境を表す「Environment: Development」というタグをスタック全体に付けることが可能です。

```typescript:bin/cdk_test_study.ts
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { CdkTestStudyStack } from '../lib/cdk_test_study-stack';

const app = new cdk.App();
const stack = new CdkTestStudyStack(app, 'CdkTestStudyStack', {});
cdk.Tags.of(stack).add('Environment', 'Development');
```

## Stack内の特定のリソースに同一のTagを付与したい場合
スタック内の特定のリソースにのみタグを付与したい場合は、`cdk.Tags.of(リソース).add('タグキー', 'タグ値')`の形式でタグを追加します。例えば、VPCリソースに「CreatedBy: CDK」というタグを付与することで、そのリソースがCDKによって作成されたことを明示できます。
指定したscopeで作成される全てのリソースに対してタグが付与されるため、L2コンストラクトで作成したリソースを指定する場合は、そのコンストラクトで作成されるリソース全てに同一のタグが付与されます。（下記のようにタグを作成した場合、VPCだけでなくSubnetやRoute Tableなどにも同一のタグが付与されます）

```typescript:lib/cdk_test_study-stack.ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

export class CdkTestStudyStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const vpc = new ec2.Vpc(this, 'CdkTestStudyVpc', {
      maxAzs: 2,
      natGateways: 0,
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'CdkTestStudyPrivate',
          subnetType: ec2.SubnetType.PRIVATE_ISOLATED
        }
      ]
    });
    cdk.Tags.of(vpc).add('CreatedBy', 'CDK');
  }
}
```

```:作成されるテンプレートの一部
{
 "Resources": {
  "CdkTestStudyVpcD7D81CBC": {
   "Type": "AWS::EC2::VPC",
   "Properties": {
    "CidrBlock": "10.0.0.0/16",
    "EnableDnsHostnames": true,
    "EnableDnsSupport": true,
    "InstanceTenancy": "default",
    "Tags": [
     {
      "Key": "CreatedBy",
      "Value": "CDK"
     },
     {
      "Key": "Environment",
      "Value": "Development"
     },
     {
      "Key": "Name",
      "Value": "CdkTestStudyStack/CdkTestStudyVpc"
     }
    ]
   },
   "Metadata": {
    "aws:cdk:path": "CdkTestStudyStack/CdkTestStudyVpc/Resource"
   }
  },
  "CdkTestStudyVpcCdkTestStudyPrivateSubnet1Subnet8D6AE612": {
   "Type": "AWS::EC2::Subnet",
   "Properties": {
    "AvailabilityZone": {
     "Fn::Select": [
      0,
      {
       "Fn::GetAZs": ""
      }
     ]
    },
    "CidrBlock": "10.0.0.0/24",
    "MapPublicIpOnLaunch": false,
    "Tags": [
     {
      "Key": "aws-cdk:subnet-name",
      "Value": "CdkTestStudyPrivate"
     },
     {
      "Key": "aws-cdk:subnet-type",
      "Value": "Isolated"
     },
     {
      "Key": "CreatedBy",
      "Value": "CDK"
     },
     {
      "Key": "Environment",
      "Value": "Development"
     },
     {
      "Key": "Name",
      "Value": "CdkTestStudyStack/CdkTestStudyVpc/CdkTestStudyPrivateSubnet1"
     }
    ],
    "VpcId": {
     "Ref": "CdkTestStudyVpcD7D81CBC"
    }
   },
   "Metadata": {
    "aws:cdk:path": "CdkTestStudyStack/CdkTestStudyVpc/CdkTestStudyPrivateSubnet1/Subnet"
   }
  },
  "CdkTestStudyVpcCdkTestStudyPrivateSubnet1RouteTableBB6508F0": {
   "Type": "AWS::EC2::RouteTable",
   "Properties": {
    "Tags": [
     {
      "Key": "CreatedBy",
      "Value": "CDK"
     },
     {
      "Key": "Environment",
      "Value": "Development"
     },
     {
      "Key": "Name",
      "Value": "CdkTestStudyStack/CdkTestStudyVpc/CdkTestStudyPrivateSubnet1"
     }
    ],
    "VpcId": {
     "Ref": "CdkTestStudyVpcD7D81CBC"
    }
   },
   "Metadata": {
    "aws:cdk:path": "CdkTestStudyStack/CdkTestStudyVpc/CdkTestStudyPrivateSubnet1/RouteTable"
   }
  },
  "CdkTestStudyVpcCdkTestStudyPrivateSubnet1RouteTableAssociationAD59FD5B": {
   "Type": "AWS::EC2::SubnetRouteTableAssociation",
   "Properties": {
    "RouteTableId": {
     "Ref": "CdkTestStudyVpcCdkTestStudyPrivateSubnet1RouteTableBB6508F0"
    },
    "SubnetId": {
     "Ref": "CdkTestStudyVpcCdkTestStudyPrivateSubnet1Subnet8D6AE612"
    }
   },
   "Metadata": {
    "aws:cdk:path": "CdkTestStudyStack/CdkTestStudyVpc/CdkTestStudyPrivateSubnet1/RouteTableAssociation"
   }
  }
 }
}
```

# 参考
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html