これは何?

AWS VPC とオンプレミスネットワーク間のVPN接続であるSite-to-Site VPN接続(サイト間VPN)についてTerraformで構築をしたので、構築手順をご紹介したいと思います。

注意点

  • こちらの記事では動的ルーティングではなく静的ルーティングを利用する場合の構築手順をご紹介します
  • サイト間VPNについてはトンネルに関して細かい設定ができますが、今回はトンネル設定はすべてデフォルトとしました

構成図

構築手順

AWSドキュメントに沿って、下記の手順で作成します。

  • ステップ 1: カスタマーゲートウェイを作成する
  • ステップ 2: ターゲットゲートウェイを作成する
  • ステップ 3: ルーティングを設定する
  • ステップ 4: セキュリティグループを更新する
  • ステップ 5: VPN 接続を作成する
  • ステップ 6: 設定ファイルをダウンロードする
  • ステップ 7: カスタマーゲートウェイデバイスを設定する

Terraformで構築した、ステップ1〜5までの手順について、コード付きで詳細を記載します。

ステップ 1: カスタマーゲートウェイを作成する

オンプレミス側のネットワーク内のゲートウェイである、カスタマーゲートウェイを作成します。
Terraformのaws_customer_gatewayリソースについてはこちら

今回はオンプレ側のASNは65000と指定があったため、bgp_asnは65000で設定しています。

# Customer gateway
resource "aws_customer_gateway" "cgw" {
  bgp_asn    = 65000
  ip_address = var.site-to-site_vpn.onpre_ip_01 //オンプレ側のIPをvariables.tfで定義
  type       = "ipsec.1"
}

なおvariables.tfの、オンプレ側のIP・CIDRは次のように設定しています。

# -----------------------------
# Site-to-Site VPN
# -----------------------------
variable "site-to-site_vpn" {
  type = map(string)
  default = {
    onpre_ip_01   = "XXX.XXX.XXX.XXX" // オンプレ側ルーターのIP。
    onpre_cidr_01 = "YYY.YYY.YYY.YYY/24" // オンプレ側ネットワークCIDR。
  }
}

ステップ 2: ターゲットゲートウェイを作成する

ターゲットゲートウェイは、仮想プライベートゲートウェイまたは Transit Gatewayを使用します。
今回は仮想プライベートゲートウェイ(VGW)を構築します。
Terraformのaws_vpn_gatewayリソースについてはこちら

AWS側のASNは65007を指定しています。

resource "aws_vpn_gateway" "vgw" {
  vpc_id          = aws_vpc.vpc.id
  amazon_side_asn = "65007"
}

ステップ 3: ルーティングを設定する

動的ルーティングを利用する場合は、ルート伝播を有効に設定することで、Site-to-Site VPN ルートを自動的に伝播します。
ルート伝播設定のためのTerraformのaws_vpn_gateway_route_propagationリソースについてはこちら

今回は静的ルーティングでの構築であり、オンプレ側ネットワークCIDRを静的ルートとしてルートテーブルに手動で入力しておけば、ルート伝播を有効にする必要はありません。
今回はルート伝播は無効とし、VPCサブネットのルートテーブルにオンプレ側ネットワークCIDRとVGWとのルートを設定しました。

Terraformのaws_route_tableリソースについてはこちら

resource "aws_route_table" "rt_private" {
  vpc_id = aws_vpc.vpc.id

  route {
    cidr_block     = "0.0.0.0/0"
    nat_gateway_id = aws_nat_gateway.natgw.id
  }

  route {
    cidr_block = var.site-to-site_vpn.onpre_cidr_01 //オンプレ側のIPをvariables.tfで定義
    gateway_id = aws_vpn_gateway.vgw.id //仮想プライベートゲートウェイを指定
  }
}

ステップ 4: セキュリティグループを更新する

オンプレと接続するインスタンスに適用するセキュリティグループに対して、オンプレ用IPアドレスの接続を許可するルールを追加します。
Terraformのaws_security_groupリソースについてはこちら

オンプレ側ネットワークCIDRからの通信について、双方向かつ全ポートに許可しています。

resource "aws_security_group" "instance" {
  name        = "instance-sg"
  vpc_id      = aws_vpc.vpc.id

  ingress {
    description = "local"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = [var.vpc.cidr]
  }

  ingress {
    description = "Site-to-Site VPN"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = [
      var.site-to-site_vpn.onpre_cidr_01 //オンプレ側のIPをvariables.tfで定義
    ]
  }

  egress {
    description = "local"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = [var.vpc.cidr]
  }

  egress {
    description = "Site-to-Site VPN"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = [
      var.site-to-site_vpn.onpre_cidr_01 //オンプレ側のIPをvariables.tfで定義
    ]
  }
}

ステップ 5: VPN 接続を作成する

オンプレ側CGWとAWS側VGWを接続するためのVPN接続を作成していきます。
Terraformのaws_vpn_connectionリソースについてはこちら
local_ipv4_network_cidrにローカル(オンプレ)側のCIDR、remote_ipv4_network_cidrにリモート(AWS VPC)側のCIDRを設定しています。
今回は静的ルーティングのため、static_routes_onlyをtrueに設定しています。

# Site-to-site connection
resource "aws_vpn_connection" "vpnc" {
  vpn_gateway_id           = aws_vpn_gateway.vgw.id
  customer_gateway_id      = aws_customer_gateway.cgw.id
  local_ipv4_network_cidr  = var.site-to-site_vpn.onpre_cidr_01
  remote_ipv4_network_cidr = var.vpc.cidr
  static_routes_only       = true
  type                     = "ipsec.1"

}

また、今回は静的ルーティングのため、VPN接続とCGWとの間の静的ルートを別途aws_vpn_connection_routeで設定します。
Terraformのaws_vpn_connection_routeについてはこちら

resource "aws_vpn_connection_route" "onpre" {
  destination_cidr_block = var.site-to-site_vpn.onpre_cidr_01
  vpn_connection_id      = aws_vpn_connection.vpnc.id
}

構築結果

マネジメントコンソールから、Terraformで設定した通りに構築されていることを確認しました。

終わりに

今回はサイト間VPNをTerraformで構築する手順についてご紹介しました。
構築される際の参考になれば幸いです。