自动化网络部署:使用 Terraform 在 GCP 和 AWS 之间构建 VPN

本教程介绍如何使用 HashiCorp 的 Terraform,通过虚拟专用网 (VPN) 在 Google Cloud Platform (GCP) 和 Amazon Web Services (AWS) 之间建立安全私密的站点到站点连接。这是一种多云端部署。

本教程是由三部分组成的系列教程中的第三部分,该系列教程主要介绍通用网络资源模式的自动部署。本教程使用了自动网络部署:概览教程中介绍的身份验证和项目配置。

在本教程中,您可以将虚拟机 (VM) 实例部署到 GCP 和 AWS 的自定义虚拟私有云 (VPC) 网络中。然后部署支持的基础架构,用于在 GCP 和 AWS VPC 网络之间构建具有两个互联网协议安全 (IPsec) 隧道的 VPN 连接。环境和隧道部署通常可在四分钟内完成。

虽然本教程是自动网络部署:入门教程的延伸,但它不包含 Deployment Manager 配置,因为资源是被部署到 GCP 之外的提供商。不过,为了使用多个公有云提供商(包括 GCP)来部署资源,本教程将使用 Terraform 配置文件。多云端部署超出了 Deployment Manager 的预期范围。

费用

本教程使用 GCP 和 AWS 的以下可计费组件:

  • Compute Engine 实例和 Amazon Elastic Compute Cloud (Amazon EC2) 实例
  • 多 vCPU 实例,可支持较高的网络吞吐量
  • 永久性磁盘和块存储
  • 网络出站流量
  • VPN 隧道

来自虚拟机实例的传出或出站流量需遵循网络出站吞吐量上限。 本教程使用多个 vCPU 机器类型来为网络出站流量提供空余带宽。

您可以使用价格计算器根据您的预计用量来估算费用。

准备工作

  1. 选择名为 gcp-automated-networks 的 GCP 项目。

    转到“项目”页面

  2. 启动 Cloud Shell 实例。从 Cloud Shell 运行本教程中的所有终端命令。

    打开 Cloud Shell

部署架构

在本教程中,您将构建以下部署环境。

部署环境

本教程将指导您完成以下操作:

  • 在 GCP 和 AWS 中使用用户指定的 CIDR 块构建自定义 VPC 网络
  • 在每个 VPC 网络中部署虚拟机实例
  • 在每个 VPC 网络中创建 VPN 网关,并为两个 IPsec 隧道创建相关资源。

虽然 GCP 使用路由来支持等成本多路径 (ECMP) 路由,但 AWS 支持具有两个隧道(有效隧道和备用隧道)的 VPN 网关,用于实现冗余和可用性。

路由

此教程配置使用 Cloud Router 来演示动态路由。Cloud Router 使用边界网关协议 (BGP) 与 AWS 中的环境交换您的 VPC 网络路由更新。Cloud Router 的动态路由需要分别为每个 IPsec 隧道配置一个单独的 Cloud Router。 或者,您也可以配置静态路由设置。Cloud VPN 互操作指南对这两种配置进行了介绍。

准备 GCP 工作环境

在本部分中,您将执行以下操作:

  • 克隆教程代码。
  • 验证您的 GCP 区域和地区。

克隆教程代码

  1. GitHub 克隆教程代码:

    git clone https://github.com/GoogleCloudPlatform/autonetdeploy-multicloudvpn.git
  2. 转到教程目录:

    cd autonetdeploy-multicloudvpn
    

验证 GCP 区域和地区

本教程中的某些云资源(包括 Compute Engine 实例、VPN 网关和 Cloud Router)需要您明确声明预期的放置区域和/或地区。如需了解详情,请参阅 GCP 的区域和地区

本教程要求每个提供商仅对应一个区域。要优化两个云之间的连接,请选择相邻的区域。下表列出了教程文件 terraform/gcp_variables.tfterraform/aws_variables.tf 中设置的值。

字段名称 GCP 值 AWS 值
Region Name us-west1 US West (us-west-2)
Location The Dalles, Oregon, USA Oregon

准备使用 AWS

在本部分中,您将验证您的 AWS 区域。要详细了解 AWS 地区,请参阅 AWS 地区和可用性区域

  1. 登录 AWS Management Console,然后转到 VPC Dashboard。使用下拉菜单选择俄勒冈地区。

  2. EC2 DashboardVPC Dashboard 部分,查看本教程使用的资源。

准备 Terraform

