1. ホーム
  2. 記事一覧
  3. 【Terraformハンズオン】NAT GatewayにセカンダリIPアドレスを追加する方法

2024.08.27

【Terraformハンズオン】NAT GatewayにセカンダリIPアドレスを追加する方法

AWSが提供するNAT Gatewayは、プライベートサブネットにあるサーバーなどのリソースがインターネットに接続するために必要な仕組みです。今回は、このNAT Gatewayに「セカンダリIPアドレス」を追加する方法と、セカンダリIPの基礎を解説します。

NAT GatewayにセカンダリIPアドレスを追加することで同時接続数を引き上げることが可能となるため、規模の大きなサービスに必要な機能となります。ぜひ一緒に学んでいきましょう。

NAT Gatewayとは

NAT Gatewayは、AWSが提供するマネージドサービスで、NAT(Network Address Translation)の仕組みを実現します。

NATは一般的に、グローバルIPアドレスとプライベートIPアドレスを変換する技術を指します。

NAT GatewayはこのNATの仕組みをAWS上で実現し、プライベートサブネット内にあるリソースがインターネットに接続する際、プライベートIPアドレスをパブリックIPアドレスに変換する役割を果たします。

NATの仕組みに関しては以下の記事で解説しています。

https://envader.plus/article/15

セカンダリIPアドレスとは

セカンダリIPアドレスとは、プライマリIPアドレスに追加するIPアドレスで、主に通信の分散や同時接続数を増やす目的で使用します。このセカンダリIPアドレスをNAT Gatewayに追加することで、特定のIPアドレスポート番号プロトコルの組み合わせに対しての同時接続数を増やすことができます。

「特定のIPアドレスに対して」の通信でも、ポート番号、プロトコルが異なる場合には別の接続としてみなされます。

NAT Gatewayは、1つのIPアドレスで55,000の同時接続をサポートし、1つのプライマリIPアドレスと7つのセカンダリIPアドレス、合計8つのIPアドレスをNAT Gatewayに関連づけることで同時接続の制限を440,000まで引き上げることが可能になります。

https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-working-with.html#nat-gateway-edit-secondary

なぜセカンダリIPアドレスが必要なのか

NAT Gatewayが処理できる同時接続数には限界があります。先述したように1つのIPアドレス(Elastic IP)で最大55,000の同時接続が可能ですが、大量の通信が発生する環境ではこの55,000という制限を超えてしまうことが考えられます。

例として大規模の顧客を抱えるサービスでは、セールの時期など注目度が高いコンテンツであれば大量のユーザーが一気にアクセスしてくることが予想されます。このような時に、レスポンスが遅い、サイトにアクセスできないなどの障害が発生する可能性があります。

セカンダリIPアドレスを追加することで、同時接続数の上限を引き上げてユーザー影響が発生しないよう対策することが可能になります。

https://aws.amazon.com/jp/blogs/networking-and-content-delivery/attach-multiple-ips-to-a-nat-gateway-to-scale-your-egress-traffic-pattern/

同時接続数の上限を超えた場合

特定の宛先に対しての同時接続数が上限を超えた場合、その宛先への新しい接続は失敗します。

https://repost.aws/ja/knowledge-center/vpc-resolve-port-allocation-errors

この現象が発生した時には、NAT GatewayメトリクスのErrorPortAllocationPacketsDropCountの値が上昇するため、CloudWatchメトリクスでどの時間帯にどのくらい発生していたのかを確認することが可能です。

NAT ゲートウェイの CloudWatch メトリクスであるErrorPortAllocationとPacketsDropCountを使用して、NAT ゲートウェイがポート割り当てエラーを生成しているかどうか、またはパケットをドロップしているかどうかを判断できます。

AWS公式ドキュメントより引用

NAT GatewayにセカンダリIPを追加することで、このポート割り当てエラーを解消することができます。

AWS CLIでセカンダリIPアドレスを追加する方法

セカンダリIPアドレスを追加するには、AWSコンソール、AWS CLI、Terraformを使用して追加する方法があります。

AWSコンソールでの追加方法は公式ドキュメントのセカンダリ IP アドレスの関連付けを編集するにありますのでそちらを参照ください。

AWS CLIでは、次の順番でセカンダリIPを追加します。

前提条件

NAT Gateway、Elastic IPアドレスはすでに作成していることを前提にコマンドを解説します。まだ作成していない場合は、以下の記事を参考に作成しましょう。

https://envader.plus/article/450

AWS CLIコマンドを実行する

AWS CLIでNAT GatewayにセカンダリIPを追加するにはElastic IPのallocation id情報が必要になるため、次のコマンドを実行し結果を控えておきます。

aws ec2 describe-addresses

続いてNAT Gatewayの情報を取得し、結果を控えます。

aws ec2 describe-nat-gateways --query 'NatGateways[*].NatGatewayId' --output text

最後に、NAT GatewayにセカンダリIPを追加します。

