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

Resource Orchestration Service:ALIYUN::SLB::Listener

最終更新日:Feb 07, 2026

ALIYUN::SLB::Listener を使用して Server Load Balancer (SLB) リスナーを作成できます。

構文

 {
  "Type": "ALIYUN::SLB::Listener",
  "Properties": {
    "MasterSlaveServerGroupId": String,
    "AclStatus": String,
    "Protocol": String,
    "AclId": String,
    "ServerCertificateId": String,
    "HealthCheck": Map,
    "RequestTimeout": Integer,
    "IdleTimeout": Integer,
    "ListenerPort": Integer,
    "HttpConfig": Map,
    "Bandwidth": Integer,
    "AclType": String,
    "BackendServerPort": Integer,
    "Scheduler": String,
    "LoadBalancerId": String,
    "CACertificateId": String,
    "Persistence": Map,
    "VServerGroupId": String,
    "Description": String,
    "PortRange": List,
    "StartListener": Boolean,
    "EnableHttp2": String,
    "Gzip": String,
    "TLSCipherPolicy": String,
    "AclIds": List,
    "ProxyProtocolV2Enabled": Boolean,
    "ConnectionDrainTimeout": Integer,
    "Tags": List,
    "FullNatEnabled": Boolean,
    "ConnectionDrain": String
  }
}

プロパティ

プロパティ名

必須

更新可能

説明

制約条件

MasterSlaveServerGroupId

String

いいえ

いいえ

プライマリ/セカンダリサーバーグループの ID。

なし

AclStatus

String

いいえ

はい

アクセスの制御を有効化するかどうかを指定します。

有効な値:

  • on(デフォルト):アクセスの制御を有効化します。

  • off:アクセスの制御を無効化します。

EnableHttp2

String

いいえ

はい

HTTP/2 を有効化するかどうかを指定します。

有効な値:

  • on:HTTP/2 を有効化します。

  • off:HTTP/2 を無効化します。

AclId

String

いいえ

はい

このリスナーにアタッチされるアクセス制御ポリシーグループの ID。

AclStatus が on に設定されている場合、このパラメーターは必須です。

AclType

String

いいえ

はい

アクセス制御ポリシーのタイプ。

有効な値:

  • white:選択したアクセス制御ポリシーグループで指定された IP アドレスまたは CIDR ブロックからのみリクエストを転送します。ホワイトリストは、特定の IP アドレスからのみアクセスを許可するアプリケーションに適しています。ただし、ホワイトリストを使用するとリスクが発生します。ホワイトリストを設定した場合、ホワイトリストに登録された IP アドレスのみが SLB リスナーにアクセスできます。ホワイトリストを有効化したがポリシーグループに IP アドレスを追加しなかった場合、SLB リスナーはリクエストを転送しません。

  • black:選択したアクセス制御ポリシーグループで指定された IP アドレスまたは CIDR ブロックからのすべてのリクエストをブロックします。ブラックリストは、特定の IP アドレスからのアクセスのみをブロックしたいシナリオに適しています。ブラックリストを有効化したがポリシーグループに IP アドレスを追加しなかった場合、SLB リスナーはすべてのリクエストを転送します。このパラメーターは、AclStatus が on に設定されている場合に必須です。

Protocol

String

はい

いいえ

ネットワークプロトコル。

有効な値:

  • http

  • https

  • tcp

  • udp

ListenerPort

Integer

はい

いいえ

SLB インスタンスで使用されるフロントエンドポート。

値の範囲:1 ~ 65,535。

Bandwidth

Integer

はい

はい

リスナーのピーク帯域幅。

値の範囲:-1 または 1 ~ 1,000。

単位:Mbps。

注意事項:

  • 帯域幅課金方式で課金されるパブリック向けインスタンスの場合、すべてのリスナーのピーク帯域幅の合計は、SLB インスタンス作成時に指定した帯域幅を超えてはなりません。また、リスナーの帯域幅を -1 に設定することはできません。

  • トラフィック課金方式で課金されるパブリック向けインスタンスの場合、リスナーの帯域幅を -1 に設定できます。この値は、帯域幅が制限されないことを示します。

BackendServerPort

Integer

いいえ

いいえ

SLB インスタンスで使用されるバックエンドポート。

値の範囲:1 ~ 65,535。

FullNatEnabled

Boolean

いいえ

はい

フル NAT モードが有効化されている場合、バックエンドサーバーがクライアントとして外部リソースにアクセスできます。

デフォルト値:false。

注:このパラメーターは、TCP および UDP リスナーでのみ有効です。

LoadBalancerId

String

はい

いいえ

SLB インスタンスの ID。

なし

HealthCheck

Map

いいえ

はい

ヘルスチェックの設定。

詳細については、「HealthCheck のプロパティ」をご参照ください。

Persistence

Map

いいえ

はい

関連するパラメーターを永続化します。

詳細については、「Persistence のプロパティ」をご参照ください。

Scheduler

String

いいえ

いいえ

スケジューリングアルゴリズム。

有効な値:

  • wrr(デフォルト):重みの高いバックエンドサーバーほど多くのリクエストを受信します。

  • wlc:リクエストを順次バックエンドサーバーに分散します。

CACertificateId

String

いいえ

いいえ

CA 証明書の ID。

このパラメーターは、HTTPS プロトコルでのみ有効です。

ServerCertificateId

String

いいえ

はい

サーバー証明書の ID。

このパラメーターは、HTTPS プロトコルでのみ有効であり、必須です。

VServerGroupId

String

いいえ

はい

サーバーグループの ID。

なし

RequestTimeout

Integer

いいえ

いいえ

リクエストタイムアウト期間。

値の範囲:1 ~ 180。

単位:秒。

IdleTimeout

Integer

いいえ

いいえ

アイドル接続タイムアウト期間。

値の範囲:1 ~ 60。

単位:秒。

HttpConfig

Map

いいえ

いいえ

HTTP プロトコルの設定に使用されます。

詳細については、「HttpConfig のプロパティ」をご参照ください。

Description

String

いいえ

いいえ

リスナーの説明。

長さは 1 ~ 80 文字です。英字、数字、ハイフン (-)、スラッシュ (/)、ピリオド (.)、アンダースコア (_) を含めることができます。

PortRange

List

いいえ

いいえ

リスニングポート範囲。

現在、全ポートへのリスニングのみがサポートされています。つまり、StartPort は 1、EndPort は 65,535 である必要があります。

詳細については、「PortRange のプロパティ」をご参照ください。

StartListener

Boolean

いいえ

いいえ

リスナーを起動するかどうかを指定します。

有効な値:

  • true(デフォルト):リスナーを起動します。

  • false:リスナーを起動しません。

Gzip

String

いいえ

はい

Gzip 圧縮を有効化し、特定の種類のファイルを圧縮するかどうかを指定します。

有効な値:

  • true(デフォルト):有効化されます。

  • False:処理は開始されません。

TLSCipherPolicy

String

いいえ

はい

TLS セキュリティポリシー。

各セキュリティポリシーには、HTTPS で使用可能な TLS バージョンと暗号スイートが含まれます。

説明

このパラメーターは、Protocol が https に設定されている場合に有効です。

AclIds

List

いいえ

はい

リスナーに関連付けるアクセス制御ポリシー ID のリスト。

AclStatus パラメーターが on に設定されている場合、このパラメーターは必須です。AclIds は AclId よりも優先度が高くなります。

ProxyProtocolV2Enabled

Boolean

いいえ

はい

Proxy Protocol を使用して、クライアントの送信元 IP アドレスをバックエンドサーバーに渡すかどうかを指定します。

有効な値:

  • true:はい。

  • false:いいえ。

ConnectionDrainTimeout

Integer

いいえ

はい

