パイプラインの構築(その1)

【連載】

AWSで実践! 基盤構築・デプロイ自動化

【第13回】パイプラインの構築(その1)

[2019/09/19 08:00]川畑 光平 ブックマーク ブックマーク

開発ソフトウェア

本連載では、マイクロサービスアーキテクチャでの継続的デリバリ(CD:Continuous Delivery)を以下のようなパイプラインで実装していきます。

本連載で実装する継続的デリバリのパイプライン

今回は、GitHub上のアプリケーションソースコードのdevelopブランチへのプルリクエスト(PR:PullRequest)を契機に、GitHubからCodePipelineへのWebhookにより、バックエンドのマイクロサービスアプリケーションをビルドし、DockerHubへプッシュするパイプライン処理を構築していきます。

バックエンドのマイクロサービスのコンテナイメージのビルド

  1. CodeBuildがbackendアプリケーションのステージング環境向けbuildspec.ymlに記載したビルド処理を行うコンテナを実行します。
  2. ビルド処理の中で、アプリケーション実行コンテナイメージを作成し、DockerHubへプッシュします。

バックエンドのマイクロサービスのコンテナイメージのビルド

buildspec.ymlおよびDockerfileの作成

最初に、Backendマイクロサービスアプリケーションのコンテナイメージを構築する「buildspec.yml」を作成します(上記イメージ:1-1)。本連載の第10回でbuildspec.ymlを作成した際と同じような構成で、ソースコードプロジェクトのBackendマイクロサービスプロジェクトに、build/staging/buildspec.ymlを作成します。

[project-root]

├-[backend]
│ ├- src
│ │ ├- main …..
│ │ └- test …..
│ ├- build
│ │ ├- production
│ │ | └- dockerfile
│ │ ├- staging
│ │ │ └- buildspec.yml
│ │ …..
│ └- pom.xml
│ …..
└- pom.xml

buildspec.ymlは以下の通りです。

version: 0.2
env:
  parameter-store:
  DOCKER_USER: "DOCKER_USER"
  DOCKER_PASSWORD: "DOCKER_PASSWORD"
  DOCKER_REPO : "DOCKER_REPO"
  IMAGE_REPO_NAME: "BACKEND_IMAGE_REPO_NAME"
  IMAGE_TAG: "BACKEND_IMAGE_TAG_STAGING"                                     # ...(A)
phases:
  install:
    runtime-versions:
      docker: 18                                                             # ...(B)
  pre_build:
    commands:
      - echo Logging in to Docker Hub...
      - docker login -u $DOCKER_USER -p $DOCKER_PASSWORD $DOCKER_REPO        # ...(C)
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG backend/build/production # ...(D)
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $IMAGE_REPO_NAME:$IMAGE_TAG   # ...(E)
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push $IMAGE_REPO_NAME:$IMAGE_TAG                              # ...(F)
      - printf '[{"name":"mynavi-sample-continuous-delivery-backend-staging","imageUri":"%s"}]' $IMAGE_REPO_NAME:$IMAGE_TAG > imagedefinitions.json
                                                                             # ...(G)
artifacts:
  files:
    - imagedefinitions.json                                                  # ...(H)
項番 説明
A AWS Systems Manager Parameter Storeで設定したデータを環境変数に設定します。ダブルクォーテーションで囲まれた値がParamter Storeで定義した名称です。ここでは、DockerHubのユーザーIDやパスワード、ビルドするコンテナイメージの名称、バージョン名、タグ名を設定します
B Ubuntu Standard Image 2.0 以降を使用する場合は、buildspecファイルで「runtime-versions」を指定する必要があります。詳細については、「buildspecファイルのランタイムバージョンの指定」を参照してください
C DockerHubへログインします
D Dockerイメージをビルドします。Dockerfileは後述しますが、backend/build/productionに配置し、最終的にProduction環境へリリースするものを使用します
E 作成したコンテナイメージにタグを割り当てます。Stagingでは「X.X.SNAPSHOT(Xはバージョン)」とします
F 作成したコンテナイメージをDockerHubへプッシュします
G 次回以降、ECSでコンテナイメージをクラスタへデプロイするために、コンテナイメージ名とURIを定義したimagedefinitions.jsonというJSON形式のファイルを作成します。なお、ここでname属性はECSタスク定義で設定するタスク名と一致させておく必要がありますので注意してください
H imagedefinitions.jsonファイルをアーティファクトとして出力します。なお、このアーティファクトファイルはCodePipelineによりS3バケットに保存されるかたちになります

