![[ServerlessFramework] アクセスキーによるデプロイの運用方法を考えてみた](https://images.ctfassets.net/ct0aopd36mqt/wp-thumbnail-4fe785b14e998b3c159119acfb76c6d7/827db674ed6e7c651836f5c6bef1323a/serverless-framework-icon.png)
[ServerlessFramework] アクセスキーによるデプロイの運用方法を考えてみた
ServerlessFrameworkにデプロイを行う際、 ライセンスキーとアクセスキーがあることをご存知でしょうか? 両者の違いは端的に
- ライセンスキーはダッシュボードを利用しない
- アクセスキーはダッシュボードを利用する
と言えます。
今回はダッシュボードを利用するという前提で、 アクセスキーを用いてアプリケーションのデプロイをする運用方法について考えてみました。
Serverlessダッシュボードについて
ServerlessダッシュボードではApps一覧画面を見ることができます。 こんなイメージです。
画像内注記の通り、「app」「service」「stage」という概念があります。 またそれらを包含する「org」の概念があります。
ダッシュボードではもちろんApps一覧だけでなく他の情報も見れますが、 今回はこのApps一覧にデプロイしたアプリケーションがきちんと並んで表示されることをゴールとして話を進めます。
Apps一覧とクレジット消費について
ここで勘違いを防ぐためにお伝えしておかないといけないことがあります。 Apps一覧とクレジット消費の関係性については次の事実を絶対に忘れないでください。 すなわち、
アプリケーションが、Apps一覧に表示されているかどうかと、 クレジットを消費しているかどうかには、直接の関係はない
ということです。 具体的にはこんな問答が展開されます。
- Apps一覧に表示されているアプリケーションだけがクレジットを消費している?
- いいえ。一覧になくてもクレジット消費しているアプリケーションはありえます。
- 例えばライセンスキーでデプロイされたアプリケーション。
- いいえ。一覧になくてもクレジット消費しているアプリケーションはありえます。
- Apps一覧に表示されているアプリケーションは必ずクレジットを消費している?
- いいえ。デプロイされてから一定期間(10日)を経過していないアプリケーションはクレジットを消費していません。
- ダッシュボードではそのアプリケーションがクレジット消費期間に入っているのか確認することはできません(現状、私の知る限り)。
Apps一覧の過信は禁物です。 心に刻んでください。
ライセンスキーではゴールを達成できない
serverless.yamlファイルには上記で登場した
- org
- app
- service
- stage
を記載してデプロイします。 こんな感じです。
org: myorg
app: datalake
service: myservice
provider:
name: aws
stage: dev
この設定が書かれたserverless.yamlをデプロイすれば、 先ほどの画像のようにApps一覧に表示されます。
しかし、実はこのデプロイを実施するには ライセンスキーではなくアクセスキーが必要です。 実際ライセンスキーを環境変数に指定してデプロイを行おうとするとこんなエラーが出ます。
Error: This Service is enabled for Serverless Framework Dashboard because the "app" property is set. However, you are using a License Key and Dashboard features are not available when using License Keys. Please remove "app" and any other Dashboard features to continue using this Service.
日本語訳(by sonnet3.7)
エラー: 「app」プロパティが設定されているため、このサービスはServerless Framework Dashboardで有効になっています。ただし、ライセンスキーを使用しており、ライセンスキーを使用する場合はDashboard機能は利用できません。このサービスを引き続き使用するには、「app」およびその他のDashboard機能を削除してください。
「app」の指定とライセンスキーの使用は両立できないとのことです。 なぜ??と思われるかもしれませんが、「仕様です」で諦めてください。 ライセンスキーはそもそも ダッシュボードを利用しないユーザに払い出すというコンセプトである、 というのが一応の回答ではあるかと思います。
とは言え、デプロイする人はダッシュボードを見ないのだとしても、 管理者はデプロイされているアプリケーションの一覧は見たいんじゃないかな、 と思ってしまいます。 しかし現状ではライセンスキーでデプロイされたアプリケーションは 「app」を記載できないので、 先ほどのApps一覧に登場させることはできません。
ということで、Apps一覧にデプロイされているアプリケーションを一覧表示させたかったら、 デプロイ時にはライセンスキーを使ってはいけないということになります。
アクセスキーとは
アクセスキーは、Serverlessダッシュボードにログインできるユーザが発行できる CLIからのデプロイ時に使うキーです。 アクセスキーはユーザに紐づくので、 アクセスキーを使ったデプロイでは「誰がデプロイしたか」の情報も紐づくことになります。
デプロイの運用を考える
そのアクセスキーを利用した運用方法を考えていきます。
CodeBuildで利用する
私が参画しているプロジェクトでは本番や検証環境にはCodeBuildを使ってデプロイを行っています。
誰のアクセスキーを使うか
CodeBuildは特定の開発者として実行されるわけではないので、 デプロイ用のユーザを発行して、そのユーザでアクセスキーを発行するのが良いかと思います。 前述の通り「誰がデプロイしたか」の情報も利用できるようになるため、 CodeBuildがデプロイしたという情報がわかるようにしておくと良いです。
デプロイ時のアクセスキー指定方法
アクセスキーを使ってCLI環境からデプロイする際には、 環境変数SERVERLESS_ACCESS_KEY
にキーを設定することでアクセスキーが利用できます。 キーをより安全に保管しておくためにもパラメータストアにSecureStringとして保存しておき、 デプロイするシェルスクリプト内で動的に取得するようにすれば、 キーが暴露してしまうことのない運用ができそうです。
export SERVERLESS_ACCESS_KEY="$(aws ssm get-parameter --name /datalake/${env}/Serverless/DeployAccessKey --with-decryption | jq -r '.Parameter.Value')"
なおこれはライセンスキーの場合でも全く同じ手法が使えます。
ちなみにライセンスキーの場合はserverless.yamlに
licenseKey: ${ssm:/path/to/serverless-framework-license-key}
のような記載をすることでもパラメータストアからキーを取得することも可能ですが、 アクセスキーの場合はこの方法は使えないので注意してください。
開発メンバーのローカルからのデプロイ
次に開発メンバーが手元からデプロイするケースを考えます。
アクセスキーの発行
開発メンバーが利用するアクセスキーは、 当たり前ですが各開発者が自分で発行したキーを使うべきです。 ではキーの発行をどのように行うかですが、 今回はCLI環境で行うこととしました。
CLI環境でデプロイをする(しようとする)と ~/.serverlessrc
(以下、「設定ファイル」)に認証関係などの情報が保存されます。 今回は、アクセスキーはここに保存して利用する形としたいので、 ダッシュボードからの発行ではなくCLIを利用するわけです。
設定ファイルの作成
設定ファイルを作るために、一度明示的にログインを行います。
sls login
なお私の環境では、serverless.yamlが環境変数STAGE
を参照するようになっていたので、 この環境変数が設定されていない状態だと怒られてしまいました。 なので実際はSTAGE=dev sls login
を実行する必要がありました。
lease login/register or enter your license key:
と聞かれるので Login/Register
を選択します。 その後ブラウザでダッシュボードへのログイン画面が開くのでログインします。
You have multiple Orgs. Please select a default Org to use with this user account
と出る場合は、デフォルトとしたいorgを選択します。 このデフォルトorgについては後述します。
以上で設定ファイルにアクセスキーなどが保存されます。 ログインに成功すれば自動的にアクセスキー発行が行われて設定ファイルに書き込まれます。
デプロイ時のアクセスキー指定
設定ファイルにアクセスキーの記載があれば 自動的にこれが参照されてデプロイされます。
~/.serverlessrc
運用の注意点
設定ファイルが置かれる場所はホームディレクトリです。 ホームディレクトリにあると言うことは別のorgを使うプロジェクトでも同一のファイルが参照されます。 これはちょっと危険な香りがします。
基本的には問題がない
とはいえ、基本的にはserverless.yamlの中でorg
を明記するはずなので問題はありません。 orgを跨いで同一のserverless.yamlファイルを利用するという場面はまずないと思いますので、 org
を書き忘れなければ問題はありません。
明示的にorg指定がない場合
serverless.yamlにorg
が指定されていなかった場合どうなるかを一応確認してみました。 この場合は設定ファイルのusers.(ユーザIDっぽい文字列).defaultOrgName
に指定されたorgが自動的に使われるようです。
さて念の為、users.(ユーザIDっぽい文字列).defaultOrgName
も消してデプロイしてみます。 これだとどこにもorgの指定はありませんので、エラーになりま......せんでした。
なんででしょうかね...? これを実行した私の環境では、さっきデプロイしたorgAではなく別のorgBとしてデプロイが実行されました。 orgの明示的な指定やdefaultOrgの指定がなくても、 どれかしらのorgが選ばれてデプロイは実行されるようです。。 どうしてこうなるのかは調べていません。 ただ間違いなく言えるのは、serverless.yamlに明示的にorg
を指定しないのは危険すぎる、ということです。 みなさん気をつけましょう。
org
がない場合の補足
serverless.yamlに実はserverless.yamlにorg
指定がない場合は ダッシュボードのApps一覧にもアプリケーションが表示されません。
どうやらApps一覧に記載されるための条件として、 「org」「app」「service」「stage」がすべてserverless.yamlに明記されている必要があるようです。 今見たように、org
を指定しなくてもどこかしらのorgにデプロイされるというケースがあるわけですが、 じゃあその時そのorgのApps一覧にデプロイされたアプリケーションが表示されるのかというと、表示されません。 とは言え、そのアプリケーションも当然(一定期間後)課金対象です。 先述の通り、Apps一覧表示の有無とクレジット消費の有無には直接の関係はありません。
ちなみにこのルールはアプリケーションの削除(sls remove
)時にも適用されます。 つまり、Apps一覧に表示されたアプリのスタックが実態として削除されたとしても、 remove
コマンドを実行した際にorg
の明示的な指定がなかった場合、 Apps一覧からは削除されません。 あえて混乱させる言い方をすれば、Apps一覧に表示されていることと、本当にそのアプリケーションがデプロイされているかどうかには、直接の関係はないということです。
この意味でも、serverless.yamlにorg
の明示は絶対に絶対に必須です。 約束してください。
まとめ
ServerlessFrameworkにアクセスキーを使ってデプロイを行う運用方法と注意点についてまとめてみました。 ダッシュボードのApps一覧にデプロイしたアプリケーションが並ぶので視認性がかなりよくなります。 無駄なクレジット消費をしないためにもこの表示があると嬉しいと思っています。
今回色々なケースを検証したので、Apps一覧の注意点も見えてきていますが、 serverless.yamlにorg
をしっかり記載して運用していれば、 Apps一覧に載っているものは(一定期間経過で)クレジット消費していると判断できます。
以上、誰かの参考になれば幸いです。