接続ドレインのタイムアウト期間。

単位:秒。

値の範囲:10 ~ 900

Tags

List

いいえ

はい

タグのリスト。

詳細については、「Tags のプロパティ」をご参照ください。

ConnectionDrain

String

いいえ

はい

接続ドレインを有効化するかどうかを指定します。

有効な値:

  • on:はい。

  • off:いいえ。

HealthCheck の構文

"HealthCheck": {
  "Domain": String,
  "Interval": Integer,
  "URI": String,
  "HttpCode": String,
  "HealthyThreshold": Integer,
  "HealthCheckType": String,
  "Timeout": Integer,
  "UnhealthyThreshold": Integer,
  "Port": Integer,
  "Switch": String,
  "HealthCheckMethod": String,
  "Req": String,
  "Exp": String
}

HealthCheck のプロパティ

プロパティ名

必須

更新可能

説明

制約条件

Domain

String

いいえ

いいえ

ヘルスチェックで使用されるドメイン名。

有効な値:

  • $_ip

  • 1 ~ 80 文字のカスタム文字列。英字、数字、ハイフン (-)、ピリオド (.) を含めることができます。

  • empty

説明

このパラメーターを $_ip に設定するか、空欄のままにした場合、SLB は各バックエンドサーバーのプライベート IP アドレスをヘルスチェックのドメイン名として使用します。

Interval

Integer

いいえ

いいえ

ヘルスチェックの間隔。

値の範囲:1 ~ 5。

単位:秒。

URI

String

いいえ

いいえ

ヘルスチェックで使用される URI。

長さは 1 ~ 80 文字です。先頭はスラッシュ (/) で始める必要があります。英字、数字、ハイフン (-)、スラッシュ (/)、ピリオド (.)、パーセント記号 (%)、疑問符 (?)、シャープ (#)、アンパサンド (&) を含めることができます。

HttpCode

String

いいえ

いいえ

HTTP ステータスコード。

有効な値:

  • http_2xx(デフォルト)

  • http_3xx

  • http_4xx

  • http_5xx

複数の HTTP ステータスコードをカンマ (,) で区切ります。

HealthyThreshold

Integer

いいえ

いいえ

バックエンドサーバーが正常と判断されるまでに必要な、連続成功ヘルスチェックの回数。バックエンドサーバーが異常と判断された後、再び正常と判断されるには、この回数の連続成功ヘルスチェックを通過する必要があります。

値の範囲:1 ~ 10。

HealthCheckType

String

いいえ

いいえ

ヘルスチェックのタイプ。

有効な値:

  • tcp

  • http

Timeout

Integer

いいえ

いいえ

ヘルスチェック応答の最大タイムアウト期間。

値の範囲:1 ~ 50。

単位:秒。

説明

Timeout 値が Interval 値より小さい場合、Timeout 値は無視され、Interval 値がタイムアウト期間として使用されます。

UnhealthyThreshold

Integer

いいえ

いいえ

バックエンドサーバーが不健全と判定されるまでに必要な、連続した失敗したヘルスチェックの回数です。バックエンドサーバーが健全と判定された後は、不健全と判定されるために、この回数だけ連続してヘルスチェックに失敗する必要があります。

値の範囲:1 ~ 10。

Port

Integer

いいえ

いいえ

ヘルスチェックで使用されるポート。

値の範囲:0 ~ 65,535。

Switch

String

いいえ

いいえ

ヘルスチェックを有効化するかどうかを指定します。

有効な値:

  • on:ヘルスチェックを有効化します。

  • off:ヘルスチェックを無効化します。

説明

このパラメーターは、現在 HTTP または HTTPS プロトコルでのみ有効です。Switch を設定しない場合、ヘルスチェック項目を設定していない限り、デフォルトで無効になります。

HealthCheckMethod

String

いいえ

いいえ

ヘルスチェックの方法。

有効な値:

  • head

  • get

説明

このパラメーターは、Protocol が https または http に設定され、かつ Switch が on に設定されている場合に有効です。

Req

String

いいえ

いいえ

UDP リスナーのヘルスチェック用リクエスト文字列。英字および数字のみを含めることができます。

最大長:64 文字。

Exp

String

いいえ

いいえ

UDP リスナーのヘルスチェック用応答文字列。英字および数字のみを含めることができます。

最大長:64 文字。

Persistence の構文

"Persistence": {
  "PersistenceTimeout": Integer,
  "CookieTimeout": Integer,
  "XForwardedFor": String,
  "XForwardedFor_SLBID": String,
  "XForwardedFor_proto": String,
  "XForwardedFor_SLBIP": String,
  "Cookie": String,
  "StickySession": String,
  "StickySessionType": String,
  "XForwardedFor_ClientSrcPort": String,
  "XForwardedFor_SLBPORT": String
}

Persistence のプロパティ

プロパティ名

必須

更新可能

説明

制約条件

StickySession

String

いいえ

はい

セッション維持を有効化するかどうかを指定します。

有効な値:

  • on:セッション維持を有効化します。

  • off:セッション維持を無効化します。

    説明

    このパラメーターは、HTTP および HTTPS プロトコルでのみ有効です。

PersistenceTimeout

Integer

いいえ

はい

接続永続化のタイムアウト期間。

値の範囲:0 ~ 1,000。

デフォルト値:0(シャットダウンを意味します)。

単位:秒。

CookieTimeout

Integer

いいえ

はい

Cookie のタイムアウト期間。

値の範囲:1 ~ 86,400。

単位:秒。

説明

StickySession が on に設定され、StickySessionType が insert に設定されている場合、このパラメーターは必須です。

XForwardedFor

String

いいえ

はい

X-Forwarded-For ヘッダーを使用してクライアントの送信元 IP アドレスを取得するかどうかを指定します。

有効な値:

  • on:X-Forwarded-For ヘッダーを使用してクライアントの送信元 IP アドレスを取得します。

  • off(デフォルト):X-Forwarded-For ヘッダーを使用してクライアントの送信元 IP アドレスを取得しません。

XForwardedFor_proto

String

いいえ

はい

X-Forwarded-Proto ヘッダーを使用して SLB インスタンスのリスナープロトコルを取得するかどうかを指定します。

有効な値:

  • on:X-Forwarded-Proto ヘッダーを使用して SLB インスタンスのリスナープロトコルを取得します。

  • off(デフォルト):X-Forwarded-Proto ヘッダーを使用して SLB インスタンスのリスナープロトコルを取得しません。

XForwardedFor_SLBID

String

いいえ

はい

SLB-ID ヘッダーを使用して SLB インスタンスの ID を取得するかどうかを指定します。

有効な値:

  • on:SLB-ID ヘッダーを使用して SLB インスタンスの ID を取得します。

  • off(デフォルト):SLB-ID ヘッダーを使用して SLB インスタンスの ID を取得しません。

XForwardedFor_SLBIP

String

いいえ

はい

クライアント要求の送信元 IP アドレスを SLB-IP ヘッダー・フィールドから取得するかどうか。

有効な値:

  • On:クライアント要求の送信元 IP アドレスを SLB-IP ヘッダー・フィールドから取得します。

  • off(デフォルト):クライアントの送信元 IP アドレスは SLB-IP ヘッダー・フィールドから取得されません。

Cookie

String

いいえ

はい

サーバーで設定された Cookie。

長さは 1 ~ 200 文字で、ドル記号 ($) で始めてはいけません。英字および数字を含めることができますが、カンマ (,)、セミコロン (;)、スペースは含められません。

説明

StickySession が on に設定され、StickySessionType が server に設定されている場合、このパラメーターは必須です。

StickySessionType

String

いいえ

はい

Cookie を処理する方法。

有効な値:

  • insert:Cookie を挿入します。

  • server:Cookie を書き換えます。

説明

StickySession が on に設定されている場合、このパラメーターは必須です。

XForwardedFor_ClientSrcPort

String

いいえ

はい

X-Forwarded-Client-srcport ヘッダーを使用して、クライアントが SLB インスタンスに接続するために使用するポートを取得するかどうかを指定します。

有効な値:

  • on:X-Forwarded-Client-srcport ヘッダーを使用して、クライアントが SLB インスタンスに接続するために使用するポートを取得します。

  • off(デフォルト):X-Forwarded-Client-srcport ヘッダーを使用して、クライアントが SLB インスタンスに接続するために使用するポートを取得しません。

XForwardedFor_SLBPORT

String

いいえ

はい

X-Forwarded-Port ヘッダーを使用して、SLB インスタンスのリスニングポートを取得するかどうかを指定します。

有効な値:

  • On:X-Forwarded-Port ヘッダー・フィールドから SLB インスタンスで使用されるリスナープロトコルを取得します。

  • off(デフォルト):X-Forwarded-Port ヘッダーを使用して SLB インスタンスのリスニングポートを取得しません。

HttpConfig の構文

"HttpConfig": {
  "ForwardPort": Integer,
  "ListenerForward": String
}

HttpConfig のプロパティ

プロパティ名

必須

更新可否

説明

制約条件

ForwardPort

Integer

いいえ

いいえ

HTTPS リスナーで HTTP リクエストを転送するポート。

値の範囲:1 ~ 65,535。

デフォルト値:443。

ListenerForward

String

いいえ

いいえ

HTTP から HTTPS への転送を有効化するかどうかを指定します。

有効な値:

  • 有効化されます。

  • off(デフォルト):無効化されます。

PortRange の構文

"PortRange": [
  {
    "StartPort": Integer,
    "EndPort": Integer
  }
]

PortRange のプロパティ

プロパティ名

必須

更新可否

説明

制約条件

StartPort

Integer

はい

いいえ

開始ポート。

値:1。

EndPort

Integer

はい

いいえ

終了ポート。

値:65,535。

Tags の構文

"Tags": [
  {
    "Key": String,
    "Value": String
  }
]

Tags のプロパティ

プロパティ

必須

更新可否

説明

制約条件

Key

String

はい

いいえ

タグキー。

なし

Value

String

いいえ

いいえ

タグ値。

なし

戻り値

Fn::GetAtt

  • LoadBalancerId:SLB インスタンスの一意の ID。

  • ListenerPortsAndProtocol:SLB インスタンスで使用されるフロントエンドポートおよびプロトコル。

  • Arn:Alibaba Cloud リソースネーム (ARN)。

シナリオ 1:SLB リスナーの作成

クイック作成

ROSTemplateFormatVersion: '2015-09-01'
Description: Test SLB Listener
Parameters:
  SlbInstanceId:
    AssociationProperty: ALIYUN::SLB::Instance::InstanceId
    Type: String
Resources:
  Listener:
    Type: ALIYUN::SLB::Listener
    Properties:
      BackendServerPort: 8080
      Bandwidth: 50
      ListenerPort: 80
      LoadBalancerId:
        Ref: SlbInstanceId
      Protocol: https
      Scheduler: wrr
Outputs: {}
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Description": "Test SLB Listener",
  "Parameters": {
    "SlbInstanceId": {
      "AssociationProperty": "ALIYUN::SLB::Instance::InstanceId",
      "Type": "String"
    }
  },
  "Resources": {
    "Listener": {
      "Type": "ALIYUN::SLB::Listener",
      "Properties": {
        "BackendServerPort": 8080,
        "Bandwidth": 50,
        "ListenerPort": 80,
        "LoadBalancerId": {
          "Ref": "SlbInstanceId"
        },
        "Protocol": "https",
        "Scheduler": "wrr"
      }
    }
  },
  "Outputs": {
  }
}

