This topic describes how to deploy NGINX on an Elastic Compute Service (ECS) instance by using a Terraform template.
Prerequisites
You are familiar with the syntax and the structure of ROS templates. For more information, see Getting started with templates.
Sample scenario
Create an ECS instance of the virtual private cloud (VPC) network type in the Alibaba Cloud Management Console to deploy NGINX.
Usage notes
You can view the resource types of the preceding resources to obtain the details of each resource property. For more information, see View resource types.
Each resource type topic provides information about the required and optional resource properties. You must declare the required resource properties of the resource type that you want to use in the Resources section of a Terraform template.
Create a template
To find the resource types that your business requires, see List of resource types by service.
In this example, the following resource types are used: alicloud_vpc, alicloud_instance, alicloud_vswitch, alicloud_security_group, and alicloud_security_group_rule. NGINX is deployed at the same time the ECS instance is created.
Define resources and resource dependencies in the template
Define basic network resources
You can define the following basic network resources: vpc
, vsw
, and security_group
.
Use
alicloud_vpc.vpc.id
to query the output ID ofalicloud_vpc
.Use
var.***
to query the value of a custom variable that is defined in thevariable
field. For example, you can usevar.zone_id
to query the value ofzone_id
that is defined in thevariable
field.
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
}
Define security group rules
You can define the following security group rules: allow_ssh
, allow_web
, and allow_egress
.
Use alicloud_security_group.security_group.id
to query the output ID of security_group
.
# Ingress port 1 of the security group
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
}
# Ingress port 2 of the security group
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
}
# The egress port of the security group
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
}
Define an ECS instance
You can define an ECS instance
in the template.
Use
var.***
to query the value of a custom variable that is defined in thevariable
field. For example, you can usevar.instance_type
to query the value ofinstance_type
that is defined in thevariable
field.Use
local.***
to query the value of a local variable that is defined in thelocals
field. For example, you can uselocal.new_host_name
to query the value ofnew_host_name
that is defined in thelocals
field.Use
${path.cwd}
in user_data to query the current working directory.The user_data.sh file provides the initialization script that must be executed on the ECS instance. Sample initialization script:
#!/bin/bash -v
# Mount the disk to /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
# Configure the installation script.
yum install -y nginx
# Configure the startup script.
/usr/sbin/nginx
The following code provides a sample template that defines an ECS instance:
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"
}
}
Complete sample template
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
}
# The default resource name
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
}
// Basic security group configurations
resource "alicloud_security_group" "security_group" {
name = local.new_scg_name
description = "nginx scg"
vpc_id = alicloud_vpc.vpc.id
}
# Ingress port 1 of the security group
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
}
# Ingress port 2 of the security group
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
}
# The egress port of the security group
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
}
# Basic instance configurations
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
}
}
# The returned IP address of NGINX
output "nginx_ip" {
value = "http://${alicloud_instance.instance.public_ip}:8080"
}
Convert a Terraform template
You can convert a Terraform template into an ROS template in the ROS console. If you use ROS, you can group template parameters and dynamically obtain the parameter settings.
Log on to the ROS console.
In the left-side navigation pane, choose Templates > My Templates.
On the My Templates page, click Create Template.
On the Modify Template Content tab, select Terraform from the drop-down list.
Modify the content of a Terraform template.
Create a main.tf file and enter the content of the sample Terraform template.
Create a user-data.sh file and enter the content of the user_data.sh initialization script.
On the Modify Template Content tab, select ROS from the drop-down list.
The Terraform template is converted into an ROS template. Sample ROS template:
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 } # The default resource name. 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 } // Basic security group configurations resource "alicloud_security_group" "security_group" { name = local.new_scg_name description = "nginx scg" vpc_id = alicloud_vpc.vpc.id } # Ingress port 1 of the security group 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 } # Ingress port 2 of the security group 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 } # The egress port of the security group 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 } # Basic instance configurations 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" } } # The returned IP address of NGINX output "nginx_ip" { value = "http://${alicloud_instance.instance.public_ip}:8080" } user-data.sh: |- #!/bin/bash -v # Mount the disk to /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 # Configure the installation script. yum install -y nginx # Configure the startup script. /usr/sbin/nginx
Add parameter groups and dynamically obtain parameter settings
The preceding template includes the resources and resource dependencies that are required by your business. In the template, the value of system_disk_category
is static. If you want to create and deploy a stack by using this template in another region, you must modify the template content and change the resource properties.
In this case, you can add the Parameters section to the template to improve the flexibility and reusability of the template.
Add parameter groups
You can use Metadata to group the parameters that are defined in the Parameters section and define a label for each group. For more information, see Metadata.
You can group parameters based on the resources that correspond to the parameters. The following table uses the preceding template as an example to describe how to group parameters.
Group | Resource | Parameter |
Basic network configurations |
|
|
ECS instance configurations |
|
|
On the Terraform tab, create a .metadata
file and enter the following content:
{
"ALIYUN::ROS::Interface": {
"ParameterGroups": [
{
"Parameters": [
"pay_type",
"pay_period_unit",
"pay_period"
],
"Label": {
"default": {
"en": "Payment mode Configuration",
}
}
},
{
"Parameters": [
"zone_id"
],
"Label": {
"default": {
"en": "Zone Configuration"
}
}
},
{
"Parameters": [
"vpc_cidr_block",
"vswitch_cidr_block"
],
"Label": {
"default": {
"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",
}
}
}
]
}
}
Dynamically obtain parameter settings
The following section uses the instance parameter as an example to describe how to dynamically obtain parameter settings. If you want to configure filter conditions for the instance parameter in the ROS console and dynamically obtain the setting of the parameter based on different filter conditions, you can use the ALIYUN::ECS::Instance resource type that corresponds to the instance parameter to query the value of AssociationProperty
that is supported by the instance parameter in the "AssociationProperty and AssociationPropertyMetadata" topic of the ROS documentation. Then, you can query the value of AssociationPropertyMetadata that is supported by the instance parameter when ZoneId
is used as the filter condition of AssociationProperty
. In this example, the value of AssociationProperty that is supported by the instance parameter is ALIYUN::ECS::Instance::InstanceType
. For more information, see AssociationProperty and AssociationPropertyMetadata.
On the Terraform tab, enter the following content in the main.tf
file:
variable "pay_type" {
type = string
default = "PostPaid"
description = <<EOT
{
"Label": {
"en": "ECS Instance Charge Type",
},
"AllowedValues": [
"PostPaid",
"PrePaid"
],
"AssociationProperty": "ChargeType",
"AssociationPropertyMetadata": {
"LocaleKey": "InstanceChargeType"
}
}
EOT
}
variable "pay_period_unit" {
type = string
default = "Month"
description = <<EOT
{
"Label": {
"en": "Pay Period Unit",
},
"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",
},
"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": {
</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": {
"en": "VSwitch Availability Zone"
}
}
EOT
}
variable "vpc_cidr_block" {
type = string
default = "192.168.0.0/16"
description = <<EOT
{
"Label": {
"en": "VPC CIDR Block"
},
"Description": {
</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": {
"en": "Must be a sub-network segment of the proprietary network and is not occupied by other VSwitches."
},
"Label": {
"en": "VSwitch CIDR Block"
}
}
EOT
}
variable "instance_type" {
type = string
description = <<EOT
{
"Label": {
"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>]",
},
"AssociationProperty": "ALIYUN::ECS::Disk::SystemDiskCategory",
"AssociationPropertyMetadata": {
"ZoneId": "$${zone_id}",
"InstanceType": "$${instance_type}"
},
"Label": {
"en": "System Disk Type",
}
}
EOT
}
variable "system_disk_size" {
type = number
default = 40
description = <<EOT
{
"Description": {
"en": "System disk size, range of values: 40~500, units: GB."
},
"Label": {
"en": "System Disk Space"
}
}
EOT
}
variable "data_disk_category" {
type = string
description = <<EOT
{
"Label": {
"en": "Data Disk Type"
},
"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>]"
},
"AssociationProperty": "ALIYUN::ECS::Disk::DataDiskCategory",
"AssociationPropertyMetadata": {
"ZoneId": "$${zone_id}",
"InstanceType": "$${instance_type}"
}
}
EOT
}
variable "data_disk_size" {
type = number
default = 100
description = <<EOT
{
"Description": {
"en": "ECS Instance disk size, range of values: 20~32768, units: GB"
},
"MaxValue": 32768,
"MinValue": 20,
"Label": {
"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).",
},
"Label": {
"en": "Instance Password",
},
"ConstraintDescription": {
"en": "Length 8~30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ Special symbol in).",
},
"AssociationProperty": "ALIYUN::ECS::Instance::Password",
"AllowedPattern": "^[a-zA-Z0-9-\\(\\)\\`\\~\\!\\@\\#\\$\\%\\^\\&\\*\\_\\-\\+\\=\\|\\{\\}\\[\\]\\:\\;\\<\\>\\,\\.\\?\\/]*$",
"MinLength": 8,
"MaxLength": 30
}
EOT
}
Add template parameter dependencies and constraints
The preceding template defines an ECS instance. You need to add constraints for the following parameters to the template: zone_id
, instance_type
, vswitch_id
, system_disk_category
, system_disk_size
, data_disk_category
, and data_disk_size
. The preceding parameters are related to the alicloud_instance
parameter.
In the ResourcesForParameterConstraints field, you need to only define the ALIYUN::ECS::Instance resource type (alicloud_instance
) and associate the resource type with image_id
, instance_type
, and zone_id
to add constraints.
{
"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",
}
}
},
{
"Parameters": [
"zone_id"
],
"Label": {
"default": {
"en": "Zone Configuration"
}
}
},
{
"Parameters": [
"vpc_cidr_block",
"vswitch_cidr_block"
],
"Label": {
"default": {
"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",
}
}
}
]
}
}
Complete sample template
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",
}
}
},
{
"Parameters": [
"zone_id"
],
"Label": {
"default": {
"en": "Zone Configuration"
}
}
},
{
"Parameters": [
"vpc_cidr_block",
"vswitch_cidr_block"
],
"Label": {
"default": {
"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",
}
}
}
]
}
}
main.tf: |-
variable "pay_type" {
type = string
default = "PostPaid"
description = <<EOT
{
"Label": {
"en": "ECS Instance Charge Type",
},
"AllowedValues": [
"PostPaid",
"PrePaid"
],
"AssociationProperty": "ChargeType",
"AssociationPropertyMetadata": {
"LocaleKey": "InstanceChargeType"
}
}
EOT
}
variable "pay_period_unit" {
type = string
default = "Month"
description = <<EOT
{
"Label": {
"en": "Pay Period Unit",
},
"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",
},
"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": {
</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": {
"en": "VSwitch Availability Zone"
}
}
EOT
}
variable "vpc_cidr_block" {
type = string
default = "192.168.0.0/16"
description = <<EOT
{
"Label": {
"en": "VPC CIDR Block"
},
"Description": {
</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": {
"en": "Must be a sub-network segment of the proprietary network and is not occupied by other VSwitches."
},
"Label": {
"en": "VSwitch CIDR Block"
}
}
EOT
}
variable "instance_type" {
type = string
description = <<EOT
{
"Label": {
"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>]",
},
"AssociationProperty": "ALIYUN::ECS::Disk::SystemDiskCategory",
"AssociationPropertyMetadata": {
"ZoneId": "$${zone_id}",
"InstanceType": "$${instance_type}"
},
"Label": {
"en": "System Disk Type",
}
}
EOT
}
variable "system_disk_size" {
type = number
default = 40
description = <<EOT
{
"Description": {
"en": "System disk size, range of values: 40~500, units: GB."
},
"Label": {
"en": "System Disk Space"
}
}
EOT
}
variable "data_disk_category" {
type = string
description = <<EOT
{
"Label": {
"en": "Data Disk Type"
},
"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>]"
},
"AssociationProperty": "ALIYUN::ECS::Disk::DataDiskCategory",
"AssociationPropertyMetadata": {
"ZoneId": "$${zone_id}",
"InstanceType": "$${instance_type}"
}
}
EOT
}
variable "data_disk_size" {
type = number
default = 100
description = <<EOT
{
"Description": {
"en": "ECS Instance disk size, range of values: 20~32768, units: GB."
},
"MaxValue": 32768,
"MinValue": 20,
"Label": {
"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).",
},
"Label": {
"en": "Instance Password",
},
"ConstraintDescription": {
"en": "Length 8~30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;<>,.?/ Special symbol in).",
},
"AssociationProperty": "ALIYUN::ECS::Instance::Password",
"AllowedPattern": "^[a-zA-Z0-9-\\(\\)\\`\\~\\!\\@\\#\\$\\%\\^\\&\\*\\_\\-\\+\\=\\|\\{\\}\\[\\]\\:\\;\\<\\>\\,\\.\\?\\/]*$",
"MinLength": 8,
"MaxLength": 30
}
EOT
}
# The default resource names.
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
}
// The basic information about security groups.
resource "alicloud_security_group" "security_group" {
name = local.new_scg_name
description = "nginx scg"
vpc_id = alicloud_vpc.vpc.id
}
# Ingress port 1 of the security group
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
}
# Ingress port 2 of the security group
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
}
# The egress port of the security group
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
}
# Basic instance configurations
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
}
}
# The returned IP address of NGINX
output "nginx_ip" {
value = "http://${alicloud_instance.instance.public_ip}:8080"
}
user-data.sh: |-
#!/bin/bash -v
# Mount the disk to /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
# Configure the installation script.
yum install -y nginx
# Configure the startup script.
/usr/sbin/nginx