Open4

AWS Amplifyの自分用トラブルシューティング

吉村吉村

Env

OS: Win11
Node.js: 20.12.2 / npm 10.5.2

@aws-amplify/cli: 12.11.1
aws-amplify: 6.0.30

aws-cli: 2.15.41 Python/3.11.3 Windows/10 exe/AMD64 prompt/off

Amplifyは現状バックエンドの生成ツールとしてAmplify CLI(Gen1)とGen2を用意している。
Gen2の方はまだプレビュー版ということで、今回はCLIでの実行を想定している。
プレビュー版触ってみた限りでは開発体験良かったので、早くGAされて欲しい。

2024/5/7 GAされました。上記取り消し線はGA前環境です。
引き続きGen2で詰まったところ等々このスクラップに吊り下げていきます。

@aws-amplify/backend: 1.0.0
@aws-amplify/backend-cli: 1.0.1
aws-amplify: 6.2.0

吉村吉村

amplify init時に想定プロファイルと別のプロファイルでinitが実行される

※Gen1時のスクラップです。Gen2がGAされたのでもう無いと思います。

詳しく掘ってないが、以下の状況の時に起こる。

  • aws configureでアクセスキー・シークレットキーを利用したdefaultプロファイルを設定済み
  • amplify initしたいアカウントは別のアカウント(SSO Login)

ようは.aws/configが以下のような状態かつ、credentialにdefaultのアクセスキーが存在している状態。

[profile default]
region={region}

[profile sso-profile]
sso_session=sso-session-another-account
sso_account_id={another account id}
sso_role_name={role}
region={region}
output=json

[sso-session sso-session-another-account]
sso_start_url=https://{storeid}.awsapps.com/start
sso_region={region}
sso_registration_scopes=sso:account:access

この際、amplify init時にsso-profileを指定してもデフォルトのアカウントを利用してバックエンド・プロジェクトを作成してしまう。

> aws sso login --profile sso-profile
> # ログイン処理…

> amplify init
> # 対話型シェルで初期設定。デフォルト設定を拒否し、各種設定を行う。
> ? Initialize the project with the above configuration? # No

> # 設定の最後の方に設定を行うプロファイル選択。SSOのプロファイルを指定
> ? Please choose the profile you want to use # sso-profile

> # ... デプロイとamplifyフォルダの作成が行われる。
> # another accountの方で作られて欲しいが、アクセスキーを生成したIAM Userが所属するアカウントでAmplifyのプロジェクトが作られる。

「一度Web GUIで作成してamplify pullすれば上手いこと見繕ってくれないだろうか」等々やってみたが無理そうだったので、環境変数を事前に設定し、aws-cliに利用するプロファイルを明示することで回避した。

> # Powershellのプロセス環境変数設定。bashならexportでいいんじゃないだろうか。
> Env:AWS_PROFILE='sso-profile'

エディタやコンソール立ち上げるたびに設定する必要はあるが、どうせSSO Loginは必須なので一手間増えたところでREADMEとかにメモっておけば問題ないと考えて採用。

他にもaws-sso-utilを使う手などもあるが、ただでさえややこしいツールチェインに他のライブラリを介入させたくない、aws-sso-util自体が公式対応がなされるまでの予備手段である、最近ある程度公式対応されつつあるなどの理由から見送った。

先にGen2から生成したアプリを試し、こちらでは問題なかった(npx amplify <command> --profile <profile-name>でコマンドごとにprofile指定できる)ため、CLIでもそのまま機能すると思っていたが全然そんなことはなかった。
「SSO設定しとるってことはアクセスキーはもう廃止しとるやろ!」という判断なんだろうか。
なんにせよ、自分の環境のレアケースだと思うので備忘録程度に置いておくにとどめる。

参考:
https://docs.amplify.aws/javascript/tools/cli/start/set-up-cli/
https://docs.amplify.aws/react/start/getting-started/setup/
https://zenn.dev/bloomblock/articles/694ab11600f3b8
https://zenn.dev/pantone170145/articles/aws-amplify-use-sso-account

吉村吉村

Amplify Functionで生成した環境変数がTSコンパイルで落ちる

AmplifyでFunction(内部的にはLambda)を建て、その中に環境変数を引き回そうとすると、チュートリアル通りにやってもデプロイが失敗する。
https://docs.amplify.aws/react/build-a-backend/functions/environment-variables-and-secrets/

.amplify/generated/env/<function-name>.ts

export const env = process.env as LambdaProvidedEnvVars & AmplifyBackendEnvVars;
// ...
Conversion from type 'ProcessEnv' to type 'LambdaProvidedEnvVars & AmplifyBackendEnvVars' may be wrong as they cannot overlap sufficiently with each other. If you do this intentionally, convert the expression to 'unknown' first.
   Type 'ProcessEnv' is missing the following properties from type 'LambdaProvidedEnvVars': _HANDLER, _X_AMZN_TRACE_ID, AWS_DEFAULT_REGION, AWS_REGION, 20, etc. ts(2352)

issue投げて聞いてみたが、「再現せんよ」ということだったので、どうもNext.jsと併用した時にNextが生成したtsconfigやらなんやらが自動生成された内容も型チェックを行うせいで起こってるっぽい。

変にチェック緩くしたりすると絶対strictを崩すようなモノを作る自信があるので、無理やりprocess.envの型を既存の型にマージすることで回避することとした。
ググったところ、以下のように型定義を先に書いておくと通るっぽいので、自動生成されたenvの型をそのまま持ってきて提供した。
https://hagaahiro.hatenablog.com/entry/2022/01/06/231848

types/global.d.ts

declare namespace NodeJS {
  interface ProcessEnv {
    // 自動生成されたenvの型情報をそのままコピペ
    readonly _HANDLER: string;
    readonly _X_AMZN_TRACE_ID: string;
    // ...
  }
}

ビルド通すだけならこれでいいが、自動生成をコピペして持ってくるのは正直筋がよろしくないので、うまいこと型を解決するような方法がAmplify側から提供されたり、いい感じの対応法が他にあったらそっちに差し替えたい。

吉村吉村

Amplify Functionで生成した環境変数がTSコンパイルで落ちる その2

相談してたIssueで返答が来ていたので追記。
「そもそもNext.js側でコンパイルしたらAmplify側と二重コンパイルになるから、ルートのtsconfigでamplifyの自動生成フォルダをexcludeすればいいんちゃう?」とのこと。

amplifyの管理フォルダ内はamplifyフォルダ内にあるtsconfigに従ってpipeline-deploy時によしなにやってくれるので、Next.jsがやってくれてる範囲はルートでは完全無視でも問題ないらしい。
言われてみれば確かにその通りなので、tsconfig.jsonにexcludeを追加して型チェックを回避した。

/tsconfig.json

{
  // ...
  "exclude": ["node_modules", ".amplify", "./amplify"]
  // ...
}