Takenari-Yamamoto / golang-practice

golang-practice
0 stars 0 forks source link

AWS ECSにデプロイ #4

Open Takenari-Yamamoto opened 5 months ago

Takenari-Yamamoto commented 5 months ago

前提

手順

Takenari-Yamamoto commented 5 months ago

terraformでゼロからセットアップ

Takenari-Yamamoto commented 5 months ago
terraform {
  required_version = ">= 0.13"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~>3.0"
    }
  }
}

# ----------------------
# provider configuration
# ----------------------
provider "aws" {
  profile = "terraform_user"
  region  = "ap-northeast-1"
}
Takenari-Yamamoto commented 5 months ago

上をmain.goに書いていく

スクリーンショット 2024-04-24 8 12 37

`-- infra
    `-- golang-study
        |-- main.tf
        `-- vpc.tf
Takenari-Yamamoto commented 5 months ago

VPC作成

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "golang-study-vpc"
  }
}
Takenari-Yamamoto commented 5 months ago

スクリーンショット 2024-04-24 8 35 40

applyして作成を確認

Takenari-Yamamoto commented 5 months ago

terraformの状態管理がS3で管理するように追加

terraform {
  required_version = ">= 0.13"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~>3.0"
    }
  }
  # これ!!
  backend "s3" {
    bucket  = "golang-study-terraform-state"
    key     = "appserver/terraform.tfstate"
    region  = "ap-northeast-1"
    profile = "terraform_user"
  }
}
Takenari-Yamamoto commented 5 months ago

スクリーンショット 2024-04-24 8 38 37

Takenari-Yamamoto commented 5 months ago

VPCの名前変えたい BEFORE

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "golang-study-vpc"
  }
}

AFTER

resource "aws_vpc" "golang-study-vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "golang-study-vpc"
  }
}

参考になりそう: https://zenn.dev/machamp/articles/modify-terraform-resource-name

ほぼこれの通りで行けるので割愛

Takenari-Yamamoto commented 5 months ago

VPCの設計について

cidr_block = "10.0.0.0/16"

CIDRブロックとは?

CIDR表記でネットワークアドレスの範囲を指定している。 そのネットワーク内で使用可能なアドレスを指定するために使用する。

あとで読む: https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-cidr-blocks.html

Takenari-Yamamoto commented 5 months ago

サブネットの作成

resource "aws_subnet" "golang-study-public-a" {
  vpc_id                  = aws_vpc.golang-study-vpc.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = true

  tags = {
    Name = "golang-study-public-a"
  }
}

resource "aws_subnet" "golang-study-private-a" {
  vpc_id                  = aws_vpc.golang-study-vpc.id
  cidr_block              = "10.0.2.0/24"
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = false

  tags = {
    Name = "golang-study-private-a"
  }
}

インターネットゲートウェイの作成

resource "aws_internet_gateway" "golang-study-igw" {
  vpc_id = aws_vpc.golang-study-vpc.id

  tags = {
    Name = "golang-study-igw"
  }
}
Takenari-Yamamoto commented 5 months ago

ルートテーブルの作成 https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/a841bb3f26b63a216c5d8eeb3dc40fb7a84a9e00

ルートテーブルとは

Takenari-Yamamoto commented 5 months ago

セキュリティグループの作成

何を設定するの?

イングレスルール


  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

エグレスルール

egress {
  # ポート番号が指定されていないことを意味
  from_port   = 0
  to_port     = 0
  # すべてのプロトコルを表す
  protocol    = "-1"
  # 任意の宛先へのアクセスを許可する
  cidr_blocks = ["0.0.0.0/0"]
}
Takenari-Yamamoto commented 5 months ago

NATゲートウェイの作成

何を設定するの?

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/1d406010b83921d5e15e244669ebe09e461706f0

Takenari-Yamamoto commented 5 months ago

友達

https://chat.openai.com/c/858c310a-acf2-40ec-a5ac-2723ebd4d7b0

Takenari-Yamamoto commented 5 months ago

TODO

2024/04/24中にアプリケーションを動かすところまでやりたいが。。

Takenari-Yamamoto commented 5 months ago

ELBの設定

やること

Takenari-Yamamoto commented 5 months ago

ここでマルチ AZにするためにサブネットを追加しておく

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/1ef3e03adce2c431e0bcfddeed70b9681d4e855e#diff-3bf4d5a79ba3b57b9bdc2b79c518cee62a463c8bd6eb71a5a7ee725169a12d8c

Takenari-Yamamoto commented 5 months ago

セキュリティグループの作成

ALBが使用するセキュリティグループを設定します。このセキュリティグループは、特定のポート(通常はHTTP/HTTPSのポート80/443)へのアクセスを許可し、不要なトラフィックを防ぎます

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/1ef3e03adce2c431e0bcfddeed70b9681d4e855e#diff-15fb309ebdd8aa1d01a8564f28dfe9e5f5ae6bca79fff176068217e25addd6be

ALBの作成

次に、Application Load Balancer を作成します。これには、指定したセキュリティグループと選択したパブリックサブネットを関連付けます。

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/1ef3e03adce2c431e0bcfddeed70b9681d4e855e#diff-d7038ab736f1233b6ae29965fa6070aa13c8826796f42d8150b68a27753b803cR1-R20

ターゲットグループの作成

ターゲットグループを作成し、ALBがトラフィックをルーティングするEC2インスタンスやコンテナなどのエンドポイントを定義します。また、ヘルスチェックの設定を行い、ターゲットの健康状態を監視します。

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/1ef3e03adce2c431e0bcfddeed70b9681d4e855e#diff-d7038ab736f1233b6ae29965fa6070aa13c8826796f42d8150b68a27753b803cR1-R20

リスナーの設定

リスナーを作成し、ALBが受け取るトラフィックの種類(ポートとプロトコル)を定義します。リスナーは受信トラフィックをターゲットグループに転送する設定を持ちます。

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/1ef3e03adce2c431e0bcfddeed70b9681d4e855e#diff-d7038ab736f1233b6ae29965fa6070aa13c8826796f42d8150b68a27753b803cR50-R61

Takenari-Yamamoto commented 5 months ago

ちょっとこの辺理解できていないのでちゃんと調べないといけない

Takenari-Yamamoto commented 5 months ago

タイムアップ 明日やること

Takenari-Yamamoto commented 5 months ago

RDSを先に作ろうか 理由: ECSをセットするにはRDSの情報(userやpassword)が必要なため

Takenari-Yamamoto commented 5 months ago

RDS

読んでもろて https://www.bold.ne.jp/engineer-club/aws-rds

やること

Takenari-Yamamoto commented 5 months ago

ELBの設定ミスってた

│ Error: error creating EC2 Subnet: InvalidParameterValue: Value (ap-northeast-1b) for parameter availabilityZone is invalid. Subnets can currently only be created in the following availability zones: ap-northeast-1a, ap-northeast-1c, ap-northeast-1d.
│       status code: 400, request id: 7b48769b-8863-47f6-b57b-e06bb3cbec64
│ 
│   with aws_subnet.golang-study-public-b,
│   on subnet.tf line 23, in resource "aws_subnet" "golang-study-public-b":
│   23: resource "aws_subnet" "golang-study-public-b" {
│ 
╵
╷
│ Error: error creating EC2 Subnet: InvalidParameterValue: Value (ap-northeast-1b) for parameter availabilityZone is invalid. Subnets can currently only be created in the following availability zones: ap-northeast-1a, ap-northeast-1c, ap-northeast-1d.
│       status code: 400, request id: 70c4c940-16bb-458a-ab45-f05fa6633821
│ 
│   with aws_subnet.golang-study-private-b,
│   on subnet.tf line 34, in resource "aws_subnet" "golang-study-private-b":
│   34: resource "aws_subnet" "golang-study-private-b" {
│ 
╵

1-bは使えない? 無理っぽい

https://zenn.dev/socialplus/articles/532b09fce31d39

修正した

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/7c0da670b9945a67ca68346103ec252ead3b65bc

Takenari-Yamamoto commented 5 months ago

気を取り直してRDSの設定進めていく。 セキュリティグループの作成から。

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/495330c0e36a77d5e656198918406e5c1b583494#diff-15fb309ebdd8aa1d01a8564f28dfe9e5f5ae6bca79fff176068217e25addd6be

Takenari-Yamamoto commented 5 months ago

RDSインスタンスをデプロイするために使用するサブネットのグループを作成

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/495330c0e36a77d5e656198918406e5c1b583494#diff-133976118e08634b46b5947dff27be5058869bdf940d46c04534b0b3532e1efbR24-R27

Takenari-Yamamoto commented 5 months ago

RDSインスタンスの作成

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/495330c0e36a77d5e656198918406e5c1b583494#diff-133976118e08634b46b5947dff27be5058869bdf940d46c04534b0b3532e1efbR1-R20

それぞれの設定項目はコメント記載の通り https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/720831a874b636abd954b070ac503bb3dcdd1236

Takenari-Yamamoto commented 5 months ago

ECS

いよいよECSの構築

ECSとは?

この辺にまとめた https://zenn.dev/tknr_y1216/scraps/17843e2d396624

やること

Takenari-Yamamoto commented 5 months ago

ECRの作成 https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/4224b9b020b590f71a3610114f631a412ffd9d7c

Takenari-Yamamoto commented 5 months ago

golang-study直下でdocker build

docker build -f app.Dockerfile -t golang-study-app .
Takenari-Yamamoto commented 5 months ago

エラー

docker build -f app.Dockerfile -t golang-study-image .
[+] Building 34.0s (10/12)                                                                                                                                                     docker:desktop-linux
 => [internal] load build definition from app.Dockerfile                                                                                                                                       0.0s
 => => transferring dockerfile: 540B                                                                                                                                                           0.0s
 => [internal] load .dockerignore                                                                                                                                                              0.0s
 => => transferring context: 2B                                                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                                                                                               2.6s
 => [internal] load metadata for docker.io/library/golang:1.22                                                                                                                                 2.6s
 => [builder 1/4] FROM docker.io/library/golang:1.22@sha256:d5302d40dc5fbbf38ec472d1848a9d2391a13f93293a6a5b0b87c99dc0eaa6ae                                                                  31.0s
 => => resolve docker.io/library/golang:1.22@sha256:d5302d40dc5fbbf38ec472d1848a9d2391a13f93293a6a5b0b87c99dc0eaa6ae                                                                           0.0s
 => => sha256:ba9a57bc3c0cb0c1ea5d28dc03fb4451ae05dc271b53941c27edf70eaf70b6e6 63.99MB / 63.99MB                                                                                              10.2s
 => => sha256:d5302d40dc5fbbf38ec472d1848a9d2391a13f93293a6a5b0b87c99dc0eaa6ae 2.13kB / 2.13kB                                                                                                 0.0s
 => => sha256:60bdaf986dbe787297bb85c9f6a28d13ea7b9608b95206ef7ce6cdea50cd5505 49.61MB / 49.61MB                                                                                              17.4s
 => => sha256:9e100ddc6b415c632410507293430c0fe6bb4228ab320ed59548c6dc030b4e4a 23.59MB / 23.59MB                                                                                              10.7s
 => => sha256:dc2ef640c3ca64d68045332dbeecd95d9978644607ecb3dc04f8fd99965b87da 1.79kB / 1.79kB                                                                                                 0.0s
 => => sha256:295f95becd4e4f10cb8a635e714742389a05ed8cf6819992b08090f6231e0eb2 2.89kB / 2.89kB                                                                                                 0.0s
 => => sha256:353c80fdbef13719285eb0463a9a6c7769df89a3797e79ac8a52a93f85b67c3f 86.45MB / 86.45MB                                                                                              26.6s
 => => sha256:e1f3d3410be61e795a30e742673a0997a678f9080db44ab5f99e03b0bab402fc 66.27MB / 66.27MB                                                                                              21.2s
 => => extracting sha256:60bdaf986dbe787297bb85c9f6a28d13ea7b9608b95206ef7ce6cdea50cd5505                                                                                                      1.3s
 => => sha256:910e7ed9d48a0f337e6082c9686554b44f0cb9fc26a310e6fe7066410a2c96e2 175B / 175B                                                                                                    17.7s
 => => sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B                                                                                                      18.0s
 => => extracting sha256:9e100ddc6b415c632410507293430c0fe6bb4228ab320ed59548c6dc030b4e4a                                                                                                      0.3s
 => => extracting sha256:ba9a57bc3c0cb0c1ea5d28dc03fb4451ae05dc271b53941c27edf70eaf70b6e6                                                                                                      1.5s
 => => extracting sha256:353c80fdbef13719285eb0463a9a6c7769df89a3797e79ac8a52a93f85b67c3f                                                                                                      1.3s
 => => extracting sha256:e1f3d3410be61e795a30e742673a0997a678f9080db44ab5f99e03b0bab402fc                                                                                                      2.7s
 => => extracting sha256:910e7ed9d48a0f337e6082c9686554b44f0cb9fc26a310e6fe7066410a2c96e2                                                                                                      0.0s
 => => extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1                                                                                                      0.0s
 => [internal] load build context                                                                                                                                                              0.0s
 => => transferring context: 5.73kB                                                                                                                                                            0.0s
 => [stage-1 1/3] FROM docker.io/library/alpine:latest@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b                                                                 0.0s
 => [builder 2/4] WORKDIR /app                                                                                                                                                                 0.3s
 => [builder 3/4] COPY . .                                                                                                                                                                     0.0s
 => ERROR [builder 4/4] RUN CGO_ENABLED=0 GOOS=linux go build -o main .                                                                                                                        0.1s
------
 > [builder 4/4] RUN CGO_ENABLED=0 GOOS=linux go build -o main .:
0.083 package github.com/Takenari-Yamamoto/golang-study: build constraints exclude all Go files in /app
------
app.Dockerfile:9
--------------------
   7 |     WORKDIR /app
   8 |     COPY . .
   9 | >>> RUN CGO_ENABLED=0 GOOS=linux go build -o main .
  10 |     
  11 |     # final stage
--------------------
ERROR: failed to solve: process "/bin/sh -c CGO_ENABLED=0 GOOS=linux go build -o main ." did not complete successfully: exit code: 1
Takenari-Yamamoto commented 5 months ago

パスがミスってた

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/fb49639a6371ba61bbaeceea777188055bcbb6f3

原因と解決 BEFOREの問題点 元のapp.Dockerfileでは、RUN CGO_ENABLED=0 GOOS=linux go build -o main . コマンドがルートディレクトリ(/app)で実行されていました。このディレクトリには、server.go が含まれる cmd/app ディレクトリ以外にも多くのファイルやサブディレクトリが存在するため、Goのビルドシステムが正しいエントリーポイント(server.go)を自動で見つけることが難しい状況でした。特にGoのパッケージ構造が複雑な場合、ルートディレクトリからのビルドは依存関係の解決や不要なファイルのコンパイルを引き起こすことがあります。 AFTERの解決策 修正後のDockerfileでは、ビルドコマンドが RUN CGO_ENABLED=0 GOOS=linux go build -o main ./cmd/app に変更されました。この変更により、Goのビルドコマンドは具体的に cmd/app ディレクトリを対象に実行されます。server.go ファイルがこのディレクトリ内にあるため、Goのビルドシステムは正確に必要なファイルを認識し、適切なバイナリを生成できるようになりました。 この修正により、以下の点が改善されました: ビルドの精度: 正しいディレクトリを指定することで、関連しないファイルのビルドから解放され、ビルドプロセスがより正確かつ効率的になります。 エラーの削減: 不要なファイルやディレクトリをビルドプロセスに含めないことで、依存関係やコンパイルエラーの可能性が減少します。 まとめ Dockerファイルでのパス指定の精度は、特に大規模なアプリケーションや複雑なディレクトリ構造を持つプロジェクトにおいて重要です。適切なパスとコマンドを使用することで、予期せぬビルドエラーを避け、一貫性のあるビルド結果を得ることができます。

Takenari-Yamamoto commented 5 months ago

イメージを docker run して確かめる

docker run --rm -p 9000:8080 golang-study-app

DBへのアクセス情報がないからエラー

2024/04/26 06:15:53 failed to connect db: dial tcp: lookup tcp/sslmode=disable: unknown port

ちゃんと環境変数を指定しましょう

 docker run --rm -p 9000:8080 \
  --network=golang-study_app_network \
  -e DB_HOST=db \
  -e DB_PORT=5432 \
  -e DB_USER=postgres \
  -e DB_PASSWORD=password \
  -e DB_NAME=golang_study \
  golang-study-app
2024/04/26 06:45:58 success to connect db!!
2024/04/26 06:45:58 connect to http://localhost:8080/ for GraphQL playground

スクリーンショット 2024-04-26 15 47 32

ついでにちょっとリファクタ

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/b73fd6c4fc668a2b51abc32b1e47afd529e63322

Takenari-Yamamoto commented 5 months ago

ちなみに docker-compose のネットワーク名って指定したものとは違うらしい

Docker Compose がネットワーク名にプレフィックスとしてプロジェクト名を付けるため、golang-study_app_network のような名前になっています。このプレフィックスは、デフォルトでDocker Composeを実行するディレクトリ名が使用されます。これは、同じマシン上で複数のDocker Composeプロジェクトを実行している場合にネットワーク名の衝突を避けるためです。

docker-composeに 下記のようにしていても

networks:
  app_network:

実際のネットワーク名は下記のようになる。

docker network ls
NETWORK ID     NAME                        DRIVER    SCOPE
28d07750df1d   golang-study_app_network    bridge    local
Takenari-Yamamoto commented 5 months ago

先ほど作成したECRにビルドしたイメージをPUSH

ECRへの認証

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 879853972315.dkr.ecr.ap-northeast-1.amazonaws.com

Dockerイメージにタグ付け

docker tag golang-study-app:latest 879853972315.dkr.ecr.ap-northeast-1.amazonaws.com/golang-study-api-repo:latest

ECRにイメージをプッシュ

docker push 879853972315.dkr.ecr.ap-northeast-1.amazonaws.com/golang-study-api-repo:latest

OK

スクリーンショット 2024-04-26 16 34 11
Takenari-Yamamoto commented 5 months ago

残タスク

Takenari-Yamamoto commented 5 months ago

クラスタ

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/5ab12bb8436086841928299802d5c9300019a950

Takenari-Yamamoto commented 5 months ago

タスク定義

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/5ab12bb8436086841928299802d5c9300019a950

Takenari-Yamamoto commented 5 months ago

サービスの設定

https://github.com/Takenari-Yamamoto/golang-practice/pull/14/commits/519e44248a55536eaa17a8bab9d1f9a90e75a9c4

Takenari-Yamamoto commented 5 months ago

エラー

╷
│ Error: failed creating ECS service (golang-study-app-service): InvalidParameterException: The provided target group arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:targetgroup/golang-study-api-public-tg/7647b0745fe1493f has target type instance, which is incompatible with the awsvpc network mode specified in the task definition.
│ 
│   with aws_ecs_service.golang-study-app-service,
│   on ecs.tf line 93, in resource "aws_ecs_service" "golang-study-app-service":
│   93: resource "aws_ecs_service" "golang-study-app-service" {
│ 
Takenari-Yamamoto commented 5 months ago

ターゲットグループの設定が awsvpc ネットワークモードと互換性がないらしい。 ECSのタスク定義で awsvpc ネットワークモードを使用する場合、ターゲットグループのターゲットタイプは instance ではなく ip に設定する必要があるらしい

aws_lb_target_groupに下記を追加

target_type = "ip"

これだけだと「削除→再作成」っていう差分になるので既存のリソースに影響を与えてしまう。

terraform plan 

// 結果

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
  ~ update in-place
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # aws_ecs_service.golang-study-app-service will be created
  + resource "aws_ecs_service" "golang-study-app-service" {
      + cluster                            = "arn:aws:ecs:ap-northeast-1:879853972315:cluster/golang-study-cluster"
      + deployment_maximum_percent         = 200
      + deployment_minimum_healthy_percent = 100
      + desired_count                      = 1
      + enable_ecs_managed_tags            = false
      + enable_execute_command             = false
      + iam_role                           = (known after apply)
      + id                                 = (known after apply)
      + launch_type                        = "FARGATE"
      + name                               = "golang-study-app-service"
      + platform_version                   = (known after apply)
      + scheduling_strategy                = "REPLICA"
      + tags_all                           = (known after apply)
      + task_definition                    = "arn:aws:ecs:ap-northeast-1:879853972315:task-definition/golang-study-app:1"
      + wait_for_steady_state              = false

      + load_balancer {
          + container_name   = "golang-study-app"
          + container_port   = 80
          + target_group_arn = (known after apply)
        }

      + network_configuration {
          + assign_public_ip = true
          + security_groups  = [
              + "sg-0667a35dc0fb55ee4",
            ]
          + subnets          = [
              + "subnet-099ae657af4e99cdc",
              + "subnet-0c2260ef4c340c8a0",
            ]
        }
    }

  # aws_lb_listener.golang-study-api-public-listener will be updated in-place
  ~ resource "aws_lb_listener" "golang-study-api-public-listener" {
        id                = "arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:listener/app/golang-study-api-public/c2a2336715649c93/1adb2523eba4fdd1"
        tags              = {}
        # (5 unchanged attributes hidden)

      ~ default_action {
          ~ target_group_arn = "arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:targetgroup/golang-study-api-public-tg/7647b0745fe1493f" -> (known after apply)
            # (2 unchanged attributes hidden)
        }
    }

  # aws_lb_target_group.golang-study-api-public-tg must be replaced
-/+ resource "aws_lb_target_group" "golang-study-api-public-tg" {
      ~ arn                                = "arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:targetgroup/golang-study-api-public-tg/7647b0745fe1493f" -> (known after apply)
      ~ arn_suffix                         = "targetgroup/golang-study-api-public-tg/7647b0745fe1493f" -> (known after apply)
      ~ id                                 = "arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:targetgroup/golang-study-api-public-tg/7647b0745fe1493f" -> (known after apply)
      ~ load_balancing_algorithm_type      = "round_robin" -> (known after apply)
        name                               = "golang-study-api-public-tg"
      + preserve_client_ip                 = (known after apply)
      ~ protocol_version                   = "HTTP1" -> (known after apply)
        tags                               = {
            "Name" = "golang-study-api-public-tg"
        }
      ~ target_type                        = "instance" -> "ip" # forces replacement
        # (9 unchanged attributes hidden)

      - stickiness {
          - cookie_duration = 86400 -> null
          - enabled         = false -> null
          - type            = "lb_cookie" -> null
        }

        # (1 unchanged block hidden)
    }

  # aws_security_group.golang-study-db-sg will be updated in-place
  ~ resource "aws_security_group" "golang-study-db-sg" {
        id                     = "sg-054afc0a7b9ed277e"
      ~ ingress                = [
          + {
              + cidr_blocks      = []
              + description      = ""
              + from_port        = 5432
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 5432
            },
        ]
        name                   = "golang-study-db-sg"
        tags                   = {
            "Name" = "golang-study-db-sg"
        }
        # (7 unchanged attributes hidden)
    }

Plan: 2 to add, 2 to change, 1 to destroy.
Takenari-Yamamoto commented 5 months ago

これでいけた

一旦サービスを消す

一時的にデフォルトアクションを削除してターゲットグループの更新を可能に

target typeをIPに

リスナーへのターゲットグループの再割り当て

Takenari-Yamamoto commented 5 months ago

DB周りで同じ差分が出続けている??

➜  golang-study git:(4-build-aws-env) terraform plan 
aws_vpc.golang-study-vpc: Refreshing state... [id=vpc-0c8995a8464d17117]
aws_ecr_repository.golang-study-api-repo: Refreshing state... [id=golang-study-api-repo]
aws_iam_role.ecs_task_execution_role: Refreshing state... [id=ecs_task_execution_role]
aws_ecs_cluster.golang_study_cluster: Refreshing state... [id=arn:aws:ecs:ap-northeast-1:879853972315:cluster/golang-study-cluster]
aws_eip.golang-study-eip: Refreshing state... [id=eipalloc-0aa25a1b83486529e]
aws_subnet.golang-study-public-a: Refreshing state... [id=subnet-099ae657af4e99cdc]
aws_subnet.golang-study-private-a: Refreshing state... [id=subnet-099b8a012009d8af7]
aws_subnet.golang-study-private-c: Refreshing state... [id=subnet-04aae4ddfd783d1ab]
aws_subnet.golang-study-public-c: Refreshing state... [id=subnet-0c2260ef4c340c8a0]
aws_internet_gateway.golang-study-igw: Refreshing state... [id=igw-0d05829ddbb246b10]
aws_lb_target_group.golang-study-api-public-tg: Refreshing state... [id=arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:targetgroup/golang-study-api-public-tg/fd5e7fe765a80c17]
aws_security_group.golang-study-db-sg: Refreshing state... [id=sg-054afc0a7b9ed277e]
aws_security_group.golang-study-alb-sg: Refreshing state... [id=sg-03fdc2be5ca6f6bce]
aws_security_group.golang-study-sg: Refreshing state... [id=sg-0667a35dc0fb55ee4]
aws_route_table.golang-study-public: Refreshing state... [id=rtb-00115d75fbd41c6d5]
aws_nat_gateway.golang-study-ngw: Refreshing state... [id=nat-084508e81fd332c7a]
aws_lb.golang-study-api-public: Refreshing state... [id=arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:loadbalancer/app/golang-study-api-public/c2a2336715649c93]
aws_db_subnet_group.golang-study-db_subnet_group: Refreshing state... [id=golang-study-db-subnet-group]
aws_route_table.golang-study-private: Refreshing state... [id=rtb-00e4253f341fa9497]
aws_route_table_association.golang-study-public-a-association: Refreshing state... [id=rtbassoc-06b5d337dd5f93e81]
aws_route_table_association.golang-study-private-a-association: Refreshing state... [id=rtbassoc-0b0fd8a8633080f59]
aws_db_instance.golang-study-db: Refreshing state... [id=golang-study-rds]
aws_lb_listener.golang-study-api-public-listener: Refreshing state... [id=arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:listener/app/golang-study-api-public/c2a2336715649c93/1adb2523eba4fdd1]
aws_iam_role_policy_attachment.ecs_task_execution_role_policy: Refreshing state... [id=ecs_task_execution_role-20240426113529077000000001]
aws_ecs_task_definition.golang_study_app: Refreshing state... [id=golang-study-app]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.golang-study-db-sg will be updated in-place
  ~ resource "aws_security_group" "golang-study-db-sg" {
        id                     = "sg-054afc0a7b9ed277e"
      ~ ingress                = [
          + {
              + cidr_blocks      = []
              + description      = ""
              + from_port        = 5432
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 5432
            },
        ]
        name                   = "golang-study-db-sg"
        tags                   = {
            "Name" = "golang-study-db-sg"
        }
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
➜  golang-study git:(4-build-aws-env) terraform apply
aws_ecs_cluster.golang_study_cluster: Refreshing state... [id=arn:aws:ecs:ap-northeast-1:879853972315:cluster/golang-study-cluster]
aws_ecr_repository.golang-study-api-repo: Refreshing state... [id=golang-study-api-repo]
aws_vpc.golang-study-vpc: Refreshing state... [id=vpc-0c8995a8464d17117]
aws_iam_role.ecs_task_execution_role: Refreshing state... [id=ecs_task_execution_role]
aws_eip.golang-study-eip: Refreshing state... [id=eipalloc-0aa25a1b83486529e]
aws_subnet.golang-study-private-a: Refreshing state... [id=subnet-099b8a012009d8af7]
aws_internet_gateway.golang-study-igw: Refreshing state... [id=igw-0d05829ddbb246b10]
aws_security_group.golang-study-db-sg: Refreshing state... [id=sg-054afc0a7b9ed277e]
aws_subnet.golang-study-public-a: Refreshing state... [id=subnet-099ae657af4e99cdc]
aws_lb_target_group.golang-study-api-public-tg: Refreshing state... [id=arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:targetgroup/golang-study-api-public-tg/fd5e7fe765a80c17]
aws_subnet.golang-study-public-c: Refreshing state... [id=subnet-0c2260ef4c340c8a0]
aws_subnet.golang-study-private-c: Refreshing state... [id=subnet-04aae4ddfd783d1ab]
aws_security_group.golang-study-alb-sg: Refreshing state... [id=sg-03fdc2be5ca6f6bce]
aws_security_group.golang-study-sg: Refreshing state... [id=sg-0667a35dc0fb55ee4]
aws_route_table.golang-study-public: Refreshing state... [id=rtb-00115d75fbd41c6d5]
aws_nat_gateway.golang-study-ngw: Refreshing state... [id=nat-084508e81fd332c7a]
aws_lb.golang-study-api-public: Refreshing state... [id=arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:loadbalancer/app/golang-study-api-public/c2a2336715649c93]
aws_db_subnet_group.golang-study-db_subnet_group: Refreshing state... [id=golang-study-db-subnet-group]
aws_route_table.golang-study-private: Refreshing state... [id=rtb-00e4253f341fa9497]
aws_route_table_association.golang-study-public-a-association: Refreshing state... [id=rtbassoc-06b5d337dd5f93e81]
aws_route_table_association.golang-study-private-a-association: Refreshing state... [id=rtbassoc-0b0fd8a8633080f59]
aws_db_instance.golang-study-db: Refreshing state... [id=golang-study-rds]
aws_lb_listener.golang-study-api-public-listener: Refreshing state... [id=arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:listener/app/golang-study-api-public/c2a2336715649c93/1adb2523eba4fdd1]
aws_iam_role_policy_attachment.ecs_task_execution_role_policy: Refreshing state... [id=ecs_task_execution_role-20240426113529077000000001]
aws_ecs_task_definition.golang_study_app: Refreshing state... [id=golang-study-app]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.golang-study-db-sg will be updated in-place
  ~ resource "aws_security_group" "golang-study-db-sg" {
        id                     = "sg-054afc0a7b9ed277e"
      ~ ingress                = [
          + {
              + cidr_blocks      = []
              + description      = ""
              + from_port        = 5432
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 5432
            },
        ]
        name                   = "golang-study-db-sg"
        tags                   = {
            "Name" = "golang-study-db-sg"
        }
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_security_group.golang-study-db-sg: Modifying... [id=sg-054afc0a7b9ed277e]
aws_security_group.golang-study-db-sg: Modifications complete after 1s [id=sg-054afc0a7b9ed277e]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
➜  golang-study git:(4-build-aws-env) terraform apply
aws_ecs_cluster.golang_study_cluster: Refreshing state... [id=arn:aws:ecs:ap-northeast-1:879853972315:cluster/golang-study-cluster]
aws_ecr_repository.golang-study-api-repo: Refreshing state... [id=golang-study-api-repo]
aws_eip.golang-study-eip: Refreshing state... [id=eipalloc-0aa25a1b83486529e]
aws_vpc.golang-study-vpc: Refreshing state... [id=vpc-0c8995a8464d17117]
aws_iam_role.ecs_task_execution_role: Refreshing state... [id=ecs_task_execution_role]
aws_internet_gateway.golang-study-igw: Refreshing state... [id=igw-0d05829ddbb246b10]
aws_subnet.golang-study-private-a: Refreshing state... [id=subnet-099b8a012009d8af7]
aws_subnet.golang-study-public-c: Refreshing state... [id=subnet-0c2260ef4c340c8a0]
aws_subnet.golang-study-private-c: Refreshing state... [id=subnet-04aae4ddfd783d1ab]
aws_lb_target_group.golang-study-api-public-tg: Refreshing state... [id=arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:targetgroup/golang-study-api-public-tg/fd5e7fe765a80c17]
aws_security_group.golang-study-alb-sg: Refreshing state... [id=sg-03fdc2be5ca6f6bce]
aws_subnet.golang-study-public-a: Refreshing state... [id=subnet-099ae657af4e99cdc]
aws_security_group.golang-study-db-sg: Refreshing state... [id=sg-054afc0a7b9ed277e]
aws_security_group.golang-study-sg: Refreshing state... [id=sg-0667a35dc0fb55ee4]
aws_route_table.golang-study-public: Refreshing state... [id=rtb-00115d75fbd41c6d5]
aws_nat_gateway.golang-study-ngw: Refreshing state... [id=nat-084508e81fd332c7a]
aws_db_subnet_group.golang-study-db_subnet_group: Refreshing state... [id=golang-study-db-subnet-group]
aws_lb.golang-study-api-public: Refreshing state... [id=arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:loadbalancer/app/golang-study-api-public/c2a2336715649c93]
aws_route_table.golang-study-private: Refreshing state... [id=rtb-00e4253f341fa9497]
aws_route_table_association.golang-study-public-a-association: Refreshing state... [id=rtbassoc-06b5d337dd5f93e81]
aws_route_table_association.golang-study-private-a-association: Refreshing state... [id=rtbassoc-0b0fd8a8633080f59]
aws_lb_listener.golang-study-api-public-listener: Refreshing state... [id=arn:aws:elasticloadbalancing:ap-northeast-1:879853972315:listener/app/golang-study-api-public/c2a2336715649c93/1adb2523eba4fdd1]
aws_iam_role_policy_attachment.ecs_task_execution_role_policy: Refreshing state... [id=ecs_task_execution_role-20240426113529077000000001]
aws_db_instance.golang-study-db: Refreshing state... [id=golang-study-rds]
aws_ecs_task_definition.golang_study_app: Refreshing state... [id=golang-study-app]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # aws_security_group.golang-study-db-sg will be updated in-place
  ~ resource "aws_security_group" "golang-study-db-sg" {
        id                     = "sg-054afc0a7b9ed277e"
      ~ ingress                = [
          + {
              + cidr_blocks      = []
              + description      = ""
              + from_port        = 5432
              + ipv6_cidr_blocks = []
              + prefix_list_ids  = []
              + protocol         = "tcp"
              + security_groups  = []
              + self             = false
              + to_port          = 5432
            },
        ]
        name                   = "golang-study-db-sg"
        tags                   = {
            "Name" = "golang-study-db-sg"
        }
        # (7 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_security_group.golang-study-db-sg: Modifying... [id=sg-054afc0a7b9ed277e]
aws_security_group.golang-study-db-sg: Modifications complete after 0s [id=sg-054afc0a7b9ed277e]

Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
Takenari-Yamamoto commented 5 months ago

原因

Takenari-Yamamoto commented 5 months ago

とりあえず現在のstateファイルに保存されているセキュリティグループの設定を確認

terraform state show aws_security_group.golang-study-db-sg

結果

# aws_security_group.golang-study-db-sg:
resource "aws_security_group" "golang-study-db-sg" {
    arn                    = "arn:aws:ec2:ap-northeast-1:879853972315:security-group/sg-054afc0a7b9ed277e"
    description            = "security group for RDS"
    egress                 = [
        {
            cidr_blocks      = [
                "0.0.0.0/0",
            ]
            description      = ""
            from_port        = 0
            ipv6_cidr_blocks = []
            prefix_list_ids  = []
            protocol         = "-1"
            security_groups  = []
            self             = false
            to_port          = 0
        },
    ]
    id                     = "sg-054afc0a7b9ed277e"
    ingress                = [
        {
            cidr_blocks      = []
            description      = ""
            from_port        = 5432
            ipv6_cidr_blocks = []
            prefix_list_ids  = []
            protocol         = "tcp"
            security_groups  = []
            self             = false
            to_port          = 5432
        },
    ]
    name                   = "golang-study-db-sg"
    owner_id               = "879853972315"
    revoke_rules_on_delete = false
    tags                   = {
        "Name" = "golang-study-db-sg"
    }
    tags_all               = {
        "Name" = "golang-study-db-sg"
    }
    vpc_id                 = "vpc-0c8995a8464d17117"
}
Takenari-Yamamoto commented 5 months ago

Terraformが同じ差分を繰り返し適用しようとしている原因は、ingress ルールの security_groups リストが空であるために、プラン時と実際のリソースの状態との間で差異が生じている可能性が高い

by GPT

Takenari-Yamamoto commented 5 months ago

サービスをコメントアウトしたままだっだ。あほ。

サービスを元に戻した

Takenari-Yamamoto commented 5 months ago

そしてRDSのSGを修正してDONE

RDSのセキュリティグループ定義修正

Takenari-Yamamoto commented 5 months ago

失敗してる。

スクリーンショット 2024-04-26 21 58 50

cloud watchでログ見れるようにせねば。。

Takenari-Yamamoto commented 5 months ago
Takenari-Yamamoto commented 5 months ago

ログが表示されることを確認

スクリーンショット 2024-04-26 22 11 21