[Terraform] Google Cloud - AWS VPN 구축

Jade·2022년 12월 9일
0

본 포스팅은 Cloud skills boost의 Building a VPN Between Google Cloud and AWS with Terraform 실습을 진행하며 정리한 내용입니다. Cloud skills boost LAB 진행은 별도 크레딧이 필요 하며, 개인 콘솔에서 동일 내용 진행 시 과금이 발생할 수 있습니다.

개요

이 실습에서는 HashiCorp의 Terraform을 사용하여 VPN을 사용하여 Google Cloud와 Amazon Web Services(AWS) 간에 안전한 Private site-to-site Connection을 만드는 방법을 보여줍니다. 이것은 멀티 클라우드 배포입니다.

이 실습에서는 가상 머신(VM) 인스턴스를 Google Cloud 및 AWS의 VPC 네트워크에 배포합니다. 그런 다음 지원 인프라를 배포하여 Google Cloud와 AWS VPC 네트워크 간에 2개의 인터넷 프로토콜 보안(IPsec) 터널로 VPN 연결을 구성합니다.

배포 아키텍처

이 실습에서는 다음 배포 환경을 빌드합니다.

목표

이 실습에서는 다음을 수행합니다.

  • Google Cloud 및 AWS에서 사용자 지정 CIDR 블록으로 커스텀 VPC 네트워크 구축
  • 각 VPC 네트워크에 VM 인스턴스 배포
  • 각 VPC 네트워크에 VPN 게이트웨이를 만들고 2개의 IPsec 터널에 대한 관련 리소스를 만듭니다.

Google Cloud는 경로를 사용하여 ECMP 라우팅을 지원하지만 AWS는 중복성과 가용성을 위해 활성 및 대기의 두 터널이 있는 VPN 게이트웨이를 지원합니다.

라우팅

실습 구성은 Cloud Router를 사용하여 동적 라우팅을 시연합니다. Cloud Router는 BGP(Border Gateway Protocol)를 사용하여 VPC 네트워크 경로 업데이트를 AWS 환경과 교환합니다.Cloud Router에 의한 동적 라우팅에는 IPsec 터널마다 별도의 Cloud Router가 필요합니다. 또는 정적 경로로 설정을 구성할 수 있습니다.

작업 1. Google Cloud 작업 환경 준비

이 섹션에서는 가이드 코드를 복제하고 Google Cloud 리전 및 영역을 확인합니다.

  1. Google Cloud Console에서 새 Cloud Shell 창을 열고 가이드 코드를 복사합니다.

    gsutil cp gs://spls/gsp854/autonetdeploy-multicloudvpn2.tar .
    tar -xvf autonetdeploy-multicloudvpn2.tar

  2. 자습서 디렉터리로 이동합니다.

    cd autonetdeploy-multicloudvpn

Google Cloud 리전 및 영역 확인

Compute Engine 인스턴스, VPN 게이트웨이, Cloud Router를 비롯한 이 실습의 특정 클라우드 리소스를 사용하려면 원하는 배치 리전이나 영역 또는 둘 모두를 명시적으로 선언해야 합니다. 자세한 내용은 Google Cloud의 리전 및 영역을 참조하세요.

이 실습에는 각 제공자에 대해 단일 리전만 필요합니다. 두 클라우드 간의 연결을 최적화하려면 서로 가까운 지역을 선택하십시오.

다음 표에는 자습서 파일 terraform/gcp_variables.tf 및 terraform/aws_variables.tf에 설정된 값이 나열되어 있습니다.

작업 2. AWS 사용 준비

  1. AWS Management Console에 로그인합니다(왼쪽의 Open AWS Console 버튼을 클릭하고 제공된 사용자 이름과 암호로 로그인)
  2. EC2 대시보드(서비스 > 컴퓨팅 > EC2)로 이동합니다. 오른쪽 상단의 풀다운 메뉴를 사용하여 북부 버지니아 리전(us-east-1)을 선택합니다. EC2 대시보드 및 VPC 대시보드에서 실습 후반부에 배포된 리소스를 검토할 수 있습니다.

작업 3. 액세스 자격 증명 생성

이 섹션에서는 Google Cloud 및 AWS에 대한 액세스 자격 증명을 생성하고 템플릿이 이러한 액세스 자격 증명을 가리키도록 합니다.

Compute Engine 기본 서비스 계정 사용자 인증 정보 다운로드

Linux 환경인 Cloud Shell에서 gcloud는 ~/.config/gcloud 디렉터리에서 자격 증명 파일을 관리합니다. Compute Engine 기본 서비스 계정 사용자 인증 정보를 설정하려면 다음 단계를 따르세요.

  1. Google Cloud Console의 탐색 메뉴에서 IAM & Admin > Service accounts을 클릭합니다.

  2. Compute Engine default service account을 클릭하고 Acttions 아래에 있는 세로 점 3개를 클릭하고 Manage keys를 선택한 다음 ADD KEY > Create new key를 클릭합니다.

  3. JSON이 키 유형으로 선택되었는지 확인하고 CREATE를 클릭하면 [PROJECT_ID]-[UNIQUE_ID].json 형식의 파일이 로컬 컴퓨터에 다운로드됩니다. 이후 CLOSE를 클릭합니다.

  4. Cloud Shell 터미널에서 아직 autonetdeploy-multicloudvpn 폴더에 있는지 확인합니다.

  5. 다운로드한 JSON 파일을 로컬 컴퓨터에서 Cloud Shell 환경으로 업로드하려면 세로 점 3개를 클릭하고 Upload를 클릭한 다음 다운로드한 파일을 선택하고 업로드를 클릭합니다.

  6. 다운로드한 JSON 파일로 이동하고 열기를 클릭하여 업로드합니다. 파일은 홈(~) 디렉토리에 있습니다.

  7. 제공된 ./gcp_set_credentials.sh 스크립트를 사용하여 ~/.config/gcloud/credentials_autonetdeploy.json 파일을 만듭니다. 이 스크립트는 또한 새 자격 증명에 대한 참조로 terraform/terraform.tfvars를 생성합니다.

    ./gcp_set_credentials.sh ~/[PROJECT_ID]-[UNIQUE_ID].json

