日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

Terraform 使用入門(mén)

更新時(shí)間:

本文通過(guò)在阿里云 ECS 實(shí)例上搭建一個(gè) Flask Web 應(yīng)用,帶您體驗(yàn)和快速開(kāi)始使用 Terraform。

本文的主要包含兩部分內(nèi)容:

  • 通過(guò) Terraform 在阿里云上自動(dòng)化創(chuàng)建 ECS 實(shí)例以及所依賴的其他云服務(wù),如網(wǎng)絡(luò),安全組等

  • 在 ECS 實(shí)例上通過(guò) Terraform 自動(dòng)化搭建 Flask Web 服務(wù)

說(shuō)明

本教程所含示例代碼支持一鍵運(yùn)行,您可以直接運(yùn)行代碼。一鍵運(yùn)行

準(zhǔn)備工作

本文將阿里云 ClousShell 作為 Terraform 的運(yùn)行環(huán)境,因此在正式開(kāi)始之前,首先需要準(zhǔn)備以下內(nèi)容:

  1. RAM 子賬號(hào)(可選)如果您已經(jīng)有一個(gè) RAM 子賬號(hào)了,此子賬號(hào)已經(jīng)被授權(quán)了訪問(wèn) ECS 和 VPC 的權(quán)限,那么可以跳過(guò)這一步。訪問(wèn) RAM 用戶頁(yè)面,新建一個(gè)用于操作 Terraform 的子用戶,比如取名 terraform-starter,并為該子用戶授權(quán) ECS 和 VPC 的權(quán)限:AliyunECSFullAccessAliyunVPCFullAccess

  2. 啟動(dòng) Cloud Shell使用 RAM 子賬號(hào)登錄阿里云,并啟動(dòng)阿里云 Cloud Shell。阿里云 Cloud Shell 是阿里云為您創(chuàng)建的一個(gè)虛擬機(jī),預(yù)安裝了 Terraform,并在啟動(dòng)的過(guò)程中自動(dòng)配置了與此子賬號(hào)相關(guān)的訪問(wèn)憑證,因此您無(wú)需進(jìn)行任何配置可直接在 Cloud Shell 中運(yùn)行 Terraform。

重要

注意:阿里云 Cloud Shell 在無(wú)交互式操作30分鐘或者關(guān)閉所有會(huì)話窗口將視為終止操作,在終止操作后15分鐘將銷(xiāo)毀此臺(tái)虛擬機(jī)。再次啟動(dòng)云命令行時(shí),會(huì)為您創(chuàng)建一臺(tái)全新的虛擬機(jī)。因此,為了數(shù)據(jù)安全和持久化,強(qiáng)烈建議您在首次啟動(dòng) Cloud Shell 的時(shí)候創(chuàng)建并綁定一個(gè)文件存儲(chǔ)磁盤(pán),詳見(jiàn)使用限制

創(chuàng)建工作目錄

在 Cloud Shell 中創(chuàng)建一個(gè)新目錄,比如命名為:tf-quickstart。

mkdir tf-quickstart && cd tf-quickstart

編寫(xiě) Flask Web 應(yīng)用代碼

本文將構(gòu)建一個(gè) Python Flask 應(yīng)用,并使用單個(gè)文件描述要在 Web 上輸出的內(nèi)容。

創(chuàng)建名為 app.py的文件:

touch app.py

并添加如下的內(nèi)容:

# coding=utf-8
from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return '你好,阿里云!'.decode('utf-8').encode('utf-8')

app.run(host='0.0.0.0')

編寫(xiě) Terraform 代碼

在此目錄中創(chuàng)建一個(gè) Terraform 文件main.tf文件,此文件用于定義和描述 ECS 實(shí)例以及所依賴的其他阿里云資源:

touch main.tf

定義 Provider

main.tf文件中添加 Provider 的配置信息,用于描述將在哪個(gè)地域創(chuàng)建阿里云資源:

variable "region" {
  default = "cn-shanghai"
}

provider "alicloud" {
  region = var.region
}

示例代碼中將阿里云的地域設(shè)置為了上海(cn-shanghai),您可以根據(jù)需要將其更改為其他地域

定義 VPC 網(wǎng)絡(luò)環(huán)境

