こんにちは、テクニカルディレクターのおきくです。
今回CI/CDについて色々と学んでみましたので、記事に残したいと思います。CI/CDにはJenkinsやAWS CodeBuildなどがあり、CI/CDを検討するにあたって何を使うべきか悩まれたこともあるかと思います。今回はその中でAWSのAction機能を使い、Amazon ECR(以下:ECR)登録する機能を用いてみました。
この記事が少しでも役に立っていただけると幸いです。
GitHubのアクション機能とは
GitHubのアクション機能とは、GitHubが提供しているスクリプト機能です。GitHubの各種イベント(Mergeやコミットなど)をトリガーとして、スクリプトが稼働します。様々な機能が提供されており、最たる目的はリポジトリのコード品質の担保です。
そのため、プルリクエストが発行されたタイミングで、Unit TestやCode Checkを埋め込むことも可能となります。
構成
以下構成で実施いたします。
- 開発者がリポジトリに対してブランチをマージする
- GitHub ActionがブランチへのマージをトリガーにDocker Buildを実施(NuxtJsのビルドを想定)
- Docker Buildが完了したらECRへ登録
事前準備
単純にGitHubのアクションを使って登録するだけではAWSへのアクセス権限がないため、ECRへイメージを自動登録できずPermission Errorが発生します。
またDockerイメージを保存するためのリポジトリも必要になるので、事前準備としてこれからご説明する作業が必要となります。
ECRリポジトリ作成
BuildとしたDocker Imageの保存先としてECRに対してリポジトリを用意しましょう。上記の通り、リポジトリの公開先並びにリポジトリ名を設定してください。
ほとんどのプロジェクトはGitHubリポジトリを公開せずに内部で使うことが予想されますので、特に外部へ公開する理由がなければ、可視性設定はプライベートにしてください。
IAMユーザー作成
GitHubからECRへ登録するためには、新規にIAMユーザーを作成し、それをGitHubのアクションが使えるようにする必要があります。IAMユーザーに設定するべきポリシーは下記の通りとなります。
-
・AmazonEC2ContainerRegistryPowerUser
この既存のポリシーの中には、以下のようなECR登録に必要なアクセス権限があらかじめ設定されています。任意のリポジトリやアクセス権限を制限したい場合は、カスタマイズしたアクセス権を設定したポリシーを作成して、IAMにアタッチすることも可能です。
今回の記事ではその辺りのカスタマイズについては割愛しますが、クライアントからの要求に応じて適宜設定してもらえればと思います。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:GetRepositoryPolicy",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:DescribeImages",
"ecr:BatchGetImage",
"ecr:GetLifecyclePolicy",
"ecr:GetLifecyclePolicyPreview",
"ecr:ListTagsForResource",
"ecr:DescribeImageScanFindings",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:PutImage"
],
"Resource": "*"
}
]
}
GitHubの環境変数設定
IAMユーザーのシークレットキーやアクセスキーを直接AWSのActionに書いてしまうと……大きなセキュリティインシデントになります。そうならないようにするためにも、外部には公開せずに一部の管理者ないしコラボレーターだけがみれるようにする必要性があり、GitHubではそれを実現するための環境変数機能が用意されています。
上記の通り、Settings -> Secretsと進むことで設定が可能になります。
Action設定
事前準備は完了したのでActionを設定してみましょう。なお今回のハンズオンで設定した内容については以下のGitHubでも公開しています。
ちなみにActionのコードはこちらで公開しています。
さてポイントについて上から順次説明していきたいと思います。
トリガー設定
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the master branch
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
上記の通り設定することでMasterブランチへのPush並びにMasterブランチに対してのPull RequestをトリガーにActionが動くように設定します。
RunするためのLinux環境を用意
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
続いてActionをRunするためのLinuxを用意します。これについては最早おまじないのようのようなものなので、デフォルトのままで問題ないと思います。むしろそれ以外の設定方法などがありましたら教えてください。
Docker Buildの実施並びにECRへの登録
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.SECRET_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 }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
Configure AWS Credentialsで作成したIAMユーザーのアクセスキーとシークレットキーを設定して、Login to Amazon ECRでECRへログインします。Build, tag, and push image to Amazon ECRで環境変数として、リポジトリ名のURI並びにタグ設定する際にGitHubのshaキーを設定します。
そしてECRへのリポジトリへPushします。
おまけ
ここからさらにプラスαとして、ECSに対してデプロイする方法もあります。これを書いてしまうと記事自体のボリュームが相当大きくなってしまうので割愛しますが、そのような機能があるということだけご認識いただければと思います(次回以降の記事で書けたらと思います)。
その他にAWSのシークレットマネージャーの値を取得してdocker buildする方法など、AWSとの連携する方法はまだまだたくさんありますので、引き続き学習を行えたらと思います。