AWS 액세스 자격 증명 생성

이 섹션에서는 Terraform과 함께 사용할 Qwiklabs 생성 AWS 액세스 자격 증명을 설정합니다. 여기에 사용된 방법은 랩 제약으로 인해 프로덕션 또는 개인 환경의 방법과 다릅니다.

  1. 다음 명령을 실행하여 자격 증명 디렉터리 및 파일을 만듭니다.

    export username=`whoami`
    mkdir /home/$username/.aws/
    touch /home/$username/.aws/credentials_autonetdeploy

  2. 자격 증명 파일을 편집하려면 다음 명령을 실행합니다. 여기에 Qwiklabs에서 생성한 AWS Access 및 Secret key를 입력합니다.

    vi /home/$username/.aws/credentials_autonetdeploy

  3. 첫 번째 줄에 다음을 붙여넣습니다.

    [default]
  4. 다음 줄에 다음 코드를 추가합니다. Qwiklabs 연결 세부 정보 패널에서 [Your AWS Access Key]를 AWS Access Key로 교체합니다.

    aws_access_key_id=<Your AWS Access Key>
  5. 다음 줄에 다음 코드를 추가합니다. Qwiklabs 연결 세부 정보 패널에서 [Your AWS Secret Key]를 AWS Secret Key로 바꿉니다.

    aws_secret_access_key=<Your AWS Secret Key>

  6. 에디터를 저장하고 빠져나갑니다.

    :wq!
  7. 다음을 실행하여 보안 자격 증명 파일을 검사합니다.

    cat /home/$username/.aws/credentials_autonetdeploy

    파일 내용은 다음과 유사해야 합니다.

    [default]
    aws_access_key_id=AKIA3INBXVI72ZO2Z4F4
    aws_secret_access_key=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
  8. 파일 형식이 올바르게 지정되면 다음 명령을 사용하여 Terraform 환경 변수를 올바른 AWS 자격 증명 파일 경로로 설정합니다.

    export TF_VAR_aws_credentials_file_path=/home/$username/.aws/credentials_autonetdeploy


    참고: 이를 수행하는 다른 방법은 AWS 자격 증명 파일 경로를 참조하도록 terraform/terraform.tfvars 파일을 업데이트하는 것입니다.

작업 4. 프로젝트 설정

이 섹션에서는 프로젝트에서 배포 템플릿을 가리킵니다. Google Cloud는 자동화 도구에서 사용할 Google Cloud 프로젝트를 지정하는 여러 가지 방법을 제공합니다. 단순화를 위해 환경에서 프로젝트 ID를 가져오는 대신 Google Cloud 프로젝트가 템플릿 파일의 문자열 변수로 명시적으로 식별됩니다.

  1. 다음 명령어를 사용하여 Google Cloud 프로젝트 ID를 설정합니다.

    export PROJECT_ID=$(gcloud config get-value project)
    gcloud config set project $PROJECT_ID

  2. 제공된 스크립트를 사용하여 Terraform에 대한 구성 파일의 프로젝트 값을 업데이트합니다.

    ./gcp_set_project.sh

  3. 업데이트된 파일을 검토하여 project-id 값이 terraform/terraform.tfvars에 삽입되었는지 확인하십시오. cat 명령 또는 Cloud Shell 편집기를 사용하여 파일을 확인할 수 있습니다.

  4. terraform init 명령을 실행하여 이 배포에 대한 Terraform provider를 설치합니다.

    cd terraform
    terraform init

  5. Terraform plan 명령을 실행하여 자격 증명을 확인합니다.

    terraform plan

    출력 내용은 아래와 유사해야 합니다.

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

작업 5. SSH 키를 사용하여 VM 인스턴스에 연결

Google Cloud에서는 Cloud Console과 gcloud 도구가 백그라운드에서 작동하여 SSH 키를 관리합니다.

  • 키 파일을 생성하거나 업로드하지 않고 ssh 명령을 사용하여 Compute Engine 인스턴스와 통신합니다.

그러나 멀티 클라우드의 경우 Amazon Elastic Compute Cloud(EC2)의 VM 인스턴스와 연결하기 위해 퍼블릭/프라이빗 키 쌍이 필요합니다.

키 쌍 생성

  1. Cloud Shell에서 ssh-keygen을 사용하여 새 키 쌍을 생성합니다.

    ssh-keygen -t rsa -f ~/.ssh/vm-ssh-key -C $username

    암호를 묻는 메시지가 표시되면 Enter를 두 번 눌러 비워 둡니다.

  2. private key에 대한 액세스를 제한하십시오. 이것은 모범 사례입니다.

    chmod 400 ~/.ssh/vm-ssh-key

Public key를 Google Cloud로 가져오기

이 섹션에서는 키를 가져오고 등록합니다.

  1. Cloud Shell에서 Google Cloud에 공개 키를 등록합니다.

    gcloud compute config-ssh --ssh-key-file=~/.ssh/vm-ssh-key

    참고: No host aliases were added...라는 경고는 무시해도 됩니다. 명령어가 Compute Engine VM 인스턴스 업데이트를 시도하지만 아직 생성된 인스턴스가 없기 때문입니다.

  2. Cloud Console에서 Compute Engine > Metadata 페이지로 이동합니다.

  3. SSH 키를 클릭합니다. SSH 키가 있는지 확인하십시오.

  4. 키 섹션에서 SSH 키 값을 복사합니다. 다음 섹션에서 이를 사용합니다.

퍼블릭 키를 AWS로 가져오기

Google Cloud로 생성된 퍼블릭 키 파일을 재사용할 수 있습니다.

  1. AWS Management Console에서 EC2 페이지로 이동합니다.
    참고: 현재 미국 동부(버지니아 북부) us-east-1 지역에 있는지 확인합니다.

  2. EC2 Dashboard의 왼쪽에 있는 Network & Security 그룹에서 Key Pairs를 클릭합니다.

  3. Actions(작업) > Import Key Pair(키 페어 가져오기)를 클릭합니다.

  4. 이름에 vm-ssh-key를 입력합니다.

  5. Google Cloud 퍼블릭 키의 콘텐츠(Compute Engine > 메타데이터 > SSH 키)를 Public key contents box에 붙여넣습니다.

  6. 키 내용이 이전에 복사한 내용과 동일한지 확인합니다

  7. 키 페어 가져오기를 클릭합니다.