aws ec2 associate-nat-gateway-address --nat-gateway-id nat-xxxxxxxxxxx --allocation-ids eipalloc-xxxxxxxxxx

以下コマンドでNAT Gatewayを確認し、セカンダリIPの追加状況を確認します。JSON形式で出力されるため、"NatGatewayAddresses"の中に"PublicIp"が2つ存在していることを確認します。

aws ec2 describe-nat-gateways

 {  "CreateTime": "2024-08-22Txx:38:41+00:00",
     "NatGatewayAddresses": [
         {.........
          "PublicIp": "52.192.10.12",
          .........
          "PublicIp": "3.115.70.244",
          .........

セカンダリIPを追加するときの注意点

AWSコンソールからNAT GatewayにElastic IPを追加する場合、すでにNAT Gatewayが作成されている必要があります。新規作成の場合、セカンダリIPを追加する項目は表示されないため注意が必要です。

また、NAT GatewayにセカンダリIPを追加することでの追加料金の明記はされておりませんが、追加のElastic IPに対しては料金が発生します。仮にセカンダリIPを上限の7個追加した場合、7個分のElastic IP追加料金が発生することは認識しておきましょう。

https://aws.amazon.com/jp/vpc/pricing/

TerraformでNAT GatewayにセカンダリIPを追加する

TerraformでNAT GatewayにセカンダリIPを追加するためには、AWSプロバイダーのバージョンを5.10.0以上に上げる必要があります。これ以下のバージョンではサポートされていないため、Terraformで管理できません。

https://github.com/hashicorp/terraform-provider-aws/issues/29471

TerraformでNAT GatewayにセカンダリIPを追加する際の注意点

筆者がハマったことをお伝えします。

2024年8月時点で、既存のNAT GatewayにTerraformを使用してセカンダリIPをアタッチしようとすると、NAT Gatewayを新しく作り直される挙動になります。この現象はまだ改善されていないため、NAT Gatewayが再作成されてしまうのを防ぎたい場合には、AWS CLIやコンソールからセカンダリIPを追加し、その後にTerraformコードを追従するよう進めた方が良いでしょう。

https://github.com/hashicorp/terraform-provider-aws/issues/33964

プロバイダーバージョンを確認する

versions.tfなどでプロバイダーバージョンを管理している場合はバージョンを確認し、必要であれば修正します。

terraform {
  required_version = ">= 1.0.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.10.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

プロバイダーバージョンを変更した際には、terraform initコマンドを忘れずに実行します

terraform init

セカンダリIPを追加する

TerraformでセカンダリIPを追加するには、aws_nat_gatewayリソースにsecondary_allocation_idsを追加します。

data "aws_eip" "nat_eip" {
  id = "eipalloc-040f9f4f82958bd51"
}

resource "aws_nat_gateway" "nat_gateway" {
  allocation_id = aws_eip.nat.id
  subnet_id = aws_subnet.public.id
  secondary_allocation_ids = [data.aws_eip.nat_eip.id] # ここを追加
  tags = {
    Name = "nat-gateway"
  }
  depends_on = [aws_eip.nat]
}

今回はdataリソースを使って、すでにあるElastic IPを取得しセカンダリIPとして追加しています。

以下コード全体です。

locals {
  vpc = {
    cidr_block          = "10.0.0.0/16"
    subnet_cidr         = "10.0.10.0/24"
    subnet_cidr_private = "10.0.20.0/24"
  }
}

data "aws_eip" "nat_eip" {
  id = "eipalloc-040f9f4f82958bd51"
}

# vpc
resource "aws_vpc" "main" {
  cidr_block           = local.vpc.cidr_block
  enable_dns_support   = true
  enable_dns_hostnames = true
  tags = {
    Name = "main"
  }
}

# subnet
resource "aws_subnet" "public" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = local.vpc.subnet_cidr
  availability_zone       = "ap-northeast-1a"
  map_public_ip_on_launch = true
  tags = {
    Name = "public"
  }
}

resource "aws_subnet" "private" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = local.vpc.subnet_cidr_private
  availability_zone = "ap-northeast-1a"
  tags = {
    Name = "private"
  }
}

# RouteTable
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "public"
  }
}

# RouteTableAssociation
resource "aws_route_table_association" "public" {
  subnet_id      = aws_subnet.public.id
  route_table_id = aws_route_table.public.id
}

# InternetGateway
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "igw"
  }
}

# Route
resource "aws_route" "public" {
  route_table_id         = aws_route_table.public.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.igw.id
}

# private subnetのRouteTable
resource "aws_route_table" "private" {
  vpc_id = aws_vpc.main.id
  tags = {
    Name = "private"
  }
}

# private subnetのRouteTableAssociation
resource "aws_route_table_association" "private" {
  subnet_id      = aws_subnet.private.id
  route_table_id = aws_route_table.private.id
}

