AWS CDKのデプロイが「’Only root constructs may have an empty name’」というエラーとなる

2021.11.12

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、AWS CDKのデプロイが'Only root constructs may have an empty name'というエラーとなる際の確認点についてです。

先に結論

CDKコンストラクトのIDの指定し忘れでした。

CDKデプロイが'Only root constructs may have an empty name'となる

下記のようなCDKスタックの定義があります。

lib/aws-cdk-app-stack.ts

import * as cdk from '@aws-cdk/core';
import * as lambdaNodejs from '@aws-cdk/aws-lambda-nodejs';

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

    new lambdaNodejs.NodejsFunction(this, '', {
      entry: 'src/lambda/sampleHandler.ts',
      handler: 'handler',
    });
  }
}

これをCDKデプロイしてみるとOnly root constructs may have an empty nameというメッセージのエラーとなります。

$ cdk deploy

/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/constructs/src/construct.ts:54
        throw new Error('Only root constructs may have an empty name');
              ^
Error: Only root constructs may have an empty name
    at new Node (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/constructs/src/construct.ts:54:15)
    at new ConstructNode (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/@aws-cdk/core/lib/construct-compat.ts:184:24)
    at Object.createNode (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/@aws-cdk/core/lib/construct-compat.ts:55:11)
    at new Construct (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/constructs/src/construct.ts:409:26)
    at new Construct (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/@aws-cdk/core/lib/construct-compat.ts:52:5)
    at new Resource (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/@aws-cdk/core/lib/resource.ts:68:5)
    at new FunctionBase (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/@aws-cdk/aws-lambda/lib/function-base.js:17:9)
    at new Function (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/@aws-cdk/aws-lambda/lib/function.ts:304:5)
    at new NodejsFunction (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/node_modules/@aws-cdk/aws-lambda-nodejs/lib/function.ts:53:5)
    at new AwsCdkAppStack (/Users/wakatsuki.ryuta/projects/cm-rwakatsuki/aws-cdk-app/lib/aws-cdk-app-stack.ts:8:5)
Subprocess exited with error 1

対処

CDKコンストラクトのIDが空となっていたためでした。適当な値としてsampleLambdaを指定してみます。

lib/aws-cdk-app-stack.ts

import * as cdk from '@aws-cdk/core';
import * as lambdaNodejs from '@aws-cdk/aws-lambda-nodejs';

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

    new lambdaNodejs.NodejsFunction(this, 'sampleLambda', {
      entry: 'src/lambda/sampleHandler.ts',
      handler: 'handler',
    });
  }
}

CDKデプロイしてみるとエラーなく実施できました。

結局どういう意味のエラーなのか

エラーメッセージを和訳すると「ルートコンストラクトのみが空の名前を持つことができます」です。

AWS CDKにおいては、App -> Stack -> Constructという順のツリー構造を持ちます。図で表すと下記のようになります。

What is the AWS CDK? - AWS Cloud Development Kit (CDK)より引用。

今回はそのうちルートではないコンストラクトでIDを指定しなかったためエラーとなっていたようです。

ルートのコンストラクトはおそらくアプリ(App)を指しているかと思われます。下記ではスタックのIDを指定しなければ同様のエラーとなりますが、アプリではID指定は不要となっています。

bin/aws-cdk-app.ts

#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from '@aws-cdk/core';
import { AwsCdkAppStack } from '../lib/aws-cdk-app-stack';

const app = new cdk.App(); //アプリ。IDの指定不要
new AwsCdkAppStack(app, 'AwsCdkAppStack', {}); //スタック。IDを指定しないと同じエラーとなる

参考

以上