ENECHANGE Developer Blog

ENECHANGE開発者ブログ

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

こんにちは。Let's Encryptのバグ対応に伴う証明書失効とAmazon RDSおよびAmazon AuroraのSSL/TLS 証明書の期限切れイベントが重なった今週でしたが、システムは平常運転なのでホッとしているCTO室のkazです。 Let's Encryptのバグについてはこちらに書いてます...!

非機能要求としてインターネットを経由せずに通信したい場合にリクエストの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を継続してターゲットすることが可能

f:id:dev-enechange:20200306201712p:plain

  • 設定ファイル

lb_target_group

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
}

lb_target_group_attachment

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
}

lb_listener

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

lb

// 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"
  }
}

autoscaling_attachment

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というか機能リクエストしたい箇所ではあります。

------------------------------------------------------------------------

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.

------------------------------------------------------------------------