AWS CDKのコード量を削減:Amazon CloudFrontのL2コンストラクトでOACを適用

ここ最近はAWS認定資格の取得に取り組んでいました。5月に「SysOps Administrator - Associate」、6月に「Data Engineer - Associate」、7月に「Machine Learning - Specialty」、9月に「Advanced Networking - Specialty」、そして11月に「AI Practitioner」を取得し、AWS認定資格の受験ラッシュも落ち着き始めています。

Amazon CloudFrontのOrigin Access Control(OAC)用に、新しいAWS CDK L2コンストラクトが利用できるようになりました!

aws.amazon.com

当方の環境ではCDKのバージョン2.165.0で新しいL2コンストラクトが利用できることを確認しています。

早速、個人用の静的ホスティングサイトを新しいOAC用のL2コンストラクトに移行しましたので、新しいAWS CDK L2コンストラクトの記述方法やこれまでの記述方法との比較を以下に記載します!

OAC用の新しいAWS CDK L2コンストラクトの何が嬉しいのか?

OAC用の新しいAWS CDK L2コンストラクトが利用できるようになるまでは、レガシー設定であるOrigin Access Identity(OAI)として記述した後に、エスケープハッチを使用してOrigin Access Control(OAC)を利用するようにカスタマイズする必要がありました。

    // OAC用の新しいAWS CDK L2 コンストラクト が利用できる前のコード
    // CloudFront ディストリビューションの定義
    const distribution = new aws_cloudfront.Distribution(this, 'Distribution', {
      defaultRootObject: 'index.html',
      defaultBehavior: {
        origin: new aws_cloudfront_origins.S3Origin(originS3Bucket),
      },
    });

    // Origin Access Control(OAC)の定義
    const originAccessControl = new aws_cloudfront.CfnOriginAccessControl(this, 'OriginAccessControl', {
      originAccessControlConfig: {
        name: 'OriginAccessControlForOriginS3Bucket',
        originAccessControlOriginType: 's3',
        signingBehavior: 'always',
        signingProtocol: 'sigv4',
        description: 'Access Control',
      },
    });

    // CloudFront ディストリビューションをL1 コンストラクトに変換
    const cfnDistribution = distribution.node.defaultChild as aws_cloudfront.CfnDistribution

    // エスケープハッチによるカスタマイズ
    cfnDistribution.addPropertyOverride('DistributionConfig.Origins.0.OriginAccessControlId', originAccessControl.getAtt('Id'))
    cfnDistribution.addPropertyOverride('DistributionConfig.Origins.0.DomainName', originS3Bucket.bucketRegionalDomainName)
    cfnDistribution.addOverride('Properties.DistributionConfig.Origins.0.S3OriginConfig.OriginAccessIdentity', "")
    cfnDistribution.addPropertyDeletionOverride('DistributionConfig.Origins.0.CustomOriginConfig')

上記のコードの記述に加えて、静的ホスティングにおけるS3バケットのバケットポリシーも必要でした。上記のコードは一度OAIのコードを記述した上でエスケープハッチによってカスタマイズしているため、使われていないOAIリソースが存在し続けるような状況も発生していました。

上記のエスケープハッチ方法によるコードの記述が完全に不要になります。以下のコードだけでOACの実装を実現できるようになります。

    // OAC用の新しいAWS CDK L2 コンストラクト を利用したコード
    const distribution = new aws_cloudfront.Distribution(this, 'Distribution', {
      defaultBehavior: {
        origin: aws_cloudfront_origins.S3BucketOrigin.withOriginAccessControl(originS3Bucket)
      }
    })

... 記述量の差がすごいですね。まるで黒魔術のようにも見えますが ... CloudFrontのディストリビューションで作成・更新するリソースの種類を把握した上で利用するのであれば、とても便利です。

古い記述方法は非推奨になります

S3Originによる記述方法は非推奨になりました。最新のCDKのバージョンではS3BucketOriginまたはS3StaticWebsiteOriginのどちらかに変更する必要があります。aws-cdk-libパッケージを更新していく上でのリファクタリングは必須となりそうです。

OAIからの移行でダウンタイムを避けるためには、OAI、OACの両方を許可するS3バケットポリシーを一時的に記述することが望ましいです。

CDKのコード記述量が6割に

驚くべきはCDKのコード記述量です。CDK L2コンストラクトのOACを利用する前後で行数を比較してみました。(この行数は当方で利用しているシンプルな静的ホスティングサイトのスタック全体の行数を確認しています。)

CDK L2コンストラクト OAC 行数
利用前 106
利用後 73

6割のコード記述量になり、4割も削減できました。何をやっているのかぱっとでは分かりにくいエスケープハッチの記述もなくなってすっきりしました。

まとめ

Amazon CloudFront Origin Access Control(OAC)用の新しいAWS CDK L2コンストラクトは、これまでOACを適用する場合に必要だったエスケープハッチ(カスタマイズ)が不要になり、簡潔にコードを記述できるようになりました。このL2コンストラクトはOAC、S3バケットポリシーなど複数のリソースを作成しますので、作成されるリソースの内容を把握した上で利用すると望ましいでしょう。積極的に活用していきたいですね。