Posted at

AWS Amplify ConsoleでCIを頑張った話

先日のJAWS-UG横浜 #16 DevOpsで発表させてもらった内容の技術的な部分。

AWS Amplify ConsoleはCD(継続的デリバリ)に特化したサービスに現在見えるが、以下のことを自前で実施してみました。


  1. 単体試験(unittest)がAmplify Console上で自動実施できるようにする

  2. シナリオ試験(Karate)がAmplify Console上で自動実施できるようにする

  3. 1, 2で実施した結果がHTMLでレポート出力され、ブラウザから表示可能なようにする(Amplify Consoleはビルド時に毎回インスタンスが割り当てられるので、ローカルに出力したものは基本的に破棄される)

  4. 上記が実施可能なamplify.ymlを作成する


結果

適用したamplify.ymlとサンプルアプリを以下にコミットしてあります。

https://github.com/kojiisd/cognito-user-manager


どんなアプリか?

CIの対象としたアプリはCognitoのユーザ管理を簡単に実施できるWebサービスです。(Cognitoって承認とかユーザ削除とか、面倒なので)まだ作り途中ですが、ある程度機能が揃っていて画面もサーバサイドもしっかり実装されているので、こいつをCIしていきます。

クライアントはAngular 7、サーバはPython3.7のAWS Lambdaで実装しています。

スクリーンショット 2019-05-25 15.47.11.png


単体試験とシナリオ試験をAmplify Console上で行えるようにする

amplify.ymlの編集がキモになるわけですが、Amplify Consoleは勝手にビルドマシンが用意されるため、色々とインストールが必要になります。


事前準備

CI/CDを行うために足りないものをインストールしていきます。(手抜きで全ての処理をpreBuildに含んでいます。)


AWS認証設定

Serverless Frameworkでサーバ側をデプロイする仕組みにしていますが、デプロイ用の権限はデフォルトでは用意されていないため、自前で用意します。

- mkdir  -p ~/.aws

- echo "[${SLS_AWS_ACCOUNT_ID}]" > ~/.aws/credentials
- echo "aws_access_key_id = ${ACCESS_KEY}" >> ~/.aws/credentials
- echo "aws_secret_access_key = ${SECRET_KEY}" >> ~/.aws/credentials


unittest実行用にPython、Pipのインストール

Pythonはデフォルトのリポジトリだと3.4系までしかない?のでそれをインストールします。またunittestをHTML形式でレポート出力できるようにPyUnitReportをインストールします。

- yum update python34 -y

- yum -y install python34
- python3 --version
- curl https://bootstrap.pypa.io/get-pip.py | python3
- pip3 -V
- pip3 install -r requirements_test.txt -t libs
- python3 tests/test_user_handler.py

PyUnitReportはrequirements_test.txtい記載しています。

pyunitreport==0.1.4


Karate実行用にJavaとMavenのインストール

KarateはMaven, Gradleで実行が可能ですが、今回はMavenで実行します。

- yum install -y java-1.8.0-openjdk-devel.x86_64

- yum install -y apache-maven


Node.jsのDaemon化のためにforeverをインストール

本当はng e2eコマンドでKarateが実行されるようにしたかったのですが、手抜きでng serveを実施してその内容をDaemon化できるようにします。そのためにはforeverというツールがよさそうです。

- npm install -g forever


それぞれ単体試験とシナリオ試験を実行する

ここまでで事前準備が済んだので、実際に単体試験とシナリオ試験を実施してみます。またその結果をHTMLレポートとして出力しているので、S3の特定のバケットにアップロードします。

設定は以下のようになります。

# unittestによる単体試験とその結果のHTML出力、S3へのアップロード

- python3 tests/test_user_handler.py
- ls reports/html_report/ > file_path.txt
- aws s3 cp reports/html_report/`cat file_path.txt` s3://${REPORT_BUCKET}/index.html --profile=${SLS_AWS_ACCOUNT_ID}
:
:
# Karateによるシナリオ試験とその結果のHTML出力、S3へのアップロード
- mvn clean test
- ls target/
- cd target/surefire-reports/
- aws s3 cp ./ s3://${REPORT_BUCKET}/karate/ --recursive --profile=${SLS_AWS_ACCOUNT_ID}
- aws s3 cp ../karate.log s3://${REPORT_BUCKET}/karate/karate.log --profile=${SLS_AWS_ACCOUNT_ID}

それぞれS3には必要ファイルが出力されるため、確認をすると、バッチリ試験結果が出力されていました。

PyUnitReportによる単体試験結果

スクリーンショット 2019-06-01 17.40.50.png

Karateによるシナリオ試験結果

スクリーンショット 2019-06-01 17.41.01.png


まとめ

AWS Amplify Console自体はまだまだCD感の強いサービスですが、カスタマイズすることで一応CIっぽさを出すこともできました。とりあえず1本Amplify Console上で通るものをGitHubに置いているので、興味ある人は中身を見てもらえればと思います。