Terraform で GCE と AWS VPC を VPN で接続する

# 概要

GCE と AWS 間を VPN 接続する際に作成した terraform のコードメモ


# 環境

 - terraform v0.6.14


# 作成内容

- AWS
   - VPC (172.31.0.0/16)
   - subnet (172.31.1.0/24)
   - Internet Gateway
   - Customer Gateway
   - Virtual Private Gateway
   - VPN Connection
   - Route Table
 
- GCE
   - 静的アドレス取得
   - VPN 接続
   - Route
   - ファイアウォール


```HCL:vpn.tf
variable "aws_vpc_cidr_block" {
  default = "172.31.0.0/16"
}
variable "aws_zones" {
    default = {
        zone0 = "ap-northeast-1a"
        zone1 = "ap-northeast-1c"
    }
}
variable "aws_public_cidr_blocks" {
    default = {
        zone0 = "172.31.1.0/24"
        zone1 = "172.31.2.0/24"
    }
}
variable "aws_private_cidr_blocks" {
    default = {
        zone0 = "172.31.11.0/24"
        zone1 = "172.31.12.0/24"
    }
}
variable "aws_public_cidr_count" { default = 1 }
variable "aws_private_cidr_count" { default = 0 }

resource "google_compute_address" "vpn" {
  name = "gateway-to-aws"
  region = "${var.region}"
}

resource "aws_vpc" "default" {
  cidr_block = "${var.aws_vpc_cidr_block}"
  enable_dns_hostnames = true

  tags {
    Name = "${var.aws_id}"
  }
}

resource "aws_internet_gateway" "default" {
  vpc_id = "${aws_vpc.default.id}"
  tags {
    Name = "${var.aws_id}"
  }
}

resource "aws_subnet" "public" {
  vpc_id = "${aws_vpc.default.id}"
  cidr_block = "${lookup(var.aws_public_cidr_blocks, concat("zone", count.index))}"
  availability_zone = "${lookup(var.aws_zones, concat("zone", count.index))}"
  map_public_ip_on_launch = true
  count = "${var.aws_public_cidr_count}"
  tags {
    Name = "${var.aws_id}"
  }
}

resource "aws_subnet" "private" {
  vpc_id = "${aws_vpc.default.id}"
  cidr_block = "${lookup(var.aws_public_cidr_blocks, concat("zone", count.index))}"
  availability_zone = "${lookup(var.aws_zones, concat("zone", count.index))}"
  map_public_ip_on_launch = true
  count = "${var.aws_private_cidr_count}"
  tags {
    Name = "${var.aws_id}"
  }
}

resource "aws_route_table" "default" {
  vpc_id = "${aws_vpc.default.id}"
  propagating_vgws = ["${aws_vpn_gateway.default.id}"]
  route {
      cidr_block = "0.0.0.0/0"
      gateway_id = "${aws_internet_gateway.default.id}"
  }
  tags {
      Name = "${var.aws_id}"
  }
}

resource "aws_route_table_association" "public" {
  subnet_id = "${element(aws_subnet.public.*.id, count.index)}"
  route_table_id = "${aws_route_table.default.id}"
  count = "${var.aws_public_cidr_count}"
}

resource "aws_route_table_association" "private" {
  subnet_id = "${element(aws_subnet.private.*.id, count.index)}"
  route_table_id = "${aws_route_table.default.id}"
  count = "${var.aws_private_cidr_count}"
}

resource "aws_customer_gateway" "default" {
  ip_address = "${google_compute_address.vpn.address}"
  bgp_asn = "65000"
  type = "ipsec.1"
  tags {
    Name = "Gateway Into GCE"
  }
  depends_on = [ "google_compute_address.vpn" ]
}

resource "aws_vpn_gateway" "default" {
  vpc_id = "${aws_vpc.default.id}"
  tags {
    Name = "Gateway to GCE"
  }
}

resource "aws_vpn_connection" "default" {
  vpn_gateway_id = "${aws_vpn_gateway.default.id}"
  customer_gateway_id = "${aws_customer_gateway.default.id}"
  type = "ipsec.1"
  static_routes_only = true
  tags {
    Name = "VPN to GCE"
  }
}

resource "google_compute_vpn_gateway" "default" {
  name = "vpn-to-aws"
  network = "https://www.googleapis.com/compute/v1/projects/${var.project}/global/networks/${var.network}"
  region = "${var.region}"
}

resource "google_compute_forwarding_rule" "esp" {
  name = "vpn-to-aws-rule-esp"
  region = "${var.region}"
  ip_protocol = "ESP"
  ip_address = "${google_compute_address.vpn.address}"
  target = "${google_compute_vpn_gateway.default.self_link}"
}

resource "google_compute_forwarding_rule" "udp500" {
  name = "vpn-to-aws-rule-udp500"
  region = "${var.region}"
  ip_protocol = "UDP"
  port_range = "500"
  ip_address = "${google_compute_address.vpn.address}"
  target = "${google_compute_vpn_gateway.default.self_link}"
}

resource "google_compute_forwarding_rule" "udp4500" {
  name = "vpn-to-aws-rule-udp4500"
  region = "${var.region}"
  ip_protocol = "UDP"
  port_range = "4500"
  ip_address = "${google_compute_address.vpn.address}"
  target = "${google_compute_vpn_gateway.default.self_link}"
}

resource "google_compute_vpn_tunnel" "tunnel1" {
  name = "vpn-to-aws-tunnel-1"
  region = "${var.region}"
  peer_ip = "${aws_vpn_connection.default.tunnel1_address}"
  shared_secret = "${aws_vpn_connection.default.tunnel1_preshared_key}"
  ike_version = "1"
  target_vpn_gateway = "${google_compute_vpn_gateway.default.self_link}"
  depends_on = [
    "google_compute_forwarding_rule.esp",
    "google_compute_forwarding_rule.udp500",
    "google_compute_forwarding_rule.udp4500"
  ]
}

resource "google_compute_route" "vpn" {
  name = "gce-to-aws"
  network = "${var.network}"
  next_hop_vpn_tunnel = "${google_compute_vpn_tunnel.tunnel1.self_link}"
  dest_range = "${var.aws_vpc_cidr_block}"
  priority = 1000
}

resource "google_compute_firewall" "vpn" {
    name = "allow-aws"
    network = "${var.network}"
    source_ranges = [ "${var.aws_vpc_cidr_block}" ]

    allow {
        protocol = "tcp"
        ports = [ "0-65535" ]
    }

    allow {
        protocol = "udp"
        ports = [ "0-65535" ]
    }

    allow {
        protocol = "icmp"
    }
}
```

**接続確認**

GCE
![01.png](https://qiita-image-store.s3.amazonaws.com/0/105824/c6a8bfab-1aec-8583-e4ab-dcb987487284.png)


AWS
![02.png](https://qiita-image-store.s3.amazonaws.com/0/105824/95f871a2-42e3-f869-a88b-e5ae91514176.png)