使用 Terraform 部署基本 Flask Web 服务器

在本教程中,您将使用 Terraform 在 Compute Engine 上创建一个基本 Web 服务器,以此了解如何开始使用 Terraform。

在本教程中,您将执行以下操作:

  • 使用 Terraform 在 Google Cloud 中创建虚拟机。
  • 启动基本的 Python Flask 服务器。

费用

在本文档中,您将使用 Google Cloud 的以下收费组件:

Compute Engine

您可使用价格计算器根据您的预计使用情况来估算费用。 Google Cloud 新用户可能有资格申请免费试用

完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理

准备工作

准备开始学习本教程。

选择或创建项目

  1. In the Google Cloud console, go to the project selector page.

    Go to project selector

  2. Select or create a Google Cloud project.

设置权限

确保您的用户账号具有必要的 Compute Engine 权限

  • compute.instances.*
  • compute.firewalls.*

转到 IAM 页面

详细了解角色和权限。

启用该 API

Enable the Compute Engine API.

Enable the API

启动 Cloud Shell

Cloud Shell 是一个 Compute Engine 虚拟机。

与此虚拟机关联的服务凭据会自动运行,因此无需设置或下载服务账号密钥。

Terraform 已与 Cloud Shell 集成,并且 Cloud Shell 会自动对 Terraform 进行身份验证,让您只需进行较少的设置即可开始使用。

创建 Compute Engine 虚拟机

首先,在 Terraform 配置文件中定义虚拟机的设置。然后,运行 Terraform 命令以在项目中创建虚拟机。

创建目录

创建一个新目录。 在这个新目录中,为 Terraform 配置创建一个 main.tf 文件。此文件的内容描述了要在项目中创建的所有 Google Cloud 资源。

在 Cloud Shell 中:

mkdir tf-tutorial && cd tf-tutorial
nano main.tf

创建虚拟私有云网络和子网

在本部分中,您将为虚拟机的网络接口创建虚拟私有云 (VPC) 网络和子网。

将以下 Terraform 资源添加到您创建的 main.tf 文件中:

resource "google_compute_network" "vpc_network" {
  name                    = "my-custom-mode-network"
  auto_create_subnetworks = false
  mtu                     = 1460
}

resource "google_compute_subnetwork" "default" {
  name          = "my-custom-subnet"
  ip_cidr_range = "10.0.1.0/24"
  region        = "us-west1"
  network       = google_compute_network.vpc_network.id
}

创建 Compute Engine 虚拟机资源

在本部分中,您将创建一个运行 Debian 的 Compute Engine 实例。在本教程中,您将使用可用的最小机器类型。稍后,您可以升级到更大的机器类型。

将以下 google_compute_instance Terraform 资源添加到您创建的 main.tf 文件中。

# Create a single Compute Engine instance
resource "google_compute_instance" "default" {
  name         = "flask-vm"
  machine_type = "f1-micro"
  zone         = "us-west1-a"
  tags         = ["ssh"]

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-11"
    }
  }

  # Install Flask
  metadata_startup_script = "sudo apt-get update; sudo apt-get install -yq build-essential python3-pip rsync; pip install flask"

  network_interface {
    subnetwork = google_compute_subnetwork.default.id

    access_config {
      # Include this section to give the VM an external IP address
    }
  }
}

示例代码会将 Google Cloud 地区设置为 us-west1-a。您可以将其更改为其他地区

初始化 Terraform

此时,您可以运行 terraform init 来添加必要的插件并构建 .terraform 目录。

terraform init

输出:

Initializing the backend...

Initializing provider plugins...
...

Terraform has been successfully initialized!

验证 Terraform 配置

(可选)您可以验证到目前为止已构建的 Terraform 代码。运行 terraform plan,以执行以下操作:

  • 验证 main.tf 的语法是否正确
  • 显示将要创建的资源的预览
terraform plan

输出:

...

Plan: 1 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.

应用配置

如需创建虚拟机,请运行 terraform apply

terraform apply

出现提示时,输入 yes

Terraform 会调用 Google Cloud API 来设置新虚拟机。查看“虚拟机实例”页面以查看新虚拟机。

在 Google Cloud 上运行 Web 服务器