また、buildspec.ymlから実行される、ProductionのDockerfileは以下の通りです。

# Dockerfile for sample service using embedded tomcat server

FROM centos:centos7
MAINTAINER debugroom

RUN yum install -y \
    java-1.8.0-openjdk \
    java-1.8.0-openjdk-devel \
    wget tar iproute git

RUN rm -f /etc/rpm/macros.image-language-conf && \
    sed -i '/^override_install_langs=/d' /etc/yum.conf && \
    yum -y reinstall glibc-common && \
    yum clean all

ENV LANG="ja_JP.UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LC_ALL="ja_JP.UTF-8"

RUN wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
RUN sed -i s/\$releasever/6/g /etc/yum.repos.d/epel-apache-maven.repo
RUN yum install -y apache-maven
ENV JAVA_HOME /etc/alternatives/jre
RUN git clone https://github.com/debugroom/mynavi-sample-continuous-integration.git /usr/local/mynavi-sample-continuous-integration
RUN mvn install -f /usr/local/mynavi-sample-continuous-integration/common/pom.xml
RUN mvn package -f /usr/local/mynavi-sample-continuous-integration/backend/pom.xml
RUN cp /etc/localtime /etc/localtime.org
RUN ln -sf  /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

EXPOSE 8080

CMD java -jar -Dspring.profiles.active=production /usr/local/mynavi-sample-continuous-integration/backend/target/mynavi-sample-continuous-integration-backend-0.0.1-SNAPSHOT.jar

こちらは、連載「AWSで作るクラウドネイティブアプリケーション」の第4回で解説したDockerfileとほぼ同じ構成なので、詳細についてはそちらを参照していただければと思います。

AWS Sysmtems Managers Parameter Storeでの環境変数の定義

CodePipelineの設定を行う前に、前節のbuildspec.ymlで使用する環境変数を定義しておきます。設定の要領は、第10回で解説したAWS Systems Manager Parameter Storeの設定と同様です。具体的には、以下のパラメータを定義します。

  • “DOCKER_USER” : DockerHubのユーザー名
  • “DOCKER_PASSWORD”:DockerHubのユーザーのパスワード
  • “DOCKER_REPO”: https://index.docker.io/v1/
  • “BACKEND_IMAGE_REPO_NAME”:debugroom/mynavi-sample-backend
  • “BACKEND_IMAGE_TAG_STAGING”:1.0.SNAPSHOT

CodePipelineの設定

AWSコンソールの「CodePipeline」サービスを選択し、「パイプラインの作成」ボタンを押下します。

「パイプラインの作成」ボタンを押下

パイプラインの名称とロール名を入力します。

パイプラインの名称とロール名を入力

ソースプロバイダでGitHubを選択し、(初回はOAuth認証してから)レポジトリとブランチを選択します。ここでは、トリガー対象となる「develop」ブランチを選択してください。検出オプションは「GitHubウェブフック」を選択しますが、プルリクエストイベントのフィルタ設定は後ほど行います。

レポジトリとブランチを選択

続いて、コンテナイメージをビルドするための設定を行います。CodePipelineからCodeBuildを実行するようなイメージです。プロバイダを「CodeBuild」、リージョンを「東京リージョン」を選択し、「プロジェクトを作成する」を押下して、「CodeBuild」プロジェクトを作成しましょう。

コンテナイメージをビルドするための設定

