AWS Lambdaで.NET 6から.NET 8に移行したときにやったこと

# はじめに
　AWS LambdaでLTSである.NET8がランタイムサポートされました。AWS Lambdaでは.NETの以前のLTSである.NET6のランタイムサポートの廃止を2024/11/12に予定しており、廃止後も一定期間は関数の作成と更新が可能ですが、2025/1/11には新規作成がブロックされ、2025/2/11には更新もブロックされるようになります。このためLambdaで.NET6を利用しているユーザーは早期に.NET8に移行する必要があります。

# やったこと

## ターゲットフレームワークの変更
プロジェクトファイルのターゲットフレームワークを変更します。

```diff_xml:***.csproj
-    <TargetFramework>net6.0</TargetFramework>
+    <TargetFramework>net8.0</TargetFramework>
```

## aws-lambda-tools-defaults.jsonの修正

AWS Toolkit for Visual Studioのテンプレートを使っている場合は、こちらのファイルがあるはずなので修正。

```diff_json
-   "framework": "net6.0",
+   "framework": "net8.0",
```

function-runtimeを指定している場合は以下も修正が必要です。

```diff_json
-   "function-runtime": "dotnet6",
+   "function-runtime": "dotnet8",
```

## SAMテンプレートの修正

SAMテンプレートを使っている場合は以下の通り修正します。

```diff_json:serverless.template
-         "Runtime": "dotnet6",
+         "Runtime": "dotnet8",
```

## CodeBuildのImage変更

ビルドにCodeBuildを使っている場合は、Imageによってデフォルトでインストールされているランタイムが違います。.NET8からはベースOSがAmazonLinux2のイメージが使えなくなったため、AmazonLinux2023を使う必要があります。詳しくは以下のURLを参照してください。

<https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/available-runtimes.html>

ちょっと紛らわしいですが、.NET8がプリインストールされているマシンイメージは「<font color="Red">Amazon Linux 2023</font> x86_64 standard:5.0」と上記のページには書かれているのですが、CodeBuildで指定するイメージ識別子は「aws/codebuild/<font color="Red">amazonlinux2</font>-x86_64-standard:5.0」となるようです。これは以下のページを参照するとわかります。

<https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-env-ref-available.html>

以下はCloudFormationテンプレートのCodeBuildの部分の差分です。

```diff_yaml
-         Image: aws/codebuild/amazonlinux2-x86_64-standard:4.0
+         Image: aws/codebuild/amazonlinux2-x86_64-standard:5.0
```

## CodeBuildのImage変更に伴う影響の修正

ベースOSがAmazonLinux2023に変更したことで、デフォルトのパッケージ管理ツールがyumからdnfへ変更になりました。yumコマンドが使えなくなったわけではないのですが、いずれ廃れ行くyumですので、yumを使っている人はこれを機に移行しましょう。

<https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/package-management.html>

```diff_shell:buildspec.yml
- yum install -y xxx
+ dnf install -y xxx
```

また、AmazonLinux2では利用できていたEPELが、AmazonLinux2023では利用できなくなっていたので、私の場合、いつもyum installでインストールできていたものができなくなり、rpmを直接取得する形に変更しました。

```diff_shell:buildspec.yml
- yum install -y xxx
+ dnf install -y https://xxxxx/xxx.rpm
```

現在のイメージには.NET SDKが6.0と8.0の２つが入っており、ビルドマシン内の/codebuild/global.jsonによって6.0が指定されていました。

```
[Container] 2024/02/23 11:18:01.344871 Running command dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.418
 Commit:    21f869269c

Runtime Environment:
 OS Name:     amzn
 OS Version:  2023
 OS Platform: Linux
 RID:         linux-x64
 Base Path:   /root/.dotnet/sdk/6.0.418/

Host:
  Version:      8.0.1
  Architecture: x64
  Commit:       bf5e279d92

.NET SDKs installed:
  6.0.418 [/root/.dotnet/sdk]
  8.0.101 [/root/.dotnet/sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.App 6.0.26 [/root/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 8.0.1 [/root/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 6.0.26 [/root/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 8.0.1 [/root/.dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
  None

Environment variables:
  DOTNET_ROOT       [/root/.dotnet]

global.json file:
  /codebuild/global.json

Learn more:
  https://aka.ms/dotnet/info

Download .NET:
  https://aka.ms/dotnet/download

[Container] 2024/02/23 11:18:01.619815 Running command cat /codebuild/global.json
{
  "sdk": {
    "rollForward": "feature",
    "version": "6.0.0"
  }
}
```

これにより、ターゲットフレームワークが.NET8のソースのビルドを行うと以下のようなエラーが発生します。

```
error NETSDK1045: The current .NET SDK does not support targeting .NET 8.0.  Either target .NET 6.0 or lower, or use a version of the .NET SDK that supports .NET 8.0. 
```

~~この現象を回避するため、buildspec.ymlでglobal.jsonを削除するようにします。これでビルドが通るようになりました。これはそのうち修正されそうな気がします。~~
(2025/2/5 記事修正)
この現象を回避するため、buildspec.ymlのruntime-versionsで明示的に.NET8を指定します。
```diff_shell:buildspec.yml
version: 0.2
phases:
  install:
+   runtime-versions:
+      dotnet: 8.0
```

## Lambdaデプロイコマンドの修正

CodeBuildでlambdaのデプロイコマンドを使っている場合は、以下の通り修正します。コマンドがdeploy-functionの場合も同様です。

```diff_shell:buildspec.yml
- dotnet lambda deploy-serverless --framework "net6.0"
+ dotnet lambda deploy-serverless --framework "net8.0"
```

## NSwag関連の修正

NSwagを利用している場合は、以下の部分を修正。

```diff_xml:****.csproj
- 	<Exec Command="$(NSwagExe_Net60) run nswag.json /variables:ProjectPath=$(MSBuildProjectFullPath)" />
+ 	<Exec Command="$(NSwagExe_Net80) run nswag.json /variables:ProjectPath=$(MSBuildProjectFullPath)" />
```

```diff_json:nswag.json
-   "runtime": "Net60",
+   "runtime": "Net80",
```

私の場合、今回の対応でNSwagのバージョンを13から14に上げたのですが、UseSwaggerUi3が使えなくなっておりビルドエラーとなりましたので、以下の修正が入りました。

```diff_json:startup.cs
-   app.UseSwaggerUi3();
+   app.UseSwaggerUi();
```

詳細は以下
<https://github.com/RicoSuter/NSwag/issues/4524>

## NuGetパッケージの更新

.NET 8に対応していないバージョンがある場合は更新が必要です。

## その他影響箇所の修正

以下のURLを参照し、該当箇所があれば修正。

<https://learn.microsoft.com/ja-jp/aspnet/core/migration/60-70?view=aspnetcore-8.0&tabs=visual-studio>

<https://learn.microsoft.com/ja-jp/aspnet/core/migration/70-80?view=aspnetcore-8.0&tabs=visual-studio>