在本部分中,您将下载 Terraform 可执行文件。

  • 在 Cloud Shell 中,运行以下脚本:

    ./get_terraform.sh
    

    此脚本将下载 Terraform 工具的可执行二进制文件并将其解压缩到 ~/terraform 目录。脚本输出会显示一个用于更新 PATH 的导出命令。 更新 PATH 后,请验证 Terraform 是否能够正常运行:

    terraform --help
    

    生成的输出如下:

    Usage: terraform [--version] [--help] [command] [args]
    ...
    

如果您需要帮助,请参阅下载 Terraform安装 Terraform 主题。

创建 GCP 和 AWS 访问凭据

您已在概览教程中创建了凭据。 但是,您必须在 Terraform 中注册凭据。

  1. 在 Terraform 中注册您的 GCP 凭据:

    ./gcp_set_credentials.sh exists
    

    生成的输出如下:

    Updated gcp_credentials_file_path in ~/autonetdeploy-multicloudvpn/terraform/terraform.tfvars.
    
  2. 在 Terraform 中注册您的 AWS 凭证:

    ./aws_set_credentials.sh exists
    

    生成的输出如下:

    Updated aws_credentials_file_path in ~/autonetdeploy-multicloudvpn/terraform/terraform.tfvars.
    

设置项目

GCP 提供了几种用于指定自动化工具要使用的 GCP 项目的方法。为简单起见,GCP 项目由模板文件中的字符串变量明确标识,而不是从环境中拉取项目 ID。

  1. 设置项目 ID:

    gcloud config set project [YOUR-PROJECT-ID]

    生成的输出如下:

    Updated property [core/project].
    
  2. 使用提供的脚本更新 Terraform 配置文件中的项目值。

    ./gcp_set_project.sh
    

    生成的输出如下:

    Updated gcp_project_id in /home/[USER]/autonetdeploy-gcpawsvpn/terraform/terraform.tfvars.
    
  3. 查看更新后的文件 terraform/terraform.tfvars,验证 project-id 是否已插入。

  4. 运行一次性 terraform init 命令,为此部署安装 Terraform 提供商。

    pushd ./terraform && terraform init && popd > /dev/null
    
  5. 运行 Terraform plan 命令,验证凭据。

    pushd ./terraform && terraform plan && popd > /dev/null
    

    如果您没有看到红色错误文本,则表明您的身份验证可正常运作。

    生成的输出如下:

    Refreshing Terraform state in-memory prior to plan...
    ...
     +google_compute_instance.gcp-vm
    ...
    Plan: 34 to add, 0 to change, 0 to destroy.
    

检查 Terraform 配置文件

在 Terraform 中,部署配置由文件目录定义。虽然这些文件可以是 JSON 文件,但最好使用 Terraform 配置文件.tf 文件)语法,这种语法更易于理解和维护。本教程提供了一个文件集,这个文件集介绍了一种可以清晰地组织资源的方法。此集是功能部署,无需编辑即可运行。

文件名 目的
main.tf 定义提供商,并指定要在此配置中部署的云。此外,还会读取您的凭据、项目名称和所选区域。
gcp_variables.tfaws_variables.tf 声明用于对部署进行参数化和自定义的变量(例如 gcp_regiongcp_instance_type)。
gcp_compute.tfaws_compute.tf 定义部署中使用的计算资源(例如 google_compute_instance)。
vm_userdata.sh 指定在启动虚拟机实例时要运行的脚本。自动设置 iperf3 测试工具和某些封装容器脚本。
gcp_networking.tfaws_networking.tf 定义网络资源,包括 google_compute_networkgoogle_compute_subnetworkgoogle_compute_addressgoogle_compute_vpn_gatewaygoogle_compute_vpn_tunnel
gcp_security.tfaws_security.tf 定义可允许 GCP 或 AWS 环境中的测试流量的资源,包括 google_compute_firewall 规则和 aws_security_group 资源。
gcp_outputs.tfaws_outputs.tf 定义在部署完成时要输出的变量(例如,已部署的虚拟机实例的 external_ipinternal_ip)。
terraform.tfstate [输出]。指定 Terraform 在云中进行检查之后用于存储客户端资源状态的文件。如需了解详情,请参阅使用 Terraform 管理 GCP 项目
run_graph.sh Shell 脚本,用于从 Terraform 生成显示资源依赖项的 PNG 文件。您可以在 images/gcpawsvpn_plan_graph.png 中查看此脚本的输出。

