GCPとAWS間のインターネットVPN接続をterraformで構築する

# はじめに
目的はGCPとAWSをインターネットVPNで接続することです。

terraformを利用せず、コンソールから作成する手順はこの記事がわかりやすいです。
**『Amazon VPCとGoogle Compute EngineをVPN接続する』**
https://dev.classmethod.jp/cloud/vpn-interconnect-amazon-vpc-and-gce/

こんな環境の作成を目指します。
![001_AWS&GCPインターネットVPN.png](https://qiita-image-store.s3.amazonaws.com/0/169814/58b9cad3-e341-8c3c-917f-6c53a037bb56.png)




# 前提条件
terraformの設定方法は記載していません。
すでにGCP環境、AWS環境でterraformが実行できるところがスタートです。


## 【GCP】ネットワークとサブネットワークを作成する
まずはGCP側に**ネットワーク**と**サブネットワーク**を作成します。

```gcp_terraform.tf

resource "google_compute_network" "tbt-network" {
  name                    = "tbt-network"
  auto_create_subnetworks = "false"
}

#subnet
resource "google_compute_subnetwork" "tbt-network" {
  name          = "tbt-network"
  ip_cidr_range = "10.10.0.0/24"
  network       = "${google_compute_network.tbt-network.name}"
  description   = "tbt-network"
  region        = "asia-northeast1"
}

```

## 【GCP】外部IPアドレスの取得と確認
外部IPアドレスを取得します。
どんなIPアドレスが取得できたかを同時に出力します。

```output.tf
resource "google_compute_address" "tbt-vpn" {
  name = "tbt-vpn"
}

output "tbt-vpn" {
  value = "${google_compute_address.tbt-vpn.address}"
}
```

outputを設定しているのでapplyを実行すると下記のように出力されます。
このIPアドレスはAWS側の設定で使用します。

```
Outputs:

tbt-vpn = xxx.xxx.xxx.xxx
```

ここまでで作成した環境は下図の通りです。
![002_AWS&GCPインターネットVPN.png](https://qiita-image-store.s3.amazonaws.com/0/169814/002a33d7-3fb7-90a8-2987-0a3406f70409.png)


## 【AWS】VPCとサブネットを作成する
ここからAWS側の設定です。
AWS側にも**ネットワーク（VPC）**と**サブネット**を作成します。

```aws_terraform.tf

resource "aws_vpc" "tbt-vpc" {
  cidr_block           = "10.20.0.0/16"

  tags {
    Name = "tbt-vpc"
  }
}

resource "aws_subnet" "tbt-subnet-1a" {
  vpc_id            = "${aws_vpc.tbt-vpc.id}"
  cidr_block        = "10.20.0.0/24"
  availability_zone = "ap-northeast-1a"

  tags {
    Name = "tbt-subnet-1a"
  }
}
```

## 【AWS】VPN系のリソースの作成
ここからが本題。
AWSで**VPNゲートウェイ**と**カスタマーゲートウェイ**と**VPN接続**を作成します。

```aws_terrafrom.tf
resource "aws_vpn_gateway" "tbt-vpn-gateway" {
  vpc_id = "${aws_vpc.tbt-vpc.id}"

  tags {
    Name = "tbt-vpn-gateway"
  }
}

resource "aws_customer_gateway" "tbt-customer-gateway" {
  bgp_asn    = 65000
  ip_address = "xxx.xxx.xxx.xxx"
  type       = "ipsec.1"

  tags {
    Name = "tbt-customer-gateway"
  }
}

resource "aws_vpn_connection" "tbt-vpn-connection" {
  vpn_gateway_id      = "${aws_vpn_gateway.tbt-vpn-gateway.id}"
  customer_gateway_id = "${aws_customer_gateway.tbt-customer-gateway.id}"
  type                = "ipsec.1"
  static_routes_only  = true

  tags {
    Name = "tbt-vpn-connection"
  }
}
```

**aws_customer_gateway**の設定でIPアドレスを記載する箇所があります。
先ほどGCPで取得した**外部IPアドレスの値**を設定します。

## 【AWS】外部IPアドレスとPre-Shared Keyの取得
GCP側で取得したIPアドレスをAWS側の設定で使用したということは逆もまた然りです。
GCP側の設定で使用するAWS側のIPアドレスを取得します。
さらに**Pre-Shared Key**の値も出力しておきます。

```output.tf
output "tbt-vpn-connection_tunnel1_address" {
  value = "${aws_vpn_connection.tbt-vpn-connection.tunnel1_address}"
}

output "tbt-vpn-connection_tunnel1_preshared_key" {
  value = "${aws_vpn_connection.tbt-vpn-connection.tunnel1_preshared_key}"
}
```

applyを実行すると下記のように出力されます。

```
Outputs:

tbt-vpn-connection_tunnel1_address = yyy.yyy.yyy.yyy
tbt-vpn-connection_tunnel1_preshared_key = [なんか適当な文字列]
```

ここまでで作成した環境は下図の通り。
![003_AWS&GCPインターネットVPN.png](https://qiita-image-store.s3.amazonaws.com/0/169814/8fa103b2-59f3-f219-ce6a-17a998923810.png)


## 【GCP】VPNゲートウェイとVPNトンネルの作成
再びGCP側の設定（ちょっと設定項目多めですがこれで最後です！）

GCPで**VPNゲートウェイ**と**VPNトンネル**の設定をします。
さらにGCP側にはVPN接続のためのフォワーディングルールを設定する必要があるので、それもおまじないのように設定しておきます。

```gcp_terraform.tf
resource "google_compute_vpn_gateway" "tbt-vpn" {
  name    = "tbt-vpn"
  network = "${google_compute_network.tbt-network.self_link}"
}

resource "google_compute_vpn_tunnel" "tbt-vpn-tunnel1" {
  name          = "tbt-vpn-tunnel1"
  peer_ip       = "yyy.yyy.yyy.yyy"
  shared_secret = "なんか適当な文字列"

  target_vpn_gateway      = "${google_compute_vpn_gateway.tbt-vpn.self_link}"
  local_traffic_selector  = ["${google_compute_subnetwork.tbt-network.ip_cidr_range}"]
  remote_traffic_selector = ["10.20.0.0/16"]
  ike_version             = 1

  depends_on = [
    "google_compute_forwarding_rule.fr_esp",
    "google_compute_forwarding_rule.fr_udp500",
    "google_compute_forwarding_rule.fr_udp4500",
  ]
}

resource "google_compute_forwarding_rule" "fr_esp" {
  name        = "fr-esp"
  ip_protocol = "ESP"
  ip_address  = "${google_compute_address.tbt-vpn.address}"
  target      = "${google_compute_vpn_gateway.tbt-vpn.self_link}"
}

resource "google_compute_forwarding_rule" "fr_udp500" {
  name        = "fr-udp500"
  ip_protocol = "UDP"
  port_range  = "500"
  ip_address  = "${google_compute_address.tbt-vpn.address}"
  target      = "${google_compute_vpn_gateway.tbt-vpn.self_link}"
}

resource "google_compute_forwarding_rule" "fr_udp4500" {
  name        = "fr-udp4500"
  ip_protocol = "UDP"
  port_range  = "4500"
  ip_address  = "${google_compute_address.tbt-vpn.address}"
  target      = "${google_compute_vpn_gateway.tbt-vpn.self_link}"
}
```
**peer_ip**の設定でIPアドレスを記載する箇所があります。
先ほどAWSで取得した**外部IPアドレスの値**を設定します。

**shared_secret**の設定でPre-Shared Keyを設定する必要があります。
先ほどAWSで取得した**Pre-Shared Keyの値**（なんか適当な文字列）を設定します。

**remote_traffic_selector**の設定でAWS側のサブネットの情報を設定する必要があります。
例の通りであれば**10.20.0.0/16**を設定します。


## 完成！
これで下図のような構成が完成しました。![001_AWS&GCPインターネットVPN.png](https://qiita-image-store.s3.amazonaws.com/0/169814/709bb7e4-87d9-7a62-d487-41d7a465c33b.png)

このVPN環境を利用した実験記事を後日公開予定:calendar: