😭

OriginAccessControlのnameは64文字以内にする必要がある

2024/04/18に公開

タイトルの通りです。
OriginAccessControlnameに64文字以上のテキストを入れるとデプロイ時にコケます。

表示されるエラーは下記のように、情報量皆無なメッセージのみです。

Resource handler returned message: "Invalid request provided: AWS::CloudFront::OriginAccessControl" (RequestToken: 5b95a26b-63e0-ac0a-fe8e-3b51ea24ebd1, HandlerErrorCode: InvalidRequest)

対策

文字列が一定の長さを超えないように加工する関数を定義してあげましょう。
私は下記のような関数を定義し、ある程度一意性を保ちつつ名前を割り振れるようにしました。

import { Aws, Fn } from 'aws-cdk-lib';

const stackIdLength = 36;
const hyphenCount = 2;

export const createUniqueString = (
  prefix: string,
  part: string,
  maxLength: number,
): string => {
  const stackId = Fn.select(2, Fn.split('/', `${Aws.STACK_ID}`));
  const partLength = maxLength - stackIdLength - prefix.length - hyphenCount;
  const partString = Buffer.from(part).toString('base64').slice(0, partLength);
  return `${prefix}-${stackId}-${partString}`;
};

下記のような形で利用しています。

export class BucketDistribution extends Construct {
  constructor(scope: Construct, id: string) {
    super(scope, id);

    const cfnOriginAccessControl = new CfnOriginAccessControl(this, 'OriginAccessControl', {
      originAccessControlConfig: {
        name: createUniqueString('CloudFrontToS3', id, 64),
        originAccessControlOriginType: 's3',
        signingBehavior: 'always',
        signingProtocol: 'sigv4',
        description: 'S3 Access Control',
      },
    });
  }
}

まとめ

私はこの謎エラーメッセージで原因が特定できず半日溶かしました。
実はAWSのドキュメントにちゃんと「64文字制限あるよ」と書いてあります。
同じような問題で時間を溶かす人が減るようにこの記事を残しておきます。

ドキュメント
    読むの大事だね
        気をつけよう
アガルートテクノロジーズ/PrAha

Discussion