0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Github→AWS ECR→ECSのCICDをすべてterraformで管理するまで

Posted at

初めに

本プロジェクトはchatGPTと対話しながら進めました
nextjsをwebに公開する一連の流れを記録した備忘録になります
これ以降は対話した内容をchatGPTにまとめてもらったものです
大分つたないものなので要望があればちゃんと書きます

1. Next.js プロジェクトを作成し、GitHub にプッシュ

まず、Next.js のプロジェクトを作成し、それを GitHub にプッシュします。

1.1 Next.js プロジェクトの作成

npx create-next-app my-app
cd my-app

1.2 GitHub リポジトリの作成とプッシュ

git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-username/next_test.git
git push -u origin main

2. Terraform を使用して AWS 環境を構築

Terraform を使って AWS のインフラをコード化し、ECS 上で Next.js を動かす環境を作ります。

2.1 AWS CLI の設定

AWS の CLI をインストールし、認証情報を設定します。

aws configure

2.2 ネットワークの構築 (network.tf)

ECS を動作させるための VPC、サブネット、NAT ゲートウェイを設定します。

VPC の作成

resource "aws_vpc" "my_app_vpc" {
  cidr_block = "10.0.0.0/16"
  enable_dns_support = true
  enable_dns_hostnames = true
  tags = { Name = "my-app-vpc" }
}

パブリック / プライベートサブネットの作成

resource "aws_subnet" "my_app_subnets" {
  count = 2
  vpc_id = aws_vpc.my_app_vpc.id
  cidr_block = "10.0.${count.index}.0/24"
  availability_zone = element(["ap-northeast-1a", "ap-northeast-1c"], count.index)
  map_public_ip_on_launch = count.index == 0 ? true : false
  tags = { Name = "my-app-subnet-${count.index}" }
}

NAT ゲートウェイの作成

resource "aws_eip" "my_app_nat_eip" { domain = "vpc" }
resource "aws_nat_gateway" "my_app_nat_gw" {
  allocation_id = aws_eip.my_app_nat_eip.id
  subnet_id = aws_subnet.my_app_subnets[0].id
}

ルートテーブルの設定

resource "aws_route_table" "my_app_private_rt" {
  vpc_id = aws_vpc.my_app_vpc.id
  route {
    cidr_block = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.my_app_nat_gw.id
  }
}

2.3 ECS クラスターの作成 (ecs.tf)

resource "aws_ecs_cluster" "my_app_ecs_cluster" {
  name = "my-app-ecs-cluster"
}

2.4 ALB の設定 (alb.tf)

resource "aws_lb" "my_app_alb" {
  name               = "my-app-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.my_app_sg.id]
  subnets            = aws_subnet.my_app_subnets[*].id
}

3. CodePipeline を使用してビルドとデプロイを自動化

GitHub の変更をトリガーに、ECR にコンテナをプッシュし、ECS にデプロイされるようにします。

3.1 CodePipeline の設定 (codepipeline.tf)

resource "aws_codepipeline" "my_app_codepipeline" {
  name     = "my-app-codepipeline"
  role_arn = aws_iam_role.my_app_codepipeline_role.arn
  artifact_store {
    location = aws_s3_bucket.my_app_pipeline_artifacts.bucket
    type     = "S3"
  }
}

3.2 CodeBuild の buildspec.yml

ECR へのビルドとプッシュ、ECS の更新を行います。

phases:
  pre_build:
    commands:
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_REPOSITORY
  build:
    commands:
      - docker build -t my-app .
      - docker tag my-app:latest $ECR_REPOSITORY:latest
  post_build:
    commands:
      - docker push $ECR_REPOSITORY:latest
      - aws ecs update-service --cluster my-app-ecs-cluster --service my-app-service --force-new-deployment

4. デプロイの確認

ALB の URL にアクセスし、Next.js の画面が表示されることを確認します。

aws ecs describe-services --cluster my-app-ecs-cluster --services my-app-service --query 'services[*].loadBalancers[*].{DNSName:dnsName}' --output table

5. トラブルシューティングと学び

このプロジェクトを進める中で、いくつかの大きな課題に直面しました。

5.1 403 Forbidden エラー (ECR のプル失敗)

ECS が ECR からイメージを取得しようとした際に 403 Forbidden が発生。

原因: NAT ゲートウェイの未設定により、プライベートサブネットのタスクが ECR にアクセスできなかった。

解決策:

  • NAT ゲートウェイを追加し、適切なルートテーブル設定を行うことで、ECS タスクが ECR へアクセスできるように修正。

5.2 ALB のターゲットグループのヘルスチェックが失敗 (502 Bad Gateway)

ALB から ECS のタスクにリクエストを送った際に 502 Bad Gateway が発生。

原因:

  • タスク定義で containerPort の設定が不足していた。
  • Next.js のアプリが 0.0.0.0 ではなく localhost で起動されていた。

解決策:

  • ECS タスク定義に containerPort: 80 を追加。
  • next.config.js を修正し、適切なポートバインドを行う。

まとめ

AWS ECS Fargate に Next.js アプリケーションを Terraform を使ってデプロイすることができました! 🎉

次のステップとして、

  • CodeDeploy を組み込んでブルーグリーンデプロイを試す
  • CloudWatch Logs の統合を強化する
  • ALB のヘルスチェック設定を最適化する

を試すと、より安定した運用ができるようになります! 🚀

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?