2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CodePipelineからFargate(ECS)にデプロイする(1/2) - 準備編

Last updated at Posted at 2019-12-12

はじめに

Fargateを使用したECSのサービスデプロイはインプレースデプロイ一択となりますが、
CodePipelineを使ってFargateにインプレースデプロイしている記事がなかったので書いてみることにしました。
具体的にはソースコードがGitHubの特定のブランチにプッシュされたことを契機に
サンプルアプリケーションとコンテナをビルドし、ECSにインプレースデプロイする仕組みを作ります。

長くなるので2部構成とし、準備編ではFargateでECSを構成し、サンプルのWebアプリケーションをデプロイします。
実装編ではCodePipelineを利用してFargate ECS環境にインプレースデプロイを行います。

作業は以下の流れで進めていきます。

  • サンプルアプリケーションの準備
  • ALBの作成
  • Firehoseの作成
  • ECSの作成

なお、ログは最近Fargateに対応したFireLensも利用してFirehose→S3と送ってみます。

実装編は以下をご参照ください。
CodePipelineからFargate(ECS)にデプロイする(2/2) - 実装編
本記事に使用した各コードは以下で公開中です。
pideoh/fargate-inplace-deploy-sample

サンプルアプリケーションの準備

誰でも作れるをモットーに、Spring Initilizerを使って
サンプルアプリケーションのガワをサクッと作ります。
Spring Initializerを開き、以下の通り入力します。

項目 入力内容
Project Gradle Project
Language Java
Spring Boot 2.2.2
Project Metadata - Group 任意
Project Metadata - Artifact 任意
Project Metadata - Options - Java 11
Dependencies Spring Web

image.png

入力したらGenerateをクリックするとzipファイルでガワをダウンロードできます。
ここからはCLoud9で作業していきます。
Cloud9の環境構築はこちらにまとめてありますので、合わせて御覧ください。

Cloud9にDLしたzipファイルを移動し、すると以下のような構成になります。

.
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── HELP.md
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── pideoh
    │   │           └── sample
    │   │               └── SampleApplication.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       └── templates
    └── test
        └── java
            └── com
                └── pideoh
                    └── sample
                        └── SampleApplicationTests.java

src/main/java/com/pideoh/sample以下にSampleController.javaを作成し、以下のコードを追加します。

package com.pideoh.sample;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController("/")
public class SampleController {

    @GetMapping
    public String sample() {
        return "Sample\n";
    }

}

これで、$ ./gradlew bootJarを実行して、エラーが起きなければOKです。
出来上がったソースは自分のGitHubリポジトリにプッシュしておきましょう。

ALB作成

ECSで起動したサンプルアプリケーションを確認するために、ALBを作成しておきます。
ALBは特段インターネット公開する必要がないため、Internal ALBとします。
以降はEC2コンソール前提で進みます。

Target Group作成

EC2コンソールから、ロードバランシング→ターゲットグループと進み、「ターゲットグループの作成」を押下します。
設定値は名前とVPCは適宜選択し、その他のパラメータは以下とし、入力後「作成」を押下します。(デフォルトから変えるもののみ羅列)

項目 入力内容
ターゲットの種類 IP
ポート 8080

image.png

ALBの作成

同じく、ロードバランシング→ロードバランサーと進み、「ロードバランサーの作成」を押下します。
Application Load Banalncerの「作成」を選択します。
image.png

1. ロードバランサーの設定

スキームを「内部」にして「名前」、「VPC」、「AZ」、「サブネット」を入力し、次に進みます。
image.png

2. セキュリティ設定の構成

警告が出ますが、次に進みます。

3. セキュリティグループの設定

セキュリティグループを指定します。
ここでは、VPCのCIDRからのインバウンドを許可しているセキュリティグループを事前に作成し、指定します。

4. ルーティングの設定

先程作成したターゲットグループを設定し、次へ進みます。
image.png

5. ターゲットの登録、確認

次に進み、確認画面で内容に問題なければ「作成」を押下し完了します。

Firehoseの作成

Kinesisコンソールから「Data Firehose」を選択し、「Create delivery stream」を選択します。

Step 1: Name and source

「Delivery stream name」を入力し、次へ進みます。

Step 2: Process records

データ変換等はしないため、次へ進みます。

Step 3: Choose a destination