main.tf文件中添加以下 Terraform 資源,用于創(chuàng)建 VPC 和子網(wǎng) vSwitch:

  • alicloud_vpc:創(chuàng)建 VPC 網(wǎng)絡(luò)

  • alicloud_vswitch:創(chuàng)建 vSwitch 子網(wǎng)

  • alicloud_zones:動(dòng)態(tài)查詢可以創(chuàng)建特定實(shí)例規(guī)格的可用區(qū)

variable "instance_name" {
  default = "deploying-flask-web-server"
}

variable "instance_type" {
  default = "ecs.n1.tiny"
}

data "alicloud_zones" "default" {
  available_disk_category     = "cloud_efficiency"
  available_resource_creation = "VSwitch"
  available_instance_type     = var.instance_type
}

resource "alicloud_vpc" "vpc" {
  vpc_name   = var.instance_name
  cidr_block = "172.16.0.0/12"
}

resource "alicloud_vswitch" "vsw" {
  vpc_id     = alicloud_vpc.vpc.id
  cidr_block = "172.16.0.0/21"
  zone_id    = data.alicloud_zones.default.zones.0.id
}

示例代碼中 VPC 的名稱通過(guò)變量引用的方式聲明為 deploying-flask-web-server,vSwitch 的可用區(qū)通過(guò)動(dòng)態(tài)查詢的方式獲取其中一個(gè)可用區(qū)。

定義安全組

main.tf文件中添加以下 Terraform 資源,用于創(chuàng)建安全組和安全組規(guī)則:

resource "alicloud_security_group" "default" {
  name   = var.instance_name
  vpc_id = alicloud_vpc.vpc.id
}

resource "alicloud_security_group_rule" "allow_tcp_22" {
  type              = "ingress"
  ip_protocol       = "tcp"
  nic_type          = "intranet"
  policy            = "accept"
  port_range        = "22/22"
  priority          = 1
  security_group_id = alicloud_security_group.default.id
  cidr_ip           = "0.0.0.0/0"
}

resource "alicloud_security_group_rule" "allow_tcp_5000" {
  type              = "ingress"
  ip_protocol       = "tcp"
  nic_type          = "intranet"
  policy            = "accept"
  port_range        = "5000/5000"
  priority          = 1
  security_group_id = alicloud_security_group.default.id
  cidr_ip           = "0.0.0.0/0"
}

示例代碼中聲明了在 VPC 網(wǎng)絡(luò)中創(chuàng)建一個(gè)名為deploying-flask-web-server的安全組,并聲明了兩個(gè)訪問(wèn)端口 22 和 5000,其中 22 端口用于您使用 SSH 連接到 ECS 實(shí)例部署 Flask 應(yīng)用,5000 端口是 Flask 應(yīng)用的默認(rèn)訪問(wèn)端口。

定義 ECS 實(shí)例

alicloud_instance 資源添加到您創(chuàng)建的 main.tf文件中,用于創(chuàng)建 ECS 實(shí)例。

variable "image_id" {
  default = "ubuntu_18_04_64_20G_alibase_20190624.vhd"
}

variable "internet_bandwidth" {
  default = "10"
}

variable "password" {
  default = "Test@12345"
}

resource "alicloud_instance" "instance" {
  availability_zone          = data.alicloud_zones.default.zones.0.id
  security_groups            = alicloud_security_group.default.*.id
  password                   = var.password
  instance_type              = var.instance_type
  system_disk_category       = "cloud_efficiency"
  image_id                   = var.image_id
  instance_name              = var.instance_name
  vswitch_id                 = alicloud_vswitch.vsw.id
  internet_max_bandwidth_out = var.internet_bandwidth
}

output "flask_url" {
  value = format("http://%v:5000", alicloud_instance.instance.public_ip)
}

示例代碼中選擇了一個(gè)最小的共享型實(shí)例規(guī)格族n1ecs.n1.tiny,選擇 Ubuntu 18 作為操作系統(tǒng),并通過(guò)設(shè)置參數(shù) internet_bandwidth來(lái)為實(shí)例分配公網(wǎng) IP 地址。除此之外,通過(guò) output 輸出 Flask 應(yīng)用的訪問(wèn)地址

