AWS CDKv2にマイグレーションしてみた #reinvent

v2リリース!🎉🎉🎉
2021.12.03

これはCDK Advent Calendar 2021の3日目の記事です。

IoT事業部のやまたつです。

もともとは別の記事をアドカレ用に用意していたのですがAWS CDK v2.0.0のRCが取れたので急遽CDKv2の話をします。

AWS CDKv2リリース!! 🎉🎉🎉

わーい!!!

re:Inventでも発表があったようですね!

[速報] AWS CDK V2 がリリースされました!

alphaが出てから1年がかり。。。長かったなぁ。。。

簡単に主な差分に説明すると以下のとおりです。このv2によってCDKの各リソースに大幅な変更が入ったということはありません。

  • パッケージがaws-cdk-libに統一された(いくつもインストールする必要がなくなった)
  • 明示的にインストールしないと非安定版のクラスが使えないようになった
  • deprecatedなプロパティやメソッドが削除された

早速マイグレーションしてみる

ドキュメントはこちらです。

基本的には、変更するのはpackage.json, cdk.jsonとtsのimport文のみです。

0. まずはyarn cdk diff

このコマンドは「CDKが吐き出すCloudFormationテンプレート」と「デプロイされているテンプレート」との差分を出力してくれます。現状として差分が無いことを確認しましょう。 マイグレーション後に同じように唱えることで、無事にマイグレーションできたかどうかを確認することができます。

1. cdk.jsonを修正する

contextのうち、aws-cdk:@aws-cdk/で始まっているものを全て消します。

2. package.jsonを修正する

dependencies及びdevDependenciesから@aws-cdk/で始まるパッケージとaws-cdkをすべて消します。 そして以下を追加します。

{
  "devDependencies": {
    "aws-cdk": "2.0.0",
  },
  "dependencies": {
    "aws-cdk-lib": "^2.0.0",
    "@aws-cdk/assert": "^2.0.0",
    "constructs": "^10.0.0"
  }
}

修正したら yarn を唱えておきましょう。

3. コードを修正する

importのコードを以下のように修正します。

import { Construct } from 'constructs';
import {
  App,
  Stack,
  aws_s3 as s3,
  aws_lambda as lambda,
  aws_apigateway as apigateway
} from 'aws-cdk-lib';

4. yarn cdk diffで確認する

yarn cdk diffを唱えてみて、差分がAWSリソースに関係のない差分のみであれば完了です!

個人の環境では以下のような差分がでました。

  • [-] Parameter AssetParametersで始まる差分
  • [+] Parameter BootstrapVersion BootstrapVersion:で始まる差分
  • [+] Unknown Rules: {"CheckBootstrapVersion":で始まる差分
  • AWS::Lambda::FunctionCodeに関する差分
  • lambda内部で実行されるコードをデプロイするための参照の記述が変わっているようだった。lambdaのコード自体に変更はしていないので問題ないと判断した。
    Assetsのあたりの実装がv2で変わってるのかな。未調査。

AWSリソースに影響のある差分があったり、コンパイルが通らない場合は以下を実施していきます。

延長戦1. プロパティやメソッドが使えないとき

CDKv2ではv2時点で非推奨@deprecatedとなっていたプロパティやメソッドがすべて削除されています。 v1の最新にアップデートしてみて、deprecatedになっていないか確認し、JSDocに書いてある通りに移行しましょう。(大抵のdeprecatedはJSDocに移行先が書いてあります。やさしい!)

延長戦2. クラスが使えないとき

v1では「まだ未完成で破壊的変更が予想されるパッケージ(experimental)」も、それを意識せず他のパッケージと同様に使用することができました。 v2ではこれらは明示的に別パッケージ(v1のパッケージ名の最後に-alphaを付けたもの)としてインストールする必要があります。

{
  "dependencies": {
    "@aws-cdk/aws-apigatewayv2-alpha": "2.0.0-alpha.11",
  }
}

これらのパッケージは破壊的な変更が予想されるため、ハット^やチルダ~を付けずに固定バージョンで指定することをオススメします。 最新バージョンはnpmのページなどで確認してください。今日時点(2021/12/02)ではすべて2.0.0-alpha.11が最新のようです

experimentalパッケージの一覧を以下に示します(2021/12/02時点)。

@aws-cdk/aws-amplify
@aws-cdk/aws-apigatewayv2
@aws-cdk/aws-apigatewayv2-authorizers
@aws-cdk/aws-apigatewayv2-integrations
@aws-cdk/aws-apprunner
@aws-cdk/aws-appsync
@aws-cdk/aws-batch
@aws-cdk/aws-cloud9
@aws-cdk/aws-codestar
@aws-cdk/aws-glue
@aws-cdk/aws-iot
@aws-cdk/aws-iot-actions
@aws-cdk/aws-ivs
@aws-cdk/aws-kinesisanalytics-flink
@aws-cdk/aws-kinesisfirehose
@aws-cdk/aws-kinesisfirehose-destinations
@aws-cdk/aws-lambda-go
@aws-cdk/aws-lambda-python
@aws-cdk/aws-msk
@aws-cdk/aws-neptune
@aws-cdk/aws-redshift
@aws-cdk/aws-route53resolver
@aws-cdk/aws-servicecatalog
@aws-cdk/aws-servicecatalogappregistry
@aws-cdk/aws-synthetics

インストールしたらimport部分を修正しましょう。

import * as apigatewayv2 from '@aws-cdk/aws-apigatewayv2-alpha';

延長戦3. yarn cdk diffで差分が出るとき

cdk.jsonを修正します。 以下のフラグのうち、それっぽいやつを使ってみてyarn cdk diffの差分がなくなるか確認しましょう。

{
  "context": {
    "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
    "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false,
    "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
    "@aws-cdk/core:stackRelativeExports": false,
  }
}

それぞれのフラグの意味についてはドキュメントをご確認ください。

それでも差分やコンパイルエラーが出る場合

以下の2つのケースが考えられます。

v1の最新にあげても同じ問題が出る場合

CDKv2はv1のコードから自動生成して公開されているため、中の実装はv1の最新のものと同じになります。 v2にあげて差分がでるということはv1の最新時点でも同じように差分が出ているかもしれません。 この場合は地道にv1最新へのマイグレーションを行ってからv2に上げる形になるかと思います。

v1の最新では問題が出ない場合

おめでとうございます。稀有なケースを引き当てている可能性があります。GitHubでissueを作成しましょう!issue作成はこちらから! v2のbugであれば爆速で対応される可能性が高いです!

おわりに

CDKは、IaCなのでそもそもアプリケーションコードではなく、また依存している3rd partyライブラリも少ないため、バージョンアップするモチベーションが沸かないことが多いかと思います。また、気づかぬうちにexperimentalに依存していることも多く、バージョンアップによって破壊的変更を食らうことも少なくありません。
それらを鑑みると、ある程度安定したAWS環境であれば特に、CDKバージョンを塩漬けにする判断もアリかなと個人的には考えています。

一方で、AWS CDKは活発に開発が進んでいるため次々と便利な書き方ができるようになってきています。
新しいプロダクトを始める際や、今まさにCDKをどんどん更新しているようなプロダクトでは是非CDKv2を使ってみてはいかがでしょうか?

以上でした!