かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Serverless Framework で deploy 用ディレクトリへ移動→環境変数を設定する方法で deploy する環境を切り替える(その3、CircleCI に deploy する)

概要

記事一覧はこちらです。

Serverless Framework で deploy 用ディレクトリへ移動→環境変数を設定する方法で deploy する環境を切り替える(その2) の続きです。

参照したサイト・書籍

  1. Making Serverless CI/CD Easier with CircleCI and Serverless Framework
    https://aws.amazon.com/jp/blogs/apn/making-serverless-ci-cd-easier-with-circleci-and-serverless-framework/

  2. Welcome to CircleCI Documentation
    https://circleci.com/docs/ja/2.0/

    • CircleCI のドキュメントの日本語版。
  3. Configuring CircleCI
    https://circleci.com/docs/2.0/configuration-reference/

  4. あなたがnpm installをしてはいけない時
    https://blog.minimalcorp.com/users/jigen/posts/6f325dc9b8a00370b6aedf47a34cb3ce

  5. npm ciを使おう あるいはより速く
    https://qiita.com/mstssk/items/8759c71f328cab802670

  6. まさかPushデバッグしてないよね? よく使うCircleCIのデバッグ方法
    https://blog.vtryo.me/entry/circleci-debug-method

  7. いまさらだけどCircleCIに入門したので分かりやすくまとめてみた
    https://qiita.com/gold-kou/items/4c7e62434af455e977c2

目次

  1. .circleci/config.yml を作成する
  2. CircleCI で Project の設定をする
  3. AWS マネジメントコンソールで circle-ci ユーザーを作成し、アクセスキーを作成する
  4. CircleCI の管理画面から AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY を設定する
  5. .circleci/config.yml で NODE_ENV=ci npm run deploy:all を実行するよう変更する
  6. commit&push して CircleCI から deploy する
  7. AWS に作成したリソースを確認する
  8. 動作確認する
  9. 何も変更せずに deploy し直すと cache の効果でどのくらい時間が短縮されるのか?
  10. stages/prod/custom-shared-package-layer.yml の説明
  11. CircleCI で deploy したリソース一式を削除する

手順

.circleci/config.yml を作成する

.circleci/config.yml を新規作成し、まずは checkout だけ記述します。

version: 2.1
jobs:
  deploy:
    docker:
      - image: lambci/lambda:build-python3.8
    steps:
      - checkout
workflows:
  version: 2
  deploy:
    jobs:
      - deploy:
          filters:
            branches:
              only: master

Docker Image は serverless-python-requirements プラグインが使用している lambci/lambda:build-python3.8 を使用します。以下の理由で使いやすかったからです。

CircleCI で Project の設定をする

CircleCI の管理画面から「Proejcts」の画面を表示し、ksbysample-serverless-deploy の「Set Up Project」ボタンをクリックします。

f:id:ksby:20200718124240p:plain

.circleci/config.yml は追加してあるので「Add Manually」ボタンをクリックします。

f:id:ksby:20200718124458p:plain

下の画像のダイアログが表示されるので「Start Building」ボタンをクリックします。

f:id:ksby:20200718124738p:plain:w300

workflow が実行されて SUCCESS になります。

f:id:ksby:20200718143749p:plain

AWS マネジメントコンソールで circle-ci ユーザーを作成し、アクセスキーを作成する

本番環境(prod)を deploy するアカウントで circle-ci ユーザーを作成し、アクセスキーも作成します。アクセス権限は AdministratorAccess ポリシーをアタッチします。

f:id:ksby:20200718145522p:plain f:id:ksby:20200718171333p:plain

CircleCI の管理画面から AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY を設定する

CircleCI の ksbysample-serverless-deploy の画面右上の「Project Settings」ボタンをクリックします。

f:id:ksby:20200718172144p:plain

Project Settings 画面が表示されたら左側の「Environment Variables」を選択した後、右側の「Add Environment Variable」ボタンをクリックして AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY を追加します。

f:id:ksby:20200718172415p:plain f:id:ksby:20200718173018p:plain

.circleci/config.yml で NODE_ENV=ci npm run deploy:all を実行するよう変更する

.circleci/config.yml を以下のように変更します。

version: 2.1
jobs:
  deploy:
    docker:
      - image: lambci/lambda:build-python3.8
    environment:
      AWS_DEFAULT_REGION: ap-northeast-1
      STAGE: prod
      LOG_LEVEL: ERROR
      POWERTOOLS_TRACE_DISABLED: true
      NODE_PATH: /opt/nodejs/node12/node_modules:/opt/nodejs/node_modules:/var/runtime/node_modules
    steps:
      - checkout
      - run:
          name: install nodejs12.x
          command: curl https://lambci.s3.amazonaws.com/fs/nodejs12.x.tgz | tar -zx -C /
      - run: node -v
      - run: npm -v

      # Caching Dependencies
      # https://circleci.com/docs/2.0/caching/
      - restore_cache:
          keys:
            - asset-cache-v1-{{ arch }}-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
            - asset-cache-v1-{{ arch }}-{{ .Branch }}
            - asset-cache-v1
      - run: npm ci
      - run: pip install -r requirements.txt
      - run: python -m unittest -v
      - run: NODE_ENV=ci npm run deploy:all
      - save_cache:
          key: asset-cache-v1-{{ arch }}-{{ .Branch }}-{{ .Environment.CIRCLE_SHA1 }}
          paths:
            # https://docs.npmjs.com/cli/ci#example
            - $HOME/.npm
            - /var/lang/lib/python3.8
            - /root/project/.cache
