すべてのプロダクト
Search
ドキュメントセンター

Resource Orchestration Service:Terraform を使用した ECS インスタンスへの NGINX のデプロイ

最終更新日:Aug 29, 2026

Alibaba Cloud Resource Orchestration Service (ROS) は、Terraform テンプレートを使用して、完全なクラウドネットワークインフラストラクチャと Elastic Compute Service (ECS) インスタンスを自動的に作成し、単一の操作でインスタンスに NGINX をインストールして起動します。このソリューションは、Web サーバー環境を迅速かつ繰り返し構築する必要があるシナリオに適しています。

ソリューションの概要

このソリューションでは、Alibaba Cloud Resource Orchestration Service (ROS) を通じて Terraform テンプレートを実行し、完全なクラウドネットワークインフラストラクチャと ECS インスタンスを 1 回の操作で自動的に作成し、ECS インスタンスに NGINX サービスを自動的にインストールして起動します。Web サーバー環境を迅速かつ繰り返し構築する必要があるシナリオに適用されます。

ビジネスシナリオ

Alibaba Cloud VPC に ECS インスタンスを作成し、ポート 22 での Secure Shell (SSH) アクセスとポート 80 から 443 での HTTP/HTTPS アクセスを許可するセキュリティグループを構成し、データディスクをアタッチし、user_data 初期化スクリプトを使用して NGINX サービスを自動的にインストールして起動します。

テンプレートによって作成されるリソース

No.

リソース

Terraform リソースタイプ

説明

1

VPC

alicloud_vpc

分離されたネットワーク環境を提供します

2

vSwitch

alicloud_vswitch

VPC 内にサブネットを割り当て、ゾーンを指定します

3

セキュリティグループ

alicloud_security_group

ECS インスタンスのネットワークアクセスルールを制御します

4

セキュリティグループルール (SSH)

alicloud_security_group_rule

ポート 22 でのインバウンドアクセスを許可します

5

セキュリティグループルール (Web)

alicloud_security_group_rule

ポート 80 から 443 でのインバウンドアクセスを許可します

6

セキュリティグループルール (アウトバウンド)

alicloud_security_group_rule

すべてのアウトバウンドトラフィックを許可します

7

ECS インスタンス

alicloud_instance

NGINX を実行するコンピューティングノード (データディスク付き)

デプロイ後の結果

テンプレートが正常に実行されると、次のリソースが取得されます:

  • VPC、vSwitch、セキュリティグループ、セキュリティグループルールを含む完全な VPC ネットワーク環境

  • 100 GB のデータディスクと割り当てられたパブリック IP アドレスを持つ 1 つの ECS インスタンス

  • ECS インスタンスに自動的にインストールされ、起動された NGINX サービス

  • 出力で返されたパブリック IP アドレスを介したデフォルトの NGINX ページへのアクセス

アーキテクチャ図

image

前提条件

このテンプレートを使用する前に、次の条件が満たされていることを確認してください:

  • アカウント権限:Alibaba Cloud アカウントに ECS および VPC リソースを作成する権限があること。

  • 基本知識:Terraform テンプレートの基本的な構文と構造に精通していること。詳細については、「Terraform テンプレートの構造」をご参照ください。

  • リソースタイプの表示Terraform Provider alicloud リソースインデックスで Terraform リソースプロパティの詳細を表示できます。各プロパティは Optional または Required としてマークされています。

テンプレート作成チュートリアル

このチュートリアルでは、Terraform テンプレートの作成プロセスを 2 つのステージで示します:

  • ステージ 1 (基本):固定のパラメータ値を使用し、Terraform リソースの定義と依存関係に焦点を当てます。

  • ステージ 2 (高度)AssociationProperty 動的パラメータフィルタリング、パラメータのグループ化、およびパラメータ制約を追加して、コンソールエクスペリエンスを向上させます。

ステージ 1: 基本テンプレート — リソースとその依存関係の定義

ステップ 1: 基本的なネットワークリソースの定義

基本的なネットワークリソースには、alicloud_vpcalicloud_vswitch、および alicloud_security_group が含まれ、他のすべてのリソースはこれらに基づいています。Terraform は、リソース間のプロパティ参照を通じて自動的に依存関係を確立します。

# ============================================================
# 基本的なネットワーク層リソース: VPC → VSwitch → SecurityGroup
# ============================================================

resource "alicloud_vpc" "vpc" {
  cidr_block = "192.168.0.0/16"  # VPC CIDR ブロック。最大 65,534 個のプライベート IP アドレスを保持
}

resource "alicloud_vswitch" "vsw" {
  vpc_id     = alicloud_vpc.vpc.id  # VPC ID を参照。Terraform は自動的に依存関係を確立
  cidr_block = "192.168.0.0/24"    # サブネット CIDR ブロック。VPC CIDR ブロックのサブセットである必要があります
  zone_id    = "cn-beijing-h"      # このシナリオでは、例として中国 (北京) リージョンのゾーン H を使用
}

resource "alicloud_security_group" "security_group" {
  name   = "sg-for-nginx"           # セキュリティグループ名
  vpc_id = alicloud_vpc.vpc.id      # セキュリティグループを同じ VPC にバインド
}

キーポイント:

  • 暗黙的な依存関係と明示的な依存関係 (depends_on)

    • alicloud_vswitch.vswvpc_id プロパティは alicloud_vpc.vpc.id を参照します。Terraform はこの依存関係を自動的に認識し、vSwitch の前に VPC が作成されるようにします。

    • depends_on (明示的な依存関係) は、2 つのリソース間に直接の参照がないが、ビジネスロジックが特定の順序を必要とする場合にのみ必要です。

