App RunnerとGithub Actionsで自動デプロイ環境を構築する
前回までのお話
前回は、App RunnerにNext.jsをdeployしました。
やりたいこと
今回やりたいことは、CD環境の構築です。具体的に言うと、masterブランチにpush(or merge)されると、ECRにイメージを自動pushしたいと思いました。
App RunnerはECRへのpushを検知すると、自動デプロイが走る設定をボタン一つで実現できるので、後述するGithub ActionsとApp Runnerを組み合わせて、お手軽にCD環境の構築が可能です。素敵。
Github Actionsについて
簡単にいうと、Githubにデフォルトで付いているサービスで、GitHubだけでCI/CD的な機能を実現できます。無料枠がかなりでかいので、とてもおすすめです。(公式ソースを見たわけではないですが、執筆時点でpublicリポジトリなら、ずっと無料。privateリポジトリは月2000分まで無料です。安い)
参考記事
Github Actionsについては、ほぼこの記事通りにできました。感謝。が、今回はそれ以外の部分でハマったので、備忘録を兼ねて記事にまとめています。
参考: GithubActionでmasterプッシュ時にECRにimageをpushする
ECRにリポジトリを作成
こちらは前回までに作成済み。
話の本筋とは逸れますが、イメージスキャンの設定で、push時にスキャンを有効にしておくと、pushの度に脆弱性をチェックしてくれるようです。しかも無料。便利。
公式読んでる感じ、暗号化設定で、KMS 暗号化も有効にするとセキュリティー的に良いと思ったので、有効化しました。
参考: 【超待望アップデート】ECRに対する脆弱性スキャン機能が提供されました
参考: ECR が AWS KMS キーを使用したイメージの暗号化をサポート(公式)
Github Actionsを動かすアクセスキー、シークレットキーを取得
参考記事通りですが、下記の手順を踏みます。
1、awsコンソールにログイン
2、検索窓から「iam」と検索
3、ユーザー追加をクリック
4.名前に「github-actions」(名前は任意の名前)アクセスの種類は「プログラムによるアクセス」にチェックして次へ
5.「既存のポリシーを直接アタッチ」を選択→「AmazonEC2ContainerRegistryPowerUser」と検索すると権限が出てくるのでこちらをチェック
6.あとは全て次へ。アクセスキーとシークレットキーをメモしておく。
補足ですが、今回はユーザーを作成して、ユーザーに対して既存のポリシーを直接アタッチしてますが、公式を読む限り、ユーザーグループを使用して、グループに対してポリシーをアタッチする方が望ましいのかもしれません。個人的にIAMは苦手意識があり、まだまだ勉強不足なので、ご意見あれば教えていただきたいです。
[公式] IAM ユーザーにアクセス許可を割り当てるためには、ユーザーグループを使用する
Githubにシークレットキーを登録
参考記事通りですが、下記の手順を踏みます。
(ここまで参考記事通りすぎて、書いてて申し訳ないです。。)
1、githubの該当のリポジトリにいき下記3つの変数を追加する
AWS_ACCESS_KEY_ID(取得したアクセスキー)
AWS_SECRET_ACCESS_KEY(取得したシークレットキー)
AWS_ECR_REPO_NAME(ECRで作成したリポジトリ名)
上記のように変数を指定することで${{ secrets.キー名 }}とすることでその環境変数を使用できます。
Github Actionsのymlを作成
参考記事通りですが、下記の通り。
一点補足しておくと、Github Actionsを作成したことがない方は馴染みがないかもしれませんが、ルートプロジェクト直下に.githubディレクトリを作成して、直下にworkflowsディレクトリを作成。その直下にymlファイルを作成すると、yml内に定義した処理を実行できます。参考記事がとても丁寧でわかりやすいので、是非一読してみてください。
参考: GitHubの新機能「GitHub Actions」で試すCI/CD
name: Build and Push
on:
push:
branches:
- master
jobs:
build-and-push:
runs-on: ubuntu-18.04
timeout-minutes: 300
steps:
- uses: actions/checkout@v1
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ secrets.AWS_ECR_REPO_NAME }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:latest .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
masterにpush
実際にmasterにpushします。
Githubの Actionsタブを見てみると、処理が走っていることが確認できます。
ECRも見てみましょう。
ECR > リポジトリから、該当のリポジトリクリック。
良さそうです。
App Runnerをチェック。
App Runner > サービス > サービス名から、デフォルトドメインを確認すると反映されて...ない???
ハマったところ
結論的に言うと、Dockerfileが良くなかったです。元々は、ビルドをしていないイメージをpushして、開始コマンドでビルドをしていました。
App Runnerはデフォルトでアプリケーションログを出してくれるようになっていて、そちらを確認してみると下記のようなエラーが出てました。
It looks like you're trying to use TypeScript but do not have the required package(s) installed.
下記記事を読んでいると、ビルドを事前にしてイメージpushすればよいのではないかと思い、実行すると成功しました。
参考記事: Asked to install Typescript when already installed when building Docker image
(App Runner > サービス > サービス名)
修正したDockerfileはこちら
From node:14-alpine
# ワーキングディレクトリの指定
WORKDIR /usr/src/app
# linux Update, set Timezone, install bash
RUN apk --update add tzdata && \
cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
apk del tzdata && \
apk add --no-cache bash
# コピー & ペースト
COPY ./app /usr/src/app
# npm update & install & build
RUN npm install -g npm && \
npm run remove && \
npm install && \
npm run build
package.jsonはこちら
"scripts": {
"dev": "cross-env NODE_ENV=development node server/index.js",
"build": "next build",
"start": "cross-env NODE_ENV=production node server/index.js",
"remove": "rm -rf node_modules && npm run clear:hard-source-cache",
"clear:hard-source-cache": "rm -rf node_modules/.cache/hard-source/",
"type-check": "tsc --pretty --noEmit",
"format": "prettier --write **/*.{js,ts,tsx}",
"lint": "eslint . --ext ts --ext tsx --ext js",
"lintfix": "eslint --fix . --ext ts --ext tsx --ext js",
"test": "jest",
"test-all": "npm run lint && npm run type-check && npm run test"
},
開始コマンドは、npm run start
のみにしました。
(App Runner > サービス > サービス名の設定タブ)
こちらでmasterにpushしたところ、無事変更の反映が確認できました。
まとめ
App RunnerとGithub Actionsを使うと、非常にお手軽にCD環境を構築できます。
今回Github Actionsをはじめて使いましたが、Github Actionsについては、特段ハマることもなく、無料枠も大きくて非常に強力なサービスだなと思いました。
次は、Mongo DBとの接続を試していきます。
Discussion