在本教程中,您将使用脚本创建 terraform.tfvars 文件,其中包括特定于用户的 credentialsgcp_project_id 的设置。

部署 VPC 网络、虚拟机实例、VPN 网关和 IPsec 隧道

在多个云之间构建连接非常复杂。您可以在两个环境中并行部署多个资源,但在构建 IPsec 隧道时,需要仔细整理相互依赖项。因此,在代码中创建稳定的部署配置有助于扩展您的部署知识。下图总结了跨多个提供商创建此部署配置所需的步骤。

部署步骤

使用 Terraform 进行部署

Terraform 使用 terraform.tfstate 文件来捕获资源状态。若要以可读形式查看当前资源状态,您可以运行 terraform show

为使 Terraform 能够正确地向您的提供商进行身份验证,您必须先完成概览教程。 以下步骤假定您已配置了 Terraform。

  1. 在 Cloud Shell 中,转到 terraform 目录:

    pushd terraform
    
  2. 使用 Terraform validate 命令验证配置文件的语法。与后续步骤中作为 planapply 命令的一部分执行的验证检查相比,这种验证检查更简单。validate 命令不会向任何提供商进行身份验证。

    terraform validate
    

    如果您没有看到错误消息,则表明您已完成文件语法和基本语义的初始验证。如果您看到了错误消息,则表明验证失败。

  3. 使用 Terraform plan 命令在不实例化云端资源的情况下查看部署。plan 命令要求通过配置中指定的所有提供商成功进行身份验证。

    terraform plan
    

    plan 命令返回要添加、移除或更新的资源的输出列表。plan 输出的最后一行显示要添加、更改或销毁的资源的计数。

    Refreshing Terraform state in-memory prior to plan...
    ...
    Plan: 34 to add, 0 to change, 0 to destroy.
    
  4. (可选)使用 Terraform graph 命令直观呈现资源依赖项。依赖关系图可帮助您分析已部署的资源。您可以在 images/gcpawsvpn_plan_graph.png. 中查看预先准备的输出文件版本。

    run_graph.sh 脚本会创建与以下内容类似的 PNG 文件 ./gcpawsvpn_plan_graph.png

    plan_graph 文件

    run_graph.sh 脚本依赖于 graphviz 软件包。如果未安装 graphviz,则会看到 dot: command not found 消息。在 Cloud Shell 中,您可以使用以下命令安装 graphviz

    sudo apt-get install graphviz
    
  5. 使用 Terraform apply 命令创建部署:

    terraform apply
    

    apply 命令可创建具有云端备份资源的部署。apply 命令大约需要四分钟的时间来为您创建 30 多种资源,包括 GCP 和 AWS VPC 网络虚拟机实例VPN 网关IPsec 隧道apply 命令的输出包括已部署资源的详细信息以及由配置定义的输出变量。

    data.google_compute_zones.available: Refreshing state...
    ...
    Apply complete! Resources: 34 added, 0 changed, 0 destroyed.
    ...
    Outputs:
    
    aws_instance_external_ip = [AWS_EXTERNAL_IP]
    aws_instance_internal_ip = 172.16.0.100
    gcp_instance_external_ip = [GCP_EXTERNAL_IP]
    gcp_instance_internal_ip = 10.240.0.100
    
  6. 如果您需要更新配置的预期结束状态,请修改 .tf 文件。可以将端口 23 添加到 google_compute_firewall gcp_allow-ssh 规则,只需修改 gcp_security.tf 即可:

    ports = ["22", "23"]
    

    Terraform 会分析修改项并确定更新部署状态以进行匹配所需的最小更改。

    terraform apply
    

    Terraform 将 gcp-network-gcp-allow-ssh 修改为更新后的配置。

  7. 您的部署可以发送输出变量,为工作流提供帮助。在本教程中,gcp_outputs.tfaws_outputs.tf 文件已将虚拟机实例的已分配的内部和外部 IP 地址标识为输出变量。apply 步骤完成后,系统会自动打印这些地址。如果您希望在稍后的工作流中重新显示输出变量值,请使用 output 命令:

    terraform output
    

    此配置定义的输出变量包括虚拟机实例的内部和外部 IP 地址。要使用 ssh 命令进行网络验证,您需要使外部 IP 地址连接到虚拟机实例。

    aws_instance_external_ip = [AWS_EXTERNAL_IP]
    aws_instance_internal_ip = 172.16.0.100
    gcp_instance_external_ip = [GCP_EXTERNAL_IP]
    gcp_instance_internal_ip = 10.240.0.100
  8. 使用 Terraform show 命令检查已部署的资源并验证当前状态。

    terraform show
    

    生成的输出如下:

    ...
    google_compute_instance.gcp-vm:
    ...
    Outputs:
    ...
    
  9. 要查看您的实例,请使用 gcloud compute instances list,或使用 Cloud Console 的虚拟机实例面板。

    gcloud compute instances list

    生成的输出如下:

    NAME             ZONE        MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP    EXTERNAL_IP    STATUS
    gcp-vm-us-west1  us-west1-a  n1-highmem-8               10.240.0.100   [EXTERNAL IP]  RUNNING
    
  10. 使用 ssh 命令连接到 GCP 虚拟机实例,验证该实例是否能正常运行:

    ssh -i ~/.ssh/vm-ssh-key [GCP_EXTERNAL_IP]
  11. ssh 会话中运行 pingcurl 命令:

    ping -c 5 google.com
    curl ifconfig.co/ip
    
  12. 从 GCP 虚拟机实例运行简单的网络性能检查。使用预先安装的脚本对每个网络接口(外部和内部)运行测试。

    1. 通过外部 IP:

      /tmp/run_iperf_to_ext.sh
      

      此脚本会运行时长 30 秒的性能测试,该测试可生成有关网络性能的摘要数据。

      生成的输出如下:

      ...
      [SUM]   ... sender
      [SUM]   ... receiver
      ...
      
    2. 通过 VPN(内部 IP):

      /tmp/run_iperf_to_int.sh
      

      此脚本会运行时长 30 秒的性能测试,该测试可生成有关网络性能的摘要数据。

      ...
      [SUM]   ... sender
      [SUM]   ... receiver
      ...
      
  13. 在 GCP 虚拟机实例中完成检查后,输入以下命令:

    exit
    
  14. 要验证您的 AWS 虚拟机实例是否在正常运行,请使用 ssh 命令连接到该实例:

    ssh -i ~/.ssh/vm-ssh-key ubuntu@[AWS_EXTERNAL_IP]
  15. ssh 会话中运行 pingcurl 命令:

    ping -c 5 google.com
    curl ifconfig.co/ip
    
  16. 从 AWS 虚拟机实例运行简单的网络性能检查。使用预先安装的脚本对每个网络接口(外部和内部)运行测试。

    1. 通过外部 IP:

      /tmp/run_iperf_to_ext.sh
      

      此脚本会运行时长 30 秒的性能测试,该测试可生成有关网络性能的摘要数据。

      ...
      [SUM]   ... sender
      [SUM]   ... receiver
      ...
      
    2. 通过 VPN(内部 IP):

      /tmp/run_iperf_to_int.sh
      

      此脚本会运行时长 30 秒的性能测试,该测试可生成有关网络性能的摘要数据。

      ...
      [SUM]   ... sender
      [SUM]   ... receiver
      ...
      
  17. 在 AWS 虚拟机实例中完成检查后,请输入以下命令:

    exit
    