ステップ 2: セキュリティグループルールの定義

alicloud_security_group_rule は、ECS インスタンスへのネットワークトラフィックの出入りを制御します。このシナリオでは、SSH リモート接続ポートと Web アクセスポートを開く必要があります。

# ============================================================
# セキュリティグループルール: インバウンド SSH + インバウンド Web + すべてのアウトバウンドトラフィックを許可
# ============================================================

# インバウンドルール 1: SSH ポート 22 を開く (リモート管理用)
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"  # すべての IP アドレスからのアクセスを許可 (本番環境では IP 範囲を制限)
  policy            = "accept"      # accept ポリシー
  ip_protocol       = "tcp"         # TCP プロトコル
  port_range        = "22/22"       # ポート範囲: ポート 22 のみ
  priority          = 1             # 優先度: 1 (最高)
}

# インバウンドルール 2: Web ポート 80 から 443 を開く (NGINX への HTTP/HTTPS アクセス)
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"      # ポート範囲: 80 から 443
  priority          = 1
}

# アウトバウンドルール: すべてのアウトバウンドトラフィックを許可 (ECS インスタンスは yum リポジトリなどの外部ネットワークにアクセス可能)
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
}

キーポイント:

  • Terraform のポート範囲の形式は "開始ポート/終了ポート" です。たとえば、"80/443" は 80 から 443 までのすべてのポートを示し、単一のポートは "22/22" と記述します。

  • 本番環境では、悪意のあるスキャンを避けるために、SSH ルールの cidr_ip をオフィスの IP アドレスに制限してください。

  • 8080 などの別のポートを開くには、別の alicloud_security_group_rule リソースを追加します。

ステップ 3: ECS インスタンスと初期化スクリプトの定義

alicloud_instance は NGINX を実行するコンピューティングノードです。user_data プロパティは、最初の起動時に実行される初期化スクリプトを指定します。

user_data 初期化スクリプト (user-data.sh):

#!/bin/bash -v
# ---- データディスクのフォーマットとマウント ----
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

# ---- NGINX のインストールと起動 ----
yum install -y nginx
/usr/sbin/nginx

ECS インスタンスリソースの定義:

# ============================================================
# コンピューティングレイヤー: ECS インスタンス (データディスク + NGINX 初期化)
# ============================================================

resource "alicloud_instance" "instance" {
  availability_zone          = "cn-beijing-h"
  security_groups            = [alicloud_security_group.security_group.id]  # セキュリティグループを配列形式でバインド
  host_name                  = "app-for-nginx"
  instance_type              = "ecs.c6e.large"        # インスタンスタイプ (コンピューティング最適化、2 vCPU、4 GiB メモリ)
  system_disk_size           = 100                     # システムディスクサイズ
  system_disk_category       = "cloud_essd"            # システムディスクタイプ
  image_id                   = "centos_7_9_x64_20G_alibase_20210318.vhd"  # CentOS 7.9 イメージ
  vswitch_id                 = alicloud_vswitch.vsw.id # インスタンスを vSwitch にバインド
  password                   = "<YourPassword>"        # デプロイ時に実際のパスワードに置き換えてください (大文字、小文字、数字、特殊文字を含む必要があります)
  internet_charge_type       = "PayByTraffic"          # パブリック帯域幅のトラフィック課金
  internet_max_bandwidth_out = 30                      # 30 Mbit/s のアウトバウンドパブリック帯域幅
  instance_charge_type       = "PostPaid"              # 課金タイプ (従量課金またはサブスクリプション)
  user_data                  = file("${path.cwd}/user-data.sh")  # 初期化スクリプトをロード

  data_disks {              # データディスク構成
    size     = 100          # データディスクサイズ
    category = "cloud_essd" # データディスクタイプ
  }
}

# NGINX アクセス URL を出力
output "nginx_ip" {
  value = "http://${alicloud_instance.instance.public_ip}:80"
}

キーポイント: Terraform 変数参照メソッド

参照メソッド

構文

説明

変数参照

var.variable_name

variable ブロックで定義されたパラメータの値を取得します (高度なテンプレートで実証)

リソースプロパティ参照

resource_type.resource_name.property

alicloud_vpc.vpc.idalicloud_instance.instance.public_ip など、別のリソースの出力プロパティを取得します

ファイル読み込み

file("${path.cwd}/file_name")

現在の作業ディレクトリにあるファイルの内容を読み込みます

テンプレートの拡張とバリエーション:

  • user_datafile() 関数を使用して外部スクリプトファイルを読み込みます。これにより、スクリプトの保守と再利用が容易になります。

  • internet_max_bandwidth_out = 30 は 30 Mbit/s のアウトバウンド帯域幅を設定し、ECS インスタンスは自動的にパブリック IP アドレスを取得します。

  • data_disks ブロックは複数のデータディスクを追加できます。データディスクがアタッチされていない場合は省略できます。

  • テンプレートがリソースを作成した後、テンプレートの output 情報は、それらのリソースの内部プロパティを直接クエリできます。したがって、output ブロックを定義して、ECS インスタンスのパブリックアクセスアドレス (NGINX サービスのアクセスアドレス) を返すことができます。

完全な基本テンプレート

Terraform テンプレートは次のように構成されています。

main.tf ファイルの内容:

resource "alicloud_vpc" "vpc" {
  cidr_block = "192.168.0.0/16"
}

