AWS CDKで命名規則に従ってリソース名を作成する関数を作ってみました

CDKで開発する機会があり、その際にリソース命名のための関数を作成したため、ご紹介します。
もっと良いコードがある等ありましたら、コメントいただけると幸いです。

Pythonを使ってCDKを記述していたため、コード自体はPythonのコードとなります。

## 命名規則
命名規則はClassMethodさんの記事を参考にさせていただきました。
ClassMethodさん、いつもありがとうございます。

[参考とした記事はこちらです](https://dev.classmethod.jp/articles/aws-name-rule/)

参考とした上で、以下のように命名する形に決めました。
{system}-{env}-{任意に決める文字列}
S3 Bucketの場合は、末尾にAWS Account IDをつけることにします。
{system}-{env}-{任意に決める文字列}-{AWS Account ID}


## コード
気にした点は以下です。
- AWS WAFのログに対応できること
- S3BucketにはAWSアカウントのIDをつけることができること
- リソース名の最大長を侵害しないこと


```python
def naming(system, env, account_id, any_name, service=None, is_waflog=False):
    """
    system: システム名
    env: 環境名
    account_id: AWSアカウントのID
    any_name: 任意の名前
    service: 命名対象のサービス（"ec2-instance"等の文字列を想定しています）
             指定が無い場合は、Tagの命名だと判定するようにします
    is_waflog: webaclのログを格納するリソースに必要となる文字列を含めるために用意しています。
    """
    # 各リソース名の最大長を取得
    with open('max_name_len.json', 'r') as f:
        max_name_lengths = json.load(f)
    
    # 命名規則に従ってリソース名作成
    regularized_name = f'{system}-{env}-{any_name}'
    
    # waf log用リソースの場合
    if is_waflog:
        regularized_name = f'aws-waf-logs-{regularized_name}'
    
    # リソースごとに最大長を判定
    if service:
        service = service.split('-')
        max_name_length = max_name_lengths[service[0]][service[1]]
        
        # S3bucketはLowerケースとする + aws account idをつける
        if service[0] == 's3':
            regularized_name = regularized_name.lower()
            regularized_name += f'-{account_id}'

        if len(regularized_name) > max_name_length:
            regularized_name = regularized_name[:max_name_length]
        
    else:
        # tagの最大長である256を基準として判定
        max_len_tag = 256
        if len(regularized_name) > max_len_tag:
            regularized_name = regularized_name[:max_len_tag]
    
    return regularized_name
```

各リソース名の最大長を記載したファイルです。
※使ったリソースしか記述していません。
```json:max_name_len.json
{
    "apigateway": {
        "stage": 128
    },
    "cloudwatch": {
        "alarm": 255,
        "loggroup": 512,
        "metrics": 255
    },
    "cognito": {
        "userpool": 128
    },
    "ec2": {
        "instance": 256,
        "subnet": 256,
        "vpc": 256
    },
    "iam": {
        "policy": 128,
        "role": 64
    },
    "lambda": {
        "function": 64
    },
    "s3": {
        "bucket": 63
    },
    "rds": {
        "cluster": 63,
        "instance": 63,
        "subnetgroup": 255,
        "proxy": 60
    },
    "waf": {
        "rule": 128,
        "webacl": 128
    }
}
```

## 実行結果
```bash
naming('test', 'dev', '1111111', 'test-name', service='ec2-instance')
　test-dev-test-name
naming('test', 'dev', '1111111', 'test-name', service='s3-bucket')
　test-dev-test-name-1111111
naming('test', 'dev', '1111111', 'test-name', service='s3-bucket', is_waflog=True)           
　aws-waf-logs-test-dev-test-name-1111111
```

## まとめ
今回はCDKで構築を行う際に利用したリソース命名のための関数を紹介しました。CDKでは、命名規則以前に命名自体がベストプラクティスに反していたりするため、リソースへの命名をどう考えるか難しいところではあります。
どなたかの参考になれば幸いです。

[CDKベストプラクティス](https://aws.amazon.com/jp/blogs/news/best-practices-for-developing-cloud-applications-with-aws-cdk/#:~:text=%E8%87%AA%E5%8B%95%E3%81%A7%E7%94%9F%E6%88%90%E3%81%95%E3%82%8C%E3%82%8B%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E5%90%8D%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%80%81%E7%89%A9%E7%90%86%E7%9A%84%E3%81%AA%E5%90%8D%E5%89%8D%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%AA%E3%81%84)