이제 vm-ssh-key 값에 대한 AWS 항목을 볼 수 있습니다. 액세스를 위해 ssh 명령을 사용할 수 있도록 하는 구성 설정에서 이 키를 참조할 수 있습니다.

ssh 명령을 사용하여 AWS 인스턴스에 연결할 때 AWS는 Google Cloud와 다르게 동작합니다. AWS의 경우 AMI 공급자가 지원하는 일반 사용자 이름을 제공해야 합니다. 이 자습서에서 AMI 공급자는 ubuntu를 사용자로 예상합니다.

이제 자동화된 도구를 사용하여 리소스를 클라우드에 쉽게 배포할 수 있는 환경이 있습니다. 이 환경을 사용하여 실습의 나머지 부분을 완료하십시오.

작업 6. Terraform 구성 파일 검사

Terraform에서 배포 구성은 파일 디렉터리로 정의됩니다. 이러한 파일은 JSON 파일일 수 있지만 읽기 및 유지 관리가 더 쉬운 Terraform 구성 파일(.tf 파일) 구문을 사용하는 것이 좋습니다. 이 실습에서는 리소스를 깔끔하게 구성하는 한 가지 방법을 설명하는 파일 세트를 제공합니다. (아래 내용은 코드 내용 참고차 업로드 한 내용이며, 별도로 편집할 필요는 없습니다.)

  • main.tf: 공급자를 정의하고 이 구성에서 배포할 클라우드를 지정합니다. 또한 자격 증명, 프로젝트 이름 및 선택한 지역을 읽습니다.

    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat main.tf /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform main configuration file (with provider definitions).
     */
    
    provider "google" {
      version = "4.18.0"
    
      credentials = file(var.gcp_credentials_file_path)
    
      # Should be able to parse project from credentials file but cannot.
      # Cannot convert string to map and cannot interpolate within variables.
      project = var.gcp_project_id
    
      region = var.gcp_region
    }
    
    provider "aws" {
      version = "4.10.0"
    
      shared_credentials_file = pathexpand(var.aws_credentials_file_path)
    
      region = var.aws_region
    }
  • gcp_variables.tf, aws_variables.tf: 배포를 매개변수화하고 맞춤설정하는 데 사용되는 변수(예: gcp_region 및 gcp_instance_type)를 선언합니다.

    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat gcp_variables.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform variable declarations for GCP.
     */
    
    variable "gcp_credentials_file_path" {
      description = "Locate the GCP credentials .json file."
      type        = string
    }
    
    variable "gcp_project_id" {
      description = "GCP Project ID."
      type        = string
    }
    
    variable "gcp_region" {
      description = "Default to Oregon region."
      default     = "us-central1"
    }
    
    variable "gcp_instance_type" {
      description = "Machine Type. Correlates to an network egress cap."
      default     = "n1-standard-1"
    }
    
    variable "gcp_disk_image" {
      description = "Boot disk for gcp_instance_type."
      default     = "projects/ubuntu-os-cloud/global/images/family/ubuntu-1804-lts"
    }
    
    variable "gcp_network_cidr" {
      default = "10.240.0.0/16"
    }
    
    variable "gcp_subnet1_cidr" {
      default = "10.240.0.0/24"
    }
    
    variable "gcp_vm_address" {
      description = "Private IP address for GCP VM instance."
      default     = "10.240.0.100"
    }
    
    variable "GCP_TUN1_VPN_GW_ASN" {
      description = "Tunnel 1 - Virtual Private Gateway ASN, from the AWS VPN Customer Gateway Configuration"
      default     = "64512"
    }
    
    variable "GCP_TUN1_CUSTOMER_GW_INSIDE_NETWORK_CIDR" {
      description = "Tunnel 1 - Customer Gateway from Inside IP Address CIDR block, from AWS VPN Customer Gateway Configuration"
      default     = "30"
    }
    
    variable "GCP_TUN2_VPN_GW_ASN" {
      description = "Tunnel 2 - Virtual Private Gateway ASN, from the AWS VPN Customer Gateway Configuration"
      default     = "64512"
    }
    
    variable "GCP_TUN2_CUSTOMER_GW_INSIDE_NETWORK_CIDR" {
      description = "Tunnel 2 - Customer Gateway from Inside IP Address CIDR block, from AWS VPN Customer Gateway Configuration"
      default     = "30"
    }
    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat aws_variables.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform variable declarations for AWS.
     */
    
    variable "aws_credentials_file_path" {
      description = "Locate the AWS credentials file."
      type        = string
    }
    
    variable "aws_region" {
      description = "Default to Oregon region."
      default     = "us-east-1"
    }
    
    variable "aws_instance_type" {
      description = "Machine Type. Includes 'Enhanced Networking' via ENA."
      default     = "t2.micro"
    }
    
    variable "aws_disk_image" {
      description = "Boot disk for gcp_instance_type."
      default     = "ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*"
    }
    
    variable "aws_network_cidr" {
      description = "VPC network ip block."
      default     = "172.16.0.0/16"
    }
    
    variable "aws_subnet1_cidr" {
      description = "Subset block from VPC network ip block."
      default     = "172.16.0.0/24"
    }
    
    variable "aws_vm_address" {
      description = "Private IP address for AWS VM instance."
      default     = "172.16.0.100"
    }
  • gcp_compute.tf, aws_compute.tf: 배포에 사용되는 컴퓨팅 리소스(예: google_compute_instance)를 정의합니다.

    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat gcp_compute.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform compute resources for GCP.
     * Acquire all zones and choose one randomly.
     */
    
    data "google_compute_zones" "available" {
      region = var.gcp_region
    }
    
    resource "google_compute_address" "gcp-ip" {
      name   = "gcp-vm-ip-${var.gcp_region}"
      region = var.gcp_region
    }
    
    resource "google_compute_instance" "gcp-vm" {
      name         = "gcp-vm-${var.gcp_region}"
      machine_type = var.gcp_instance_type
      zone         = data.google_compute_zones.available.names[0]
    
      boot_disk {
        initialize_params {
          image = var.gcp_disk_image
        }
      }
    
      network_interface {
        subnetwork = google_compute_subnetwork.gcp-subnet1.name
        network_ip = var.gcp_vm_address
    
        access_config {
          # Static IP
          nat_ip = google_compute_address.gcp-ip.address
        }
      }
    
      # Cannot pre-load both gcp and aws since that creates a circular dependency.
      # Can pre-populate the AWS IPs to make it easier to run tests.
      metadata_startup_script = replace(
        replace(file("vm_userdata.sh"), "<EXT_IP>", aws_eip.aws-ip.public_ip),
        "<INT_IP>",
        var.aws_vm_address,
      )
    }
    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat aws_compute.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform compute resources for AWS.
     */
    
    data "aws_ami" "ubuntu" {
      most_recent = true
    
      filter {
        name   = "name"
        values = [var.aws_disk_image]
      }
    
      filter {
        name   = "virtualization-type"
        values = ["hvm"]
      }
    
      owners = ["099720109477"] # Canonical
    }
    
    resource "aws_eip" "aws-ip" {
      vpc = true
    
      instance                  = aws_instance.aws-vm.id
      associate_with_private_ip = var.aws_vm_address
    }
    
    resource "aws_instance" "aws-vm" {
      ami           = data.aws_ami.ubuntu.id
      instance_type = var.aws_instance_type
      subnet_id     = aws_subnet.aws-subnet1.id
      key_name      = "vm-ssh-key"
    
      associate_public_ip_address = true
      private_ip                  = var.aws_vm_address
    
      vpc_security_group_ids = [
        aws_security_group.aws-allow-icmp.id,
        aws_security_group.aws-allow-ssh.id,
        aws_security_group.aws-allow-vpn.id,
        aws_security_group.aws-allow-internet.id,
      ]
    
      user_data = replace(
        replace(
          file("vm_userdata.sh"),
          "<EXT_IP>",
          google_compute_address.gcp-ip.address,
        ),
        "<INT_IP>",
        var.gcp_vm_address,
      )
    
      tags = {
        Name = "aws-vm-${var.aws_region}"
      }
    }
  • vm_userdata.sh: VM 인스턴스를 시작할 때 실행할 스크립트를 지정합니다. iperf3 테스트 도구와 일부 래퍼 스크립트를 자동으로 설정합니다.

    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat vm_userdata.sh
    #!/bin/bash -xe
    
    # Copyright 2017 Google Inc.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #   http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    # Make it easy to run iperf3.
    echo "iperf3 -c <EXT_IP> -p 80 -i 1 -t 30 -P 8 -V" > /tmp/run_iperf_to_ext.sh
    chmod 755 /tmp/run_iperf_to_ext.sh
    echo "iperf3 -c <INT_IP> -p 80 -i 1 -t 30 -P 8 -V" > /tmp/run_iperf_to_int.sh
    chmod 755 /tmp/run_iperf_to_int.sh
    
    # Setup iperf3.
    apt-get update
    apt-get install -y iperf3
    
    cat > /etc/systemd/system/iperf3.service <<EOF
    [Unit]
    Description=iPerf 3 Server
    [Service]
    Restart=always
    TimeoutStartSec=0
    RestartSec=3
    WorkingDirectory=/tmp
    ExecStart=/usr/bin/iperf3 -s -p 80
    [Install]
    WantedBy=multi-user.target
    EOF
    
    systemctl daemon-reload
    systemctl enable iperf3
    systemctl start iperf3
  • gcp_networking.tf, aws_networking.tf: google_compute_network, google_compute_subnetwork, google_compute_address, google_compute_vpn_gateway 및 google_compute_vpn_tunnel을 비롯한 네트워킹 리소스를 정의합니다.

    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat gcp_networking.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform networking resources for GCP.
     * Updated by Sureskills/Kogneos 21/04/2022
     */
    
    resource "google_compute_network" "gcp-network" {
      name                    = "gcp-network"
      auto_create_subnetworks = "false"
    }
    
    resource "google_compute_subnetwork" "gcp-subnet1" {
      name          = "gcp-subnet1"
      ip_cidr_range = var.gcp_subnet1_cidr
      network       = google_compute_network.gcp-network.name
      region        = var.gcp_region
    }
    
    /*
     * ----------VPN Connection----------
     */
    
    resource "google_compute_ha_vpn_gateway" "gcp-vpn-gw" {
      name    = "gcp-vpn-gw-${var.gcp_region}"
      network = google_compute_network.gcp-network.name
      region  = var.gcp_region
    }
    
    resource "google_compute_external_vpn_gateway" "external_gateway" {
      name            = "aws-gateway"
      redundancy_type = "FOUR_IPS_REDUNDANCY"
      description     = "Dual AWS VPN gateways"
      interface {
        id         = 0
        ip_address = aws_vpn_connection.aws-vpn-connection1.tunnel1_address
      }
      interface {
        id         = 1
        ip_address = aws_vpn_connection.aws-vpn-connection1.tunnel2_address
      }
      interface {
        id         = 2
        ip_address = aws_vpn_connection.aws-vpn-connection2.tunnel1_address
      }
      interface {
        id         = 3
        ip_address = aws_vpn_connection.aws-vpn-connection2.tunnel2_address
      }
    }
    
     /* ----------VPN Tunnel1----------
     */
    resource "google_compute_vpn_tunnel" "gcp-tunnel1" {
      name                            = "gcp-tunnel1"
      peer_external_gateway           = google_compute_external_vpn_gateway.external_gateway.id
      peer_external_gateway_interface = 0
      shared_secret                   = aws_vpn_connection.aws-vpn-connection1.tunnel1_preshared_key
      ike_version                     = 2
      vpn_gateway                     = google_compute_ha_vpn_gateway.gcp-vpn-gw.self_link
      router                          = google_compute_router.gcp-router1.name
      vpn_gateway_interface           = 0
    }
    
    resource "google_compute_router" "gcp-router1" {
      name    = "gcp-router1"
      region  = var.gcp_region
      network = google_compute_network.gcp-network.name
      bgp {
        asn = aws_customer_gateway.aws-cgw-1.bgp_asn
        advertise_mode    = "CUSTOM"
        advertised_groups = ["ALL_SUBNETS"]
      }
    }
    
    resource "google_compute_router_peer" "gcp-router1-peer" {
      name            = "gcp-to-aws-bgp1"
      router          = google_compute_router.gcp-router1.name
      region          = google_compute_router.gcp-router1.region
      peer_ip_address = aws_vpn_connection.aws-vpn-connection1.tunnel1_vgw_inside_address
      peer_asn        = var.GCP_TUN1_VPN_GW_ASN
      interface       = google_compute_router_interface.router_interface1.name
    }
    
    resource "google_compute_router_interface" "router_interface1" {
      name       = "gcp-to-aws-interface1"
      router     = google_compute_router.gcp-router1.name
      region     = google_compute_router.gcp-router1.region
      ip_range   = "${aws_vpn_connection.aws-vpn-connection1.tunnel1_cgw_inside_address}/${var.GCP_TUN1_CUSTOMER_GW_INSIDE_NETWORK_CIDR}"
      vpn_tunnel = google_compute_vpn_tunnel.gcp-tunnel1.name
    }
    
     /* ----------VPN Tunnel2----------
     */
    resource "google_compute_vpn_tunnel" "gcp-tunnel2" {
      name                            = "gcp-tunnel2"
      peer_external_gateway           = google_compute_external_vpn_gateway.external_gateway.id
      peer_external_gateway_interface = 1
      shared_secret                   = aws_vpn_connection.aws-vpn-connection1.tunnel2_preshared_key
      ike_version                     = 2
      vpn_gateway                     = google_compute_ha_vpn_gateway.gcp-vpn-gw.self_link
      router                          = google_compute_router.gcp-router2.name
      vpn_gateway_interface           = 0
    }
    
    resource "google_compute_router" "gcp-router2" {
      name    = "gcp-router2"
      region  = var.gcp_region
      network = google_compute_network.gcp-network.name
      bgp {
        asn = aws_customer_gateway.aws-cgw-1.bgp_asn
        advertise_mode    = "CUSTOM"
        advertised_groups = ["ALL_SUBNETS"]
      }
    }
    
    resource "google_compute_router_peer" "gcp-router2-peer" {
      name            = "gcp-to-aws-bgp2"
      router          = google_compute_router.gcp-router2.name
      region          = google_compute_router.gcp-router2.region
      peer_ip_address = aws_vpn_connection.aws-vpn-connection1.tunnel2_vgw_inside_address
      peer_asn        = var.GCP_TUN2_VPN_GW_ASN
      interface       = google_compute_router_interface.router_interface2.name
    }
    
    resource "google_compute_router_interface" "router_interface2" {
      name       = "gcp-to-aws-interface2"
      router     = google_compute_router.gcp-router2.name
      region     = google_compute_router.gcp-router2.region
      ip_range   = "${aws_vpn_connection.aws-vpn-connection1.tunnel2_cgw_inside_address}/${var.GCP_TUN2_CUSTOMER_GW_INSIDE_NETWORK_CIDR}"
      vpn_tunnel = google_compute_vpn_tunnel.gcp-tunnel2.name
    }
    
     /* ----------VPN Tunnel3----------
     */
    resource "google_compute_vpn_tunnel" "gcp-tunnel3" {
      name                            = "gcp-tunnel3"
      peer_external_gateway           = google_compute_external_vpn_gateway.external_gateway.id
      peer_external_gateway_interface = 2
      shared_secret                   = aws_vpn_connection.aws-vpn-connection2.tunnel1_preshared_key
      ike_version                     = 2
      vpn_gateway                     = google_compute_ha_vpn_gateway.gcp-vpn-gw.self_link
      router                          = google_compute_router.gcp-router3.name
      vpn_gateway_interface           = 1
    }
    
    resource "google_compute_router" "gcp-router3" {
      name    = "gcp-router3"
      region  = var.gcp_region
      network = google_compute_network.gcp-network.name
      bgp {
        asn = aws_customer_gateway.aws-cgw-2.bgp_asn
        advertise_mode    = "CUSTOM"
        advertised_groups = ["ALL_SUBNETS"]
      }
    }
    
    resource "google_compute_router_peer" "gcp-router3-peer" {
      name            = "gcp-to-aws-bgp3"
      router          = google_compute_router.gcp-router3.name
      region          = google_compute_router.gcp-router3.region
      peer_ip_address = aws_vpn_connection.aws-vpn-connection2.tunnel1_vgw_inside_address
      peer_asn        = var.GCP_TUN1_VPN_GW_ASN
      interface       = google_compute_router_interface.router_interface3.name
    }
    
    resource "google_compute_router_interface" "router_interface3" {
      name       = "gcp-to-aws-interface3"
      router     = google_compute_router.gcp-router3.name
      region     = google_compute_router.gcp-router3.region
      ip_range   = "${aws_vpn_connection.aws-vpn-connection2.tunnel1_cgw_inside_address}/${var.GCP_TUN1_CUSTOMER_GW_INSIDE_NETWORK_CIDR}"
      vpn_tunnel = google_compute_vpn_tunnel.gcp-tunnel3.name
    }
    
    /* ----------VPN Tunnel4----------
     */
    resource "google_compute_vpn_tunnel" "gcp-tunnel4" {
      name                            = "gcp-tunnel4"
      peer_external_gateway           = google_compute_external_vpn_gateway.external_gateway.id
      peer_external_gateway_interface = 3
      shared_secret                   = aws_vpn_connection.aws-vpn-connection2.tunnel2_preshared_key
      ike_version                     = 2
      vpn_gateway                     = google_compute_ha_vpn_gateway.gcp-vpn-gw.self_link
      router                          = google_compute_router.gcp-router4.name
      vpn_gateway_interface           = 1
    }
    
    resource "google_compute_router" "gcp-router4" {
      name    = "gcp-router4"
      region  = var.gcp_region
      network = google_compute_network.gcp-network.name
      bgp {
        asn = aws_customer_gateway.aws-cgw-2.bgp_asn
        advertise_mode    = "CUSTOM"
        advertised_groups = ["ALL_SUBNETS"]
      }
    }
    
    resource "google_compute_router_peer" "gcp-router4-peer" {
      name            = "gcp-to-aws-bgp4"
      router          = google_compute_router.gcp-router4.name
      region          = google_compute_router.gcp-router4.region
      peer_ip_address = aws_vpn_connection.aws-vpn-connection2.tunnel2_vgw_inside_address
      peer_asn        = var.GCP_TUN2_VPN_GW_ASN
      interface       = google_compute_router_interface.router_interface4.name
    }
    
    resource "google_compute_router_interface" "router_interface4" {
      name       = "gcp-to-aws-interface4"
      router     = google_compute_router.gcp-router4.name
      region     = google_compute_router.gcp-router4.region
      ip_range   = "${aws_vpn_connection.aws-vpn-connection2.tunnel2_cgw_inside_address}/${var.GCP_TUN2_CUSTOMER_GW_INSIDE_NETWORK_CIDR}"
      vpn_tunnel = google_compute_vpn_tunnel.gcp-tunnel4.name
    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat aws_networking.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform networking resources for AWS.
     */
    
    resource "aws_vpc" "aws-vpc" {
      cidr_block           = var.aws_network_cidr
      enable_dns_support   = true
      enable_dns_hostnames = true
      tags = {
        "Name" = "aws-vpc"
      }
    }
    
    resource "aws_subnet" "aws-subnet1" {
      vpc_id     = aws_vpc.aws-vpc.id
      cidr_block = var.aws_subnet1_cidr
    
      tags = {
        Name = "aws-vpn-subnet"
      }
    }
    
    resource "aws_internet_gateway" "aws-vpc-igw" {
      vpc_id = aws_vpc.aws-vpc.id
    
      tags = {
        Name = "aws-vpc-igw"
      }
    }
    
    /*
     * ----------VPN Connection----------
     */
    
    resource "aws_vpn_gateway" "aws-vpn-gw" {
      vpc_id = aws_vpc.aws-vpc.id
    }
    
    resource "aws_customer_gateway" "aws-cgw-1" {
      bgp_asn    = 65000
      ip_address = google_compute_ha_vpn_gateway.gcp-vpn-gw.vpn_interfaces[0].ip_address
      type       = "ipsec.1"
      tags = {
        "Name" = "aws-customer-gw"
      }
    }
    resource "aws_customer_gateway" "aws-cgw-2" {
      bgp_asn    = 65000
      ip_address = google_compute_ha_vpn_gateway.gcp-vpn-gw.vpn_interfaces[1].ip_address
      type       = "ipsec.1"
      tags = {
        "Name" = "aws-customer-gw"
      }
    }
    
    resource "aws_default_route_table" "aws-vpc" {
      default_route_table_id = aws_vpc.aws-vpc.default_route_table_id
      route {
        cidr_block = "0.0.0.0/0"
        gateway_id = aws_internet_gateway.aws-vpc-igw.id
      }
      propagating_vgws = [
        aws_vpn_gateway.aws-vpn-gw.id,
      ]
    }
    
    resource "aws_vpn_connection" "aws-vpn-connection1" {
      vpn_gateway_id      = aws_vpn_gateway.aws-vpn-gw.id
      customer_gateway_id = aws_customer_gateway.aws-cgw-1.id
      type                = "ipsec.1"
      static_routes_only  = false
      tags = {
        "Name" = "aws-vpn-connection1"
      }
    }
    
    resource "aws_vpn_connection" "aws-vpn-connection2" {
      vpn_gateway_id      = aws_vpn_gateway.aws-vpn-gw.id
      customer_gateway_id = aws_customer_gateway.aws-cgw-2.id
      type                = "ipsec.1"
      static_routes_only  = false
      tags = {
        "Name" = "aws-vpn-connection2"
      }
    }
  • gcp_security.tf, aws_security.tf: google_compute_firewall 규칙 및 aws_security_group 리소스를 포함하여 GCP 또는 AWS 환경에서 테스트 트래픽을 허용하기 위한 리소스를 정의합니다.

    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat gcp_security.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform security (firewall) resources for GCP.
     */
    
    # Allow PING testing.
    resource "google_compute_firewall" "gcp-allow-icmp" {
      name    = "${google_compute_network.gcp-network.name}-gcp-allow-icmp"
      network = google_compute_network.gcp-network.name
    
      allow {
        protocol = "icmp"
      }
    
      source_ranges = [
        "0.0.0.0/0",
      ]
    }
    
    # Allow SSH for iperf testing.
    resource "google_compute_firewall" "gcp-allow-ssh" {
      name    = "${google_compute_network.gcp-network.name}-gcp-allow-ssh"
      network = google_compute_network.gcp-network.name
    
      allow {
        protocol = "tcp"
        ports    = ["22"]
      }
    
      source_ranges = [
        "0.0.0.0/0",
      ]
    }
    
    # Allow traffic from the VPN subnets.
    resource "google_compute_firewall" "gcp-allow-vpn" {
      name    = "${google_compute_network.gcp-network.name}-gcp-allow-vpn"
      network = google_compute_network.gcp-network.name
    
      allow {
        protocol = "tcp"
        ports    = ["0-65535"]
      }
    
      allow {
        protocol = "udp"
        ports    = ["0-65535"]
      }
    
      source_ranges = [
        var.aws_subnet1_cidr,
      ]
    }
    
    # Allow TCP traffic from the Internet.
    resource "google_compute_firewall" "gcp-allow-internet" {
      name    = "${google_compute_network.gcp-network.name}-gcp-allow-internet"
      network = google_compute_network.gcp-network.name
    
      allow {
        protocol = "tcp"
        ports    = ["80"]
      }
    
      source_ranges = [
        "0.0.0.0/0",
      ]
    }
    
    resource "google_compute_firewall" "https" {
      name    = "gcp-network-https"
      network = google_compute_network.gcp-network.name
      allow {
        protocol = "tcp"
        ports    = ["443"]
      }
      direction = "INGRESS"
      source_ranges = ["0.0.0.0/0"]
    }
    
    resource "google_compute_firewall" "gcp-allow-all" {
      name    = "gcp-network-allow-all"
      network = google_compute_network.gcp-network.name
      allow {
        protocol = "all"
      }
      direction = "INGRESS"
      source_ranges = ["0.0.0.0/0"]
    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat aws_security.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform security (firewall) resources for AWS.
     */
    
    # Allow PING testing.
    resource "aws_security_group" "aws-allow-icmp" {
      name        = "aws-allow-icmp"
      description = "Allow icmp access from anywhere"
      vpc_id      = aws_vpc.aws-vpc.id
    
      ingress {
        from_port   = 8
        to_port     = 0
        protocol    = "icmp"
        cidr_blocks = ["0.0.0.0/0"]
      }
    }
    
    # Allow SSH for iperf testing.
    resource "aws_security_group" "aws-allow-ssh" {
      name        = "aws-allow-ssh"
      description = "Allow ssh access from anywhere"
      vpc_id      = aws_vpc.aws-vpc.id
    
      ingress {
        from_port   = 22
        to_port     = 22
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
    }
    
    # Allow traffic from the VPN subnets.
    resource "aws_security_group" "aws-allow-vpn" {
      name        = "aws-allow-vpn"
      description = "Allow all traffic from vpn resources"
      vpc_id      = aws_vpc.aws-vpc.id
    
      ingress {
        from_port   = 0
        to_port     = 0
        protocol    = "-1"
        cidr_blocks = [var.gcp_subnet1_cidr]
      }
    }
    
    # Allow TCP traffic from the Internet.
    resource "aws_security_group" "aws-allow-internet" {
      name        = "aws-allow-internet"
      description = "Allow http traffic from the internet"
      vpc_id      = aws_vpc.aws-vpc.id
    
      ingress {
        from_port   = 80
        to_port     = 80
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
    
      egress {
        from_port   = 0
        to_port     = 0
        protocol    = "-1"
        cidr_blocks = ["0.0.0.0/0"]
      }
    }
    
    resource "aws_default_security_group" "default" {
      vpc_id = aws_vpc.aws-vpc.id
    
      ingress {
        protocol  = -1
        self      = true
        from_port = 0
        to_port   = 0
            cidr_blocks = ["0.0.0.0/0"]
      }
    
      egress {
        from_port   = 0
        to_port     = 0
        protocol    = "-1"
        cidr_blocks = ["0.0.0.0/0"]
      }
  • gcp_outputs.tf, aws_outputs.tf: 배포 완료 시 출력할 변수를 정의합니다(예: 배포된 VM 인스턴스의 external_ip 및 internal_ip).

    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat gcp_outputs.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform output variables for GCP.
     */
    
    output "gcp_instance_external_ip" {
      value = <<-EOF
      ${google_compute_instance.gcp-vm.network_interface[0].access_config[0].nat_ip}
    EOF
    
    }
    
    output "gcp_instance_internal_ip" {
      value = google_compute_instance.gcp-vm.network_interface[0].network_ip
    }
    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat aws_outputs.tf
    /*
     * Copyright 2017 Google Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */
    
    /*
     * Terraform output variables for AWS.
     */
    
    output "aws_instance_external_ip" {
      value = aws_eip.aws-ip.public_ip
    }
    
    output "aws_instance_internal_ip" {
      value = aws_instance.aws-vm.private_ip
    }
  • terraform.tfstate: terraform이 인프라를 형상화한 결과를 저장하는 파일입니다.

  • run_graph.sh: 리소스 종속성을 보여주는 Terraform에서 PNG 파일을 생성하기 위한 셸 스크립트입니다. images/gcpawsvpn_plan_graph.png에서 이 스크립트의 출력을 볼 수 있습니다.

    student_00_119992008864@cloudshell:~/autonetdeploy-multicloudvpn/terraform (qwiklabs-gcp-04-33db51b2c919)$ cat run_graph.sh
    #!/bin/bash
    
    # Copyright 2017 Google Inc.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #   http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    # Run Terraform graph command with some color-formatting and emit a png.
    # terraform graph -type plan | dot -Tpng > graph.png
    #
    # Useful graphviz links:
    # graphviz docs: http://www.graphviz.org/doc/info/attrs.html
    # graphviz colors: http://www.graphviz.org/doc/info/colors.html
    # webgraphviz viewer: http://www.webgraphviz.com
    
    function runGraph() {
      local THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
      local T_CMD="terraform graph -type plan"
      local D_CMD='dot -Tpng'
      local SED_EX1='s/\[root\] //g'
      local SED_EX2='/.*aws.*shape = "box"/ s/shape = "box"/shape = "box", style = "filled", fillcolor = "coral"/'
      local SED_EX3='/.*google.*shape = "box"/ s/shape = "box"/shape = "box", style = "filled", fillcolor = "deepskyblue"/'
      local SED_EX4='s/shape = "diamond"/shape = "diamond", style = "filled", fillcolor = "aquamarine"/'
      local OUT_FILE="${THIS_DIR}/gcpawsvpn_plan_graph.png"
    
      if [ -e ${OUT_FILE} ]; then
        echo "${OUT_FILE} already exists. Exiting."
        exit 1
      fi
    
      ${T_CMD} | sed -e "${SED_EX1}" -e "${SED_EX2}" -e "${SED_EX3}" \
                 -e "${SED_EX4}" | ${D_CMD} > ${OUT_FILE}
      echo "Wrote ${OUT_FILE}."
    }
    
    runGraph

작업 7. VPC 네트워크, VM 인스턴스, VPN 게이트웨이 및 IPsec 터널 배포

여러 클라우드 간에 연결을 구축하는 것은 복잡합니다. 두 환경 모두에서 많은 리소스를 병렬로 배포할 수 있지만 IPsec 터널을 구축할 때는 상호 종속성을 신중하게 고려해야 합니다. 이러한 이유로 코드에서 안정적인 배포 구성을 설정하는 것은 배포 지식을 확장하는 데 유용한 방법입니다. 다음 그림은 여러 공급자에 걸쳐 이 배포 구성을 만드는 데 필요한 단계를 요약한 것입니다.

작업 8. Terraform으로 배포

Terraform은 terraform.tfstate 파일을 사용하여 리소스 상태를 알 수 있습니다. 현재 리소스 상태를 읽을 수 있는 형식으로 보려면 terraform show를 실행할 수 있습니다.

  1. Cloud Shell에서 terraform 디렉터리로 이동합니다.

    cd ~/autonetdeploy-multicloudvpn/terraform

  2. Terraform validation 명령을 사용하여 구성 파일의 구문을 검증하십시오. 이 유효성 검사는 후속 단계에서 계획 및 적용 명령의 일부로 수행되는 것보다 간단합니다. 유효성 검사 명령은 공급자를 인증하지 않습니다.

    terraform validate

오류 메시지가 표시되지 않으면 파일 구문 및 기본 의미 체계의 초기 유효성 검사를 완료한 것입니다. 오류 메시지가 표시되면 유효성 검사가 실패한 것입니다.

  1. Terraform plan 명령을 사용하여 클라우드에서 리소스를 바로 생성하기 전 내용을 검토합니다. plan 명령을 사용하려면 구성에 지정된 모든 Provider와의 성공적인 인증이 필요합니다.
    terraform plan

plan 명령은 추가, 제거 또는 업데이트할 리소스의 출력 목록을 반환합니다. 계획 출력의 마지막 줄에는 추가, 변경 또는 제거할 리소스 수가 표시됩니다.

  1. Terraform apply 명령을 사용하여 배포를 만듭니다.

    terraform apply

    Apply 명령은 클라우드에 백업 리소스가 포함 된 배포를 만듭니다. 약 4 분 안에 Apply는 GCP 및 AWS VPC 네트워크, VM 인스턴스, VPN 게이트웨이 및 IPsec 터널을 포함하여 30 개 이상의 리소스를 생성합니다. Apply 명령의 출력에는 배포 된 리소스의 세부 사항과 구성에 의해 정의 된 출력 변수가 포함됩니다.

  2. yes를 입력한 다음 Enter를 눌러 승인합니다

  3. 배포는 워크 플로우를 돕기 위해 출력 변수를 방출 할 수 있습니다. 이 자습서에서 VM 인스턴스의 할당 된 내부 및 외부 IP 주소는 GCP_OUTPUTS.TF 및 AWS_OUTPUTS.TF 파일에 의해 출력 변수로 식별되었습니다. 이 주소는 적용 단계가 완료되면 자동으로 인쇄됩니다. 워크 플로에서 나중에 출력 변수 값을 다시 재생하려면 출력 명령을 사용하려면 다음과 같습니다.

    terraform output


    이 구성으로 정의된 출력 변수에는 VM 인스턴스의 내부 및 외부 IP 주소가 포함됩니다. 네트워크 유효성 검사에 ssh 명령을 사용하려면 VM 인스턴스에 연결할 외부 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
  4. Terraform show 명령을 사용하여 배포된 리소스를 검사하고 현재 상태를 확인합니다.

    terraform show
  5. 인스턴스를 검토하려면 VM 인스턴스 패널에서 gcloud compute instances list를 사용하거나 Cloud Console을 사용하세요.

    gcloud compute instances list

  6. ssh 명령을 사용하여 연결하여 Google Cloud VM 인스턴스가 작동하는지 확인합니다.

    ssh -i ~/.ssh/vm-ssh-key [GCP_EXTERNAL_IP]

    호스트의 신뢰성을 확인하라는 메시지가 표시됩니다. yes를 입력합니다.

  7. ssh 세션에서 ping 및 curl 명령을 실행합니다.

    ping -c 5 google.com
    curl ifconfig.co/ip

  8. Google Cloud VM 인스턴스에서 간단한 네트워크 성능 검사를 실행합니다. 사전 설치된 스크립트를 사용하여 외부 및 내부의 각 네트워크 인터페이스에서 테스트를 실행합니다.

  • 외부 IP를 통해:

    /tmp/run_iperf_to_ext.sh

    이 스크립트는 네트워크 성능에 대한 요약 데이터를 생성하는 30초 성능 테스트를 실행합니다.

  • VPN 사용(내부 IP):

    /tmp/run_iperf_to_int.sh

    이 스크립트는 네트워크 성능에 대한 요약 데이터를 생성하는 30초 성능 테스트를 실행합니다.
    [참고] 출력이 한 번 표시되면 iperf를 종료합니다.

  1. Google Cloud VM 인스턴스에서 확인을 완료하면 다음 명령어를 입력합니다.

    exit

  2. AWS VM 인스턴스가 작동하는지 확인하려면 ssh 명령을 사용하여 연결합니다.

    ssh -i ~/.ssh/vm-ssh-key ubuntu@[AWS_EXTERNAL_IP]

    호스트의 신뢰성을 확인하라는 메시지가 표시됩니다. yes를 입력합니다.

  3. ssh 세션에서 ping 및 curl 명령을 실행합니다.

    ping -c 5 google.com
    curl ifconfig.co/ip

  4. AWS VM 인스턴스에서 간단한 네트워크 성능 검사를 실행합니다. 사전 설치된 스크립트를 사용하여 외부 및 내부의 각 네트워크 인터페이스에서 테스트를 실행합니다.

  • 외부 IP를 통해:
    /tmp/run_iperf_to_ext.sh
  • VPN 사용(내부 IP):
    /tmp/run_iperf_to_int.sh
  1. AWS VM 인스턴스에서 확인을 완료하면 다음 명령을 입력합니다.
    exit

VPN을 사용하여 Google Cloud와 AWS 간의 안전한 개인 사이트 간 연결을 성공적으로 배포했습니다!

만일 LAB 환경이 아닐 경우, 불필요한 과금 예방을 위해 terraform destroy 명령을 사용하여 구축한 인프라를 삭제하세요.


참고1. Google Cloud 기반 Terraform 문서
참고2. Linux에서 iperf3 도구를 사용하여 네트워크 처리량을 테스트하는 방법

profile
우당탕탕 좌충우돌 인프라 여행기

0개의 댓글