resource "alicloud_vswitch" "vsw" {
  vpc_id     = alicloud_vpc.vpc.id
  cidr_block = "192.168.0.0/24"
  zone_id    = "cn-beijing-h"
}

# 基本的なセキュリティグループ構成
resource "alicloud_security_group" "security_group" {
  name        = "sg-for-nginx"
  description = "nginx scg"
  vpc_id      = alicloud_vpc.vpc.id
}

# インバウンドルール 1: SSH
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: Web
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          = "cn-beijing-h"
  security_groups            = [alicloud_security_group.security_group.id]
  host_name                  = "app-for-nginx"
  instance_type              = "ecs.c6e.large"
  system_disk_size           = 100
  system_disk_category       = "cloud_essd"
  image_id                   = "centos_7_9_x64_20G_alibase_20210318.vhd"
  vswitch_id                 = alicloud_vswitch.vsw.id
  password                   = "<YourPassword>"  # デプロイ時に実際のパスワードに置き換えてください
  internet_charge_type       = "PayByTraffic"
  internet_max_bandwidth_out = 30
  instance_charge_type       = "PostPaid"
  user_data                  = file("${path.cwd}/user-data.sh")

  data_disks {
    size     = 100
    category = "cloud_essd"
  }
}

# NGINX アクセス URL を返す
output "nginx_ip" {
  value = "http://${alicloud_instance.instance.public_ip}:80"
}

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
# NGINX をインストール
yum install -y nginx
# NGINX を起動
/usr/sbin/nginx

次のテンプレートは、上記の 3 つのステップを組み合わせた、すぐに使用できる完全なテンプレートです。ROS を使用して Terraform テンプレートをデプロイするには、テンプレートを ROS Workspace 形式でラップする必要があります。

ROS Workspace 形式の完全なテンプレート:

ROSTemplateFormatVersion: '2015-09-01'
Transform: Aliyun::Terraform-v1.2
Workspace:
  main.tf: |-

    resource "alicloud_vpc" "vpc" {
      cidr_block = "192.168.0.0/16"
    }

    resource "alicloud_vswitch" "vsw" {
      vpc_id     = alicloud_vpc.vpc.id
      cidr_block = "192.168.0.0/24"
      zone_id    = "cn-beijing-h"
    }

    # 基本的なセキュリティグループ構成
    resource "alicloud_security_group" "security_group" {
      name        = "sg-for-nginx"
      description = "nginx scg"
      vpc_id      = alicloud_vpc.vpc.id
    }

    # インバウンドルール 1: SSH
    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: Web
    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          = "cn-beijing-h"
      security_groups            = [alicloud_security_group.security_group.id]
      host_name                  = "app-for-nginx"
      instance_type              = "ecs.c6e.large"
      system_disk_size           = 100
      system_disk_category       = "cloud_essd"
      image_id                   = "centos_7_9_x64_20G_alibase_20210318.vhd"
      vswitch_id                 = alicloud_vswitch.vsw.id
      password                   = "<YourPassword>"
      internet_charge_type       = "PayByTraffic"
      internet_max_bandwidth_out = 30
      instance_charge_type       = "PostPaid"
      user_data                  = file("${path.cwd}/user-data.sh")

      data_disks {
        size     = 100
        category = "cloud_essd"
      }
    }

    # NGINX アクセス URL を返す
    output "nginx_ip" {
      value = "http://${alicloud_instance.instance.public_ip}:80"
    }
  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
    # NGINX をインストール
    yum install -y nginx
    # NGINX を起動
    /usr/sbin/nginx

ステージ 2: 高度なテンプレート — パラメータ化と動的構成

基本テンプレートでは variable ブロックや、variable がサポートする descriptiondefault などの動的フィルタリング構成が定義されていません。基本テンプレートを ROS コンソールで使用すると、パラメータが相互にリンクされず、選択したゾーンで在庫切れのインスタンスタイプなど、無効な組み合わせが選択される可能性があります。

次の最適化により、コンソールエクスペリエンスとテンプレートの再利用性が大幅に向上します:

  • 動的パラメータフィルタリング (AssociationProperty)variabledescription に JSON 形式で AssociationProperty を構成することで、コンソールが利用可能なオプションを自動的にフィルタリングします。

  • 条件付き表示 (Visible.Condition):課金タイプに基づいてサブスクリプション期間パラメータを動的に表示または非表示にします。

  • パラメータのグループ化 (.metadata ファイル):.metadata ファイルに ParameterGroups を構成することで、コンソールがパラメータを論理グループで表示します。

  • パラメータ制約 (ResourcesForParameterConstraints):.metadata ファイルにリソース制約を定義して、パラメータの組み合わせが有効であることを確認します。

パラメータ依存関係グラフ

pay_type (課金タイプ)
  ├── pay_period_unit (期間単位、PrePaid のみ表示)
  └── pay_period (サブスクリプション期間、PrePaid のみ表示)

zone_id (ゾーン、コアフィルターパラメータ)
  ├── instance_type (インスタンスタイプ、ゾーン + 課金タイプでフィルタリング)
  │    ├── system_disk_category (システムディスクタイプ、ゾーン + インスタンスタイプでフィルタリング)
  │    └── data_disk_category (データディスクタイプ、ゾーン + インスタンスタイプでフィルタリング)