workflows:
  version: 2
  deploy:
    jobs:
      - deploy:
          filters:
            branches:
              only: master

commit&push して CircleCI から deploy する

master ブランチに commit&push すると worflow が動作して無事 SUCCESS になりました。

f:id:ksby:20200718184952p:plain

各 step にかかった時間は以下の通りです。

f:id:ksby:20200718185126p:plain f:id:ksby:20200718185228p:plain

NODE_ENV=ci npm run deploy:all の状況を見ると per-env の後に cross-env-shell "cd $SERVICE_DIR && npx sls deploy -v" が実行されており、npm-scripts の deploy-service:ci が実行されていることが分かります。

f:id:ksby:20200718185517p:plain f:id:ksby:20200718185625p:plain f:id:ksby:20200718190502p:plain f:id:ksby:20200718185839p:plain f:id:ksby:20200718185957p:plain f:id:ksby:20200718190110p:plain f:id:ksby:20200718190223p:plain f:id:ksby:20200718190316p:plain

AWS に作成したリソースを確認する

作成されたリソースを確認すると全てに STAGE 名である prod が入っています。

■Lambda 関数 f:id:ksby:20200718192438p:plain

■Lambda レイヤー f:id:ksby:20200718192550p:plain

■IAM ロール f:id:ksby:20200718192700p:plain

■CloudWatch ロググループ f:id:ksby:20200718192814p:plain

■S3 バケット f:id:ksby:20200718192956p:plain

■CloudFormation スタック f:id:ksby:20200718193108p:plain

API Gateway f:id:ksby:20200718193205p:plain

■SQS キュー f:id:ksby:20200718193334p:plain

■DynamoDB テーブル f:id:ksby:20200718193442p:plain

動作確認する

Postman から API Gateway の endpoint にアクセスすると 200 OK が返ってきて、

f:id:ksby:20200718204452p:plain

DynamoDB の sample-table-prod テーブルにデータが保存されました。

f:id:ksby:20200718204559p:plain

ksbysample-upload-bucket-prod バケットに sample.jpg をアップロードすると、

f:id:ksby:20200718204715p:plain f:id:ksby:20200718204822p:plain

ksbysample-resize-bucket-prod バケットに sample_thumb.jpg が生成されました。

f:id:ksby:20200718204929p:plain f:id:ksby:20200718205012p:plain

Pillow を使用したリサイズ処理も問題なく動作しています。

何も変更せずに deploy し直すと cache の効果でどのくらい時間が短縮されるのか?

.circleci/config.yml 内で1行改行してから revert して master ブランチに commit&push してみると、前回と比較して deploy 時間が約半分になりました。

f:id:ksby:20200718210014p:plain f:id:ksby:20200718210117p:plain

ただし、この時気づきましたが Lambda Layer の shared_package_layer のバージョンが1つ上がっていました。少し試してみたのですが deploy すると変更点がなくてもバージョンが1つ上がってしまうようです。変更がなければバージョンが上がらないようにしたいのですが、CI/CD 前提ならば Lambda Layer は別レポジトリに分けた方が良いのかもしれません。。。

stages/prod/custom-shared-package-layer.yml の説明

stages/prod/custom-shared-package-layer.yml に以下のように記述しましたが、

pythonRequirements:
  # dockerizePip: true
  fileName: ../../requirements.txt
  noDeploy:
    - aws-lambda-context
    - boto3
    - moto
  useStaticCache: true
  useDownloadCache: true
  cacheLocation: /root/project/.cache
  staticCacheMaxVersions: 3
  layer:
    name: "shared-package-layer-${env:STAGE}"
    description: 共通パッケージ用 Lambda Layer
  • デフォルトの cacheLocation ではエラーになるため、CircleCI の working_directory の下のディレクトリを指定します。
  • useStaticCache、useDownloadCache を true にして cache を使うよう設定します。
  • serverless-python-requirements プラグインの cache を CircleCI の cache 機能で cache するので、staticCacheMaxVersions で履歴数を少なめに指定してサイズが大きくならないようにします。

CircleCI で deploy したリソース一式を削除する

stages/prod/.envrc で AWS_PROFILE に削除可能な profile を設定しておいてから、以下のコマンドを実行すれば削除されます。

$ cd stages/prod
$ npm run remove:all

f:id:ksby:20200719004105p:plain f:id:ksby:20200719004157p:plain f:id:ksby:20200719004308p:plain

履歴

2020/07/19
初版発行。