Crée un écouteur SLB.
Syntaxe
{
"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
}
}
Propriétés
|
Nom de la propriété |
Type |
Obligatoire |
Mise à jour autorisée |
Description |
Contraintes |
|
MasterSlaveServerGroupId |
String |
Non |
Non |
ID du groupe de serveurs principal/secondaire. |
Aucune |
|
AclStatus |
String |
Non |
Oui |
Indique s'il faut activer le contrôle d'accès. |
Valeurs valides :
|
|
EnableHttp2 |
String |
Non |
Oui |
Indique s'il faut activer HTTP/2. |
Valeurs valides :
|
|
AclId |
String |
Non |
Oui |
ID du groupe de politiques de contrôle d'accès associé à l'écouteur. |
Ce paramètre est obligatoire lorsque AclStatus est défini sur on. |
|
AclType |
String |
Non |
Oui |
Type de la politique de contrôle d'accès. |
Valeurs valides :
|
|
Protocol |
String |
Oui |
Non |
Protocole de l'écouteur. |
Valeurs valides :
|
|
ListenerPort |
Integer |
Oui |
Non |
Port frontal de l'instance SLB. |
Plage de valeurs : 1 à 65 535. |
|
Bandwidth |
Integer |
Oui |
Oui |
Bande passante maximale de l'écouteur. |
Plage de valeurs : -1 ou 1 à 1 000. Unité : Mbps. Remarques :
|
|
BackendServerPort |
Integer |
Non |
Non |
Port backend de l'instance SLB. |
Plage de valeurs : 1 à 65 535. |
|
FullNatEnabled |
Boolean |
Non |
Oui |
Indique s'il faut activer le mode full-NAT. Lorsqu'il est activé, les serveurs backend peuvent accéder aux ressources externes en tant que clients. |
Valeur par défaut : false. Remarque : ce paramètre n'est valide que pour les écouteurs TCP et UDP. |
|
LoadBalancerId |
String |
Oui |
Non |
ID de l'instance SLB. |
Aucune |
|
HealthCheck |
Map |
Non |
Oui |
Paramètres de vérification de l'état de santé. |
Pour plus d'informations, consultez Propriétés HealthCheck. |
|
Persistence |
Map |
Non |
Oui |
Paramètres de persistance de session. |
Pour plus d'informations, consultez Propriétés Persistence. |
|
Scheduler |
String |
Non |
Non |
Algorithme de planification. |
Valeurs valides :
|
|
CACertificateId |
String |
Non |
Non |
ID du certificat CA. |
Ce paramètre n'est valide que pour le protocole HTTPS. |
|
ServerCertificateId |
String |
Non |
Oui |
ID du certificat de serveur. |
Ce paramètre est obligatoire et n'est valide que pour le protocole HTTPS. |
|
VServerGroupId |
String |
Non |
Oui |
ID du groupe de serveurs. |
Aucune |
|
RequestTimeout |
Integer |
Non |
Non |
Délai d'expiration de la requête. |
Plage de valeurs : 1 à 180. Unité : secondes. |
|
IdleTimeout |
Integer |
Non |
Non |
Délai d'expiration des connexions inactives. |
Plage de valeurs : 1 à 60. Unité : secondes. |
|
HttpConfig |
Map |
Non |
Non |
Configuration HTTP. |
Pour plus d'informations, consultez Propriétés HttpConfig. |
|
Description |
String |
Non |
Non |
Description de l'écouteur. |
La longueur doit être comprise entre 1 et 80 caractères. Elle peut contenir des lettres, des chiffres, des traits d'union (-), des barres obliques (/), des points (.) et des traits de soulignement (_). |
|
PortRange |
List |
Non |
Non |
Plage de ports d'écoute. |
Actuellement, seule l'écoute sur tous les ports est prise en charge. Cela signifie que StartPort doit être 1 et EndPort doit être 65 535. Pour plus d'informations, consultez Propriétés PortRange. |
|
StartListener |
Boolean |
Non |
Non |
Indique s'il faut démarrer l'écouteur. |
Valeurs valides :
|
|
Gzip |
String |
Non |
Oui |
Indique s'il faut activer la compression Gzip. |
Valeurs valides :
|
|
TLSCipherPolicy |
String |
Non |
Oui |
Politique de sécurité TLS. |
Chaque politique de sécurité contient les versions TLS et les suites de chiffrement pouvant être utilisées pour HTTPS. Remarque
Ce paramètre est valide lorsque Protocol est défini sur |
|
AclIds |
List |
Non |
Oui |
ID des politiques de contrôle d'accès à associer à l'écouteur. |
Ce paramètre est obligatoire si le paramètre |
|
ProxyProtocolV2Enabled |
Boolean |
Non |
Oui |
Indique s'il faut utiliser le protocole Proxy pour transmettre les adresses IP des clients aux serveurs backend. |
Valeurs valides :
|
|
ConnectionDrainTimeout |
Integer |
Non |
Oui |
Délai d'expiration pour la vidange des connexions. |
Unité : secondes. Plage de valeurs : 10 à 900. |
|
Tags |
List |
Non |
Oui |
Les tags. |
Pour plus d'informations, consultez Propriétés Tags. |
|
ConnectionDrain |
String |
Non |
Oui |
Indique s'il faut activer la vidange des connexions. |
Valeurs valides :
|
Syntaxe 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
}
Propriétés HealthCheck
|
Nom de la propriété |
Type |
Obligatoire |
Mise à jour autorisée |
Description |
Contraintes |
|
Domain |
String |
Non |
Non |
Nom de domaine utilisé pour les vérifications de l'état de santé. |
Valeurs valides :
Remarque
Si vous définissez ce paramètre sur $_ip ou le laissez vide, SLB utilise l'adresse IP privée de chaque serveur backend comme nom de domaine pour les vérifications de l'état de santé. |
|
Interval |
Integer |
Non |
Non |
Intervalle entre les vérifications de l'état de santé. |
Plage de valeurs : 1 à 5. Unité : secondes. |
|
URI |
String |
Non |
Non |
URI utilisé pour les vérifications de l'état de santé. |
La valeur doit comporter entre 1 et 80 caractères. Elle doit commencer par une barre oblique (/). Elle peut contenir des lettres, des chiffres, des traits d'union (-), des barres obliques (/), des points (.), des signes pourcent (%), des points d'interrogation (?), des dièses (#) et des esperluettes (&). |
|
HttpCode |
String |
Non |
Non |
Code d'état HTTP. |
Valeurs valides :
Séparez plusieurs codes d'état HTTP par des virgules (,). |
|
HealthyThreshold |
Integer |
Non |
Non |
Nombre de vérifications de l'état de santé réussies consécutives requises avant de déclarer un serveur backend sain. |
Plage de valeurs : 1 à 10. |
|
HealthCheckType |
String |
Non |
Non |
Type de vérification de l'état de santé. |
Valeurs valides :
|
|
Timeout |
Integer |
Non |
Non |
Délai d'expiration pour une réponse de vérification de l'état de santé. |
Plage de valeurs : 1 à 50. Unité : secondes. Remarque
Si la valeur Timeout est inférieure à la valeur Interval, la valeur Timeout est ignorée et la valeur Interval est utilisée comme délai d'expiration. |
|
UnhealthyThreshold |
Integer |
Non |
Non |
Nombre de vérifications de l'état de santé échouées consécutives requises avant de déclarer un serveur backend non sain. |
Plage de valeurs : 1 à 10. |
|
Port |
Integer |
Non |
Non |
Port utilisé pour les vérifications de l'état de santé. |
Plage de valeurs : 0 à 65 535. |
|
Switch |
String |
Non |
Non |
Indique s'il faut activer les vérifications de l'état de santé. |
Valeurs valides :
Remarque
Ce paramètre n'est actuellement valide que pour les protocoles HTTP ou HTTPS. Si vous ne définissez pas Switch, les vérifications de l'état de santé sont désactivées par défaut, sauf si vous avez configuré des éléments de vérification de l'état de santé. |
|
HealthCheckMethod |
String |
Non |
Non |
Méthode de vérification de l'état de santé. |
Valeurs valides :
Remarque
Ce paramètre est valide lorsque Protocol est défini sur |
|
Req |
String |
Non |
Non |
Chaîne de requête pour les vérifications de l'état de santé UDP. Seules les lettres et les chiffres sont autorisés. |
La longueur maximale est de 64 caractères. |
|
Exp |
String |
Non |
Non |
Chaîne de réponse attendue pour les vérifications de l'état de santé UDP. Seules les lettres et les chiffres sont autorisés. |
La longueur maximale est de 64 caractères. |
Syntaxe 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
}
Propriétés Persistence
|
Nom de la propriété |
Type |
Obligatoire |
Mise à jour autorisée |
Description |
Contraintes |
|
StickySession |
String |
Non |
Oui |
Indique s'il faut activer la persistance de session. |
Valeurs valides :
|
|
PersistenceTimeout |
Integer |
Non |
Oui |
Délai d'expiration pour la persistance de connexion. |
Plage de valeurs : 0 à 1 000. Valeur par défaut : 0 (désactivé). Unité : secondes. |
|
CookieTimeout |
Integer |
Non |
Oui |
Délai d'expiration du cookie. |
Plage de valeurs : 1 à 86 400. Unité : secondes. Remarque
Ce paramètre est obligatoire lorsque StickySession est défini sur on et StickySessionType est défini sur insert. |
|
XForwardedFor |
String |
Non |
Oui |
Indique s'il faut utiliser l'en-tête X-Forwarded-For pour récupérer l'adresse IP du client. |
Valeurs valides :
|
|
XForwardedFor_proto |
String |
Non |
Oui |
Indique s'il faut utiliser l'en-tête X-Forwarded-Proto pour récupérer le protocole de l'écouteur SLB. |
Valeurs valides :
|
|
XForwardedFor_SLBID |
String |
Non |
Oui |
Indique s'il faut utiliser l'en-tête SLB-ID pour récupérer l'ID de l'instance SLB. |
Valeurs valides :
|
|
XForwardedFor_SLBIP |
String |
Non |
Oui |
Indique s'il faut récupérer l'adresse IP du client à partir de l'en-tête SLB-IP. |
Valeurs valides :
|
|
Cookie |
String |
Non |
Oui |
Cookie configuré sur le serveur. |
La valeur doit comporter entre 1 et 200 caractères et ne peut pas commencer par un signe dollar ($). Elle peut contenir des lettres et des chiffres, mais ne peut pas contenir de virgules (,), de points-virgules (;) ou d'espaces. Remarque
Ce paramètre est obligatoire lorsque StickySession est défini sur on et StickySessionType est défini sur server. |
|
StickySessionType |
String |
Non |
Oui |
Méthode de gestion des cookies. |
Valeurs valides :
Remarque
Ce paramètre est obligatoire lorsque StickySession est défini sur on. |
|
XForwardedFor_ClientSrcPort |
String |
Non |
Oui |
Indique s'il faut utiliser l'en-tête X-Forwarded-Client-srcport pour récupérer le port client. |
Valeurs valides :
|
|
XForwardedFor_SLBPORT |
String |
Non |
Oui |
Indique s'il faut utiliser l'en-tête X-Forwarded-Port pour récupérer le port d'écoute SLB. |
Valeurs valides :
|
Syntaxe HttpConfig
"HttpConfig": {
"ForwardPort": Integer,
"ListenerForward": String
}
Propriétés HttpConfig
|
Nom de la propriété |
Type |
Obligatoire |
Mise à jour autorisée |
Description |
Contraintes |
|
ForwardPort |
Integer |
Non |
Non |
Port vers lequel les requêtes HTTP sont transférées pour un écouteur HTTPS. |
Plage de valeurs : 1 à 65 535. Valeur par défaut : 443. |
|
ListenerForward |
String |
Non |
Non |
Indique s'il faut activer le transfert HTTP vers HTTPS. |
Valeurs valides :
|
Syntaxe PortRange
"PortRange": [
{
"StartPort": Integer,
"EndPort": Integer
}
]
Propriétés PortRange
|
Nom de la propriété |
Type |
Obligatoire |
Mise à jour autorisée |
Description |
Contraintes |
|
StartPort |
Integer |
Oui |
Non |
Port de début. |
Valeur : 1. |
|
EndPort |
Integer |
Oui |
Non |
Port de fin. |
Valeur : 65 535. |
Syntaxe Tags
"Tags": [
{
"Key": String,
"Value": String
}
]
Propriété Tags
|
Propriété |
Type |
Obligatoire |
Mise à jour autorisée |
Description |
Contraintes |
|
Key |
String |
Oui |
Non |
Clé du tag. |
Aucune |
|
Value |
String |
Non |
Non |
Valeur du tag. |
Aucune |
Valeurs de retour
Fn::GetAtt
LoadBalancerId : ID unique de l'instance SLB.
ListenerPortsAndProtocol : Ports frontaux et protocoles utilisés par l'instance SLB.
Arn : Nom de ressource Alibaba Cloud (ARN).
Exemples
Scénario 1 : Créer un écouteur 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": {
}
}Scénario 2 : Créer un écouteur SLB avec vérifications de l'état de santé
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": {
}
}Scénario 3 : Créer un service web haute disponibilité
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"
]
}
}
}Pour plus d'exemples, consultez les modèles publics contenant cette ressource.