コアアプローチ:まずゾーンと ECS 課金タイプを選択し、それに応じて ECS インスタンスタイプをフィルタリングします (サブスクリプション課金タイプが選択されている場合は、期間単位とサブスクリプション期間も選択する必要があります)。最後に、ゾーンと ECS インスタンスタイプに基づいてディスクタイプをフィルタリングします。各ステップでは、現在の条件下で利用可能なオプションのみが表示され、無効な組み合わせを防ぎます。

AssociationProperty の仕組み

1. zone_id — ゾーン (基本パラメータ)

AssociationPropertyALIYUN::ECS::ZoneId に設定して、現在のリージョン内のすべてのゾーンをリスト表示して選択できるようにします。例:

variable "zone_id" {
  type        = string
  description = <<EOT
  {
    # AssociationProperty は、パラメータが関連付けられているリソースプロパティタイプを指定します
    # ROS コンソールは、この構成に基づいて利用可能な値をリスト表示します
    "AssociationProperty": "ALIYUN::ECS::ZoneId",
    "Label": {
      "zh-cn": "VSwitch 可用性ゾーン",
      "en": "VSwitch Availability Zone"
    },
    "Description": {
      "zh-cn": "後続のパラメータフィルタリングのために可用性ゾーンを選択します",
      "en": "Select availability zone for resource filtering"
    }
  }
  EOT
}

このパラメータは、後続のすべてのパラメータのフィルタリングの基礎となります。ゾーンが選択されると、他のパラメータのオプションリストがそれに応じて更新されます。

2. pay_type — ECS 支払いタイプ

pay_type パラメータを定義し、AssociationPropertyMetadata.Visible.Condition を使用して、条件に基づいてパラメータを動的に切り替えます。サブスクリプション期間パラメータは、サブスクリプション課金タイプ (PrePaid) が選択されている場合にのみ表示されます。例:

variable "pay_type" {
  type    = string
  default = "PostPaid"
  description = <<EOT
  {
    "Label": { "en": "ECS Instance Charge Type", "zh-cn": "支払いタイプ" },
    "AllowedValues": ["PostPaid", "PrePaid"],
    "AssociationProperty": "ChargeType"
  }
  EOT
}
variable "pay_period_unit" {
  type    = string
  default = "Month"
  description = <<EOT
  {
    "Label": { "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::Not": { "Fn::Equals": ["$${pay_type}", "PostPaid"] }
        }
      }
    }
  }
  EOT
}

ROS コンソールで従量課金タイプ (PostPaid) が選択されると、サブスクリプション期間パラメータは自動的に非表示になります。これらのパラメータは、サブスクリプション課金タイプ (PrePaid) が選択されている場合にのみ表示されます。

3. instance_type — ECS インスタンスタイプ

AssociationPropertyALIYUN::ECS::Instance::InstanceType に設定して、利用可能な ECS インスタンスタイプをリスト表示し、${zone_id}${pay_type} を関連付けて、指定されたゾーンで指定された課金タイプで利用可能なインスタンスタイプをフィルタリングします。例:

variable "instance_type" {
  type = string
  description = <<EOT
  {
    "Label": { "zh-cn": "インスタンスタイプ", "en": "Instance Type" },
    "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
    "AssociationPropertyMetadata": {
      "ZoneId": "$${zone_id}",
      "InstanceChargeType": "$${pay_type}"
    }
  }
  EOT
}

インスタンスタイプの在庫はゾーンによって異なります。フィルタリングしないと、ゾーンで在庫切れのインスタンスタイプが選択され、作成が失敗する可能性があります。

4. system_disk_category — システムディスクタイプ

AssociationPropertyALIYUN::ECS::Disk::SystemDiskCategory に設定して、利用可能なシステムディスクタイプをリスト表示し、${zone_id}${instance_type} を関連付けて、指定されたゾーンと指定された ECS インスタンスタイプでサポートされている ECS システムディスクタイプをフィルタリングします。例:

variable "system_disk_category" {
  type = string
  description = <<EOT
  {
    "Label": { "zh-cn": "システムディスクタイプ", "en": "System Disk Type" },
    "Description": {
      "zh-cn": "オプション: cloud_efficiency, cloud_ssd, cloud_essd",
      "en": "Options: cloud_efficiency, cloud_ssd, cloud_essd"
    },
    "AssociationProperty": "ALIYUN::ECS::Disk::SystemDiskCategory",
    "AssociationPropertyMetadata": {
      "ZoneId": "$${zone_id}",
      "InstanceType": "$${instance_type}"
    }
  }
  EOT
}

システムディスクタイプの可用性は、ゾーン (一部のゾーンは ESSD をサポートしていません) とインスタンスタイプ (一部のインスタンスタイプは特定のディスクタイプのみをサポートしています) の両方に依存します。

5. data_disk_category — データディスクタイプ

AssociationPropertyALIYUN::ECS::Disk::DataDiskCategory に設定して、利用可能なデータディスクタイプをリスト表示します。フィルタリングメカニズムはシステムディスクタイプと同じです。${zone_id}${instance_type} を関連付けて、現在のゾーンとインスタンスタイプの両方でサポートされているデータディスクタイプをフィルタリングします。例:

variable "data_disk_category" {
  type = string
  description = <<EOT
  {
    "Label": { "zh-cn": "データディスクタイプ", "en": "Data Disk Type" },
    "Description": {
      "zh-cn": "オプション: cloud_efficiency, cloud_ssd, cloud_essd",
      "en": "Options: cloud_efficiency, cloud_ssd, cloud_essd"
    },
    "AssociationProperty": "ALIYUN::ECS::Disk::DataDiskCategory",
    "AssociationPropertyMetadata": {
      "ZoneId": "$${zone_id}",
      "InstanceType": "$${instance_type}"
    }
  }
  EOT
}

