AWS CDK で Lambda 関数を作ったときに Log の Retention Period を指定したらちょっと面白かった話

先日、AWS CDK を使ってとある Lambda 関数をデプロイしました。 その Lambda 関数は Go で書かれたものですが、動作に必要な S3 や DynamoDB などのリソースを準備したり IAM Role に適切な Policy を設定してそれを使うようにしたり Lambda 関数自体のメモリサイズやタイムアウト時間などいろいろなパラメータを指定しなければなりません。しかもこの関数を開発用の AWS アカウントと本番環境用の AWS アカウント両方に作らなければなりません。このような場合には CDK のような IaC (Infrastructure as Code) の実現を支援してくれる仕組みはありがたいですね。

で、今回構築した Lambda の関数名を仮に FooFunc とでもしておきましょう。

CDK のコードは TypeScript で書きました。 lambda.Function コンストラクトを用いて以下のように構築しました。

    const fn = new lambda.Function(this, 'FooFunc', {
      functionName: 'FooFunc',
      runtime: lambda.Runtime.GO_1_X,
      handler: 'foo',
      code: lambda.Code.fromAsset('./foo.zip'),
      role: role,
      memorySize: 1024,
      timeout: cdk.Duration.seconds(30),
      logRetention: cwlogs.RetentionDays.ONE_WEEK,
      currentVersionOptions: {
        removalPolicy: cdk.RemovalPolicy.RETAIN,
      },
    });

これでデプロイすると FooFunc が出来上がっていて期待通りに動きました。

Lambda のログの保持期間 (logRetention) を 1 週間に指定してあります。 これを忘れると CloudWatch Logs に永遠にログが残り続けて地味に費用がかさんでしまうので、この設定をしっかりと行っておくのがよいですね。

で、この連休中に AWS からお知らせが来て、Node.js 10.x の Runtime はサポート終了ですよ、とのこと。4/30 に Node.js の本家が 10.x のサポートを終了したのに合わせ、AWS も 7 月末でサポートを終了するのでそれまでにより新しいバージョンに移行するように、とのことでした。

お知らせにはご丁寧に aws cli で Node.js 10.x の Runtime を使っている Lambda 関数の一覧を出力するためのコマンドラインまで書かれていましたのでそれを実行してみました。

すると、先日作ったばかりの FooFunc の名前が見つかったのです。 FooFunc の Runtime は Go のはずなのにおかしいな、と思いました。

Node.js 10.x を使っているとして見つかった関数の名前は、正確には FooFunc_LogRetention${UniqueID} のような長い名前でした。${UniqueID} の部分はランダムな英数字の 30 文字くらいの羅列です。長いので LogRetention 関数と呼ぶことにします。

自分ではそのような関数を作った覚えはありませんが、CloudFormation の Stack を見るとたしかに FooFunc の仲間です。

名前からすると Log の Retention Period を設定するための関数のようです。 コードを読んでみてもやはりそのような処理の内容が書かれていました。

で、この LogRetention 関数の Runtime が Node.js 10.x だったわけです。

僕が使っていた CDK のバージョンがちょっと古かったためでしょうか。すぐに CDK のバージョンを更新しました。

LogRetention 関数の Runtime のバージョンを試しに手動で最新の 14.x に上げてみて、その後に CDK で FooFunc をデプロイしてみましたが、Node の Runtime バージョンが巻き戻ったりすることもなく、logRetention の設定もきちんと反映されましたのでとりあえずはこの状態で運用していこうと思います。