接下来,您将创建一个 Web 应用,将其部署到虚拟机,并创建防火墙规则以允许客户端向该 Web 应用发出请求。

添加自定义 SSH 防火墙规则

default 网络中的 default-allow-ssh 防火墙规则允许您使用 SSH 连接到虚拟机。如果您希望使用自己的自定义防火墙规则,则可以在 main.tf 文件的末尾添加以下资源:

resource "google_compute_firewall" "ssh" {
  name = "allow-ssh"
  allow {
    ports    = ["22"]
    protocol = "tcp"
  }
  direction     = "INGRESS"
  network       = google_compute_network.vpc_network.id
  priority      = 1000
  source_ranges = ["0.0.0.0/0"]
  target_tags   = ["ssh"]
}

运行 terraform apply 以创建防火墙规则。

使用 SSH 连接到虚拟机

使用 SSH 连接到虚拟机,验证到目前为止一切内容是否均已正确设置。

  1. 转到“虚拟机实例”页面

  2. 找到名为 flask-vm 的虚拟机。

  3. 连接列中,点击 SSH

    系统会为正在运行的虚拟机打开“浏览器中的 SSH”终端窗口。

如需了解详情,请参阅连接到虚拟机

构建 Flask 应用

您将为本教程构建一个 Python Flask 应用,以便可以使用单个文件描述您的 Web 服务器并测试端点。

  1. 在“浏览器中的 SSH”终端中,创建名为 app.py 的文件。

    nano app.py
    
  2. 将以下内容添加到 app.py 文件中:

    from flask import Flask
    app = Flask(__name__)
    
    @app.route('/')
    def hello_cloud():
      return 'Hello Cloud!'
    
    app.run(host='0.0.0.0')
    
  3. 运行 app.py

    python3 app.py
    

    Flask 默认会通过 localhost:5000 传送流量。

  4. 打开另一个 SSH 连接:

    1. 转到“虚拟机实例”页面
    2. 找到名为 flask-vm 的虚拟机,然后点击 SSH
  5. 在第二个 SSH 连接中,运行 curl 以确认您在 app.py 中配置的问候语是否正确返回。

    curl http://0.0.0.0:5000
    

    此命令的输出为 Hello Cloud

打开虚拟机上的端口 5000

如需从本地计算机连接到 Web 服务器,虚拟机必须打开端口 5000。Google Cloud 允许您使用防火墙规则打开流量端口。

main.tf 文件的末尾添加以下 google_compute_firewall Terraform 资源。

resource "google_compute_firewall" "flask" {
  name    = "flask-app-firewall"
  network = google_compute_network.vpc_network.id

  allow {
    protocol = "tcp"
    ports    = ["5000"]
  }
  source_ranges = ["0.0.0.0/0"]
}

在 Cloud Shell 中,运行 terraform apply 以创建防火墙规则。

为 Web 服务器网址添加输出变量

  1. main.tf 的末尾,添加 Terraform 输出变量以输出 Web 服务器网址:

    // A variable for extracting the external IP address of the VM
    output "Web-server-URL" {
     value = join("",["http://",google_compute_instance.default.network_interface.0.access_config.0.nat_ip,":5000"])
    }
    
  2. 运行 terraform apply

    terraform apply
    

    出现提示时,输入 yes。 Terraform 会将虚拟机的外部 IP 地址和端口 5000 输出到屏幕上,如下所示:

    Web-server-URL = "http://IP_ADDRESS:5000"
    

    您可以随时运行 terraform output 来返回此输出:

    terraform output
    
  3. 点击上一步中的网址,您将会看到“Hello Cloud!”消息。

    这意味着您的服务器正在运行。

问题排查

  • 如果未启用所需的 API,Terraform 将返回错误。错误消息包含用于启用相应 API 的链接。启用 API 后,您可以重新运行 terraform apply

  • 如果您无法通过 SSH 连接到虚拟机:

清理

完成本教程后,您可以删除自己创建的所有内容,以免产生任何额外费用。

Terraform 允许您通过运行 terraform destroy 命令来移除配置文件中定义的所有资源:

terraform destroy

输入 yes 以允许 Terraform 删除您的资源。

后续步骤