動的パラメータフィルタリングテンプレート

variable "zone_id" {
  type        = string
  description = <<EOT
  {
    "AssociationProperty": "ALIYUN::ECS::ZoneId",
    "Label": {
      "zh-cn": "VSwitch 可用性ゾーン",
      "en": "VSwitch Availability Zone"
    },
    "Description": {
      "zh-cn": "後続のパラメータフィルタリングのために可用性ゾーンを選択します",
      "en": "Select availability zone for resource filtering"
    }
  }
  EOT
}
variable "pay_type" {
  type    = string
  default = "PostPaid"
  description = <<EOT
  {
    "Label": { "en": "ECS Instance Charge Type", "zh-cn": "支払いタイプ" },
    "AllowedValues": ["PostPaid", "PrePaid"],
    "AssociationProperty": "ChargeType"
  }
  EOT
}
variable "pay_period_unit" {
  type    = string
  default = "Month"
  description = <<EOT
  {
    "Label": { "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::Not": { "Fn::Equals": ["$${pay_type}", "PostPaid"] }
        }
      }
    }
  }
  EOT
}
variable "instance_type" {
  type = string
  description = <<EOT
  {
    "Label": { "zh-cn": "インスタンスタイプ", "en": "Instance Type" },
    "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
    "AssociationPropertyMetadata": {
      "ZoneId": "$${zone_id}",
      "InstanceChargeType": "$${pay_type}"
    }
  }
  EOT
}
variable "system_disk_category" {
  type = string
  description = <<EOT
  {
    "Label": { "zh-cn": "システムディスクタイプ", "en": "System Disk Type" },
    "Description": {
      "zh-cn": "オプション: cloud_efficiency, cloud_ssd, cloud_essd",
      "en": "Options: cloud_efficiency, cloud_ssd, cloud_essd"
    },
    "AssociationProperty": "ALIYUN::ECS::Disk::SystemDiskCategory",
    "AssociationPropertyMetadata": {
      "ZoneId": "$${zone_id}",
      "InstanceType": "$${instance_type}"
    }
  }
  EOT
}
variable "data_disk_category" {
  type = string
  description = <<EOT
  {
    "Label": { "zh-cn": "データディスクタイプ", "en": "Data Disk Type" },
    "Description": {
      "zh-cn": "オプション: cloud_efficiency, cloud_ssd, cloud_essd",
      "en": "Options: cloud_efficiency, cloud_ssd, cloud_essd"
    },
    "AssociationProperty": "ALIYUN::ECS::Disk::DataDiskCategory",
    "AssociationPropertyMetadata": {
      "ZoneId": "$${zone_id}",
      "InstanceType": "$${instance_type}"
    }
  }
  EOT
}

AssociationProperty のカスケードフィルターの仕組み

ROS コンソールでスタックを作成すると、パラメータはカスケードシーケンスで選択されます:

  • ゾーン (zone_id) を選択します。

  • ECS 課金タイプ (pay_type) を選択します。

  • ECS インスタンスタイプのドロップダウンリストが自動的に更新され、選択した課金タイプをサポートし、選択したゾーンで在庫があるインスタンスタイプのみが表示されます。

  • ECS インスタンスタイプを選択すると、システムディスクタイプとデータディスクタイプのドロップダウンリストが自動的に更新され、選択したゾーンと選択したインスタンスタイプの両方でサポートされているディスクタイプのみが表示されます。

    このようにして、各ステップでは現在の条件下で利用可能なオプションのみが表示され、無効なパラメータの組み合わせによるデプロイの失敗を最初から防ぎます。

メタデータのパラメータグループ化

MetadataALIYUN::ROS::Interface 構成は、パラメータを複数の論理グループに分割し、各グループにタイトルを付けます。コンソールはパラメータをグループごとに表示するため、指定するエクスペリエンスが大幅に向上します。

メタデータ構文構造

Terraform タブの下に .metadata ファイルを作成し、パラメータのグループ化 (ParameterGroups) とパラメータ制約 (ResourcesForParameterConstraints) を構成します:

{
  "ALIYUN::ROS::Interface": {
    "ResourcesForParameterConstraints": {
      "resource": {
        "Type": "ALIYUN::ECS::Instance",
        "Properties": {
        }
      }
    },
    "ParameterGroups": [
      {
        "Parameters": ["parameter_name_1", "parameter_name_2", "parameter_name_3"],
        "Label": { "default": { "zh-cn": "XXXX 構成", "en": "Configuration" } }
      }
    ]
  }
}

メタデータ構文ルール:

  • ParametersLabel は両方とも必須です。

  • Parameters にリストされているパラメータ名は、variable パラメータ名と完全に同じでなければなりません。

  • どのグループにも含まれていないパラメータは、コンソールのグループ化されていないエリアに表示されます。

このシナリオのパラメータグループ化設計

このテンプレートは、12 個のパラメータをリソースタイプごとに 3 つのグループに分割します:

┌─────────────────────────────────────────────────────┐
│  ネットワーク構成                                   │
│  ├── VSwitch ゾーン (zone_id)                         │
│  ├── VPC CIDR ブロック (vpc_cidr_block)                │
│  └── VSwitch CIDR ブロック (vswitch_cidr_block)        │
├─────────────────────────────────────────────────────┤
│  支払い構成                                         │
│  ├── ECS 課金タイプ (pay_type)                    │
│  ├── ECS サブスクリプション期間単位 (pay_period_unit) │
│  └── ECS サブスクリプション期間 (pay_period)         │
├─────────────────────────────────────────────────────┤
│  ECS インスタンス構成                               │
│  ├── ECS インスタンスタイプ (instance_type)              │
│  ├── システムディスクタイプ (system_disk_category)        │
│  ├── システムディスクサイズ (system_disk_size)            │
│  ├── データディスクタイプ (data_disk_category)            │
│  ├── データディスクサイズ (data_disk_size)                │
│  └── ECS インスタンスパスワード (instance_password)      │
└─────────────────────────────────────────────────────┘

.metadata ファイルの構成

Terraform タブの下に .metadata ファイルを作成し、パラメータのグループ化とパラメータ制約を構成します:

{
  "ALIYUN::ROS::Interface": {
    "ResourcesForParameterConstraints": {
      "instance": {
        "Type": "ALIYUN::ECS::Instance",
        "Properties": {
          "InstanceType": { "Ref": "instance_type" },
          "ImageId": "centos_7_9_x64_20G_alibase_20210318.vhd",
          "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": ["vpc_cidr_block", "zone_id", "vswitch_cidr_block"],
        "Label": { "default": { "zh-cn": "ネットワーク構成", "en": "Network Configuration" } }
      },
      {
        "Parameters": ["pay_type", "pay_period_unit", "pay_period"],
        "Label": { "default": { "zh-cn": "支払い構成", "en": "Payment Configuration" } }
      },
      {
        "Parameters": ["instance_type", "system_disk_category", "system_disk_size", "data_disk_category", "data_disk_size", "instance_password"],
        "Label": { "default": { "zh-cn": "ECS インスタンス構成", "en": "ECS Instance Configuration" } }
      }
    ]
  }
}

キーポイント:

  • 仮想 ALIYUN::ECS::Instance リソースが定義され、テンプレート内のパラメータを ECS リソースのプロパティに関連付けます。

  • ROS コンソールは、この定義に基づいて、指定されたゾーンが選択されたインスタンスタイプとディスクタイプをサポートしているかどうかなど、パラメータの組み合わせの有効性を検証します。

  • Ref 構文は、var. プレフィックスなしで Terraform 変数名を参照します。

完全な高度なテンプレート

次のテンプレートは、ROS Workspace 形式でラップされた完全な高度なテンプレートであり、ROS コンソールで直接デプロイできます:

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",
              "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": ["vpc_cidr_block", "zone_id", "vswitch_cidr_block"],
            "Label": { "default": { "zh-cn": "ネットワーク構成", "en": "Network Configuration" } }
          },
          {
            "Parameters": ["pay_type", "pay_period_unit", "pay_period"],
            "Label": { "default": { "zh-cn": "支払い構成", "en": "Payment Configuration" } }
          },
          {
            "Parameters": ["instance_type", "system_disk_category", "system_disk_size", "data_disk_category", "data_disk_size", "instance_password"],
            "Label": { "default": { "zh-cn": "ECS インスタンス構成", "en": "ECS Instance Configuration" } }
          }
        ]
      }
    }
  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::Not": { "Fn::Equals": ["$${pay_type}", "PostPaid"] }
            }
          }
        }
      }
      EOT
    }
    variable "zone_id" {
      type = string
      description = <<EOT
      {
        "AssociationProperty": "ALIYUN::ECS::ZoneId",
        "Label": { "zh-cn": "VSwitch 可用性ゾーン", "en": "VSwitch Availability Zone" },
        "Description": {
          "zh-cn": "可用性ゾーンを選択します。インスタンスタイプとディスクカテゴリはそれに応じてフィルタリングされます。",
          "en": "Select availability zone. Instance types and disk categories will be filtered accordingly."
        }
      }
      EOT
    }
    variable "vpc_cidr_block" {
      type    = string
      default = "192.168.0.0/16"
      description = <<EOT
      {
        "Label": { "zh-cn": "VPC CIDR ブロック", "en": "VPC CIDR Block" },
        "Description": {
          "zh-cn": "VPC IP 範囲。推奨: 10.0.0.0/8, 172.16.0.0/12, または 192.168.0.0/16",
          "en": "VPC IP range. Recommended: 10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16"
        }
      }
      EOT
    }
    variable "vswitch_cidr_block" {
      type    = string
      default = "192.168.0.0/24"
      description = <<EOT
      {
        "Label": { "zh-cn": "VSwitch CIDR ブロック", "en": "VSwitch CIDR Block" },
        "Description": {
          "zh-cn": "VPC CIDR のサブネットである必要があり、他の VSwitch と重複してはなりません",
          "en": "Must be a subnet of VPC CIDR and not overlap with other VSwitches"
        }
      }
      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
      {
        "Label": { "zh-cn": "システムディスクタイプ", "en": "System Disk Type" },
        "Description": {
          "zh-cn": "オプション: cloud_efficiency, cloud_ssd, cloud_essd",
          "en": "Options: cloud_efficiency, cloud_ssd, cloud_essd"
        },
        "AssociationProperty": "ALIYUN::ECS::Disk::SystemDiskCategory",
        "AssociationPropertyMetadata": {
          "ZoneId": "$${zone_id}",
          "InstanceType": "$${instance_type}"
        }
      }
      EOT
    }
    variable "system_disk_size" {
      type    = number
      default = 40
      description = <<EOT
      {
        "Label": { "zh-cn": "システムディスクサイズ", "en": "System Disk Size" },
        "Description": {
          "zh-cn": "システムディスクサイズ、範囲: 40~500 GB",
          "en": "System disk size, range: 40~500 GB"
        }
      }
      EOT
    }
    variable "data_disk_category" {
      type = string
      description = <<EOT
      {
        "Label": { "zh-cn": "データディスクタイプ", "en": "Data Disk Type" },
        "Description": {
          "zh-cn": "オプション: cloud_efficiency, cloud_ssd, cloud_essd",
          "en": "Options: cloud_efficiency, cloud_ssd, cloud_essd"
        },
        "AssociationProperty": "ALIYUN::ECS::Disk::DataDiskCategory",
        "AssociationPropertyMetadata": {
          "ZoneId": "$${zone_id}",
          "InstanceType": "$${instance_type}"
        }
      }
      EOT
    }
    variable "data_disk_size" {
      type    = number
      default = 100
      description = <<EOT
      {
        "Label": { "zh-cn": "データディスク容量", "en": "Data Disk Space" },
        "Description": {
          "zh-cn": "ECS データディスクサイズ、範囲: 20~32768 GiB",
          "en": "ECS data disk size, range: 20~32768 GiB"
        },
        "MaxValue": 32768,
        "MinValue": 20
      }
      EOT
    }
    variable "instance_password" {
      type      = string
      sensitive = true
      description = <<EOT
      {
        "Label": { "zh-cn": "ログインパスワード", "en": "Instance Password" },
        "Description": {
          "zh-cn": "長さ 8-30、大文字、小文字、数字、特殊文字のうち少なくとも 3 種類を含む必要があります",
          "en": "Length 8-30, must contain at least 3 of: uppercase, lowercase, digits, special characters"
        },
        "AssociationProperty": "ALIYUN::ECS::Instance::Password",
        "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
    }

    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
    }

    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]
      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
      }
    }

    output "nginx_ip" {
      value = "http://${alicloud_instance.instance.public_ip}:80"
    }
  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
    # NGINX をインストール
    yum install -y nginx
    # NGINX を起動
    /usr/sbin/nginx