# private subnetのRoute
resource "aws_route" "private" {
  route_table_id         = aws_route_table.private.id
  destination_cidr_block = "0.0.0.0/0"
  nat_gateway_id         = aws_nat_gateway.nat_gateway.id
}

# Elastic IP
resource "aws_eip" "nat" {
  vpc = true

  tags = {
    Name = "nat-eip"
  }
}

# NAT Gateway
resource "aws_nat_gateway" "nat_gateway" {
  allocation_id = aws_eip.nat.id
  subnet_id = aws_subnet.public.id
  secondary_allocation_ids = [data.aws_eip.nat_eip.id]
  tags = {
    Name = "nat-gateway"
  }
  depends_on = [aws_eip.nat]
}

まとめ

この記事では、NAT GatewayにセカンダリIPアドレスを追加する方法、セカンダリIPアドレスの基礎を解説しました。NAT GatewayにセカンダリIPアドレスを追加することで、同時接続数を大幅に増加させることができます。

AWSのインフラエンジニアであれば押さえておきたい項目になるため、AWS CLIやTerraformを使った設定方法も含め理解しておきましょう。

【番外編】USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

IT未経験者必見 USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

プログラミング塾に半年通えば、一人前になれると思っているあなた。それ、勘違いですよ。「なぜ間違いなの?」「正しい勉強法とは何なの?」ITを学び始める全ての人に知って欲しい。そう思って書きました。是非読んでみてください。

「フリーランスエンジニア」

近年やっと世間に浸透した言葉だ。ひと昔まえ、終身雇用は当たり前で、大企業に就職することは一種のステータスだった。しかし、そんな時代も終わり「優秀な人材は転職する」ことが当たり前の時代となる。フリーランスエンジニアに高価値が付く現在、ネットを見ると「未経験でも年収400万以上」などと書いてある。これに釣られて、多くの人がフリーランスになろうとITの世界に入ってきている。私もその中の1人だ。数年前、USBも知らない状態からITの世界に没入し、そこから約2年間、毎日勉学を行なった。他人の何十倍も努力した。そして、企業研修やIT塾で数多くの受講生の指導経験も得た。そこで私は、伸びるエンジニアとそうでないエンジニアをたくさん見てきた。そして、稼げるエンジニア、稼げないエンジニアを見てきた。

「成功する人とそうでない人の違いは何か?」

私が出した答えは、「量産型エンジニアか否か」である。今のエンジニア市場には、量産型エンジニアが溢れている!!ここでの量産型エンジニアの定義は以下の通りである。

比較的簡単に学習可能なWebフレームワーク(WordPress, Rails)やPython等の知識はあるが、ITの基本概念を理解していないため、単調な作業しかこなすことができないエンジニアのこと。

多くの人がフリーランスエンジニアを目指す時代に中途半端な知識や技術力でこの世界に飛び込むと返って過酷な労働条件で働くことになる。そこで、エンジニアを目指すあなたがどう学習していくべきかを私の経験を交えて書こうと思った。続きはこちらから、、、、

note記事3000いいね超えの殿堂記事 今すぐ読む

エンベーダー編集部

エンベーダーは、ITスクールRareTECHのインフラ学習教材として誕生しました。 「遊びながらインフラエンジニアへ」をコンセプトに、インフラへの学習ハードルを下げるツールとして運営されています。

RareTECH 無料体験授業開催中! オンラインにて実施中! Top10%のエンジニアになる秘訣を伝授します! RareTECH講師への質疑応答可

関連記事

2020.02.25

完全未経験からエンジニアを目指す爆速勉強法

USBも知らなかった私が独学でプログラミングを勉強してGAFAに入社するまでの話

  • キャリア・学習法
  • エンジニア

2024.04.17

Terraform活用法: AWS EC2 Auto ScalingGroupを構築してみよう

こちらの記事では、Amazon EC2 Auto Scalingの機能を[Terraform](https://www.terraform.io/)で実装する方法を解説します。

  • AWS
  • ハンズオン
  • Terraform

2024.07.29

インフラ・クラウドエンジニア必見!AzureとAWSのRBACの違いを徹底解説

クラウドサービスを利用する上で、セキュリティとアクセス管理は非常に重要です。特にAzureとAWSは、それぞれ独自のRBAC(ロールベースアクセス制御)を提供しており、その違いを理解することが求められます。本記事では、初心者インフラ・クラウドエンジニアに向けて、AzureとAWSのRBACの違いを詳しく解説します。

  • AWS
  • Azure
  • サイバーセキュリティ
  • インフラエンジニア

2024.04.14

手を動かして身につける AWSでサーバレスのハンズオン

サーバレスコンピューティングの最大のメリットは、インフラの管理から解放されることです。開発者はサーバーのプロビジョニングや保守に関する心配をする必要がなく、アプリケーションのコードの作成とその実行に専念できます。より迅速にアプリケーションを市場に投入することが可能となり、イノベーションの速度を高めることができます。

  • AWS
  • ハンズオン