本文以Terraform版ECS單機部署Nginx服務為例,由簡入難的向您介紹如何編輯Terraform模板。
前提條件
請您提前瞭解模板文法和結構。更多資訊,請參見模板快速入門。
情境樣本
在阿里雲Virtual Private Cloud中建立ECS執行個體,並在ECS執行個體中部署Nginx服務。
使用須知
您可以訪問對應的資源類型查看屬性詳情。具體操作,請參見查看資源類型。
資源類型文檔為每個屬性定義了Optional(可選)、Required(必須)等資訊。如果將屬性定義為Required(必須),則要求必須在模板資源中聲明該屬性;反之,則為非必須。
編輯模板
您可以通過資源類型索引文檔尋找所需的資源類型。更多資訊,請參見資源類型索引。
例如:當前情境中需要建立Virtual Private Cloud(alicloud_vpc)、ECS執行個體(alicloud_instance)、交換器(alicloud_vswitch)、安全性群組(alicloud_security_group)和安全性群組規則(alicloud_security_group_rule),在建立ECS執行個體的同時會安裝Nginx服務。
定義模板多種資源及其依賴關係
定義基礎網路資源
您可以通過模板定義基礎網路資源vpc
、vsw
、security_group
。
使用
alicloud_vpc.vpc.id
擷取資源alicloud_vpc
的輸出ID屬性值。使用
var.***
擷取自訂變數,即variable
中的參數值。例如var.zone_id
擷取的是variable
中zone_id
的值。
resource "alicloud_vpc" "vpc" {
cidr_block = "10.1.0.0/21"
}
resource "alicloud_vswitch" "vsw" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = "172.16.0.0/21"
zone_id = var.zone_id
}
resource "alicloud_security_group" "security_group" {
name = "new-group"
vpc_id = alicloud_vpc.vpc.id
}
定義安全性群組規則
您可以通過模板定義安全性群組規則allow_ssh
、allow_web
、allow_egress
。
使用alicloud_security_group.security_group.id
擷取安全性群組security_group
資源的輸出ID屬性值。
# 安全性群組入口端1
resource "alicloud_security_group_rule" "allow_ssh" {
security_group_id = alicloud_security_group.security_group.id
type = "ingress"
cidr_ip = "0.0.0.0/0"
policy = "accept"
ip_protocol = "tcp"
port_range = "22/22"
priority = 1
}
# 安全性群組入口端2
resource "alicloud_security_group_rule" "allow_web" {
security_group_id = alicloud_security_group.security_group.id
type = "ingress"
cidr_ip = "0.0.0.0/0"
policy = "accept"
ip_protocol = "tcp"
port_range = "80/443"
priority = 1
}
# 安全性群組出口端
resource "alicloud_security_group_rule" "allow_egress" {
security_group_id = alicloud_security_group.security_group.id
type = "egress"
cidr_ip = "0.0.0.0/0"
policy = "accept"
ip_protocol = "tcp"
port_range = "1/65535"
priority = 1
}
定義ECS執行個體
您可以通過模板定義ECS執行個體instance
。
使用
var.***
擷取自訂變數,即variable
中的參數值。例如:var.instance_type
擷取的是variable
中instance_type
的值。使用
local.***
擷取本地變數,即locals
中的參數值。例如:local.new_host_name
擷取的是locals
中new_host_name
的值。使用user_data中的
${path.cwd}
擷取當前工作目錄。user_data.sh檔案中包含Elastic Compute Service需要執行的初始化指令碼。user_data.sh初始化指令碼如下所示。
#!/bin/bash -v
# 掛盤到/disk1
cat >> /root/InitDataDisk.sh << "EOF"
#!/bin/bash
echo "p
n
p
w
" | fdisk -u /dev/vdb
EOF
/bin/bash /root/InitDataDisk.sh
rm -f /root/InitDataDisk.sh
mkfs -t ext4 /dev/vdb1
cp /etc/fstab /etc/fstab.bak
mkdir /disk1
echo `blkid /dev/vdb1 | awk '{print $2}' | sed 's/\\\"//g'` /disk1 ext4 defaults 0 0 >> /etc/fstab
mount -a
# 這裡配置安裝指令碼
yum install -y nginx
# 配置啟動指令碼
/usr/sbin/nginx
定義ECS執行個體模板如下所示。
resource "alicloud_instance" "instance" {
availability_zone = var.zone_id
security_groups = [alicloud_security_group.security_group.id]
# series III
host_name = local.new_host_name
instance_type = var.instance_type
system_disk_size = 500
system_disk_category = "cloud_essd"
image_id = "centos_7_9_x64_20G_alibase_20210318.vhd"
vswitch_id = alicloud_vswitch.vsw.id
password = var.instance_password
internet_charge_type = "PayByTraffic"
internet_max_bandwidth_out = 30
instance_charge_type = var.pay_type
period = var.pay_period
period_unit = var.pay_period_unit
user_data = file("${path.cwd}/user-data.sh")
data_disks {
size = 100
category = "cloud_essd"
}
}
完整模板樣本
variable "pay_type" {
type = string
}
variable "pay_period_unit" {
type = string
}
variable "pay_period" {
type = number
}
variable "zone_id" {
type = string
}
variable "vpc_cidr_block" {
type = string
}
variable "vswitch_cidr_block" {
type = string
}
variable "instance_type" {
type = string
}
variable "system_disk_category" {
type = string
}
variable "system_disk_size" {
type = number
}
variable "data_disk_category" {
type = string
}
variable "data_disk_size" {
type = number
}
variable "instance_password" {
type = string
}
# 預設資源名稱
locals {
production_name = "nginx"
new_scg_name = "sg-for-${local.production_name}"
new_host_name = "app-for-${local.production_name}"
}
resource "alicloud_vpc" "vpc" {
cidr_block = var.vpc_cidr_block
}
resource "alicloud_vswitch" "vsw" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = var.vswitch_cidr_block
zone_id = var.zone_id
}
# 安全性群組基本資料配置
resource "alicloud_security_group" "security_group" {
name = local.new_scg_name
description = "nginx scg"
vpc_id = alicloud_vpc.vpc.id
}
# 安全性群組入口端1
resource "alicloud_security_group_rule" "allow_ssh" {
security_group_id = alicloud_security_group.security_group.id
type = "ingress"
cidr_ip = "0.0.0.0/0"
policy = "accept"
ip_protocol = "tcp"
port_range = "22/22"
priority = 1
}
# 安全性群組入口端2
resource "alicloud_security_group_rule" "allow_web" {
security_group_id = alicloud_security_group.security_group.id
type = "ingress"
cidr_ip = "0.0.0.0/0"
policy = "accept"
ip_protocol = "tcp"
port_range = "80/443"
priority = 1
}
# 安全性群組出口端
resource "alicloud_security_group_rule" "allow_egress" {
security_group_id = alicloud_security_group.security_group.id
type = "egress"
cidr_ip = "0.0.0.0/0"
policy = "accept"
ip_protocol = "tcp"
port_range = "1/65535"
priority = 1
}
# 執行個體基本配置
resource "alicloud_instance" "instance" {
availability_zone = var.zone_id
security_groups = [alicloud_security_group.security_group.id]
# series III
host_name = local.new_host_name
instance_type = var.instance_type
system_disk_size = var.system_disk_size
system_disk_category = var.system_disk_category
image_id = "centos_7_9_x64_20G_alibase_20210318.vhd"
vswitch_id = alicloud_vswitch.vsw.id
password = var.instance_password
internet_charge_type = "PayByTraffic"
internet_max_bandwidth_out = 30
instance_charge_type = var.pay_type
period = var.pay_period
period_unit = var.pay_period_unit
user_data = file("${path.cwd}/user-data.sh")
data_disks {
size = var.data_disk_size
category = var.data_disk_category
}
}
# 返回Nginx的IP地址
output "nginx_ip" {
value = "http://${alicloud_instance.instance.public_ip}:8080"
}
Terraform模板類型轉換
您可以通過Resource Orchestration Service控制台將Terraform模板轉換成ROS模板,使用ROS資源實現添加模板參數分組與動態擷取參數配置。
在左側導覽列,選擇模板>我的模板。
在我的模板頁面,單擊建立模板。
在編輯模板內容頁簽的下拉頁表中,選擇Terraform。
編輯Terraform模板。
建立main.tf檔案,輸入完整模板樣本中建立的Terraform模板。
建立user-data.sh檔案,輸入user_data.sh初始化指令碼內容。
在編輯模板內容頁簽的下拉頁表中,選擇ROS。
您已成功將Terraform模板轉換為ROS模板,ROS模板樣本如下所示。
ROSTemplateFormatVersion: '2015-09-01' Transform: Aliyun::Terraform-v1.2 Workspace: main.tf: |- variable "pay_type" { type = string } variable "pay_period_unit" { type = string } variable "pay_period" { type = number } variable "zone_id" { type = string } variable "instance_type" { type = string } variable "vpc_cidr_block" { type = string } variable "vsw_cidr_block" { type = string } variable "instance_password" { type = string } # 預設資源名稱 locals { production_name = "nginx" new_vpc_name = "vpc-for-${local.production_name}" new_vsw_name = "vsw-for-${local.production_name}" new_scg_name = "sg-for-${local.production_name}" new_host_name = "app-for-${local.production_name}" } resource "alicloud_vpc" "vpc" { vpc_name = local.new_vpc_name cidr_block = var.vpc_cidr_block } resource "alicloud_vswitch" "vsw" { vpc_id = alicloud_vpc.vpc.id cidr_block = var.vsw_cidr_block zone_id = var.zone_id } # 安全性群組基本資料配置 resource "alicloud_security_group" "security_group" { name = local.new_scg_name description = "nginx scg" vpc_id = alicloud_vpc.vpc.id } # 安全性群組入口端1 resource "alicloud_security_group_rule" "allow_ssh" { security_group_id = alicloud_security_group.security_group.id type = "ingress" cidr_ip = "0.0.0.0/0" policy = "accept" ip_protocol = "tcp" port_range = "22/22" priority = 1 } # 安全性群組入口端2 resource "alicloud_security_group_rule" "allow_web" { security_group_id = alicloud_security_group.security_group.id type = "ingress" cidr_ip = "0.0.0.0/0" policy = "accept" ip_protocol = "tcp" port_range = "80/443" priority = 1 } # 安全性群組出口端 resource "alicloud_security_group_rule" "allow_egress" { security_group_id = alicloud_security_group.security_group.id type = "egress" cidr_ip = "0.0.0.0/0" policy = "accept" ip_protocol = "tcp" port_range = "1/65535" priority = 1 } # 執行個體基本配置 resource "alicloud_instance" "instance" { availability_zone = var.zone_id security_groups = [alicloud_security_group.security_group.id] # series III host_name = local.new_host_name instance_type = var.instance_type system_disk_size = 500 system_disk_category = "cloud_essd" image_id = "centos_7_9_x64_20G_alibase_20210318.vhd" vswitch_id = alicloud_vswitch.vsw.id password = var.instance_password internet_charge_type = "PayByTraffic" internet_max_bandwidth_out = 30 instance_charge_type = var.pay_type period = var.pay_period period_unit = var.pay_period_unit user_data = file("${path.cwd}/user-data.sh") data_disks { size = 100 category = "cloud_essd" } } # 返回Nginx的IP地址 output "nginx_ip" { value = "http://${alicloud_instance.instance.public_ip}:8080" } user-data.sh: |- #!/bin/bash -v # 掛盤到/disk1 cat >> /root/InitDataDisk.sh << "EOF" #!/bin/bash echo "p n p w " | fdisk -u /dev/vdb EOF /bin/bash /root/InitDataDisk.sh rm -f /root/InitDataDisk.sh mkfs -t ext4 /dev/vdb1 cp /etc/fstab /etc/fstab.bak mkdir /disk1 echo `blkid /dev/vdb1 | awk '{print $2}' | sed 's/\\\"//g'` /disk1 ext4 defaults 0 0 >> /etc/fstab mount -a # 這裡配置安裝指令碼 yum install -y nginx # 配置啟動指令碼 /usr/sbin/nginx
添加模板參數分組與動態擷取參數配置
在以上模板中您已經完成對多種資源及其依賴關係的定義。其中instance資源的system_disk_category
屬性值為固定值,當您在不同地區建立資源棧時,需要調整模板內容和變更資源屬性值以達到部署資源棧的目的。
您可以對模板添加Parameters,從而提高模板的靈活性和可複用性。
添加模板參數分組
您可以在模板中使用中繼資料(Metadata)對Parameters中定義的參數進行分組,並定義參數分組標籤。更多資訊,請參見中繼資料(Metadata)。
您可以根據不同資源與資源對應的參數進行參數分組。以當前模板為例,您可以將資源按照如下結果劃分。
資源參數分類 | 資源名稱 | 參數名稱 |
基礎網路設定 |
|
|
ECS執行個體資源配置 |
|
|
在Terraform標籤下,建立.metadata
檔案,輸入以下內容。
{
"ALIYUN::ROS::Interface": {
"ParameterGroups": [
{
"Parameters": [
"pay_type",
"pay_period_unit",
"pay_period"
],
"Label": {
"default": {
"en": "Payment mode Configuration",
"zh-cn": "付費模式配置"
}
}
},
{
"Parameters": [
"zone_id"
],
"Label": {
"default": {
"zh-cn": "可用性區域配置",
"en": "Zone Configuration"
}
}
},
{
"Parameters": [
"vpc_cidr_block",
"vswitch_cidr_block"
],
"Label": {
"default": {
"zh-cn": "選擇已有基礎資源配置",
"en": "Choose existing Infrastructure Configuration"
}
}
},
{
"Parameters": [
"instance_type",
"system_disk_category",
"system_disk_size",
"data_disk_category",
"data_disk_size",
"instance_password"
],
"Label": {
"default": {
"en": "Instance",
"zh-cn": "ECS執行個體配置"
}
}
}
]
}
}
動態擷取參數配置
以instance參數為例,當您需要在ROS控制台上對參數設定篩選條件並動態選擇參數配置時,可以按照參數對應的資源類型(ALIYUN::ECS::Instance)在AssociationProperty和AssociationPropertyMetadata文檔中查詢到該參數支援的AssociationProperty
取值 (ALIYUN::ECS::Instance::InstanceType),然後查看對篩選到的AssociationProperty
設定過濾條件為ZoneId
的AssociationPropertyMetadata
取值。更多資訊,請參見AssociationProperty和AssociationPropertyMetadata。
在Terraform標籤下的main.tf
檔案中輸入以下內容。
variable "pay_type" {
type = string
default = "PostPaid"
description = <<EOT
{
"Label": {
"en": "ECS Instance Charge Type",
"zh-cn": "付費類型"
},
"AllowedValues": [
"PostPaid",
"PrePaid"
],
"AssociationProperty": "ChargeType",
"AssociationPropertyMetadata": {
"LocaleKey": "InstanceChargeType"
}
}
EOT
}
variable "pay_period_unit" {
type = string
default = "Month"
description = <<EOT
{
"Label": {
"en": "Pay Period Unit",
"zh-cn": "購買資源時間長度周期"
},
"AllowedValues": [
"Month",
"Year"
],
"AssociationProperty": "PayPeriodUnit",
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Not": {
"Fn::Equals": [
"$${pay_type}",
"PostPaid"
]
}
}
}
}
}
EOT
}
variable "pay_period" {
type = number
default = 1
description = <<EOT
{
"Label": {
"en": "Period",
"zh-cn": "購買資源時間長度"
},
"AllowedValues": [
1,
2,
3,
4,
5,
6,
7,
8,
9
],
"AssociationProperty": "PayPeriod",
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Or": [
{
"Fn::Equals": [
"$${pay_type}",
"PrePaid"
]
},
{
"Fn::Equals": [
"$${pay_type}",
"undefined"
]
}
]
}
}
}
}
EOT
}
variable "zone_id" {
type = string
description = <<EOT
{
"AssociationProperty": "ALIYUN::ECS::Instance:ZoneId",
"Description": {
"zh-cn": "可用性區域ID。<br><b>註: <font color='blue'>選擇前請確認該可用性區域是否支援建立ECS資源的規格,建議與其他交換器可用性區域不同。</font></b>",
"en": "Availability Zone ID.<br><b>notex:<font color='blue'>before selecting, please confirm that the Availability Zone supports the specification of creating ECS resources,which is recommended to be different from other VSwitch Availability Zone.</font></b>"
},
"Label": {
"zh-cn": "交換器可用性區域",
"en": "VSwitch Availability Zone"
}
}
EOT
}
variable "vpc_cidr_block" {
type = string
default = "192.168.0.0/16"
description = <<EOT
{
"Label": {
"zh-cn": "專用網路網段",
"en": "VPC CIDR Block"
},
"Description": {
"zh-cn": "建立專用網路IP位址區段範圍,推薦使用以下的IP位址區段<br><font color='green'>[10.0.0.0/8]</font><br><font color='green'>[172.16.0.0/12]</font><br><font color='green'>[192.168.0.0/16]。</font>",
"en": "New proprietary network IP address segment range, recommended use of the following IP address segments<br><font color='green'>[10.0.0.0/8]</font><br><font color='green'>[172.16.0.0/12]</font><br><font color='green'>[192.168.0.0/16].</font>"
}
}
EOT
}
variable "vswitch_cidr_block" {
type = string
default = "192.168.0.0/24"
description = <<EOT
{
"Description": {
"zh-cn": "必須是所屬專用網路的子網段,並且沒有被其他交換器佔用。",
"en": "Must be a sub-network segment of the proprietary network and is not occupied by other VSwitches."
},
"Label": {
"zh-cn": "交換器網段",
"en": "VSwitch CIDR Block"
}
}
EOT
}
variable "instance_type" {
type = string
description = <<EOT
{
"Label": {
"zh-cn": "執行個體規格",
"en": "Instance Type"
},
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
"AssociationPropertyMetadata": {
"InstanceChargeType": "$${pay_type}",
"ZoneId": "$${zone_id}"
}
}
EOT
}
variable "system_disk_category" {
type = string
description = <<EOT
{
"Description": {
"en": "<font color='blue'><b>Optional values:</b></font><br>[cloud_efficiency: <font color='green'>Efficient Cloud Disk</font>]<br>[cloud_ssd: <font color='green'>SSD Cloud Disk</font>]<br>[cloud_essd: <font color='green'>ESSD Cloud Disk</font>]<br>[cloud: <font color='green'>Cloud Disk</font>]<br>[ephemeral_ssd: <font color='green'>Local SSD Cloud Disk</font>]",
"zh-cn": "<font color='blue'><b>可選值:</b></font><br>[cloud_efficiency: <font color='green'>高效雲端硬碟</font>]<br>[cloud_ssd: <font color='green'>SSD雲端硬碟</font>]<br>[cloud_essd: <font color='green'>ESSD雲端硬碟</font>]<br>[cloud: <font color='green'>普通雲端硬碟</font>]<br>[ephemeral_ssd: <font color='green'>本地SSD盤</font>]"
},
"AssociationProperty": "ALIYUN::ECS::Disk::SystemDiskCategory",
"AssociationPropertyMetadata": {
"ZoneId": "$${zone_id}",
"InstanceType": "$${instance_type}"
},
"Label": {
"en": "System Disk Type",
"zh-cn": "系統硬碟類型"
}
}
EOT
}
variable "system_disk_size" {
type = number
default = 40
description = <<EOT
{
"Description": {
"zh-cn": "系統硬碟大小,取值範圍:40~500,單位:GB。",
"en": "System disk size, range of values: 40~500, units: GB."
},
"Label": {
"zh-cn": "系統硬碟空間",
"en": "System Disk Space"
}
}
EOT
}
variable "data_disk_category" {
type = string
description = <<EOT
{
"Label": {
"zh-cn": "資料盤類型",
"en": "Data Disk Type"
},
"Description": {
"zh-cn": "<font color='blue'><b>可選值:</b></font><br>[cloud_efficiency: <font color='green'>高效雲端硬碟</font>]<br>[cloud_ssd: <font color='green'>SSD雲端硬碟</font>]<br>[cloud_essd: <font color='green'>ESSD雲端硬碟</font>]<br>[cloud: <font color='green'>普通雲端硬碟</font>]",
"en": "<font color='blue'><b>Optional values:</b></font><br>[cloud_efficiency: <font color='green'>Efficient Cloud Disk</font>]<br>[cloud_ssd: <font color='green'>SSD Cloud Disk</font>]<br>[cloud_essd: <font color='green'>ESSD Cloud Disk</font>]<br>[cloud: <font color='green'>Cloud Disk</font>]"
},
"AssociationProperty": "ALIYUN::ECS::Disk::DataDiskCategory",
"AssociationPropertyMetadata": {
"ZoneId": "$${zone_id}",
"InstanceType": "$${instance_type}"
}
}
EOT
}
variable "data_disk_size" {
type = number
default = 100
description = <<EOT
{
"Description": {
"zh-cn": "ECS執行個體資料盤大小,單位為GiB。取值範圍:20~32768",
"en": "ECS Instance disk size, range of values: 20~32768, units: GB"
},
"MaxValue": 32768,
"MinValue": 20,
"Label": {
"zh-cn": "資料盤空間",
"en": "Data Disk Space"
}
}
EOT
}
variable "instance_password" {
type = string
sensitive = true
description = <<EOT
{
"Description": {
"en": "Server login password, Length 8~30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ Special symbol in).",
"zh-cn": "登入密碼,長度8~30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ 中的特殊符號)。"
},
"Label": {
"en": "Instance Password",
"zh-cn": "登入密碼"
},
"ConstraintDescription": {
"en": "Length 8~30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ Special symbol in).",
"zh-cn": "長度8~30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ 中的特殊符號)。"
},
"AssociationProperty": "ALIYUN::ECS::Instance::Password",
"AllowedPattern": "^[a-zA-Z0-9-\\(\\)\\`\\~\\!\\@\\#\\$\\%\\^\\&\\*\\_\\-\\+\\=\\|\\{\\}\\[\\]\\:\\;\\<\\>\\,\\.\\?\\/]*$",
"MinLength": 8,
"MaxLength": 30
}
EOT
}
添加模板參數關聯與約束
Terraform模板中定義了ECS執行個體,其中需要約束的參數(zone_id
、instance_type
、vswitch_id
、system_disk_category
、system_disk_size
、data_disk_category
、data_disk_size
)都與alicloud_instance
有關。
在ResourcesForParameterConstraints欄位中只需要定義資源類型ALIYUN::ECS::Instance(alicloud_instance
),並關聯image_id
、instance_type
、zone_id
參數就可以實現對instance_type
、zone_id
的約束。
{
"ALIYUN::ROS::Interface": {
"ResourcesForParameterConstraints": {
"instance": {
"Type": "ALIYUN::ECS::Instance",
"Properties": {
"InstanceType": {
"Ref": "instance_type"
},
"ImageId": "centos_7_9_x64_20G_alibase_20210318.vhd",
"VSwitchId": {
"Ref": "vswitch_id"
},
"ZoneId": {
"Ref": "zone_id"
},
"SystemDiskCategory": {
"Ref": "system_disk_category"
},
"SystemDiskSize": {
"Ref": "system_disk_size"
},
"DataDiskCategory": {
"Ref": "data_disk_category"
},
"DataDiskSize": {
"Ref": "data_disk_size"
}
}
}
},
"ParameterGroups": [
{
"Parameters": [
"pay_type",
"pay_period_unit",
"pay_period"
],
"Label": {
"default": {
"en": "Payment mode Configuration",
"zh-cn": "付費模式配置"
}
}
},
{
"Parameters": [
"zone_id"
],
"Label": {
"default": {
"zh-cn": "可用性區域配置",
"en": "Zone Configuration"
}
}
},
{
"Parameters": [
"vpc_cidr_block",
"vswitch_cidr_block"
],
"Label": {
"default": {
"zh-cn": "選擇已有基礎資源配置",
"en": "Choose existing Infrastructure Configuration"
}
}
},
{
"Parameters": [
"instance_type",
"system_disk_category",
"system_disk_size",
"data_disk_category",
"data_disk_size",
"instance_password"
],
"Label": {
"default": {
"en": "Instance",
"zh-cn": "ECS執行個體配置"
}
}
}
]
}
}
完整模板樣本
ROSTemplateFormatVersion: '2015-09-01'
Transform: Aliyun::Terraform-v1.2
Workspace:
.metadata: |-
{
"ALIYUN::ROS::Interface": {
"ResourcesForParameterConstraints": {
"instance": {
"Type": "ALIYUN::ECS::Instance",
"Properties": {
"InstanceType": {
"Ref": "instance_type"
},
"ImageId": "centos_7_9_x64_20G_alibase_20210318.vhd",
"VSwitchId": {
"Ref": "vswitch_id"
},
"ZoneId": {
"Ref": "zone_id"
},
"SystemDiskCategory": {
"Ref": "system_disk_category"
},
"SystemDiskSize": {
"Ref": "system_disk_size"
},
"DataDiskCategory": {
"Ref": "data_disk_category"
},
"DataDiskSize": {
"Ref": "data_disk_size"
}
}
}
},
"ParameterGroups": [
{
"Parameters": [
"pay_type",
"pay_period_unit",
"pay_period"
],
"Label": {
"default": {
"en": "Payment mode Configuration",
"zh-cn": "付費模式配置"
}
}
},
{
"Parameters": [
"zone_id"
],
"Label": {
"default": {
"zh-cn": "可用性區域配置",
"en": "Zone Configuration"
}
}
},
{
"Parameters": [
"vpc_cidr_block",
"vswitch_cidr_block"
],
"Label": {
"default": {
"zh-cn": "選擇已有基礎資源配置",
"en": "Choose existing Infrastructure Configuration"
}
}
},
{
"Parameters": [
"instance_type",
"system_disk_category",
"system_disk_size",
"data_disk_category",
"data_disk_size",
"instance_password"
],
"Label": {
"default": {
"en": "Instance",
"zh-cn": "ECS執行個體配置"
}
}
}
]
}
}
main.tf: |-
variable "pay_type" {
type = string
default = "PostPaid"
description = <<EOT
{
"Label": {
"en": "ECS Instance Charge Type",
"zh-cn": "付費類型"
},
"AllowedValues": [
"PostPaid",
"PrePaid"
],
"AssociationProperty": "ChargeType",
"AssociationPropertyMetadata": {
"LocaleKey": "InstanceChargeType"
}
}
EOT
}
variable "pay_period_unit" {
type = string
default = "Month"
description = <<EOT
{
"Label": {
"en": "Pay Period Unit",
"zh-cn": "購買資源時間長度周期"
},
"AllowedValues": [
"Month",
"Year"
],
"AssociationProperty": "PayPeriodUnit",
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Not": {
"Fn::Equals": [
"$${pay_type}",
"PostPaid"
]
}
}
}
}
}
EOT
}
variable "pay_period" {
type = number
default = 1
description = <<EOT
{
"Label": {
"en": "Period",
"zh-cn": "購買資源時間長度"
},
"AllowedValues": [
1,
2,
3,
4,
5,
6,
7,
8,
9
],
"AssociationProperty": "PayPeriod",
"AssociationPropertyMetadata": {
"Visible": {
"Condition": {
"Fn::Or": [
{
"Fn::Equals": [
"$${pay_type}",
"PrePaid"
]
},
{
"Fn::Equals": [
"$${pay_type}",
"undefined"
]
}
]
}
}
}
}
EOT
}
variable "zone_id" {
type = string
description = <<EOT
{
"AssociationProperty": "ALIYUN::ECS::Instance:ZoneId",
"Description": {
"zh-cn": "可用性區域ID。<br><b>註: <font color='blue'>選擇前請確認該可用性區域是否支援建立ECS資源的規格,建議與其他交換器可用性區域不同。</font></b>",
"en": "Availability Zone ID.<br><b>notex:<font color='blue'>before selecting, please confirm that the Availability Zone supports the specification of creating ECS resources,which is recommended to be different from other VSwitch Availability Zone.</font></b>"
},
"Label": {
"zh-cn": "交換器可用性區域",
"en": "VSwitch Availability Zone"
}
}
EOT
}
variable "vpc_cidr_block" {
type = string
default = "192.168.0.0/16"
description = <<EOT
{
"Label": {
"zh-cn": "專用網路網段",
"en": "VPC CIDR Block"
},
"Description": {
"zh-cn": "建立專用網路IP位址區段範圍,推薦使用以下的IP位址區段<br><font color='green'>[10.0.0.0/8]</font><br><font color='green'>[172.16.0.0/12]</font><br><font color='green'>[192.168.0.0/16]。</font>",
"en": "New proprietary network IP address segment range, recommended use of the following IP address segments<br><font color='green'>[10.0.0.0/8]</font><br><font color='green'>[172.16.0.0/12]</font><br><font color='green'>[192.168.0.0/16].</font>"
}
}
EOT
}
variable "vswitch_cidr_block" {
type = string
default = "192.168.0.0/24"
description = <<EOT
{
"Description": {
"zh-cn": "必須是所屬專用網路的子網段,並且沒有被其他交換器佔用。",
"en": "Must be a sub-network segment of the proprietary network and is not occupied by other VSwitches."
},
"Label": {
"zh-cn": "交換器網段",
"en": "VSwitch CIDR Block"
}
}
EOT
}
variable "instance_type" {
type = string
description = <<EOT
{
"Label": {
"zh-cn": "執行個體規格",
"en": "Instance Type"
},
"AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
"AssociationPropertyMetadata": {
"InstanceChargeType": "$${pay_type}",
"ZoneId": "$${zone_id}"
}
}
EOT
}
variable "system_disk_category" {
type = string
description = <<EOT
{
"Description": {
"en": "<font color='blue'><b>Optional values:</b></font><br>[cloud_efficiency: <font color='green'>Efficient Cloud Disk</font>]<br>[cloud_ssd: <font color='green'>SSD Cloud Disk</font>]<br>[cloud_essd: <font color='green'>ESSD Cloud Disk</font>]<br>[cloud: <font color='green'>Cloud Disk</font>]<br>[ephemeral_ssd: <font color='green'>Local SSD Cloud Disk</font>]",
"zh-cn": "<font color='blue'><b>可選值:</b></font><br>[cloud_efficiency: <font color='green'>高效雲端硬碟</font>]<br>[cloud_ssd: <font color='green'>SSD雲端硬碟</font>]<br>[cloud_essd: <font color='green'>ESSD雲端硬碟</font>]<br>[cloud: <font color='green'>普通雲端硬碟</font>]<br>[ephemeral_ssd: <font color='green'>本地SSD盤</font>]"
},
"AssociationProperty": "ALIYUN::ECS::Disk::SystemDiskCategory",
"AssociationPropertyMetadata": {
"ZoneId": "$${zone_id}",
"InstanceType": "$${instance_type}"
},
"Label": {
"en": "System Disk Type",
"zh-cn": "系統硬碟類型"
}
}
EOT
}
variable "system_disk_size" {
type = number
default = 40
description = <<EOT
{
"Description": {
"zh-cn": "系統硬碟大小,取值範圍:40~500,單位:GB。",
"en": "System disk size, range of values: 40~500, units: GB."
},
"Label": {
"zh-cn": "系統硬碟空間",
"en": "System Disk Space"
}
}
EOT
}
variable "data_disk_category" {
type = string
description = <<EOT
{
"Label": {
"zh-cn": "資料盤類型",
"en": "Data Disk Type"
},
"Description": {
"zh-cn": "<font color='blue'><b>可選值:</b></font><br>[cloud_efficiency: <font color='green'>高效雲端硬碟</font>]<br>[cloud_ssd: <font color='green'>SSD雲端硬碟</font>]<br>[cloud_essd: <font color='green'>ESSD雲端硬碟</font>]<br>[cloud: <font color='green'>普通雲端硬碟</font>]",
"en": "<font color='blue'><b>Optional values:</b></font><br>[cloud_efficiency: <font color='green'>Efficient Cloud Disk</font>]<br>[cloud_ssd: <font color='green'>SSD Cloud Disk</font>]<br>[cloud_essd: <font color='green'>ESSD Cloud Disk</font>]<br>[cloud: <font color='green'>Cloud Disk</font>]"
},
"AssociationProperty": "ALIYUN::ECS::Disk::DataDiskCategory",
"AssociationPropertyMetadata": {
"ZoneId": "$${zone_id}",
"InstanceType": "$${instance_type}"
}
}
EOT
}
variable "data_disk_size" {
type = number
default = 100
description = <<EOT
{
"Description": {
"zh-cn": "ECS執行個體資料盤大小,單位為GiB。取值範圍:20~32768。",
"en": "ECS Instance disk size, range of values: 20~32768, units: GB."
},
"MaxValue": 32768,
"MinValue": 20,
"Label": {
"zh-cn": "資料盤空間",
"en": "Data Disk Space"
}
}
EOT
}
variable "instance_password" {
type = string
sensitive = true
description = <<EOT
{
"Description": {
"en": "Server login password, Length 8~30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ Special symbol in).",
"zh-cn": "登入密碼,長度8~30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ 中的特殊符號)。"
},
"Label": {
"en": "Instance Password",
"zh-cn": "登入密碼"
},
"ConstraintDescription": {
"en": "Length 8~30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ Special symbol in).",
"zh-cn": "長度8~30,必須包含三項(大寫字母、小寫字母、數字、 ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ 中的特殊符號)。"
},
"AssociationProperty": "ALIYUN::ECS::Instance::Password",
"AllowedPattern": "^[a-zA-Z0-9-\\(\\)\\`\\~\\!\\@\\#\\$\\%\\^\\&\\*\\_\\-\\+\\=\\|\\{\\}\\[\\]\\:\\;\\<\\>\\,\\.\\?\\/]*$",
"MinLength": 8,
"MaxLength": 30
}
EOT
}
# 預設資源名稱。
locals {
production_name = "nginx"
new_scg_name = "sg-for-${local.production_name}"
new_host_name = "app-for-${local.production_name}"
}
resource "alicloud_vpc" "vpc" {
cidr_block = var.vpc_cidr_block
}
resource "alicloud_vswitch" "vsw" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = var.vswitch_cidr_block
zone_id = var.zone_id
}
# 安全性群組基本資料配置
resource "alicloud_security_group" "security_group" {
name = local.new_scg_name
description = "nginx scg"
vpc_id = alicloud_vpc.vpc.id
}
# 安全性群組入口端1
resource "alicloud_security_group_rule" "allow_ssh" {
security_group_id = alicloud_security_group.security_group.id
type = "ingress"
cidr_ip = "0.0.0.0/0"
policy = "accept"
ip_protocol = "tcp"
port_range = "22/22"
priority = 1
}
# 安全性群組入口端2
resource "alicloud_security_group_rule" "allow_web" {
security_group_id = alicloud_security_group.security_group.id
type = "ingress"
cidr_ip = "0.0.0.0/0"
policy = "accept"
ip_protocol = "tcp"
port_range = "80/443"
priority = 1
}
# 安全性群組出口端
resource "alicloud_security_group_rule" "allow_egress" {
security_group_id = alicloud_security_group.security_group.id
type = "egress"
cidr_ip = "0.0.0.0/0"
policy = "accept"
ip_protocol = "tcp"
port_range = "1/65535"
priority = 1
}
# 執行個體基本配置
resource "alicloud_instance" "instance" {
availability_zone = var.zone_id
security_groups = [alicloud_security_group.security_group.id]
# series III
host_name = local.new_host_name
instance_type = var.instance_type
system_disk_size = var.system_disk_size
system_disk_category = var.system_disk_category
image_id = "centos_7_9_x64_20G_alibase_20210318.vhd"
vswitch_id = alicloud_vswitch.vsw.id
password = var.instance_password
internet_charge_type = "PayByTraffic"
internet_max_bandwidth_out = 30
instance_charge_type = var.pay_type
period = var.pay_period
period_unit = var.pay_period_unit
user_data = file("${path.cwd}/user-data.sh")
data_disks {
size = var.data_disk_size
category = var.data_disk_category
}
}
# 返回Nginx的IP地址
output "nginx_ip" {
value = "http://${alicloud_instance.instance.public_ip}:8080"
}
user-data.sh: |-
#!/bin/bash -v
# 掛盤到/disk1
cat >> /root/InitDataDisk.sh << "EOF"
#!/bin/bash
echo "p
n
p
w
" | fdisk -u /dev/vdb
EOF
/bin/bash /root/InitDataDisk.sh
rm -f /root/InitDataDisk.sh
mkfs -t ext4 /dev/vdb1
cp /etc/fstab /etc/fstab.bak
mkdir /disk1
echo `blkid /dev/vdb1 | awk '{print $2}' | sed 's/\\\"//g'` /disk1 ext4 defaults 0 0 >> /etc/fstab
mount -a
# 這裡配置安裝指令碼
yum install -y nginx
# 配置啟動指令碼
/usr/sbin/nginx