設定については、第11回で解説した通りです。ただし、1カ所だけ異なる点として、忘れずに「特権付与」にチェックを入れる必要があります。今回はBuildイメージの中でdockerコマンドを利用するため、アクセス権限の付与が必要です。また、buildspec.ymlは前節で作成したパスに配置されてあるものを指定するようにしましょう。

入力後に、「CodePipelineに進む」を押下して元のパイプラインの設定画面に戻り、「次に」ボタンの押下で次の設定へ進みます。

ビルドプロジェクトの作成(プロジェクト名、環境など)

ビルドプロジェクトの作成(セキュリティグループ、ログなど)

「デプロイステージを追加する」画面が表示されますが、ここは次回設定するので「導入段階をスキップ」を選択してください。

ここでは「導入段階をスキップ」を選択

作成するとパイプライン処理が起動し始めます。ただし、まだ作成したパイプラインのサービスロールにSystems Manager Paramter Storeの権限を付与していないため、実行エラーになります。

実行エラーになる

そこで、第11回で解説したAWS Systems Manager Parameter Storeへのアクセス権限の付与と同じ要領で、作成したサービスロールにアクセス権限を付与します。また、「編集する」ボタンで、GitHubからのWebhookでfeature/*****ブランチからのdevelopブランチに対するPRがマージされたことをトリガーとするように設定しておきましょう。設定する値は以下の通りです。

  • イベントタイプ:PULL_REQUEST_MERGED
  • HEAD_REF:^refs/heads/develop$
  • BASE_REF:^refs/heads/feature/.*

作成したサービスロールにアクセス権限を付与

設定後、改めて、パイプライン処理を実行してみましょう。ビルド処理の完了と、DockerHub上にコンテナイメージがプッシュされているかどうかを確認してください。

改めて実行すると無事完了する

以上で、ベースとなるパイプラインとBakcendサービスのコンテナイメージのビルド処理パイプラインが作成されました。次回以降は、ECSクラスタ上にコンテナイメージをデプロイするパイプラインを構築していきます。

著者紹介


川畑 光平(KAWABATA Kohei) - NTTデータ 課長代理

金融機関システム業務アプリケーション開発・システム基盤担当を経て、現在はソフトウェア開発自動化関連の研究開発・推進に従事。

Red Hat Certified Engineer、Pivotal Certified Spring Professional、AWS Certified Solutions Architect Professional等の資格を持ち、アプリケーション基盤・クラウドなどさまざまな開発プロジェクト支援にも携わる。2019 APN AWS Top Engineers & Ambassadors選出。

※ 本記事は掲載時点の情報であり、最新のものとは異なる場合がございます。予めご了承ください。

一覧はこちら

連載目次

もっと知りたい!こちらもオススメ

若手CTOが導く! テックカンパニー化に向けたDMM.comのエンジニア評価制度改革

若手CTOが導く! テックカンパニー化に向けたDMM.comのエンジニア評価制度改革

動画配信、オンラインゲームから太陽光発電まで、40以上のさまざまな事業を手がけるDMM.com。同社は昨年、技術志向のテックカンパニーへと変革していくため、「当たり前を作り続ける」というDMM TECH VISIONを公開した。

関連リンク

この記事に興味を持ったら"いいね!"を Click
Facebook で IT Search+ の人気記事をお届けします

会員登録(無料)

注目の特集/連載
[解説動画] Googleアナリティクス分析&活用講座 - Webサイト改善の正しい考え方
[解説動画] 個人の業務効率化術 - 短時間集中はこうして作る
知りたい! カナコさん 皆で話そうAIのコト
教えてカナコさん! これならわかるAI入門
対話システムをつくろう! Python超入門
Kubernetes入門
AWSで作るクラウドネイティブアプリケーションの基本
PowerShell Core入門
徹底研究! ハイブリッドクラウド
マイナビニュース スペシャルセミナー 講演レポート/当日講演資料 まとめ
セキュリティアワード特設ページ

一覧はこちら

今注目のIT用語の意味を事典でチェック!

一覧はこちら

ページの先頭に戻る