はじめに
serverlessからCI/CDの一般提供がアナウンスされました!
自分は簡単なバッチ処理などをlambdaで動かしており、lamdbaの構成管理やリリースにserverlessを利用していたので、早速CI/CDから実行してみました!
デプロイ手順
1.サインアップ
ダッシュボード画面にアクセス
GitHubOAuthでの認証を許可
「next」をクリック
ユーザー名(デフォルトだとGitHubユーザー名)を設定し、「next」をクリック
アプリケーション名(デフォルトだと「myapp」)を設定し、「done」をクリック
CLIでのdeployのコマンドが表示されるが、「close」をクリック
ダッシュボード画面が表示される
2.appの設定
デフォルトで作成された「myapp」を開いて、アプリケーションを設定します。
デプロイサービスからGitHubを選択、デプロイしたいリポジトリを選択して画面下の「save settings」をクリック
(とりあえず動作するのを確認したいので、詳細な設定はデフォルトのままにしてます)
3.profileの設定
AWS環境へ接続権限を付与する為、profileを設定します。
(appを作成する際に、設定するprofileを指定する為、環境やアプリケーション毎に専用のprofileを作成する方が良さそうです。)
メニューから「profiles」を選択し、「default」をクリック
AWSへアクセスする為のロールを設定する画面が表示されるので、「shared AWS account」をクリック
「Create a role wizard」のリンクをクリック
AWSのIAMロールのコンソール画面に遷移するので、CI/CDからアクセスするロールを作成
(デフォルトだとポリシーがAdministratorAccessになるので、作成するリソースに合わせて権限を変える方が安全)
作成したIAMロールのarnを入力し、「save」をクリック
4.デプロイ
とりあえず動くのを確認したいので、masterに対してテストのコミットを上げてみます。
デプロイが進行する画面が表示
上部のメニューから「deployments」すると、デプロイ履歴の一覧が画面が表示されるので、対象のデプロイを選択
デプロイのレポートやログを確認できる詳細画面が表示
修正箇所
元々は以下の手順で手動でデプロイしていたのですが、そのままで失敗する為、いくつか修正を行いました。
# pluginをインストール sls plugin install -n serverless-python-requirements sls plugin install -n serverless-plugin-aws-alerts sls plugin install -n serverless-pseudo-parameters # デプロイ sls deploy --verbose --stage dev --alexaskill <alexaSkill Id>
package.jsonをリポジトリにあげる
Build step: serverless deploy Serverless Error --------------------------------------- Serverless plugin "serverless-python-requirements" not found. Make sure it's installed and listed in the "plugins" section of your serverless config file.
CI/CDではbuild Stepにてnpm install
でインストールする為、package.json
をリポジトリに追加が必要です。
requirements.txtを作成する
Error -------------------------------------------------- Error: pipenv not found! Install it with 'pip install pipenv'. at ServerlessPythonRequirements.pipfileToRequirements (/alexa-skill-seibu-bus/node_modules/serverless-python-requirements/lib/pipenv.js:28:13) at ServerlessPythonRequirements.tryCatcher (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/util.js:16:23) at Promise._settlePromiseFromHandler (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/promise.js:547:31) at Promise._settlePromise (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/promise.js:604:18) at Promise._settlePromiseCtx (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/promise.js:641:10) at _drainQueueStep (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/async.js:97:12) at _drainQueue (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/async.js:86:9) at Async._drainQueues (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/async.js:102:5) at Immediate.Async.drainQueues [as _onImmediate] (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/async.js:15:14) at runCallback (timers.js:705:18) at tryOnImmediate (timers.js:676:5) at processImmediate (timers.js:658:5) at process.topLevelDomainCallback (domain.js:121:23) For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
Pipfileでパッケージを管理していたのですが、pipenv
がインストールされていないようなのでrequirements.txt
を作成して、リポジトリに上げておきます。
pipenv run pip freeze > requirements.txt
serverless-python-requirements
がPipfileも存在していると、そちらを優先してpkgを取得するようなので、 usePipenv: false
のオプションを追加し、Pipfileを利用しないように設定します。
custom: defaultStage: dev pythonRequirements: # dockerizePip: non-linux usePipenv: false
python3.6→3.7に変更
Error -------------------------------------------------- Error: python3.6 not found! Try the pythonBin option. at pipAcceptsSystem (/alexa-skill-seibu-bus/node_modules/serverless-python-requirements/lib/pip.js:100:13) at installRequirements (/alexa-skill-seibu-bus/node_modules/serverless-python-requirements/lib/pip.js:168:9) at installRequirementsIfNeeded (/alexa-skill-seibu-bus/node_modules/serverless-python-requirements/lib/pip.js:551:3) at ServerlessPythonRequirements.installAllRequirements (/alexa-skill-seibu-bus/node_modules/serverless-python-requirements/lib/pip.js:630:29) at ServerlessPythonRequirements.tryCatcher (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/util.js:16:23) at Promise._settlePromiseFromHandler (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/promise.js:547:31) at Promise._settlePromise (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/promise.js:604:18) at Promise._settlePromise0 (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/promise.js:649:10) at Promise._settlePromises (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/promise.js:729:18) at _drainQueueStep (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/async.js:93:12) at _drainQueue (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/async.js:86:9) at Async._drainQueues (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/async.js:102:5) at Immediate.Async.drainQueues [as _onImmediate] (/alexa-skill-seibu-bus/node_modules/bluebird/js/release/async.js:15:14) at runCallback (timers.js:705:18) at tryOnImmediate (timers.js:676:5) at processImmediate (timers.js:658:5) at process.topLevelDomainCallback (domain.js:121:23) For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
python3.6がないので、runtimeをpython3.7
に変更します。
provider: name: aws runtime: python3.7
オプションの渡し方を変更
Error -------------------------------------------------- Error: subscription 'type' is required at _class.setSubscription (/alexa-skill-seibu-bus/node_modules/@serverless/platform-sdk/src/deployments/index.js:129:13) at /alexa-skill-seibu-bus/node_modules/@serverless/lib/deployment/parse.js:267:20 at Generator.next (<anonymous>) at asyncGeneratorStep (/alexa-skill-seibu-bus/node_modules/@serverless/enterprise-plugin/lib/deployment/parse.js:21:103) at _next (/alexa-skill-seibu-bus/node_modules/@serverless/enterprise-plugin/lib/deployment/parse.js:23:194) For debugging logs, run again after setting the "SLS_DEBUG=*" environment variable.
デプロイ時に --alexaskill
オプションで、環境差異の値を渡していたのですが、profileにて変数として設定し、変数から値を取得するように変更します。
events: # - alexaSkill: ${opt:alexaskill} - alexaSkill: ${param:alexaSkillId}
profileの「parameters」を選択し、変数を追加後「Save」をクリック
おわり
とりあえずserverless CI/CDを利用して、デプロイできるのを確認しました。
ブランチによるステージと本番のリリース分けなど、実際の運用には細かな設定が足りてませんが、簡単にローカルでのデプロイから変更することが出来ました!
CircleCIやGithub Actionsなどの汎用的に使えるCI/CDツールから、terraform CloudやserverlessCI/CDなどツールに特化したCI/CDツールも出てきて、選択肢の幅が広がりますね!
フリープランだとデプロイの同時実行数などに制限がある事も多いので、デプロイ処理自体が違う場合は、CI/CDツールを自体を分ける事で並行でデプロイできるので、個人の開発や予算がない組織では利用するのは良さそうです!