您已使用 VPN 在 GCP 与 AWS 之间成功部署了安全私密的站点到站点连接。

清理

清理已部署的资源。在运行 destroy 部署命令之前,系统将继续向您收取虚拟机实例的费用。

  1. 运行可选的 plan -destroy 命令查看受 destroy 影响的资源:

    terraform plan -destroy
    

    生成的输出如下:

    Refreshing Terraform state in-memory prior to plan...
    ...
    Plan: 0 to add, 0 to change, 34 to destroy.
    
  2. 由于 destroy 命令将永久删除您的资源,因此您必须输入 yes 来确认您的意愿。destroy 命令通常需要 100 秒左右即可完成:

    terraform destroy
    

    生成的输出如下:

    Do you really want to destroy?
      Terraform will delete all your managed infrastructure.
      There is no undo. Only 'yes' will be accepted to confirm.
        Enter a value: yes
    

    输入 yes,确认销毁已创建的资源。

    Destroy complete! Resources: 34 destroyed.
    
  3. 运行 show 命令来显示资源的状态:

    terraform show
    

    由于您销毁了所有资源,因此 show 命令不会输出任何行,这表明目前没有部署任何资源。

  4. 最后,恢复目录:

    popd > /dev/null
    

现在,您已在 GCP 和 AWS 实例之间成功部署了安全私密的站点到站点连接,并完成了清理操作。

后续步骤