前回はALBを立てるところまで行いました。
今回は実際のソースをパイプラインでデプロイしてサブドメインでアクセスするところまで行います。
AWS周りで難しいのはネットワーク周りと、権限周りだと思っていますが、何が難しいって、トラブルシューティングの方法がわからない。
下記に記載しているやり方はFargateでのデプロイ方法だが、実際には、まずEC2で行い、次にECSのEC2で行い、最後にECSのFargateで行うことで、なんとか形になりました。
構成
- dbはローカルに閉じる
- Fargeteでスケーラブルにしておく。
- ALBでサブドメインでルーティングする。
ソースの用意
今回はgolangのhelloworldで
hellogoというプロジェクト名でmain.goを作成
main.go
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
docker-compose.yml
version: '3'
services:
api:
build: .
command: go run main.go
volumes:
- .:/hellogo
ports:
- 8080:8080
Dockerfile
FROM golang:1.10.0
WORKDIR /go
ADD . /go
EXPOSE 8080
CMD ["go", "run", "main.go"]
buildspec.yml
version: 0.2
phases:
pre_build:
commands:
- echo Logging in to Amazon ECR...
- echo $AWS_DEFAULT_REGION
- $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
build:
commands:
- echo Build started on `date`
- echo Building the Docker image...
- docker build --no-cache -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker image...$AWS_ACCOUNT_ID....$IMAGE_REPO_NAME:$IMAGE_TAG
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
- REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
- echo "[{\"name\":\"${CONTAINAR_NAME}\",\"imageUri\":\"${REPOSITORY_URI}:${IMAGE_TAG}\"}]" > imagedefinitions.json
artifacts:
files: imagedefinitions.json
- portは8080:8080でListen
- githubにプッシュする
ECRリポジトリを作成
リポジトリ名:hellogo-image-repo
CodeBuildでビルドプロジェクトを作成
プロジェクトの設定
プロジェクト名:hellogo-build-project
送信元
ソースプロバイダ:GitHub
リポジトリ:GitHubアカウントリポジトリ
GitHubリポジトリ:hellogo
環境
環境イメージ:マネージド型イメージ
オペレーティングシステム:Ubuntu
ランタイム:Standard
イメージ:aws/codebuild/standard:1.0
イメージのバージョン:aws/codebuild/standard:1.0-1.8.0
特権付与:チェック
サービスロール:既存のサービスロール
ロール名:CodeBuildServiceRole ※ない場合は作る必要あり。
環境変数:以下を参照
AWS_DEFAULT_REGION:ap-northeast-1
AWS_ACCOUNT_ID:AWSユーザIDを設定
IMAGE_REPO_NAME:hellogo-image-repo
IMAGE_TAG:latest
CONTAINAR_NAME:hellogo-containar
※全てプレーンテキスト
Buildspec
ビルド仕様:buildspecファイルを仕様する
アーティファクト
タイプ:アーティファクトなし
ECSタスクを作成
AmazonECSのサイドバータスク定義より新しいタスクの定義を作成する。
起動タイプの互換性の選択
FARGATE
タスクとコンテナの定義の設定
タスク定義名:hellogo-task
タスクロール:なし
ネットワークモード:awsvpc
タスクの実行ロール:ecsTaskExectionRole ※ない場合は作成する。
タスクメモリ:0.5GB ※ビルドするだけのタスクなのでとりあえずミニマム
タスクCPU:0.25 vCPU ※ビルドするだけのタスクなのでとりあえずミニマム
コンテナの定義:
コンテナ名:hellogo-containar
イメージ:上記で作成したECRリポジトリのlatest
ポートマッピング:8080
ECSクラスタ作成
クラスターテンプレートの選択:ネットワーキングのみ
クラスタの設定
クラスタ名:hellogo-cluster
サービスの作成
上記で作成したクラスタにサービスを作成する。
サービスの設定
起動タイプ:FARGATE
タスク定義(ファミリー):hellogo-task
リビジョン:latest
プラットフォームのバージョン:LATEST
クラスタ:hellogo-cluster
サービス名:hellogo-service
タスク数:1
ネットワーク構成
クラスタVPC:前回作成したVPC
サブネット:全部設定しておく
セキュリティグループ:全部設定しておく
パブリックIPの自動割り当て:ENABLED
ロードバランサーの種類:Application Load Balancer
ロードバランサー名:web-app-alb
コンテナの選択:hellogo-containar:8080:8080
ロードバランサーに追加をクリック
ターゲットグループ名:web-app-tg-1
CodePipelineでパイプラインを作成する
パイプラインの設定を選択する
パイプライン名:hellogo-pipeline
ロール名:既存のサービスロールからAWSCodePipelineServiceを選択
ソースステージ
ソースプロバイダー:GitHub
リポジトリとブランチを選択しGitHubウェブフックにチェックをつける
ビルドステージ
プロバイダーを構築する:AWSCodeBuild
リージョン:アジアンパシフィック(東京)
プロジェクト名:hellogo-build-project
デプロイステージ
デプロイプロバイダー:AmazonECS
リージョン:アジアンパシフィック(東京)
クラスタ名:hellogo-cluster
サービス名:hellogo-service
- 実行完了
- この時点でロードバランサのDNS 名でアクセスできます。
- 20分くらいかかってしまいました。
サブドメインを設定し、リバースプロキシ対応する
サブドメイン作成
Route53のサイドバーからホストゾーンを選択し、対象のドメインをクリック
レコードセットの作成をクリック
名前:サブドメインを入力 ※今回はhellogoにしておく
エイリアス:はい
エイリアス先:web-app-alb ※前回作成したALBを設定
ロードバランサの設定
EC2のサイドバーよりロードバランサを選択し、一覧上の対象のロードバランサの下部リスナータグより
ルールの表示編集にて設定をする。
追記
- アプリを不安ごとにロードバランサーとターゲットグループを作る必要がある。
- echoを導入して、デプロイした場合、ヘルスチェックで何度も失敗になってしまっていた。その場合はターゲットグループのヘルスチェックの閾値を変更する。下記の値にしたらうまくいった!
正常のしきい値 :5
非正常のしきい値 :2
参考
ロールやポリシー周りでエラーになった場合はここを参考にした。とりあえず画面からぽちぽちユーザにポリシーを付与すればOK
CodePipeline/CodeBuild/ECR/ECS/Fargateのコンテナデプロイ基盤を構築してみました - LCL Engineers' Blog
以上