Destinationの選択をします。
ここではS3に転送するため、以下の通り入力し、次へ進みます。

項目 入力内容
Destination Amazon S3
S3 bucket 出力先のバケット
S3 prefix log/sample-app/
S3 error prefix error/firehose/sample-app/

FireShot Capture 006 - Amazon Kinesis Firehose - ap-northeast-1.console.aws.amazon.com.png

Step 4: Configure settings

Permissionsの「IAM Role」にて、「Create new or choose」を選択します。
「IAMロール」にて、「新しいIAMロール」を選択して「許可」を押下します。
許可を押すと作成されたIAMロール名が入力されるため、次へ進みます。

Step 5: Review

内容が問題ないか確認して作成を押せば完了です。

ECSの作成

いよいよ、ECSを作成してきます。
ここからはECSコンソールで操作していきます。

ECRの作成

「Repositories」を選択し、「リポジトリを作成」を押下します。
リポジトリ名を入力し、プッシュ時にスキャンを有効にした上で「リポジトリを作成」を押下し、リポジトリを作成します。

ECRへコンテナのプッシュ

Cloud9に戻り、ソースのルートディレクトリに「build-template」ディレクトリを作成する。
作成したディレクトリにDockerfileを作成し、以下を記述する。

FROM amazoncorretto:11.0.5

## Make application directory
RUN set -x && mkdir -p /opt/app

## 
COPY ./build/libs/sample-0.0.1-SNAPSHOT.jar /opt/app

## Environment Variables
STOPSIGNAL 15
EXPOSE 8080
CMD ["java","-jar","/opt/apps/sample-0.0.1-SNAPSHOT.jar"]

ここまでで以下のようになっている、はず。

.
├── build.gradle
├── build-template
│   └── Dockerfile
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── HELP.md
├── settings.gradle
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── pideoh
    │   │           └── sample
    │   │               ├── SampleApplication.java
    │   │               └── SampleController.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       └── templates
    └── test
        └── java
            └── com
                └── pideoh
                    └── sample
                        └── SampleApplicationTests.java

ソースのディレクトリにてソースのビルドとコンテナビルド、先程作成したコンテナリポジトリにコンテナをプッシュします。

  • アプリケーションのビルド
$ ./gradlew build

> Task :test
2019-12-13 01:28:11.174  INFO 15592 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

BUILD SUCCESSFUL in 7s
5 actionable tasks: 5 executed
  • コンテナのビルドとプッシュ
$ docker build -f build-template/Dockerfile -t 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/pideoh/sample-api:latest .                                                                                                                                        
Sending build context to Docker daemon  18.03MB
Step 1/6 : FROM amazoncorretto:11.0.5
 ---> baf7d8995918
Step 2/6 : RUN set -x && mkdir -p /opt/app
 ---> Using cache
 ---> 95eec55cf32a
Step 3/6 : COPY ./build/libs/sample-0.0.1-SNAPSHOT.jar /opt/app
 ---> Using cache
 ---> 9d8367f599ca
Step 4/6 : STOPSIGNAL 15
 ---> Using cache
 ---> 2f794c817a3a
Step 5/6 : EXPOSE 8080
 ---> Using cache
 ---> ed1bfa2854a3
Step 6/6 : CMD ["java","-jar","/opt/apps/sample-0.0.1-SNAPSHOT.jar"]
 ---> Using cache
 ---> 45673049a1a8
Successfully built 45673049a1a8
Successfully tagged 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/pideoh/sample-api:latest
$ docker tag 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/pideoh/sample-api:latest 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/pideoh/sample-api:20191213
$ $(aws ecr get-login --no-include-email)
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /home/ec2-user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/pideoh/sample-api:latest
The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/pideoh/sample-api]
067a7f1bc871: Pushed 
a8d07ad8783f: Pushed 
8e2692204e8e: Pushed 
fdf6c4a26006: Pushed 
latest: digest: sha256:34e5ee5ceca59d4b3d760bf28b4e62e4586a937253ac2b7225d90d7010d415e4 size: 1161
$ docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/pideoh/sample-api:20191213The push refers to repository [123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/pideoh/sample-api]
067a7f1bc871: Layer already exists 
a8d07ad8783f: Layer already exists 
8e2692204e8e: Layer already exists 
fdf6c4a26006: Layer already exists 
20191213: digest: sha256:34e5ee5ceca59d4b3d760bf28b4e62e4586a937253ac2b7225d90d7010d415e4 size: 1161