シナリオ 2:ヘルスチェック付き SLB リスナーの作成

クイック作成

ROSTemplateFormatVersion: '2015-09-01'
Description: Test SLB Listener
Parameters:
  SlbInstanceId:
    AssociationProperty: ALIYUN::SLB::Instance::InstanceId
    Type: String
Resources:
  Listener:
    Type: ALIYUN::SLB::Listener
    Properties:
      ListenerPort: 80
      Bandwidth: 10
      HealthCheck:
        HttpCode: http_2xx,http_3xx,http_4xx,http_5xx
        HealthCheckType: http
        UnhealthyThreshold: 3
        Timeout: 5
        HealthyThreshold: 3
        Port: 80
        URI: /
        Interval: 5
      LoadBalancerId:
        Ref: SlbInstanceId
      BackendServerPort: 80
      Protocol: http
Outputs: {}
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Description": "Test SLB Listener",
  "Parameters": {
    "SlbInstanceId": {
      "AssociationProperty": "ALIYUN::SLB::Instance::InstanceId",
      "Type": "String"
    }
  },
  "Resources": {
    "Listener": {
      "Type": "ALIYUN::SLB::Listener",
      "Properties": {
        "BackendServerPort": 8080,
        "Bandwidth": 50,
        "ListenerPort": 80,
        "LoadBalancerId": {
          "Ref": "SlbInstanceId"
        },
        "Protocol": "https",
        "Scheduler": "wrr"
      }
    }
  },
  "Outputs": {
  }
}

シナリオ 3:高可用性 Web サービスの作成

クイック作成

ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: Build a high-availability web service that includes dual-zone ECS instances, an SLB instance, and NAS mounts. The service supports automatic configuration synchronization and public network access.
  en: Constructing a highly available web service comprises dual availability zone
    ECS instances, a Load Balancer (SLB), Network Attached Storage (NAS) mounts, automatic
    configuration synchronization, and is accessible via the public internet.
Parameters:
  NasZone1:
    AssociationProperty: 'ALIYUN::ECS::Instance::ZoneId'
    Type: String
    Description:
      zh-cn: Zone 1 must be different from Zone 2.
      en: Availability zone 1 must be different from Availability zone 2.
    Label:
      zh-cn: NAS Zone 1
      en: NAS Availability Zone1
  NasZone2:
    AssociationProperty: 'ALIYUN::ECS::Instance::ZoneId'
    Type: String
    Description:
      zh-cn: Zone 2 must be different from Zone 1.
      en: Availability zone 2 must be different from Availability zone 1.
    Label:
      zh-cn: NAS Zone 2
      en: NAS Availability Zone2
  CommonName:
    Default: high-availability
    Type: String
  InstancePassword:
    Type: String
    Description:
      zh-cn: >-
        The logon password of the server. The password must be 8 to 30 characters in length and contain at least three of the following character types: uppercase letters, lowercase letters, digits, and special characters. Special characters include ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
      en: >-
        Server login password, Length 8~30, must contain three(Capital letters,
        lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special
        symbol in).
    MinLength: 8
    Label:
      zh-cn: Instance Password
      en: Instance Password
    AllowedPattern: '[0-9A-Za-z\_\-\&:;''<>,=%`~!@#\(\)\$\^\*\+\|\{\}\[\]\.\?\/]+$'
    NoEcho: true
    MaxLength: 30
    AssociationProperty: 'ALIYUN::ECS::Instance::Password'
    ConstraintDescription:
      zh-cn: 'The password must be 8 to 30 characters in length and contain at least three of the following character types: uppercase letters, lowercase letters, digits, and special characters. Special characters include ()`~!@#$%^&*_-+=|{}[]:;''<>,.?/'
      en: >-
        Length 8~30, must contain three(Capital letters, lowercase letters,
        numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in).
  EcsInstanceType2:
    AssociationProperty: 'ALIYUN::ECS::Instance::InstanceType'
    AssociationPropertyMetadata:
      SystemDiskCategory: cloud_essd
      InstanceChargeType: PostPaid
      ZoneId: '${Zone2}'
    Type: String
    Label:
      zh-cn: Instance Type of Zone 2
      en: Instance Type Of Availability Zone2
  Zone2:
    AssociationProperty: 'ALIYUN::ECS::Instance::ZoneId'
    Type: String
    Description:
      zh-cn: Zone 2 must be different from Zone 1.
      en: Availability zone 2 must be different from Availability zone 1.
    Label:
      zh-cn: vSwitch Zone 2
      en: VSwitch Availability Zone2
  Zone1:
    AssociationProperty: 'ALIYUN::ECS::Instance::ZoneId'
    Type: String
    Description:
      zh-cn: Zone 1 must be different from Zone 2.
      en: Availability zone 1 must be different from Availability zone 2.
    Label:
      zh-cn: vSwitch Zone 1
      en: VSwitch Availability Zone1
  EcsInstanceType1:
    AssociationProperty: 'ALIYUN::ECS::Instance::InstanceType'
    AssociationPropertyMetadata:
      SystemDiskCategory: cloud_essd
      InstanceChargeType: PostPaid
      ZoneId: '${Zone1}'
    Type: String
    Label:
      zh-cn: Instance Type of Zone 1
      en: Instance Type Of Availability Zone1