Terraform テンプレート構文クイックリファレンス

構文

このテンプレートでの目的

var.variable_name

var.zone_id

変数で定義された入力パラメータ値を参照します

local.variable_name

local.new_host_name

locals ブロックで定義されたローカル変数を参照します

resource_type.name.property

alicloud_vpc.vpc.id

別のリソースの出力プロパティを参照し、自動的に依存関係を確立します

file("path")

file("${path.cwd}/user-data.sh")

外部ファイルの内容をプロパティ値として読み込みます

"${expression}"

"sg-for-${local.production_name}"

文字列補間。文字列に変数の値を埋め込みます

<<EOT ... EOT

description = <<EOT {...} EOT

複数行文字列。JSON 構成を埋め込むために使用されます

$${variable_name}

"$${pay_type}"

description の JSON 内で別の変数の現在の値を参照します

デプロイ

デプロイパラメータ

必須入力パラメータ (デプロイ時に指定する必要があります)

パラメータ

タイプ

説明

制約

zone_id

String

vSwitch ゾーン

コンソールでの動的選択

instance_type

String

ECS インスタンスタイプ

ゾーンによって自動的にフィルタリング

system_disk_category

String

システムディスクタイプ

ゾーン + インスタンスタイプによって自動的にフィルタリング

data_disk_category

String

データディスクタイプ

ゾーン + インスタンスタイプによって自動的にフィルタリング

instance_password

String

ECS ログインパスワード

長さ 8~30 文字で、大文字、小文字、数字、特殊文字を含む必要があります

オプションパラメータ (デフォルト値があり、変更しないことも可能です)

パラメータ

デフォルト

説明

pay_type

PostPaid

課金タイプ (PostPaid は従量課金、PrePaid はサブスクリプション)

pay_period_unit

Month

サブスクリプション期間単位 (PrePaid のみ表示)

pay_period

1

サブスクリプション期間 (PrePaid のみ表示)

vpc_cidr_block

192.168.0.0/16

VPC CIDR ブロック範囲

vswitch_cidr_block

192.168.0.0/24

vSwitch サブネット CIDR ブロック

system_disk_size

40

システムディスクサイズ (GB)、有効値: 40~500

data_disk_size

100

データディスクサイズ (GiB)、有効値: 20~32768

デプロイ方法

方法 1: ROS コンソール経由でのデプロイ

  1. ROS コンソールにログインします。

  2. 左側のナビゲーションウィンドウで、[テンプレート] > [マイテンプレート] > [テンプレートの作成] を選択します。

  3. テンプレートタイプとして、テラフォーム テンプレートを選択します。

  4. main.tf ファイルを作成し、高度なテンプレートから main.tf の内容を貼り付けます。

  5. user-data.sh ファイルを作成し、user-data.sh スクリプトの内容を貼り付けます。

  6. .metadata ファイルを作成し、.metadata JSON 構成を貼り付けます。

  7. テンプレートを保存した後、[スタック] > [スタックの作成] > [既存のテンプレートを選択] > [マイテンプレート] に移動し、テンプレートを選択します。

  8. 構成パラメータをグループごとに指定し、[作成] をクリックします。

  9. スタックのステータスが CREATE_COMPLETE に変わるまで待ち、[出力] タブで NGINX アクセス URL を表示します。

方法 2: ROS IaC Code 経由でのデプロイ

