[AWS CDK] スタックの合成が “Resolution error: Authorizer (<Construct Path>) must be attached to a RestApi.” というエラーになる場合の確認ポイント

2024.02.28

こんにちは、CX 事業本部製造ビジネステクノロジー部の若槻です。

今回は、AWS CDK スタックの合成(Synthesize)が Resolution error: Authorizer (<Construct Path>) must be attached to a RestApi. というエラーになる場合の確認ポイントについてです。

事象

次のような CDK コード(TypeScript)のスタックに対して CDK Synth を行おうとしました。REST API に Congnito オーソライザーがアタッチされていましたが、一時的に認証機能を無効化するため、オーソライザーの設定をコメントアウトした、という状況です。

import { aws_lambda_nodejs, aws_apigateway, aws_cognito } from "aws-cdk-lib";
import { Construct } from "constructs";

interface ApiConstructProps {
  cognitoUserPool: aws_cognito.UserPool;
  restApiFunc: aws_lambda_nodejs.NodejsFunction;
}

export class ApiConstruct extends Construct {
  constructor(scope: Construct, id: string, props: ApiConstructProps) {
    super(scope, id);

    const { cognitoUserPool, restApiFunc } = props;

    /**
     * Cognito ユーザープール Authorizer を作成
     */
    const cognitoUserPoolsAuthorizer =
      new aws_apigateway.CognitoUserPoolsAuthorizer(
        this,
        "CognitoUserPoolsAuthorizer",
        {
          cognitoUserPools: [cognitoUserPool],
        },
      );

    /**
     * REST API を作成
     */
    new aws_apigateway.LambdaRestApi(this, "RestApi", {
      handler: restApiFunc,
      //defaultMethodOptions: { authorizer: cognitoUserPoolsAuthorizer }, // コメントアウト
    });
  }
}

しかし、CDK Synth を行うと次のようなエラーが発生しました。

$ npx cdk synth
(中略)

Error: Resolution error: Resolution error: Resolution error: Authorizer (<スタック名>/Api/CognitoUserPoolsAuthorizer) must be attached to a RestApi.

原因

原因は、CognitoUserPoolsAuthorizer のリソースが作成されようとしているが、Rest API にアタッチされていないためでした。

AWS CLI の aws apigateway create-authorizer コマンドのドキュメントを見ると、オーソライザーを使用する REST API の指定は必須となっています。

  create-authorizer
--rest-api-id <value>
--name <value>
--type <value>
[--provider-arns <value>]
[--auth-type <value>]
[--authorizer-uri <value>]
[--authorizer-credentials <value>]
[--identity-source <value>]
[--identity-validation-expression <value>]
[--authorizer-result-ttl-in-seconds <value>]

解決

解決方法としては、次のように CognitoUserPoolsAuthorizer のリソースを作成するコード自体も合わせてコメントアウトすることです。

import { aws_lambda_nodejs, aws_apigateway, aws_cognito } from "aws-cdk-lib";
import { Construct } from "constructs";

interface ApiConstructProps {
  cognitoUserPool: aws_cognito.UserPool;
  restApiFunc: aws_lambda_nodejs.NodejsFunction;
}

export class ApiConstruct extends Construct {
  constructor(scope: Construct, id: string, props: ApiConstructProps) {
    super(scope, id);

    const { cognitoUserPool, restApiFunc } = props;

    /**
     * Cognito ユーザープール Authorizer を作成
     */
    // const cognitoUserPoolsAuthorizer =
    //   new aws_apigateway.CognitoUserPoolsAuthorizer(
    //     this,
    //     "CognitoUserPoolsAuthorizer",
    //     {
    //       cognitoUserPools: [cognitoUserPool],
    //     },
    //   );

    /**
     * REST API を作成
     */
    new aws_apigateway.LambdaRestApi(this, "RestApi", {
      handler: restApiFunc,
      // defaultMethodOptions: { authorizer: cognitoUserPoolsAuthorizer }, // コメントアウト
    });
  }
}

これにより、CDK Synth が正常に実行できました。

$ npx cdk synth
Bundling asset (中略)...

⚡ Done in 81ms

その他の Resolution error

過去の自分のブログを漁ってみると、CDK 利用時に Resolution error に遭遇したケースが他にもいくつかありました。

下記では、実際には行えない異なるリージョン間のクロススタック参照を行おうとして発生しています。

Resolution error: Cannot use resource 'CdkAppStack/topic' in a cross-environment fashion, the resource's physical name must be explicit set or use PhysicalName.GENERATE_IF_NEEDED.

また下記では、IAM Role のプリンシパルの構成時の不備により発生しています。

Resolution error: All principals in a PolicyStatement must have the same Conditions (got '{}' and '{"StringEquals":{"aws:SourceAccount":"${Token[AWS.AccountId.9]}"}}'). Use multiple statements instead..

よって Resolution error が発生した場合は、CDK の記述の何らかの不備により合成で解決できなくなっている可能性が高いため、エラーメッセージを参考にしつつ確認を行うと良いでしょう。

参考

以上