Serverless Framework の Deprecation warning: * is not accessible エラー対処法
問題
Serverless Framework 2.x 系を使用しており, serverless.yml
の記述は以下のようになっています。 ググるとよく出てくるありがちな設定。
provider:
stage: ${opt:stage, self:custom.default.stage}
profile: ${opt:profile, self:custom.defaultProfile}
custom:
defaultStage: production
defaultProfile: ap-northeast-1
本日 serverless print
を実行するとき,このようなエラーを踏みました。
Serverless: Deprecation warning: "provider.profile" is not accessible (configured behind variables which cannot be resolved at this stage).
Starting with next major release, this will be communicated with a thrown error.
Set "variablesResolutionMode: 20210326" in your service config, to adapt to this behavior now
More Info: https://www.serverless.com/framework/docs/deprecations/#NEW_VARIABLES_RESOLVER
また, serlverless print --profile=xxx
と指定すると,以下のようなエラーが出るようになりました。
Serverless: Deprecation warning: Detected unrecognized CLI options: "--profile".
Starting with the next major, Serverless Framework will report them with a thrown error
More Info: https://www.serverless.com/framework/docs/deprecations/#UNSUPPORTED_CLI_OPTIONS
どうすればよいのでしょうか?
解決策
--profile
は非標準オプションです。非標準オプションのみ環境変数で代用します。
provider:
stage: ${opt:stage, self:custom.default.stage}
profile: ${env:AWS_PROFILE, self:custom.defaultProfile}
custom:
defaultStage: production
defaultProfile: ap-northeast-1
解説
エラーメッセージを良く読めば答えが書いてあるのですが,順を追って説明します。観点は2つあります。
変数解決の方法が変わった❓
"provider.profile" is not accessible (configured behind variables which cannot be resolved at this stage)
だけだとちょっと分かりにくいのですが, エラーメッセージを読む限りでは,新しいリゾルバでは provider
は他の項目よりも早く解決される仕様になっているようです。ではどこまでなら許されるのでしょうか?
以下のようにしたところ, どちらのパターンもエラー無しに動作しました。
provider:
stage: ${opt:stage, self:custom.default.stage}
# 環境変数あり・なし両方 OK
profile: ${env:AWS_PROFILE}
custom:
defaultStage: production
defaultProfile: ap-northeast-1
provider:
stage: ${opt:stage, self:custom.default.stage}
profile: ${self:custom.defaultProfile}
custom:
defaultStage: production
defaultProfile: ap-northeast-1
${env:*}
や ${self:custom}
の参照は全く問題ないようです。というか, ${opt:*}
でも ${opt:stage}
はちゃんと参照できていますね。では何が問題…?
serverless
コマンドが標準オプション以外を受け取らなくなった❗
2つ目のエラーである
Detected unrecognized CLI options: "--profile".
がこの問題の本質です。従来は独自定義したオプションを CLI から受け取ることが出来ていたんですが, バージョン 3.x からは標準定義されたオプション以外は受け取れなくなるようです。
sls print --help
の実行結果は以下のようになりました。
print ......................... Print your compiled and resolved config file
--format ...........................Print configuration in given format ("yaml", "json", "text"). Default: yaml
--path .............................Optional period-separated path to print a sub-value (eg: "provider.name")
--transform ........................Optional transform-function to apply to the value ("keys")
--region / -r ......................Region of the service
--app ..............................Dashboard app
--org ..............................Dashboard org
--use-local-credentials ............Rely on locally resolved AWS credentials instead of loading them from Dashboard provider settings (applies only to services integrated with Dashboard)
--config / -c ......................Path to serverless config file
--stage / -s .......................Stage of the service
--help / -h ........................Show this message
--version ..........................Show version info
--stage
が含まれているので問題なし, --profile
は独自定義なのでダメ!そういうことでした。最初の「変数解決の方法が変わった」に関しては,標準定義されているオプションについては正しく参照できたので,結局まだ深くは分かっていないところです。現時点では,非標準オプションを非推奨化した影響で副次的にこのエラーも踏んでいるという形になっていると言えます。
またリンク先を読むと,以下のような記述がありました。
Note: If you've used such options to aid dynamic resolution of service configuration (passing custom values to
${opt:..}
resolvers). We suggest to rely on environment variables instead. Setup of environment variables is also way more convenient since we've added support for.env
files.
結果的には以下のように,非標準オプションのみ環境変数で代用する形に落ち着きそうですね。
provider:
stage: ${opt:stage, self:custom.default.stage}
profile: ${env:AWS_PROFILE, self:custom.defaultProfile}
custom:
defaultStage: production
defaultProfile: ap-northeast-1
provider:
stage: ${opt:stage, 'production'}
profile: ${env:AWS_PROFILE, 'ap-northeast-1'}
Discussion