はじめに
皆さんはじめまして! 今回 Rakus Developers Blog 初投稿となる株式会社ラクスの大原(kzak_24)と申します。
インフラ開発部 SRE課に所属しております。
どうぞよろしくお願いいたします。
先日、アサインされているプロジェクトにて、CIツールにGitHub Actionsを採用する運びとなり、AWSのサービスと連携しての技術検証を終えました。結論、想像していたよりも簡単にCIパイプラインを構築することができ、非常に便利だと感じました。そこで今回は、検証内容や実装ポイントなどをご紹介していきたいと思います。
情報量が多く、すべてをお伝えすることはできませんが、GitHub ActionsとAWSを使って、CIを始めたいという方のご参考となれば幸いです。
目次
GitHub Actions とは?
GitHubのドキュメントには次のように記載されています。
GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged pull requests to production.
Google先生による翻訳
GitHub Actionsは、継続的インテグレーションおよび継続的デリバリー(CI / CD)プラットフォームであり、ビルド、テスト、およびデプロイのパイプラインを自動化できます。リポジトリへのすべてのプルリクエストをビルドしてテストするワークフローを作成したり、マージされたプルリクエストを本番環境にデプロイしたりできます。
簡単に言うと、GitHubリポジトリで起きるイベントをトリガーにしたCI/CDパイプラインを構築できるプラットフォームということになります。
GitHub Actionsには以下のような構成要素があります。
- Workflow
- GitHub Actionsの一連の処理をまとめた単位。1つのファイルで1つのワークフローを定義できる
- Event
- ワークフローを実行するトリガー
- Job
- ランナー上で実行される処理の単位。ジョブが分かれると別の環境で処理が実行される
- Step
- ジョブが実行する処理の集合。
- Actions
- ワークフローの最小構成要素。コマンドの実行やアクションという一連の処置がまとまったライブラリのようなものを実行することができる
- Runner
- 処理を実行する環境
検証環境の構成
今回の検証では以下のような構成でCIパイプラインを構築しました。
開発者のPR作成から、最終的にAmazon ECRにコンテナイメージをプッシュするところまで、このパイプラインでは実行します。
CIは以下のような流れで実行されます。
- 開発者がアプリケーションリポジトリでPRを作成
- PRマージというEventを検知し、CIが起動
- Test Workflowが実行される
- Build Workflowが実行され、AWS CodeBuildが実行される
- CodeBuildで作成されたコンテナイメージをAmazon ECRにプッシュ
事前準備
それでは、CIを動作させる為の準備をしていきましょう。
今回必要なものは以下の通りです。
※ 今回は以下の項目の作成、取得については完了済みという前提で、説明を省略します。
ワークフローの定義ファイルの作成
- ワークフローを実行するアプリケーションのルートディレクトリに
.github/workflows/
というディレクトリを作成します。 test_workflow.yaml
、build_workflow.yaml
を.github/workflows/
配下に作成します。
GitHub ActionsのワークフローはYAML形式で定義し、.github/workflows/
に配置することで、ワークフローとして管理されます。
個人用アクセストークンの取得
GitHub Actionsの中でリポジトリに特定の操作を行う際、アクセストークンが必要になる為、個人用アクセストークンを取得します。(今回は後述するrepository_dispatchという処理で使用します)。
- まずGitHubのページにアクセスし、ページ右上隅のプロフィールをクリックし、「Settings」をクリックします。
- スライダー最下の「Developer settings」をクリックします。
- スライダーから、「Personal access tokens」をクリックします。
- 「Generate new token」をクリックします。
- パスワード入力を求められるので、入力します。
- 作成するアクセストークンの説明や有効期限、権限スコープを設定します。
- 今回はリポジトリに関する操作権限をスコープに設定します。
- 今回はリポジトリに関する操作権限をスコープに設定します。
- ページ下部の「Generate token」をクリックします。
- 作成したアクセストークンの値が表示されます。
- このタイミングでしか表示されないので、注意してください。
- このタイミングでしか表示されないので、注意してください。
- 再度アクセストークンのページにアクセスすると、トークンが作成されていることが確認できます。
- 有効期限の延長や権限スコープの変更もここから行えます。
- 有効期限の延長や権限スコープの変更もここから行えます。
リポジトリのSecrets作成
GitHub Actionsの中で使用するAWSのクレデンシャルやアクセストークンなどの情報は、Secretsという機能で暗号化したシークレットとして使用します。 取得したAWSクレデンシャルと個人用アクセストークンをSecretsに登録します。
- リポジトリのメインページにアクセスします。
- リポジトリ名の下の「Settings」をクリックします。
- スライダーから「Secrets」をクリックし、「Actions」をクリックします。
- シークレットの管理ページが表示されるので、「New repository secret」をクリックします。
- Nameにシークレットの名前(任意)を設定し、Valueに取得したアクセスキーIDの値を入力します。
- 「Add Secrets」をクリックし、Repository secretsに作成したシークレットがあることを確認します。
- 同様にシークレットアクセスキー、個人用アクセストークンも登録します。
workflowファイル
今回の検証で作成したワークフローファイルは以下のようになっています。
test_workflow.yaml
name: Test Workflow on: pull_request: branches: - main types: - closed jobs: Lint-Test: runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v2 - name: Run Lint run: | docker-compose up -d --remove-orphans docker-compose exec -T next npm run lint echo "Lint succees!." - name: Run Test run: | docker-compose exec -T next npm run test echo "Test succees!." - name: Dispatch Build Workflow uses: peter-evans/repository-dispatch@v1 with: token: ${{secrets.REPO_ACCESS_TOKEN}} repository: 検証用のリポジトリ event-type: ci-sample
build_workflow.yaml
name: Build Workflow on: repository_dispatch: types: - ci-sample env: REGION: ap-northeast-1 PROJECT_NAME: example_CI_build_project IMAGE_TAG: ci-sample jobs: Build: runs-on: ubuntu-latest steps: - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }} aws-region: ${{ env.REGION }} - name: Run CodeBuild uses: aws-actions/aws-codebuild-run-build@v1 with: project-name: ${{ env.PROJECT_NAME }} env-vars-for-codebuild: IMAGE_TAG env: IMAGE_TAG: ${{ env.IMAGE_TAG }}
それでは、中身について説明していきます。
Eventの定義
まずは、ワークフローを実行するトリガーとなるイベントの定義です。
test_workflow.yaml
(一部抜粋)
on: pull_request: branches: - main types: - closed
GitHub Actionsでは、on
セクションにイベントを定義します。
上記のように定義することで、mainブランチへPRをマージしたことをトリガーにワークフローを実行できます。
pull_request
の他にも、push
や手動実行を行うworkflow_dispatch
というイベントも定義できます。
また、repository_dispatch
というイベントを定義することで、あるワークフローから別のワークフローを実行するイベントを送信できます。
test_workflow.yaml
(一部抜粋)
- name: Dispatch Build Workflow uses: peter-evans/repository-dispatch@v1 with: token: ${{secrets.REPO_ACCESS_TOKEN}} repository: 検証用のリポジトリ event-type: ci-sample
build_workflow.yaml
(一部抜粋)
on: repository_dispatch: types: - ci-sample
テスト用ワークフローの中でci-sample
というパラメーターが設定されたrepository_dispatch
イベントをビルド用ワークフローに送信しています。
指定されたイベントが送信されたことをトリガーにビルド用のワークフローが実行されるようになっています。
また、uses
を使用することで、アクションという一連の処置をまとめたライブラリのような機能を使用できます。
テスト用ワークフローではpeter-evans/repository-dispatch
というアクションを使用して、repository_dispatchイベントを送信しています。
Jobの定義
続いて、ジョブの定義について見ていきましょう。
test_workflow.yaml
(一部抜粋)
jobs: Lint-Test: runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v2 - name: Run Lint run: | docker-compose up -d --remove-orphans docker-compose exec -T next npm run lint echo "Lint succees!."
ジョブはjobs
セクションに定義します。
Lint-Test
でジョブの名前を定義しており。ジョブは複数作成することが可能です。
runs-on
でそのジョブが実行されるランナーの仮想環境を指定できます。
steps
セクションでジョブが実行するステップを定義します。steps
はname
でそれぞれ名前を指定することができ、順次実行されます。
uses
、run
で実行するアクションやコマンドを定義しています。
AWSサービスとの連携
続いて、AWSサービスと連携する処理について見ていきましょう。
build_workflow.yaml
(一部抜粋)
- name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }} aws-region: ${{ env.REGION }}
ここでは、aws-actions/configure-aws-credentials
というアクションを使用して、GitHub ActionsのランナーからAWSサービスを操作できるように、AWSクレデンシャルを設定しています。
secrets.AWS_ACCESS_KEY
でリポジトリに設定したSecretsから値を取得しています。
build_workflow.yaml
(一部抜粋)
- name: Run CodeBuild uses: aws-actions/aws-codebuild-run-build@v1 with: project-name: ${{ env.PROJECT_NAME }} env-vars-for-codebuild: IMAGE_TAG env: IMAGE_TAG: ${{ env.IMAGE_TAG }}
ここでは、aws-actions/aws-codebuild-run-build
というアクションを使用して、GitHub ActionsからAWS CodeBuildを実行しています。
また、env-vars-for-codebuild
に環境変数を渡すと、CodeBuild側の環境変数として設定してくれるので、ワークフローで定義した値がコンテナイメージにタグ付けされます(今回の場合、ci-sample
がタグ付けされます)。
buildspec
ワークフローを実行する前に、buildspecについて、少し説明します。
buildspecとはCodeBuildで実行する上でのビルド仕様のことです。
buildspec.yaml
を作成し、プロジェクトのルートディレクトリに配置することで、CodeBuildは自動でbuildspec.yaml
を検知し、定義された内容通りに処理を実行してくれます。
今回の検証で作成したbuildspecファイルは以下の通りになります。
buildspec.yaml
version: 0.2 env: parameter-store: DOCKER_USER: dockerhub-user DOCKER_TOKEN: dockerhub-token phases: install: runtime-versions: docker: 19 pre_build: commands: - echo Logging in to Amazon ECR... - aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com - echo $DOCKER_TOKEN | docker login -u $DOCKER_USER --password-stdin build: commands: - echo Build start - echo Building the Docker image... - docker-compose build - docker tag リポジトリ名_next:latest ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_REPO_NAME}:${IMAGE_TAG} post_build: commands: - echo Build completed - echo Pushing the Docker image... - docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_REPO_NAME}:${IMAGE_TAG}
少し省略しますが、各セクションがそれぞれ何をしているか、簡単に説明します。
pre_build
: ECRにログインbuild
:docker-compose
でコンテナイメージをビルドし、ワークフローから渡された値でタグ付けpost_build
:build
セクションで作成したコンテナイメージをECRにプッシュ
ワークフローの実行
それではワークフローを実行し、ECRプッシュまで実行できているか確認していきましょう!
今回はリポジトリページ上で確認していきます。
テスト用ワークフローを実行
ますはテスト用ワークフローについて確認していきましょう。
mainブランチに対して、PRを作成します。
PRをマージします。
リポジトリのトップページから、「Actions」をクリックします。
Workflowの一覧から、「Test workflow」をクリックします。
- mainブランチへのPRマージをトリガーにワークフローが実行されていることが確認できます。
- 赤枠部分(実行中のワークフロー)をクリックします。
- 実行中のジョブ一覧が表示されるので、赤枠部分(実行中のジョブ)をクリックします。
- 経過時間やステータスなどを確認できます。
- 経過時間やステータスなどを確認できます。
- 実行中のStep一覧が表示されます。
- Stepごとにコマンドやアクションのログを確認できます。
- Lintとテストが正常に完了していることが確認できます。
- Stepがすべて正常に終了すると、緑色のチェックが入ります。
- Stepごとにコマンドやアクションのログを確認できます。
Dispatch Build Workflow
というStepで、ビルド用のワークフローが実行されるトリガーとなるrepository_dispatch
イベントを送信している為、Test workflowの実行が終了すると、Build workflowが自動的に実行されます。
ビルド用ワークフローを実行
続いてビルド用ワークフローについて確認していきましょう。
前述した通り、ビルド用のワークフローはテスト用のワークフローの中で、repository_dispatch
イベントが送信されることをトリガーに実行されます。
処理の確認の流れは先ほどのテスト用ワークフローと同様です。
リポジトリのトップページから、「Actions」をクリックします。
Workflowの一覧から、「Build workflow」をクリックします。
repository_dispatch
イベントをトリガーにビルド用ワークフローが起動していることが確認できます(Repository dispatch triggered と記載されていますね)- 赤枠部分(実行中のワークフロー)をクリックします。
- 実行中のジョブ一覧が表示されるので、赤枠部分(実行中のジョブ)をクリックします。
- 実行中のStep一覧が表示されます。
- Run CodeBuildのログからCodeBuildが実行されていることが確認できます(GitHub ActionsからCodeBuildのログを確認できます)。
- ECRへのプッシュが完了していることが確認できます
- Run CodeBuildのログからCodeBuildが実行されていることが確認できます(GitHub ActionsからCodeBuildのログを確認できます)。
- ECRにプッシュされたコンテナイメージを確認します。
- 想定通り、タグに
ci-sample
が設定されたイメージがプッシュされていることを確認できました!
- 想定通り、タグに
終わりに
最後までご覧いただきありがとうございます。
今回はGitHub ActionsとAWSサービスを連携したCIパイプラインの構築について、ご紹介しました。
CIパイプラインの整備は開発サイクルの高速化に繋がるので、今後もしっかりと学んでいきたいと思います。
GitHub Actionsでは他にもPR作成やコミットの自動化など、便利な機能がたくさんあるので、今後も記事の発信を継続していきたいです
参考文献
エンジニア中途採用サイト
ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
ご興味ありましたら是非ご確認をお願いします。
https://career-recruit.rakus.co.jp/career_engineer/カジュアル面談お申込みフォーム
どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
以下フォームよりお申込みください。
rakus.hubspotpagebuilder.comラクスDevelopers登録フォーム
https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/イベント情報
会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com