この記事は?
Github ActionsとLocalStackを使って、インフラにAWSを利用しているシステムのCI環境を構築した時のメモ
-
Github Actions
- Githubにpushしたりmergeしたりしたら自動であれこれやらせたいときに使う機能
- masterのコードを取ってきてDockerコンテナ内でビルド&AWSへデプロイ等ができる
- Privateリポジトリかつフリープランなら月2,000分まで無料、Publicなら完全無料
-
LocalStack
- Dockerコンテナ内に仮想のAWS環境を作れるツール
- 今回はGithub Actionsでこのコンテナにデプロイして統合テストを実行してみる
LocalStack公式のドキュメントは↓
サンプルコードは↓
デプロイするシステム
Lambdaを介してS3へファイルをアップロードするシステム
詳しくはこちらの記事を参照(ぶっちゃけするまでもないと思う)
手を動かす
workflowの定義
まずはGithub Actionsでやってほしいことを書いていく
プロジェクトの.github/workflows
以下に適当な名前のyamlファイルを置くことで、Github Actionsがそれを読み込み処理を実行してくれる
このyamlファイルをワークフローという
とりあえず↓のようなファイルを作成してほしい
※今回はyamlファイルに何もかもベタ書きしてるけど実務で利用する場合は適宜スクリプトファイル化した方が見やすいと思う(ITのところとか)
name: IntegrationTest
on:
push:
branches: [main]
env:
REGION: ap-northeast-1
jobs:
test:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install modules
run: |
pip install --upgrade pyopenssl
pip install localstack awscli-local
docker pull localstack/localstack
npm install -g aws-cdk-local aws-cdk
npm install
- name: Start LocalStack
run: localstack start -d
- name: Check container status
run: |
count=0
while [ $(docker inspect --format='{{json .State.Health}}' localstack_main | jq '.Status == "healthy"') != "true" ];
do
count=$(($count + 1))
echo "waiting..."
sleep 5
if [ $count == 10 ]; then
echo "Check container status timeout"
exit 1
fi
done
- name: Configure aws credeintals
run: |
aws configure set region ${{ env.REGION }}
- name: Deploy
run: |
cdklocal bootstrap
cdklocal deploy LocalstackStack --require-approval never
- name: Execute integration test
run: |
awslocal lambda invoke \
--function-name test-function \
--payload '{ "file": "test", "key": "test.txt" }' \
--cli-binary-format raw-in-base64-out \
--region ${{ env.REGION }} \
response.json
awslocal s3api get-object \
--bucket test-bucket \
--key test.txt \
--region ${{ env.REGION }} \
response.json
ちなみに、ワークフローの構文については↓のドキュメントが詳しいのでよくわかんないことがあったら読んでみよう
このワークフローのポイント
on
どんなイベントが起きたときにこのワークフローを実行するかの設定
今回はmainブランチにpushしたときにしているが、PullRequest作成時やmainブランチにマージした時など細かく設定できる
runs-on
このワークフローを動かす仮想環境を指定する
今回はubuntu-20.04
なので↓の環境で動かすことになる
このページの"Installed Software"以下にインストール済みのソフトが列挙してあるが、これと今回のCIに必要なソフトとを照らし合わせると...
- ✅Node.js
- ✅Python
- ✅Docker
- ✅AWS CLI
- AWS CLI Local
- AWS CDK
- AWS CDK Local
- LocalStack
✅が付いているのは予めインストールされているので、それ以外をインストールするステップを追加してあげればOK、ということになる
steps.Checkout
ワークフローを実行する対象となるブランチへチェックアウトしているステップ
儀式みたいなもんです
steps.Install modules
node_modulesやらLocalStackやら色々インストールするステップ
これいる?ってなりそうなコマンド
pip install --upgrade pyopenssl
docker pull localstack/localstack
こちらにもあるようにGithubActionsのubuntu-20.04
に入っているpyOpenSSLのバージョンが原因でエラーとなってしまうためアップデートしている
また、localstackコマンド実行時にDockerHubから最新のイメージをとってきてはくれないので、あらかじめ最新版をpullしてきている
steps.Check container status
LocalStackのコンテナ(localstack_main)の起動に時間がかかるため、ステータスがhealthy
になっているか定期的にチェックするスクリプトを実行
ここはもっとスマートなやり方があると思う...
steps.Deploy
ここではcdklocalでbootstrap→deployと実行しているだけなので特に問題はない
ただし、deployコマンド実行時にyes noを聞かれてしまうのでそれを無効化する必要がある
方法は以下の2通り
-
--require-approval never
オプションをつける -
cdk.json
に"requireApproval": "never"
を追加する
steps.Execute integration test
名前そのまま統合テストを実行している
Lambdaを実行してS3に出力された成果物をとってきているだけ
きっちりやるならファイルの中身をjqコマンドで期待値通りか確認したりロググループ見てエラーレベルのログがないか確認いしたりした方がいいと思う
動作確認
.github/workflows/integration-test.yaml
が書けたらさっそくGithubにpushしよう
するとActions
タブにこんなのが表示されるので特にエラーがなければOK