重要

注意:這只是一個(gè)開(kāi)發(fā)服務(wù)器,并且設(shè)置了一個(gè)簡(jiǎn)單的登錄密碼,請(qǐng)勿將其用于生產(chǎn)部署。

定義 Flask Web 應(yīng)用

main.tf文件中,添加null_resource資源來(lái)將 app.py 文件上傳到 ECS 實(shí)例的 tmp 目錄下,并完成自動(dòng)執(zhí)行:

# deploy flask
resource "null_resource" "deploy" {
  triggers = {
    script_hash = filesha256("app.py")
  }
  # 上傳文件
  provisioner "file" {
    connection {
      type     = "ssh"
      user     = "root"
      password = var.password
      host     = alicloud_instance.instance.public_ip
    }
    source      = "app.py"
    destination = "/tmp/app.py"
  }
# 部署
  provisioner "remote-exec" {
    connection {
      type     = "ssh"
      user     = "root"
      password = var.password
      host     = alicloud_instance.instance.public_ip
    }
    inline = [
      # 安裝 Flask
      "pip install flask",
      # 部署前先停止 Flask (運(yùn)行端口是 5000)
      "nohup python /tmp/app.py &>/tmp/output.log &",
      "sleep 2"
    ]
  }
}

運(yùn)行 Terraform 命令

在完成 Terraform 代碼的編寫(xiě)后,開(kāi)始運(yùn)行 Terraform 命令來(lái)完成 ECS 實(shí)例的自動(dòng)創(chuàng)建和 Flask 應(yīng)用的自動(dòng)搭建。

選擇 Terraform 版本

阿里云 Cloud Shell 中預(yù)安裝了多個(gè) Terraform 版本,可以通過(guò)命令tfenv list進(jìn)行查看,并且0.12.31為默認(rèn)版本。您可以根據(jù)自身需要,通過(guò)tfenv use <版本號(hào)>命令來(lái)修改默認(rèn)版本。本文選擇 1.3.7 版本(建議選擇 1.x.x 版本):

tfenv use 1.3.7

截屏2024-09-05 20.32.13.png

初始化 Terraform

運(yùn)行terraform init構(gòu)建.terraform目錄并添加阿里云的插件:

terraform init

截屏2024-09-05 20.38.27.png

預(yù)覽 Terraform 代碼

(可選)您可以預(yù)覽當(dāng)前已構(gòu)建的 Terraform 代碼。運(yùn)行terraform plan實(shí)現(xiàn)如下功能:

  • 驗(yàn)證main.tf中 Terraform 代碼的語(yǔ)法是否正確

  • 顯示當(dāng)前 Terraform 代碼將要?jiǎng)?chuàng)建的資源的預(yù)覽結(jié)果

terraform plan

截屏2024-09-13 17.36.18.png

預(yù)覽結(jié)果顯示,總計(jì)將創(chuàng)建 7 個(gè)資源。

執(zhí)行 Terraform 代碼

根據(jù)預(yù)覽結(jié)果,確認(rèn)無(wú)誤后,運(yùn)行terraform apply來(lái)實(shí)現(xiàn) 7 個(gè)資源的自動(dòng)化創(chuàng)建。

terraform apply

出現(xiàn)提示時(shí),輸入yes以允許 Terraform 創(chuàng)建所有定義的資源。

截屏2024-09-06 09.24.43.png

執(zhí)行成功,Terraform 會(huì)調(diào)用阿里云的 API 完成了 ECS 實(shí)例的自動(dòng)化創(chuàng)建以及 Flask 應(yīng)用的自動(dòng)化搭建。可訪問(wèn)“ECS 實(shí)例”頁(yè)面查看實(shí)例詳情。

查看結(jié)果

Terraform 執(zhí)行成功后,輸出了 Flask 應(yīng)用的訪問(wèn) URL,您可直接點(diǎn)擊 URL 進(jìn)行訪問(wèn):

截屏2024-09-06 09.38.47.png

清理資源

完成本文的操作后,您可以通過(guò)運(yùn)行terraform destroy命令來(lái)刪除代碼文件中定義的所有資源,以免產(chǎn)生任何額外費(fèi)用:

terraform destroy

輸入yes以允許 Terraform 刪除您的資源。

截屏2024-09-05 21.06.39.png

執(zhí)行成功,所有資源均已被釋放。

完整示例

為了便于您快速體驗(yàn) Terraform,本文提供了完整的 Terraform 代碼,并且將 Flask Web 頁(yè)面中要輸出的內(nèi)容通過(guò)變量web_content進(jìn)行了定義,F(xiàn)lask Python 代碼也直接內(nèi)嵌到了 Terraform 代碼中,您可以一鍵復(fù)制后直接運(yùn)行。

說(shuō)明

本教程所含示例代碼支持一鍵運(yùn)行,您可以直接運(yùn)行代碼。一鍵運(yùn)行

variable "region" {
  default = "cn-shanghai"
}

variable "web_content" {
  default = "你好,阿里云!"
}

variable "instance_name" {
  default = "deploying-flask-web-server"
}

variable "instance_type" {
  default = "ecs.n1.tiny"
}

variable "image_id" {
  default = "ubuntu_18_04_64_20G_alibase_20190624.vhd"
}

variable "internet_bandwidth" {
  default = 10
}

variable "password" {
  default = "Test@12345"
}

provider "alicloud" {
  region = var.region
}

data "alicloud_zones" "default" {
  available_disk_category     = "cloud_efficiency"
  available_resource_creation = "VSwitch"
  available_instance_type     = var.instance_type
}

resource "alicloud_vpc" "vpc" {
  vpc_name   = var.instance_name
  cidr_block = "172.16.0.0/12"
}

resource "alicloud_vswitch" "vsw" {
  vpc_id     = alicloud_vpc.vpc.id
  cidr_block = "172.16.0.0/21"
  zone_id    = data.alicloud_zones.default.zones.0.id
}

resource "alicloud_security_group" "default" {
  name   = var.instance_name
  vpc_id = alicloud_vpc.vpc.id
}

resource "alicloud_instance" "instance" {
  availability_zone          = data.alicloud_zones.default.zones.0.id
  security_groups            = alicloud_security_group.default.*.id
  password                   = var.password
  instance_type              = var.instance_type
  system_disk_category       = "cloud_efficiency"
  image_id                   = var.image_id
  instance_name              = var.instance_name
  vswitch_id                 = alicloud_vswitch.vsw.id
  internet_max_bandwidth_out = var.internet_bandwidth
}

resource "alicloud_security_group_rule" "allow_tcp_22" {
  type              = "ingress"
  ip_protocol       = "tcp"
  nic_type          = "intranet"
  policy            = "accept"
  port_range        = "22/22"
  priority          = 1
  security_group_id = alicloud_security_group.default.id
  cidr_ip           = "0.0.0.0/0"
}

resource "alicloud_security_group_rule" "allow_tcp_5000" {
  type              = "ingress"
  ip_protocol       = "tcp"
  nic_type          = "intranet"
  policy            = "accept"
  port_range        = "5000/5000"
  priority          = 1
  security_group_id = alicloud_security_group.default.id
  cidr_ip           = "0.0.0.0/0"
}

# deploy flask
resource "null_resource" "deploy" {
  triggers = {
    web_content = var.web_content
    script_hash = sha256("${local.app_content}")
  }
  provisioner "remote-exec" {
    connection {
      type     = "ssh"
      user     = "root"
      password = var.password
      host     = alicloud_instance.instance.public_ip
    }
    inline = [
      # 安裝 Flask
      "pip install flask",
      # 部署前先停止 Flask (運(yùn)行端口是 5000)
      "kill $(netstat -tulnp | grep \":5000\" | awk '{ print $7 }' | cut -d'/' -f1)",
      # 部署 Flask
      "echo \"${local.app_content}\" > /tmp/app.py",
      "nohup python /tmp/app.py &>/tmp/output.log &",
      "sleep 2"
    ]
  }
}
output "flask_url" {
  value = format("http://%v:5000", alicloud_instance.instance.public_ip)
}

locals {
  app_content = <<EOF
# coding=utf-8
from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
    return '${var.web_content}'.decode('utf-8').encode('utf-8')

app.run(host='0.0.0.0')

EOF
}