IaC Code は、自然言語プロンプトを通じてインフラストラクチャテンプレートを生成、デプロイ、管理する、クラウドインフラストラクチャ向けの AI コードとしてのインフラストラクチャ (IaC) アシスタントです。そのアーキテクチャは、マルチクラウドワークフロー向けに設計されています。次のプロンプトは、このソリューションの参照プロンプトです:

# プロンプト

Terraform テンプレートを使用して ECS インスタンスを作成し、NGINX サービスをデプロイするのを手伝ってください。
要件:
1. 基本ネットワークとして新しい VPC と `vSwitch` を作成します。
2. セキュリティグループは、ポート 22 (SSH) とポート 80 から 443 (Web アクセス) でのインバウンドアクセスを許可します。
3. ECS インスタンスにはパブリック IP アドレスが必要で、アウトバウンド帯域幅は 30 Mbit/s です。
4. 100 GB のデータディスクをアタッチし、フォーマットして /disk1 にマウントします。
5. user_data スクリプトを通じて NGINX を自動的にインストールして起動します。
6. zone_id、instance_type、system_disk_category、および data_disk_category はすべて AssociationProperty 動的フィルタリングが必要です。
7. 課金タイプパラメータには条件付き表示が必要です (サブスクリプション期間はサブスクリプション課金の場合にのみ表示されます)。

よくある質問

Q1: デプロイがエラーメッセージ "The specified InstanceType is not available in the zone" で失敗します

原因:選択した ECS インスタンスタイプが指定されたゾーンで在庫切れです。

ソリューション:

  • 高度なテンプレートでは、AssociationPropertyResourcesForParameterConstraints と連携して利用可能なインスタンスタイプを自動的にフィルタリングするため、この問題を防ぎます。

  • 基本テンプレートを使用する場合は、Elastic Compute Service (ECS) 料金でターゲットゾーンのインスタンスタイプの在庫を確認してください。

Q2: ECS インスタンスは作成されましたが、NGINX ページにアクセスできません

トラブルシューティング手順:

  • セキュリティグループルールがポート 80 でのインバウンドアクセスを許可しているかどうかを確認します (allow_web ルールを確認)。

  • ECS インスタンスにログインし、systemctl status nginx を実行して NGINX が期待どおりに実行されているかどうかを確認します。

  • user_data スクリプトが正常に実行されたかどうかを確認します:cat /var/log/messages | grep cloud-init を表示します。

  • ECS インスタンスにパブリック IP アドレスがあるかどうかを確認します (パブリック IP アドレスは internet_max_bandwidth_out > 0 の場合に自動的に割り当てられます)。

Q3: user_data スクリプトの実行に失敗し、データディスクがマウントされません

原因:イメージに互換性がないか、データディスクのデバイス名が一致しない可能性があります。

ソリューション:

  • user_data スクリプトで使用されている /dev/vdb は、データディスクのデフォルトのデバイス名です。テンプレートで data_disks ブロックが構成されていることを確認してください。

  • CentOS 以外のイメージを使用する場合、パーティションコマンドを調整する必要がある場合があります (たとえば、fdisk の代わりに parted を使用)。

  • データディスクが不要な場合は、data_disks ブロックと user_data スクリプトのディスクマウント部分を削除できます。

Q4: Terraform テンプレートを ROS テンプレートに変換するにはどうすればよいですか?

方法 1: コンソールで変換

  • ROS コンソールで、テンプレート > マイテンプレート > テンプレートの作成 を選択します。

  • まず、テラフォーム テンプレートタブでテンプレートを作成します。

  • Ros テンプレートタブに切り替え、右上隅で YAML を選択します。システムは Terraform テンプレートを次の形式に自動的に変換します:

ROSTemplateFormatVersion: '2015-09-01'
Transform: Aliyun::Terraform-v1.2
Workspace:
  .metadata: |-
    { ... }  # パラメータのグループ化と制約の構成
  main.tf: |-
    ...      # Terraform テンプレートの内容
  user-data.sh: |-
    ...      # 初期化スクリプトの内容

方法 2: テンプレート変換ツールを使用

rostran transform templates/terraform/alicloud/main.tf --target-format json

Q5: Apache や Tomcat など、別の Web サービスをデプロイするにはどうすればよいですか?

変更点:

  • user-data.sh のインストールコマンドと開始コマンドを変更します:

    • Apache: yum install -y httpd && systemctl start httpd

    • Tomcat: JDK をインストールしてから、Tomcat をダウンロードして起動します。

  • セキュリティグループルールのポート範囲を調整します (たとえば、Tomcat はデフォルトでポート 8080 を使用します)。

  • 出力のポート番号を変更します。

Q6: 新規作成ではなく、既存の VPC を使用するにはどうすればよいですか?

ソリューション:VPC と vSwitch を既存のリソースから選択するように変更します:

variable "vpc_id" {
  type = string
  description = <<EOT
  {
    "Label": { "zh-cn": "既存の VPC" },
    "AssociationProperty": "ALIYUN::ECS::VPC::VPCId"
  }
  EOT
}
variable "vswitch_id" {
  type = string
  description = <<EOT
  {
    "Label": { "zh-cn": "既存の VSwitch" },
    "AssociationProperty": "ALIYUN::VPC::VSwitch::VSwitchId",
    "AssociationPropertyMetadata": {
      "VpcId": "$${vpc_id}"
    }
  }
  EOT
}

次に、alicloud_instancevswitch_idvar.vswitch_id に変更し、alicloud_vpc および alicloud_vswitch リソースブロックを削除します。

リソースのデプロイに関する問題の詳細については、「よくある質問」をご参照ください。