Rules:
  DifferentZones2:
    Assertions:
      - Assert:
          'Fn::Not':
            'Fn::Equals':
              - Ref: NasZone1
              - Ref: NasZone2
        AssertDescription: NAS Zones must be different
  DifferentZones1:
    Assertions:
      - Assert:
          'Fn::Not':
            'Fn::Equals':
              - Ref: Zone1
              - Ref: Zone2
        AssertDescription: ECS Zones must be different
Outputs:
  ECS1URL:
    Description: ECS 1 URL
    Value:
      'Fn::Sub':
        - >-
          https://ecs.console.alibabacloud.com/#/server/region/${region}?instanceIds=${InstanceID}
        - InstanceID:
            'Fn::Select':
              - '0'
              - 'Fn::GetAtt':
                  - EcsInstanceGroup1
                  - InstanceIds
          region:
            Ref: 'ALIYUN::Region'
  FileSystemId1:
    Description:
      zh-cn: Master NAS
      en: Master NAS
    Value:
      'Fn::Sub':
        - 'https://nas.console.alibabacloud.com/${region}/filesystem/${InstanceID}'
        - InstanceID:
            'Fn::GetAtt':
              - MasterFileSystem
              - FileSystemId
          region:
            Ref: 'ALIYUN::Region'
  ECS2URL:
    Description: ECS 2 URL
    Value:
      'Fn::Sub':
        - >-
          https://ecs.console.alibabacloud.com/#/server/region/${region}?instanceIds=${InstanceID}
        - InstanceID:
            'Fn::Select':
              - '0'
              - 'Fn::GetAtt':
                  - EcsInstanceGroup1
                  - InstanceIds
          region:
            Ref: 'ALIYUN::Region'
  SlbIpAddress:
    Description:
      zh-cn: The public IP address exposed to the Internet.
      en: Public IP Addresses
    Value:
      'Fn::Sub':
        - 'http://${ServerAddress}'
        - ServerAddress:
            'Fn::GetAtt':
              - Slb
              - IpAddress
  FileSystemId2:
    Description:
      zh-cn: Secondary NAS
      en: Backup NAS
    Value:
      'Fn::Sub':
        - 'https://nas.console.alibabacloud.com/${region}/filesystem/${InstanceID}'
        - InstanceID:
            'Fn::GetAtt':
              - BackupFileSystem
              - FileSystemId
          region:
            Ref: 'ALIYUN::Region'
  MountInfo1:
    Description:
      zh-cn: NAS mount directory 1 on the ECS instance
      en: NAS mounting directory 1 on ECS
    Value: '/nas_master'
  MountInfo2:
    Description:
      zh-cn: NAS mount directory 2 on the ECS instance
      en: NAS mounting directory 2 on ECS
    Value: '/nas_backup'
