2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TerraformでAWS AppMeshを使ってECS Fargateのサービスを統合する(その2 バックエンドサービス通信編)

Last updated at Posted at 2021-01-02

はじめに

AWS AppMesh記事第2弾。
前回の記事の続き。

今回は、前回記事のフロント側サービス(サービスA)にも AppMesh を適用して、バックエンド通信も含めて統合することを目指す。

前回に引き続き、本記事を書いている 2021/1/2 時点で AWS AppMesh はまだまだ発展途上なサービスであり、情報が変わる可能性があることはご了承いただきたい。

バックエンドサービス通信編で目指す構成

前回の構成を以下のように変更する。

  • 前回の構成

figure1_1.png

  • 今回の構成

figure2.png

サービスAは後続のサービスBに HTTP リクエストを転送する機能を持ったプロキシである前提だ。

今回は、サービスBは特に触らず、サービスAについて変更を行っていく。

AppMesh のサービスAに関連した項目の設定

基本的にサービスBに行った変更とは大きく変わらない。
ECS に関連した変更は前回と同じであるため、今回は割愛する。
※サービスAはロードバランサ配下にいるため、その設定は削除しない。

AppMesh に関連したリソースを以下のように変更する。
今回も、aws_appmesh_virtual_serviceaws_appmesh_virtual_node を作成する。
メッシュそのものは、サービスA/Bで共通であるため今回は作成しない。

resource "aws_appmesh_virtual_service" "service_a" {
  name      = "${aws_service_discovery_service.service_a.name}.${aws_service_discovery_private_dns_namespace.internal.name}"
  mesh_name = aws_appmesh_mesh.trial.id

  spec {
    provider {
      virtual_node {
        virtual_node_name = aws_appmesh_virtual_node.service_a.name
      }
    }
  }
}

resource "aws_appmesh_virtual_node" "service_a" {
  name      = local.service_a_appmesh_virtualnode_name
  mesh_name = aws_appmesh_mesh.trial.id

  spec {
    listener {
      port_mapping {
        port     = 80
        protocol = "http"
      }
      health_check {
        protocol            = "http"
        path                = "/healthcheck"
        healthy_threshold   = 2
        unhealthy_threshold = 2
        timeout_millis      = 2000
        interval_millis     = 5000
      }
    }

    backend {
      virtual_service {
        virtual_service_name = aws_appmesh_virtual_service.service_b.name
      }
    }

    service_discovery {
      aws_cloud_map {
        namespace_name = [サービスディスカバリの名前空間]
        service_name   = [サービスAのサービス名]
      }
    }

    logging {
      access_log {
        file {
          path = "/dev/stdout"
        }
      }
    }
  }
}

ポイントは

    backend {
      virtual_service {
        virtual_service_name = aws_appmesh_virtual_service.service_b.name
      }
    }

の部分で、この設定によりバックエンド通信をプロキシ経由に変更する。

動かしてみる

これで、NLB のパブリックドメインに対して curl でトラフィックを入れてみると、サービスB側の情報が返却されるだろう。

その上で、サービスAの CloudWatch Logs を確認すると、以下の2つのアクセスログが出力されていることが分かる。

[2021-01-02T11:20:33.732Z] "GET / HTTP/1.1" 200 - 0 413 3 3 "-" "curl/7.61.1" "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" "service-b.appmesh-trial.internal" "xxx.xxx.xxx.xxx:80"
[2021-01-02T11:20:33.730Z] "GET / HTTP/1.1" 200 - 0 413 5 5 "-" "curl/7.61.1" "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" "appmesh-trial-svc-a-nlb-230cfbfddd423b72.elb.ap-northeast-1.amazonaws.com" "127.0.0.1:80"

また、サービスB側のログにも以下が出力されている。

[2021-01-02T11:20:33.734Z] "GET / HTTP/1.1" 200 - 0 413 0 0 "-" "curl/7.61.1" "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" "service-b.appmesh-trial.internal" "127.0.0.1:80"

マスクしているが、xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx には同じ値が入っていて、トラフィックを一意に識別することができる。

また、X-Ray のサービスマップは以下のように変わる。

キャプチャ2.png

分かりにくいが、下がサービスA、上がサービスBだ。
サービスBにも Client から線が延びているのは、ヘルスチェックのトラフィックが計上されているためだ。
エンドユーザトランザクションはサービスA側からしか入れていない。

このように簡単にサービスマップを後付けで作ることができるのも AppMesh のポイントだろう。

2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?