うまくいけばこのように登録されるはずです。
ここに表示されている「イメージのURI」は後で利用するためメモしておきます。
image.png

タスク定義の作成

タスク定義から「タスク定義の作成」を押下します。

ステップ 1: 起動タイプの互換性の選択

「Fargate」を選択し、次へ進みます。

ステップ 2: タスクとコンテナの定義の設定

以下の項目を入力していきます。

項目 入力内容
タスク定義名 任意の名前を入力します
タスクロール コンテナに付与するIAMロールを選択します。今回はFireLensからFirehoseにログを流すため、Firehoseにアクセスできるポリシーを付与したIAMロールが必要です。
タスク実行ロール すでに存在する場合はecsTaskExecutionRoleを選択し、存在しない場合は「新しいロールを作成」を選択します
タスクメモリ (GB) 0.5GB
タスク CPU (vCPU) 0.25vCPU
Enable FireLens integration チェックボックスを選択し、Applyを押下します
コンテナの定義 - コンテナの追加 - コンテナ名 sample-api
コンテナの定義 - コンテナの追加 - イメージ 先程メモした「イメージのURI」を入力します
コンテナの定義 - コンテナの追加 - ポートマッピング 8080 tcp
コンテナの定義 - コンテナの追加 - ヘルスチェック- コマンド CMD-SHELL, curl -f http://localhost:8080/ || exit 1
コンテナの定義 - コンテナの追加 - 環境 - コマンド java,-jar,/opt/app/sample-0.0.1-SNAPSHOT.jar
コンテナの定義 - コンテナの追加 - ログ設定 Auto-configure CloudWatch Logsのチェックボックスを外します
コンテナの定義 - コンテナの追加 - ログ設定 - ログドライバー awsfirelens
コンテナの定義 - コンテナの追加 - ログ設定 - ログオプション Name:firehose
コンテナの定義 - コンテナの追加 - ログ設定 - ログオプション region:ap-northeast-1
コンテナの定義 - コンテナの追加 - ログ設定 - ログオプション delivery_stream:作成したFirehoseのリソース名
コンテナの定義 - log_route - 環境 - コマンド Auto-configure CloudWatch Logsのチェックボックスを入れます

上記をすべて入力すると、以下のようになるはずです。
image.png

ECSクラスターの作成

ECS→クラスター画面から「クラスターの作成」を押下します。

ステップ 1: クラスターテンプレートの選択

「ネットワーキングのみ」を選択し次に進みます。

ステップ 2: クラスターの設定

「クラスター名」を入力して作成します。

サービスの作成

ECS→クラスター画面から先程作成したクラスタを選択し、クラスタの画面に入ります。
「サービス」タブで「作成」を押下します。

ステップ 1: サービスの設定

以下の項目を入力していきます。

項目 入力内容
起動タイプ Fargate
タスク定義 - ファミリー、リビジョン 先程作成したタスク定義を選択します
サービス名 サービス名を入力します
タスクの数 1

ステップ 2: ネットワーク構成

以下の項目を入力していきます。

項目 入力内容
クラスター VPC コンテナを構築するVPCを選択します
サブネット コンテナを構築するサブネットを選択します
セキュリティグループ ALB作成に使ったセキュリテイグループを選択します
パブリック IP の自動割り当て DISABLED
ロードバランサーの種類 Application Load Balancer
ロードバランサー名 作成したALBを選択します
ロードバランス用のコンテナ sample-api:8080が選択されていることを確認し、ロードバランサーに追加を選択します
プロダクションリスナーポート 80:HTTP
ターゲットグループ名 作成したターゲットグループを選択します

ステップ 3: Auto Scaling (オプション)

特に設定しないため、次に進みます。

ステップ 4: 確認

問題なければ「サービスの作成」を押下します。

動作確認

お疲れ様でした。これで基本的に設定は終わっているはずです。
ELBのエンドポイントにアクセスして、「Sample」と帰ってくれば、無事動作しています。
また、S3上にアクセスログが出力されていれば、ログも正常に出力されています。
次回はいよいよCodePipelineを使ってGitHubにソースコードがPushされるとAPビルド→コンテナビルド→コンテナ起動する仕組みを作ります。

2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?