Resources:
  SlbListener:
    Type: 'ALIYUN::SLB::Listener'
    Properties:
      Protocol: http
      HealthCheck:
        HealthCheckType: http
        Interval: 2
        URI: /
        UnhealthyThreshold: 3
        HealthyThreshold: 3
        Timeout: 5
        HttpCode: 'http_2xx,http_3xx,http_4xx,http_5xx'
        Port: 80
      ListenerPort: 80
      Bandwidth: 10
      BackendServerPort: 80
      LoadBalancerId:
        Ref: Slb
    DependsOn:
      - Slb
  EcsSecurityGroup:
    Type: 'ALIYUN::ECS::SecurityGroup'
    Properties:
      SecurityGroupIngress:
        - Priority: 1
          PortRange: 80/80
          NicType: internet
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
      VpcId:
        Ref: EcsVpc
      SecurityGroupEgress:
        - Priority: 1
          PortRange: '-1/-1'
          DestCidrIp: 0.0.0.0/0
          NicType: internet
          IpProtocol: all
        - Priority: 1
          PortRange: '-1/-1'
          DestCidrIp: 0.0.0.0/0
          NicType: intranet
          IpProtocol: all
      SecurityGroupName:
        'Fn::Sub': '${CommonName}_sg'
  MasterNasMountTarget:
    Type: 'ALIYUN::NAS::MountTarget'
    Properties:
      NetworkType: Vpc
      FileSystemId:
        Ref: MasterFileSystem
      VpcId:
        Ref: EcsVpc
      VSwitchId:
        Ref: EcsVSwitch3
      AccessGroupName: DEFAULT_VPC_GROUP_NAME
  EcsVSwitch4:
    Type: 'ALIYUN::ECS::VSwitch'
    Properties:
      VSwitchName:
        'Fn::Sub': '${CommonName}_vsw_002'
      VpcId:
        Ref: EcsVpc
      CidrBlock: 192.168.4.0/24
      ZoneId:
        Ref: NasZone2
  MasterFileSystem:
    Type: 'ALIYUN::NAS::FileSystem'
    Properties:
      StorageType: Capacity
      ProtocolType: NFS
      VpcId:
        Ref: EcsVpc
      Description: MasterNAS
      ZoneId:
        Ref: NasZone1
  EcsVSwitch2:
    Type: 'ALIYUN::ECS::VSwitch'
    Properties:
      VSwitchName:
        'Fn::Sub': '${CommonName}_vsw_002'
      VpcId:
        Ref: EcsVpc
      CidrBlock: 192.168.2.0/24
      ZoneId:
        Ref: Zone2
  EcsVSwitch3:
    Type: 'ALIYUN::ECS::VSwitch'
    Properties:
      VSwitchName:
        'Fn::Sub': '${CommonName}_vsw_002'
      VpcId:
        Ref: EcsVpc
      CidrBlock: 192.168.3.0/24
      ZoneId:
        Ref: NasZone1
  EcsVSwitch1:
    Type: 'ALIYUN::ECS::VSwitch'
    Properties:
      VSwitchName:
        'Fn::Sub': '${CommonName}_vsw_001'
      VpcId:
        Ref: EcsVpc
      CidrBlock: 192.168.1.0/24
      ZoneId:
        Ref: Zone1
  BackupFileSystem:
    Type: 'ALIYUN::NAS::FileSystem'
    Properties:
      StorageType: Capacity
      ProtocolType: NFS
      VpcId:
        Ref: EcsVpc
      Description: BackupNAS
      ZoneId:
        Ref: NasZone2
  BackupNasMountTarget:
    Type: 'ALIYUN::NAS::MountTarget'
    Properties:
      NetworkType: Vpc
      FileSystemId:
        Ref: BackupFileSystem
      VpcId:
        Ref: EcsVpc
      VSwitchId:
        Ref: EcsVSwitch4
      AccessGroupName: DEFAULT_VPC_GROUP_NAME
  EcsInstanceGroup1:
    Type: 'ALIYUN::ECS::InstanceGroup'
    Properties:
      SystemDiskCategory: cloud_essd
      VpcId:
        Ref: EcsVpc
      SecurityGroupId:
        Ref: EcsSecurityGroup
      SystemDiskSize: 40
      ImageId: aliyun_3_x64_20G_alibase_20230727.vhd
      SpotStrategy: SpotAsPriceGo
      IoOptimized: optimized
      VSwitchId:
        Ref: EcsVSwitch1
      Password:
        Ref: InstancePassword
      InstanceName:
        'Fn::Sub': '${CommonName}_ecs_001'
      InstanceType:
        Ref: EcsInstanceType1
      ZoneId:
        Ref: Zone1
      MaxAmount: 1
  EcsInstanceGroup2:
    Type: 'ALIYUN::ECS::InstanceGroup'
    Properties:
      SystemDiskCategory: cloud_essd
      VpcId:
        Ref: EcsVpc
      SecurityGroupId:
        Ref: EcsSecurityGroup
      SystemDiskSize: 40
      ImageId: aliyun_3_x64_20G_alibase_20230727.vhd
      SpotStrategy: SpotAsPriceGo
      IoOptimized: optimized
      VSwitchId:
        Ref: EcsVSwitch2
      Password:
        Ref: InstancePassword
      InstanceName:
        'Fn::Sub': '${CommonName}_ecs_002'
      InstanceType:
        Ref: EcsInstanceType2
      ZoneId:
        Ref: Zone2
      MaxAmount: 1
  EcsVpc:
    Type: 'ALIYUN::ECS::VPC'
    Properties:
      VpcName:
        'Fn::Sub': '${CommonName}_vpc'
      CidrBlock: 192.168.0.0/16
  SlbBackendServerAttachment:
    Type: 'ALIYUN::SLB::BackendServerAttachment'
    Properties:
      BackendServerList:
        'Fn::ListMerge':
          - 'Fn::GetAtt':
              - EcsInstanceGroup1
              - InstanceIds
          - 'Fn::GetAtt':
              - EcsInstanceGroup2
              - InstanceIds
      BackendServerWeightList:
        - 100
        - 100
      LoadBalancerId:
        Ref: Slb
  Slb:
    Type: 'ALIYUN::SLB::LoadBalancer'
    Properties:
      AddressType: internet
      LoadBalancerName:
        'Fn::Sub': '${CommonName}-slb'
      InstanceChargeType: PayByCLCU
      PayType: PayOnDemand
  InstanceRunCommand:
    Type: 'ALIYUN::ECS::RunCommand'
    Properties:
      CommandContent:
        'Fn::Sub': >-
          #!/bin/bash

          if [ ! -f .ros.provision ]; then
            echo "Name: High-availability web service with shared storage" > .ros.provision
          fi


          name=$(grep "^Name:" .ros.provision | awk -F':' '{print $2}' | sed -e
          's/^[[:space:]]*//' -e 's/[[:space:]]*$//')

          if [[ "$name" != "High-availability web service with shared storage" ]]; then
            echo "This instance has already been configured using the one-click deployment of the \"$name\" tutorial. You cannot use the one-click deployment of this tutorial."
            exit 0
          fi


          echo "#########################"

          echo "# Check Network"

          echo "#########################"

          ping -c 2 -W 2 aliyun.com > /dev/null

          if [[ $? -ne 0 ]]; then
            echo "The current instance cannot access the public network."
            exit 0
          fi


          if ! grep -q "^Step1: Prepare Environment$" .ros.provision; then
            echo "#########################"
            echo "# Prepare Environment"
            echo "#########################"
            systemctl status firewalld
            systemctl stop firewalld
            echo "Step1: Prepare Environment" >> .ros.provision
          else
            echo "#########################"
            echo "# Environment has been ready"
            echo "#########################"
          fi


          if ! grep -q "^Step2: Install Nginx and deploy service$"
          .ros.provision; then
            echo "#########################"
            echo "# Install Nginx"
            echo "#########################"
            sudo yum -y install nginx
            sudo wget -O /usr/share/nginx/html/index.html https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20231013/jhgg/index.html
            sudo wget -O /usr/share/nginx/html/lipstick.png https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20230925/zevs/lipstick.png
            sudo systemctl start nginx
            sudo systemctl enable nginx
            echo "Step2: Install Nginx and deploy service" >> .ros.provision
          else
            echo "#########################"
            echo "# Nginx has been installed"
            echo "#########################"
          fi


          if ! grep -q "^Step3: Mount to the ECS" .ros.provision; then
            echo "#########################"
            echo "# Mount to the ECS"
            echo "#########################"
            mkdir /nas_master
            mkdir /nas_backup
            sudo yum install -y nfs-utils
            sudo echo "options sunrpc tcp_slot_table_entries=128" >>  /etc/modprobe.d/sunrpc.conf
            sudo echo "options sunrpc tcp_max_slot_table_entries=128" >>  /etc/modprobe.d/sunrpc.conf
            sudo mount -t nfs -o vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${MasterNasMountTarget.MountTargetDomain}:/ /nas_master
            sudo mount -t nfs -o vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${BackupNasMountTarget.MountTargetDomain}:/ /nas_backup
          
            sudo echo "${MasterNasMountTarget.MountTargetDomain}:/ /nas_master nfs vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev,noresvport 0 0" >> /etc/fstab
            
            sudo echo "${BackupNasMountTarget.MountTargetDomain}:/ /nas_backup nfs vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev,noresvport 0 0" >> /etc/fstab

            df -h | grep aliyun
          else
            echo "#########################"
            echo "# The ECS has been attached to the Nas"
            echo "#########################"
          fi


          if ! grep -q "^Step4: Shared file$" .ros.provision; then
            echo "#########################"
            echo "# Shared file"
            echo "#########################"
            sudo cp -Lvr /usr/share/nginx/html /nas_master
            sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
            echo "Step4: Shared file" >> .ros.provision
          else
            echo "#########################"
            echo "# File has been Shared"
            echo "#########################"
          fi


          if ! grep -q "^Step5: Install inotify-tools、rsync$" .ros.provision;
          then
            echo "#########################"
            echo "# Install inotify-tools, rsync"
            echo "#########################"
            sudo yum install -y inotify-tools rsync
            echo "Step6: Install inotify-tools, rsync" >> .ros.provision
          else
            echo "#########################"
            echo "# Inotify-tools has been installed"
            echo "#########################"
          fi

          if ! grep -q "^Step6: Install synchronization server$" .ros.provision;
          then
            echo "#########################"
            echo "# Install synchronization server"
            echo "#########################"
            sudo wget -P /etc/systemd/system/ https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20231017/pftz/sync_nas.sh
            sudo wget -P /etc/systemd/system/ https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/en-US/20230925/wmaj/sync_check_switch.sh
            sudo chmod +x /etc/systemd/system/sync_nas.sh
            sudo chmod +x /etc/systemd/system/sync_check_switch.sh
            cat > /etc/systemd/system/sync-check-switch.service << \EOF
          [Unit]

          Description=Sync Check Switch

          After=network.target


          [Service]

          ExecStart=/etc/systemd/system/sync_check_switch.sh

          RestartSec=3

          Restart=always


          [Install]

          WantedBy=default.target

          EOF

            cat > /etc/systemd/system/sync-nas.service << \EOF
          [Unit]

          Description=Sync NAS Service

          After=network.target


          [Service]

          ExecStart=/etc/systemd/system/sync_nas.sh

          Restart=always

          RestartSec=3


          [Install]

          WantedBy=default.target

          EOF

            sudo systemctl daemon-reload
            sudo systemctl start sync-nas.service
            sudo systemctl enable sync-check-switch.service
            sudo systemctl start sync-check-switch.service
            sudo systemctl enable sync-nas.service
            echo "Step6: Install " >> .ros.provision
          else
            echo "#########################"
            echo "# Synchronization server has been installed"
            echo "#########################"
          fi
      Type: RunShellScript
      Sync: true
      InstanceIds:
        - Ref: EcsInstanceGroup1
        - Ref: EcsInstanceGroup2
      Timeout: '300'
