閉域網を使用したアプリケーション間通信の実現

非機能要求としてインターネットを経由せずに通信したい場合にリクエストのGatewayとして内部Load Balancerを使用することがあるのですが、その内部Load Balancerに対してElastic Beanstalkで制御しているEC2 Instanceを継続的にターゲットし続けることが必要になってきます。

VPC間を通信するためにVPC Endpoint・VPC EndpointServicesなどがあるのですが、今回は同一VPC内の同一サブネット内での通信のため、これらのコンポーネントは不要です。開発環境などにおいてはコスト削減のためにEC2 Instanceを起動・停止を制御しています。インターネット向けのLoad BalancerではAutoscaling Groupと連携し、EC2 Instanceをターゲットし続けることが可能なのですがElastic Beanstalkで管理していない内部Load Balancer(Elastic Beanstalkは同時に複数のLoad Balancerを作成できない)は初回にターゲットに指定したEC2 Instanceがターミネートされると、次回起動してくるEC2 Instanceを継続してターゲットできません。そこで、個別にAutoscaling Attachmentを作成し、Elastic Beanstalkで制御しているAutoscaling Groupと個別で作成したTarget Groupを連携させます。そうすることで、時間やリソース次第で増減するEC2 Instanceを継続してターゲットすることが可能になります。

- 非機能要求まとめ
  1. アプリケーション間通信で閉域網を使用するが、RequesterとAccepterは同一VPC・同一SubnetなのでVPC Endpointは不要
  2. Elastic Beanstalkとは別に作成したLoad BalancerのTarget GroupをElastic Beanstalkと連携させたい
  3. Elastic Beanstalkで管理しているAutoscaling Groupに個別で作成したLoad BalancerのTarget Groupをアタッチする
  4. 個別に作成したLoad Balancerで時間やリソース次第で増減するEC2 Instanceを継続してターゲットすることが可能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58788/aa76e963-df20-2364-2943-9ce962a6bebb.png)


- 設定ファイル

<summary>`lb_target_group`</summary>

```tf
resource "aws_lb_target_group" "int_nlb_target_group" {
  name        = "int_nlb_target_group"
  target_type = "instance"
  port        = 80
  protocol    = "TCP"
  vpc_id      = data.aws_vpc.xxxx.id
}
```

<summary>`lb_target_group_attachment`</summary>

```tf
resource "aws_lb_target_group_attachment" "int_nlb_target_group_attachment_1" {
  target_group_arn = aws_lb_target_group.int_nlb_target_group.arn
  target_id        = "i-xxxxxxxxxxxxx"
  port             = 80
}

resource "aws_lb_target_group_attachment" "int_nlb_target_group_attachment_2" {
  target_group_arn = aws_lb_target_group.int_nlb_target_group.arn
  target_id        = "i-xxxxxxxxxxxxx"
  port             = 80
}
```

<summary>`lb_listener`</summary>

```tf
resource "aws_lb_listener" "int_nlb_listener" {
  load_balancer_arn = aws_lb.int_nlb.arn
  port              = "80"
  protocol          = "TCP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.int_nlb_target_group.arn
  }
}
```
<summary>`lb`</summary>

```tf
// Changing this value for load balancers of type network will force a recreation of the resource.
resource "aws_lb" "int_nlb" {
  name               = "int-nlb"
  internal           = true
  load_balancer_type = "network"
  subnets            = ["subnet-xxxxxxxxxxxxx", "subnet-xxxxxxxxxxxxx"]

  access_logs {
    bucket  = "xxxxxxxxxxxxx"
    prefix  = "xxxxxxxxxxxxx/xxxxxxxxxxxxx/xxxxxxxxxxxxx"
    enabled = true
  }

  tags = {
    Name        = "int-nlb"
    Environment = "xxxxxx"
  }
}
```
<summary>`autoscaling_attachment`</summary>

```tf
resource "aws_autoscaling_attachment" "nt_nlb_asg_attachment" {
  autoscaling_group_name = aws_elastic_beanstalk_environment.xxxxxxxxxxxxx.autoscaling_groups[0]
  alb_target_group_arn   = aws_lb_target_group.int_nlb_target_group.arn
}
```

初回にハードコードしたInstanceIDが差分として出力されつづけてしまう解決できていない課題があります...
issueというか機能リクエストしたい箇所ではあります。

```tf
------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_lb_target_group_attachment.int_nlb_target_group_attachment will be created
  + resource "aws_lb_target_group_attachment" "int_nlb_target_group_attachment" {
      + id               = (known after apply)
      + port             = 80
      + target_group_arn = "arn:aws:elasticloadbalancing:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      + target_id        = "i-xxxxxxxxxxxxxx"
    }

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

------------------------------------------------------------------------
```