Metadata:
  'ALIYUN::ROS::Interface':
    ParameterGroups:
      - Parameters:
          - Zone1
          - Zone2
          - NasZone1
          - NasZone2
        Label:
          default:
            zh-cn: Zone Configuration
            en: Availability Zone
      - Parameters:
          - EcsInstanceType1
          - EcsInstanceType2
          - InstancePassword
        Label:
          default:
            zh-cn: ECS Instance Configuration
            en: Instance Configure
    TemplateTags:
      - 'acs:technical-solution:high-availability-architecture:high-availability-web-service-with-shared-storage-tech_solu_12'
    Hidden:
      - CommonName
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Description": {
    "zh-cn": "Build a high-availability web service that includes dual-zone ECS instances, an SLB instance, and NAS mounts. The service supports automatic configuration synchronization and public network access.",
    "en": "Constructing a highly available web service comprises dual availability zone ECS instances, a Load Balancer (SLB), Network Attached Storage (NAS) mounts, automatic configuration synchronization, and is accessible via the public internet."
  },
  "Parameters": {
    "NasZone1": {
      "AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
      "Type": "String",
      "Description": {
        "zh-cn": "Zone 1 must be different from Zone 2.",
        "en": "Availability zone 1 must be different from Availability zone 2."
      },
      "Label": {
        "zh-cn": "NAS Zone 1",
        "en": "NAS Availability Zone1"
      }
    },
    "NasZone2": {
      "AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
      "Type": "String",
      "Description": {
        "zh-cn": "Zone 2 must be different from Zone 1.",
        "en": "Availability zone 2 must be different from Availability zone 1."
      },
      "Label": {
        "zh-cn": "NAS Zone 2",
        "en": "NAS Availability Zone2"
      }
    },
    "CommonName": {
      "Default": "high-availability",
      "Type": "String"
    },
    "InstancePassword": {
      "Type": "String",
      "Description": {
        "zh-cn": "The logon password of the server. The password must be 8 to 30 characters in length and contain at least three of the following character types: uppercase letters, lowercase letters, digits, and special characters. Special characters include ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/",
        "en": "Server login password, Length 8~30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)."
      },
      "MinLength": 8,
      "Label": {
        "zh-cn": "Instance Password",
        "en": "Instance Password"
      },
      "AllowedPattern": "[0-9A-Za-z\\_\\-\\&:;'<>,=%`~!@#\\(\\)\\$\\^\\*\\+\\|\\{\\}\\[\\]\\.\\?\\/]+$",
      "NoEcho": true,
      "MaxLength": 30,
      "AssociationProperty": "ALIYUN::ECS::Instance::Password",
      "ConstraintDescription": {
        "zh-cn": "The password must be 8 to 30 characters in length and contain at least three of the following character types: uppercase letters, lowercase letters, digits, and special characters. Special characters include ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/",
        "en": "Length 8~30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)."
      }
    },
    "EcsInstanceType2": {
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
      "AssociationPropertyMetadata": {
        "SystemDiskCategory": "cloud_essd",
        "InstanceChargeType": "PostPaid",
        "ZoneId": "${Zone2}"
      },
      "Type": "String",
      "Label": {
        "zh-cn": "Instance Type of Zone 2",
        "en": "Instance Type Of Availability Zone2"
      }
    },
    "Zone2": {
      "AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
      "Type": "String",
      "Description": {
        "zh-cn": "Zone 2 must be different from Zone 1.",
        "en": "Availability zone 2 must be different from Availability zone 1."
      },
      "Label": {
        "zh-cn": "vSwitch Zone 2",
        "en": "VSwitch Availability Zone2"
      }
    },
    "Zone1": {
      "AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
      "Type": "String",
      "Description": {
        "zh-cn": "Zone 1 must be different from Zone 2.",
        "en": "Availability zone 1 must be different from Availability zone 2."
      },
      "Label": {
        "zh-cn": "vSwitch Zone 1",
        "en": "VSwitch Availability Zone1"
      }
    },
    "EcsInstanceType1": {
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
      "AssociationPropertyMetadata": {
        "SystemDiskCategory": "cloud_essd",
        "InstanceChargeType": "PostPaid",
        "ZoneId": "${Zone1}"
      },
      "Type": "String",
      "Label": {
        "zh-cn": "Instance Type of Zone 1",
        "en": "Instance Type Of Availability Zone1"
      }
    }
  },
  "Rules": {
    "DifferentZones2": {
      "Assertions": [
        {
          "Assert": {
            "Fn::Not": {
              "Fn::Equals": [
                {
                  "Ref": "NasZone1"
                },
                {
                  "Ref": "NasZone2"
                }
              ]
            }
          },
          "AssertDescription": "NAS Zones must be different"
        }
      ]
    },
    "DifferentZones1": {
      "Assertions": [
        {
          "Assert": {
            "Fn::Not": {
              "Fn::Equals": [
                {
                  "Ref": "Zone1"
                },
                {
                  "Ref": "Zone2"
                }
              ]
            }
          },
          "AssertDescription": "ECS Zones must be different"
        }
      ]
    }
  },
  "Outputs": {
    "ECS1URL": {
      "Description": "ECS 1 URL",
      "Value": {
        "Fn::Sub": [
          "https://ecs.console.alibabacloud.com/#/server/region/${region}?instanceIds=${InstanceID}",
          {
            "InstanceID": {
              "Fn::Select": [
                "0",
                {
                  "Fn::GetAtt": [
                    "EcsInstanceGroup1",
                    "InstanceIds"
                  ]
                }
              ]
            },
            "region": {
              "Ref": "ALIYUN::Region"
            }
          }
        ]
      }
    },
    "FileSystemId1": {
      "Description": {
        "zh-cn": "Master NAS",
        "en": "Master NAS"
      },
      "Value": {
        "Fn::Sub": [
          "https://nas.console.alibabacloud.com/${region}/filesystem/${InstanceID}",
          {
            "InstanceID": {
              "Fn::GetAtt": [
                "MasterFileSystem",
                "FileSystemId"
              ]
            },
            "region": {
              "Ref": "ALIYUN::Region"
            }
          }
        ]
      }
    },
    "ECS2URL": {
      "Description": "ECS 2 URL",
      "Value": {
        "Fn::Sub": [
          "https://ecs.console.alibabacloud.com/#/server/region/${region}?instanceIds=${InstanceID}",
          {
            "InstanceID": {
              "Fn::Select": [
                "0",
                {
                  "Fn::GetAtt": [
                    "EcsInstanceGroup1",
                    "InstanceIds"
                  ]
                }
              ]
            },
            "region": {
              "Ref": "ALIYUN::Region"
            }
          }
        ]
      }
    },
    "SlbIpAddress": {
      "Description": {
        "zh-cn": "The public IP address exposed to the Internet.",
        "en": "Public IP Addresses"
      },
      "Value": {
        "Fn::Sub": [
          "http://${ServerAddress}",
          {
            "ServerAddress": {
              "Fn::GetAtt": [
                "Slb",
                "IpAddress"
              ]
            }
          }
        ]
      }
    },
    "FileSystemId2": {
      "Description": {
        "zh-cn": "Secondary NAS",
        "en": "Backup NAS"
      },
      "Value": {
        "Fn::Sub": [
          "https://nas.console.alibabacloud.com/${region}/filesystem/${InstanceID}",
          {
            "InstanceID": {
              "Fn::GetAtt": [
                "BackupFileSystem",
                "FileSystemId"
              ]
            },
            "region": {
              "Ref": "ALIYUN::Region"
            }
          }
        ]
      }
    },
    "MountInfo1": {
      "Description": {
        "zh-cn": "NAS mount directory 1 on the ECS instance",
        "en": "NAS mounting directory 1 on ECS"
      },
      "Value": "/nas_master"
    },
    "MountInfo2": {
      "Description": {
        "zh-cn": "NAS mount directory 2 on the ECS instance",
        "en": "NAS mounting directory 2 on ECS"
      },
      "Value": "/nas_backup"
    }
  },
  "Resources": {
    "SlbListener": {
      "Type": "ALIYUN::SLB::Listener",
      "Properties": {
        "Protocol": "http",
        "HealthCheck": {
          "HealthCheckType": "http",
          "Interval": 2,
          "URI": "/",
          "UnhealthyThreshold": 3,
          "HealthyThreshold": 3,
          "Timeout": 5,
          "HttpCode": "http_2xx,http_3xx,http_4xx,http_5xx",
          "Port": 80
        },
        "ListenerPort": 80,
        "Bandwidth": 10,
        "BackendServerPort": 80,
        "LoadBalancerId": {
          "Ref": "Slb"
        }
      },
      "DependsOn": [
        "Slb"
      ]
    },
    "EcsSecurityGroup": {
      "Type": "ALIYUN::ECS::SecurityGroup",
      "Properties": {
        "SecurityGroupIngress": [
          {
            "Priority": 1,
            "PortRange": "80/80",
            "NicType": "internet",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          }
        ],
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "SecurityGroupEgress": [
          {
            "Priority": 1,
            "PortRange": "-1/-1",
            "DestCidrIp": "0.0.0.0/0",
            "NicType": "internet",
            "IpProtocol": "all"
          },
          {
            "Priority": 1,
            "PortRange": "-1/-1",
            "DestCidrIp": "0.0.0.0/0",
            "NicType": "intranet",
            "IpProtocol": "all"
          }
        ],
        "SecurityGroupName": {
          "Fn::Sub": "${CommonName}_sg"
        }
      }
    },
    "MasterNasMountTarget": {
      "Type": "ALIYUN::NAS::MountTarget",
      "Properties": {
        "NetworkType": "Vpc",
        "FileSystemId": {
          "Ref": "MasterFileSystem"
        },
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "VSwitchId": {
          "Ref": "EcsVSwitch3"
        },
        "AccessGroupName": "DEFAULT_VPC_GROUP_NAME"
      }
    },
    "EcsVSwitch4": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "VSwitchName": {
          "Fn::Sub": "${CommonName}_vsw_002"
        },
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "CidrBlock": "192.168.4.0/24",
        "ZoneId": {
          "Ref": "NasZone2"
        }
      }
    },
    "MasterFileSystem": {
      "Type": "ALIYUN::NAS::FileSystem",
      "Properties": {
        "StorageType": "Capacity",
        "ProtocolType": "NFS",
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "Description": "MasterNAS",
        "ZoneId": {
          "Ref": "NasZone1"
        }
      }
    },
    "EcsVSwitch2": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "VSwitchName": {
          "Fn::Sub": "${CommonName}_vsw_002"
        },
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "CidrBlock": "192.168.2.0/24",
        "ZoneId": {
          "Ref": "Zone2"
        }
      }
    },
    "EcsVSwitch3": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "VSwitchName": {
          "Fn::Sub": "${CommonName}_vsw_002"
        },
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "CidrBlock": "192.168.3.0/24",
        "ZoneId": {
          "Ref": "NasZone1"
        }
      }
    },
    "EcsVSwitch1": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "VSwitchName": {
          "Fn::Sub": "${CommonName}_vsw_001"
        },
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "CidrBlock": "192.168.1.0/24",
        "ZoneId": {
          "Ref": "Zone1"
        }
      }
    },
    "BackupFileSystem": {
      "Type": "ALIYUN::NAS::FileSystem",
      "Properties": {
        "StorageType": "Capacity",
        "ProtocolType": "NFS",
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "Description": "BackupNAS",
        "ZoneId": {
          "Ref": "NasZone2"
        }
      }
    },
    "BackupNasMountTarget": {
      "Type": "ALIYUN::NAS::MountTarget",
      "Properties": {
        "NetworkType": "Vpc",
        "FileSystemId": {
          "Ref": "BackupFileSystem"
        },
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "VSwitchId": {
          "Ref": "EcsVSwitch4"
        },
        "AccessGroupName": "DEFAULT_VPC_GROUP_NAME"
      }
    },
    "EcsInstanceGroup1": {
      "Type": "ALIYUN::ECS::InstanceGroup",
      "Properties": {
        "SystemDiskCategory": "cloud_essd",
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "SecurityGroupId": {
          "Ref": "EcsSecurityGroup"
        },
        "SystemDiskSize": 40,
        "ImageId": "aliyun_3_x64_20G_alibase_20230727.vhd",
        "SpotStrategy": "SpotAsPriceGo",
        "IoOptimized": "optimized",
        "VSwitchId": {
          "Ref": "EcsVSwitch1"
        },
        "Password": {
          "Ref": "InstancePassword"
        },
        "InstanceName": {
          "Fn::Sub": "${CommonName}_ecs_001"
        },
        "InstanceType": {
          "Ref": "EcsInstanceType1"
        },
        "ZoneId": {
          "Ref": "Zone1"
        },
        "MaxAmount": 1
      }
    },
    "EcsInstanceGroup2": {
      "Type": "ALIYUN::ECS::InstanceGroup",
      "Properties": {
        "SystemDiskCategory": "cloud_essd",
        "VpcId": {
          "Ref": "EcsVpc"
        },
        "SecurityGroupId": {
          "Ref": "EcsSecurityGroup"
        },
        "SystemDiskSize": 40,
        "ImageId": "aliyun_3_x64_20G_alibase_20230727.vhd",
        "SpotStrategy": "SpotAsPriceGo",
        "IoOptimized": "optimized",
        "VSwitchId": {
          "Ref": "EcsVSwitch2"
        },
        "Password": {
          "Ref": "InstancePassword"
        },
        "InstanceName": {
          "Fn::Sub": "${CommonName}_ecs_002"
        },
        "InstanceType": {
          "Ref": "EcsInstanceType2"
        },
        "ZoneId": {
          "Ref": "Zone2"
        },
        "MaxAmount": 1
      }
    },
    "EcsVpc": {
      "Type": "ALIYUN::ECS::VPC",
      "Properties": {
        "VpcName": {
          "Fn::Sub": "${CommonName}_vpc"
        },
        "CidrBlock": "192.168.0.0/16"
      }
    },
    "SlbBackendServerAttachment": {
      "Type": "ALIYUN::SLB::BackendServerAttachment",
      "Properties": {
        "BackendServerList": {
          "Fn::ListMerge": [
            {
              "Fn::GetAtt": [
                "EcsInstanceGroup1",
                "InstanceIds"
              ]
            },
            {
              "Fn::GetAtt": [
                "EcsInstanceGroup2",
                "InstanceIds"
              ]
            }
          ]
        },
        "BackendServerWeightList": [
          100,
          100
        ],
        "LoadBalancerId": {
          "Ref": "Slb"
        }
      }
    },
    "Slb": {
      "Type": "ALIYUN::SLB::LoadBalancer",
      "Properties": {
        "AddressType": "internet",
        "LoadBalancerName": {
          "Fn::Sub": "${CommonName}-slb"
        },
        "InstanceChargeType": "PayByCLCU",
        "PayType": "PayOnDemand"
      }
    },
    "InstanceRunCommand": {
      "Type": "ALIYUN::ECS::RunCommand",
      "Properties": {
        "CommandContent": {
          "Fn::Sub": "#!/bin/bash\nif [ ! -f .ros.provision ]; then\n  echo \"Name: High-availability web service with shared storage\" > .ros.provision\nfi\n\nname=$(grep \"^Name:\" .ros.provision | awk -F':' '{print $2}' | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')\nif [[ \"$name\" != \"High-availability web service with shared storage\" ]]; then\n  echo \"This instance has already been configured using the one-click deployment of the \\\"$name\\\" tutorial. You cannot use the one-click deployment of this tutorial.\"\n  exit 0\nfi\n\necho \"#########################\"\necho \"# Check Network\"\necho \"#########################\"\nping -c 2 -W 2 aliyun.com > /dev/null\nif [[ $? -ne 0 ]]; then\n  echo \"The current instance cannot access the public network.\"\n  exit 0\nfi\n\nif ! grep -q \"^Step1: Prepare Environment$\" .ros.provision; then\n  echo \"#########################\"\n  echo \"# Prepare Environment\"\n  echo \"#########################\"\n  systemctl status firewalld\n  systemctl stop firewalld\n  echo \"Step1: Prepare Environment\" >> .ros.provision\nelse\n  echo \"#########################\"\n  echo \"# Environment has been ready\"\n  echo \"#########################\"\nfi\n\nif ! grep -q \"^Step2: Install Nginx and deploy service$\" .ros.provision; then\n  echo \"#########################\"\n  echo \"# Install Nginx\"\n  echo \"#########################\"\n  sudo yum -y install nginx\n  sudo wget -O /usr/share/nginx/html/index.html https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20231013/jhgg/index.html\n  sudo wget -O /usr/share/nginx/html/lipstick.png https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20230925/zevs/lipstick.png\n  sudo systemctl start nginx\n  sudo systemctl enable nginx\n  echo \"Step2: Install Nginx and deploy service\" >> .ros.provision\nelse\n  echo \"#########################\"\n  echo \"# Nginx has been installed\"\n  echo \"#########################\"\nfi\n\nif ! grep -q \"^Step3: Mount to the ECS\" .ros.provision; then\n  echo \"#########################\"\n  echo \"# Mount to the ECS\"\n  echo \"#########################\"\n  mkdir /nas_master\n  mkdir /nas_backup\n  sudo yum install -y nfs-utils\n  sudo echo \"options sunrpc tcp_slot_table_entries=128\" >>  /etc/modprobe.d/sunrpc.conf\n  sudo echo \"options sunrpc tcp_max_slot_table_entries=128\" >>  /etc/modprobe.d/sunrpc.conf\n  sudo mount -t nfs -o vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${MasterNasMountTarget.MountTargetDomain}:/ /nas_master\n  sudo mount -t nfs -o vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ${BackupNasMountTarget.MountTargetDomain}:/ /nas_backup\n\n  sudo echo \"${MasterNasMountTarget.MountTargetDomain}:/ /nas_master nfs vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev,noresvport 0 0\" >> /etc/fstab\n  \n  sudo echo \"${BackupNasMountTarget.MountTargetDomain}:/ /nas_backup nfs vers=3,nolock,proto=tcp,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,_netdev,noresvport 0 0\" >> /etc/fstab\n\n  df -h | grep aliyun\nelse\n  echo \"#########################\"\n  echo \"# The ECS has been attached to the Nas\"\n  echo \"#########################\"\nfi\n\nif ! grep -q \"^Step4: Shared file$\" .ros.provision; then\n  echo \"#########################\"\n  echo \"# Shared file\"\n  echo \"#########################\"\n  sudo cp -Lvr /usr/share/nginx/html /nas_master\n  sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak\n  echo \"Step4: Shared file\" >> .ros.provision\nelse\n  echo \"#########################\"\n  echo \"# File has been Shared\"\n  echo \"#########################\"\nfi\n\nif ! grep -q \"^Step5: Install inotify-tools, rsync$\" .ros.provision; then\n  echo \"#########################\"\n  echo \"# Install inotify-tools, rsync\"\n  echo \"#########################\"\n  sudo yum install -y inotify-tools rsync\n  echo \"Step6: Install inotify-tools, rsync\" >> .ros.provision\nelse\n  echo \"#########################\"\n  echo \"# Inotify-tools has been installed\"\n  echo \"#########################\"\nfi\nif ! grep -q \"^Step6: Install synchronization server$\" .ros.provision; then\n  echo \"#########################\"\n  echo \"# Install synchronization server\"\n  echo \"#########################\"\n  sudo wget -P /etc/systemd/system/ https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/zh-CN/20231017/pftz/sync_nas.sh\n  sudo wget -P /etc/systemd/system/ https://help-static-aliyun-doc.aliyuncs.com/file-manage-files/en-US/20230925/wmaj/sync_check_switch.sh\n  sudo chmod +x /etc/systemd/system/sync_nas.sh\n  sudo chmod +x /etc/systemd/system/sync_check_switch.sh\n  cat > /etc/systemd/system/sync-check-switch.service << \\EOF\n[Unit]\nDescription=Sync Check Switch\nAfter=network.target\n\n[Service]\nExecStart=/etc/systemd/system/sync_check_switch.sh\nRestartSec=3\nRestart=always\n\n[Install]\nWantedBy=default.target\nEOF\n\n  cat > /etc/systemd/system/sync-nas.service << \\EOF\n[Unit]\nDescription=Sync NAS Service\nAfter=network.target\n\n[Service]\nExecStart=/etc/systemd/system/sync_nas.sh\nRestart=always\nRestartSec=3\n\n[Install]\nWantedBy=default.target\nEOF\n\n  sudo systemctl daemon-reload\n  sudo systemctl start sync-nas.service\n  sudo systemctl enable sync-check-switch.service\n  sudo systemctl start sync-check-switch.service\n  sudo systemctl enable sync-nas.service\n  echo \"Step6: Install \" >> .ros.provision\nelse\n  echo \"#########################\"\n  echo \"# Synchronization server has been installed\"\n  echo \"#########################\"\nfi"
        },
        "Type": "RunShellScript",
        "Sync": true,
        "InstanceIds": [
          {
            "Ref": "EcsInstanceGroup1"
          },
          {
            "Ref": "EcsInstanceGroup2"
          }
        ],
        "Timeout": "300"
      }
    }
  },
  "Metadata": {
    "ALIYUN::ROS::Interface": {
      "ParameterGroups": [
        {
          "Parameters": [
            "Zone1",
            "Zone2",
            "NasZone1",
            "NasZone2"
          ],
          "Label": {
            "default": {
              "zh-cn": "Zone Configuration",
              "en": "Availability Zone"
            }
          }
        },
        {
          "Parameters": [
            "EcsInstanceType1",
            "EcsInstanceType2",
            "InstancePassword"
          ],
          "Label": {
            "default": {
              "zh-cn": "ECS Instance Configuration",
              "en": "Instance Configure"
            }
          }
        }
      ],
      "TemplateTags": [
        "acs:technical-solution:high-availability-architecture:high-availability-web-service-with-shared-storage-tech_solu_12"
      ],
      "Hidden": [
        "CommonName"
      ]
    }
  }
}

その他の例については、「このリソースを含むパブリックテンプレート」をご参照ください。