Tous les produits
Search
Centre de documentation

Resource Orchestration Service:ALIYUN::SAE::Application

Dernière mise à jour :Aug 12, 2026

Le type de resource ALIYUN::SAE::Application permet de créer une application Serverless App Engine (SAE).

Syntaxe

{
  "Type": "ALIYUN::SAE::Application",
  "Properties": {
    "Timezone": String,
    "AppDescription": String,
    "MountDesc": String,
    "NasId": String,
    "WarStartOptions": String,
    "Liveness": String,
    "Memory": Integer,
    "WebContainer": String,
    "SlsConfigs": String,
    "Cpu": Integer,
    "Deploy": Boolean,
    "PackageVersion": String,
    "AppName": String,
    "Jdk": String,
    "JarStartArgs": String,
    "PreStop": String,
    "Readiness": String,
    "PackageType": String,
    "CommandArgs": String,
    "Envs": String,
    "VSwitchId": String,
    "ImageUrl": String,
    "PostStart": String,
    "JarStartOptions": String,
    "MountHost": String,
    "Replicas": Integer,
    "CustomHostAlias": String,
    "VpcId": String,
    "Tags": List,
    "SecurityGroupId": String,
    "Command": String,
    "EdasContainerVersion": String,
    "PackageUrl": String,
    "NamespaceId": String,
    "AssociateEip": Boolean,
    "AcrInstanceId": String,
    "OssAkId": String,
    "ProgrammingLanguage": String,
    "OssAkSecret": String,
    "Python": String,
    "BaseAppId": String,
    "EnableEbpf": String,
    "PhpArmsConfigLocation": String,
    "PhpConfig": String,
    "MicroRegistrationConfig": String,
    "TerminationGracePeriodSeconds": Integer,
    "ConfigMapMountDesc": String,
    "PvtzDiscoverySvc": String,
    "AcrAssumeRoleArn": String,
    "TomcatConfig": String,
    "AppSource": String,
    "PythonModules": String,
    "NasConfigs": String,
    "MicroRegistration": String,
    "ServiceTags": String,
    "ImagePullSecrets": String,
    "AutoConfig": Boolean,
    "KafkaConfigs": String,
    "Php": String,
    "OssMountDescs": List,
    "PhpConfigLocation": String,
    "SaeVersion": String,
    "NewSaeVersion": String,
    "EnableNewArms": Boolean,
    "EnableSidecarResourceIsolated": Boolean,
    "SidecarContainersConfig": List,
    "InitContainersConfig": List
  }
}

Propriétés

Propriété

Type

Obligatoire

Modifiable

Description

Contraintes

AppName

String

Oui

Non

Nom de l'application.

Le nom peut contenir jusqu'à 36 caractères. Il doit commencer par une lettre et peut comporter des lettres, des chiffres et des traits d'union (-).

Cpu

Integer

Oui

Oui

Ressources CPU nécessaires pour chaque instance. Seules les spécifications définies sont prises en charge.

Valeurs valides :

  • 500

  • 1000

  • 2000

  • 4000

  • 8000

  • 16000

  • 32000

Unité : millicores.

Memory

Integer

Oui

Oui

Mémoire requise pour chaque instance. Seules les spécifications définies sont prises en charge.

Ce paramètre correspond directement au CPU et ne prend actuellement en charge que les spécifications suivantes :

  • 1024 : correspond à 500 millicores de CPU.

  • 2048 : correspond à 500 et 1000 millicores de CPU.

  • 4096 : correspond à 1000 et 2000 millicores de CPU.

  • 8192 : correspond à 2000 et 4000 millicores de CPU.

  • 16384 : correspond à 4000 et 8000 millicores de CPU.

  • 32768 : correspond à 16000 millicores de CPU.

  • 65536 : correspond à 8000, 16000 et 32000 millicores de CPU.

  • 131072 : correspond à 32000 millicores de CPU.

Unité : Mo.

NamespaceId

String

Oui

Non

ID du namespace EDAS.

Seuls les namespaces dont le nom contient des lettres minuscules et des traits d'union (-) sont pris en charge. Le nom doit commencer par une lettre minuscule.

PackageType

String

Oui

Non

Type de package de l'application.

Valeurs valides :

  • FatJar

  • War

  • Image

Replicas

Integer

Oui

Non

Nombre initial d'instances.

Aucune

AcrAssumeRoleArn

String

Non

Non

ARN (Alibaba Cloud Resource Name) du rôle RAM requis pour récupérer des images entre comptes.

Pour plus d'informations, consultez Accorder des autorisations à un rôle RAM.

AcrInstanceId

String

Non

Oui

ID de l'instance ACR Enterprise.

Aucune

AppDescription

String

Non

Non

Description de l'application.

La description peut contenir jusqu'à 1024 caractères.

AppSource

String

Non

Non

Application microservice.

Valeurs valides :

  • micro_service

AssociateEip

Boolean

Non

Non

Indique s'il faut associer une EIP.

Valeurs valides :

  • true : associer une EIP.

  • false : ne pas associer d'EIP.

AutoConfig

Boolean

Non

Non

Détermine si l'environnement réseau doit être configuré automatiquement.

Valeurs valides :

  • true : SAE configure automatiquement l'environnement réseau lors de la création de l'application. Les valeurs de NamespaceId, VpcId, vSwitchId et SecurityGroupId sont ignorées.

  • false : configurez manuellement l'environnement réseau lors de la création de l'application dans SAE.

Remarque

Si vous définissez ce paramètre sur true, les autres valeurs NamespaceId transmises sont ignorées.

BaseAppId

String

Non

Non

ID de l'application de base.

Aucune

Command

String

Non

Oui

Commande de démarrage de l'image.

La commande doit correspondre à un exécutable présent dans le conteneur, par exemple sleep.

La définition de cette commande remplace la commande de démarrage d'origine de l'image.

CommandArgs

String

Non

Oui

Paramètres de la commande de démarrage de l'image.

Aucune

ConfigMapMountDesc

String

Non

Non

Description du montage ConfigMap.

Utilisez les éléments de configuration créés sur la page Configurations du namespace pour injecter des informations de configuration dans le conteneur. Les paramètres sont décrits ci-dessous :

  • configMapId : ID de l'instance ConfigMap.

  • key : la clé.

  • mountPath : le chemin de montage.

Remarque

Vous pouvez transmettre le paramètre sae-sys-configmap-all pour monter toutes les clés.

CustomHostAlias

String

Non

Oui

Mappage d'hôte personnalisé dans le conteneur.

Mappage d'hôte personnalisé dans le conteneur. Le format est [{"hostName":"samplehost","ip":"127.0.XX.XX"}] .

  • hostName : nom de domaine ou nom d'hôte.

  • ip : adresse IP.

Deploy

Boolean

Non

Non

Indique si l'application doit être déployée immédiatement.

Valeurs valides :

  • true : déploiement immédiat.

  • false (par défaut) : pas de déploiement immédiat.

EdasContainerVersion

String

Non

Oui

Environnement d'exécution utilisé par l'application EDAS Pandora.

Aucune

EnableEbpf

String

Non

Non

Active la surveillance des applications non Java via la technologie eBPF.

Valeurs valides :

  • true : activer.

  • false : désactiver. Valeur par défaut.

EnableNewArms

Boolean

Non

Non

Indique s'il faut activer la nouvelle fonctionnalité Arms.

Valeurs valides :

  • true : activer

  • false : désactiver

EnableSidecarResourceIsolated

Boolean

Non

Oui

Détermine si l'isolation des ressources du conteneur sidecar doit être activée.

Valeurs valides :

  • true : isoler les ressources.

  • false : ne pas isoler les ressources.

Envs

String

Non

Oui

Variables d'environnement du conteneur.

Le format du paramètre de variable d'environnement du conteneur est le suivant : [{"name":"envtmp","value":"0"}].

  • name : nom de la variable d'environnement.

  • value : valeur de la variable d'environnement ou référence à une variable d'environnement.

ImagePullSecrets

String

Non

Non

ID du secret correspondant.

Aucune

ImageUrl

String

Non

Oui

Adresse de l'image.

Une adresse d'image ne peut être configurée que pour les applications de type Image.

InitContainersConfig

List

Non

Oui

Liste des configurations de conteneurs d'initialisation.

Pour plus d'informations, consultez Propriétés InitContainersConfig.

JarStartArgs

String

Non

Oui

Paramètres de démarrage de l'application dans un package JAR.

La commande de démarrage par défaut de l'application est $JAVA_HOME/bin/java $JarStartOptions -jar $CATALINA_OPTS "$package_path" $JarStartArgs.

JarStartOptions

String

Non

Oui

Options de démarrage de l'application dans un package JAR.

La commande de démarrage par défaut de l'application est $JAVA_HOME/bin/java $JarStartOptions -jar $CATALINA_OPTS "$package_path" $JarStartArgs.

Jdk

String

Non

Oui

Version du JDK requise par le package de déploiement.

Ce paramètre n'est pas pris en charge pour les images.

KafkaConfigs

String

Non

Non

Résumé des configurations pour la collecte des journaux vers Kafka.

Les paramètres sont décrits ci-dessous :

  • kafkaEndpoint : endpoint du service de l'API Kafka.

  • kafkaInstanceId : ID de l'instance Kafka.

  • kafkaConfigs : résumé des configurations pour un ou plusieurs journaux. Pour plus d'informations sur les valeurs valides, consultez le paramètre de requête KafkaConfigs dans cette rubrique.

Liveness

String

Non

Oui

Vérification de l'état de santé du conteneur. Un conteneur qui échoue à cette vérification est redémarré.

Seules les commandes exécutées dans le conteneur sont prises en charge. Exemple : {"exec":{"command":["sleep","5s"]},"initialDelaySeconds":10,"timeoutSeconds":11}.

MicroRegistration

String

Non

Non

Sélectionnez le registre de services Nacos.

Valeurs valides :

  • 0 : Nacos intégré à SAE.

  • 1 : Nacos créé par l'utilisateur.

  • 2 : Nacos commercial MSE.

MicroRegistrationConfig

String

Non

Non

Informations de configuration du registre de services.

Aucune

MountDesc

String

Non

Oui

Description du montage.

Aucune

MountHost

String

Non

Oui

Cible de montage du système de fichiers NAS dans le VPC.

Aucune

NasConfigs

String

Non

Non

Configurations pour le montage d'un système de fichiers NAS.

Les paramètres sont décrits ci-dessous :

  • mountPath : chemin de montage du conteneur.

  • readOnly : si la valeur est false, vous disposez d'autorisations en lecture et en écriture.

  • nasId : ID NAS.

  • mountDomain : adresse cible de montage du conteneur. Pour plus d'informations, consultez DescribeMountTargets.

  • nasPath : chemin relatif du fichier NAS.

NasId

String

Non

Oui

ID du système de fichiers NAS monté.

Le système de fichiers NAS doit disposer d'un quota de cible de montage disponible, ou sa cible de montage doit se trouver sur un vSwitch du VPC. Si vous ne spécifiez pas ce paramètre mais indiquez le paramètre MountDesc, un système de fichiers NAS est automatiquement acheté et monté sur le vSwitch du VPC.

NewSaeVersion

String

Non

Non

Nouvelle version de SAE.

Valeurs valides :

  • lite

  • std

  • pro

OssAkId

String

Non

Non

AccessKey ID pour les opérations de lecture et d'écriture OSS.

Aucune

OssAkSecret

String

Non

Non

AccessKey secret pour les opérations de lecture et d'écriture OSS.

Aucune

OssMountDescs

List

Non

Non

Description du montage OSS.

Les paramètres sont décrits ci-dessous :

  • bucketName : nom du bucket.

  • bucketPath : répertoire ou objet OSS créé dans OSS. Si le répertoire de montage OSS n'existe pas, une exception est déclenchée.

  • mountPath : chemin du conteneur dans SAE. Si le chemin existe, il est écrasé. S'il n'existe pas, il est créé.

  • readOnly : indique si le chemin du conteneur dispose d'une autorisation en lecture seule pour les ressources du répertoire monté. Valeurs valides :

    • true : autorisation en lecture seule.

    • false : autorisations en lecture et en écriture.

PackageUrl

String

Non

Oui

Adresse du package de déploiement.

Ce paramètre est valide lorsque PackageType est défini sur War ou FatJar.

PackageVersion

String

Non

Oui

Numéro de version du package déployé.

Ce paramètre est obligatoire lorsque PackageType est défini sur War ou FatJar.

Php

String

Non

Non

Version PHP requise par le package de déploiement PHP.

Aucune.

PhpArmsConfigLocation

String

Non

Non

Chemin de montage pour la surveillance des applications PHP. Assurez-vous que le serveur PHP charge le fichier de configuration depuis ce chemin.

Vous n'avez pas besoin de vous soucier du contenu de la configuration. SAE génère automatiquement le fichier de configuration approprié.

PhpConfig

String

Non

Non

Contenu du fichier de configuration PHP.

Aucune

PhpConfigLocation

String

Non

Non

Chemin de montage pour la configuration de démarrage de l'application PHP.

Assurez-vous que le serveur PHP démarre en utilisant ce fichier de configuration.

PostStart

String

Non

Oui

Script à exécuter après le démarrage du conteneur.

Script à exécuter après le démarrage du conteneur. Exemple : {"exec":{"command":"cat","/etc/group"}}.

PreStop

String

Non

Oui

Script à exécuter avant la suppression du conteneur.

Script à exécuter avant la suppression du conteneur. Exemple : {"exec":{"command":"cat","/etc/group"}}.

ProgrammingLanguage

String

Non

Non

Langage de programmation de la pile technologique de l'application.

Valeurs valides :

  • java : langage Java.

  • php : langage PHP.

  • other : langages multiples, tels que Python, C++, Go et Node.js.

PvtzDiscoverySvc

String

Non

Non

Active l'enregistrement et la découverte de services K8s.

Les paramètres sont décrits ci-dessous :

  • serviceName : nom du service. Le format est Custom-Namespace ID. Le suffixe -Namespace ID ne peut pas être personnalisé. Vous devez spécifier le suffixe en fonction du namespace de l'application. Par exemple, si vous sélectionnez le namespace par défaut dans la région Chine (Pékin), le suffixe est -cn-beijing-default.

  • namespaceId : ID du namespace.

  • portProtocols : ports et protocoles. Le numéro de port doit être compris dans la plage [1, 65535]. Les protocoles pris en charge sont TCP et UDP.

  • portAndProtocol : port et protocole. Le numéro de port doit être compris dans la plage [1, 65535]. Les protocoles pris en charge sont TCP et UDP. Le paramètre portProtocols est recommandé. Si vous définissez portProtocols, seul portProtocols prend effet.

  • enable : active l'enregistrement et la découverte de services K8s.

Python

String

Non

Non

Environnement Python.

PYTHON 3.9.15 est pris en charge.

PythonModules

String

Non

Non

Dépendances de modules pour une installation personnalisée.

Par défaut, les dépendances définies dans le fichier requirements.txt du répertoire racine sont installées. Si aucune configuration ou package logiciel personnalisé n'est disponible, vous pouvez spécifier les dépendances à installer.

Readiness

String

Non

Oui

Script de vérification de l'état de démarrage de l'application.

Script de vérification de l'état de démarrage de l'application. Exemple : {"exec":{"command":["sleep","6s"]},"initialDelaySeconds":15,"timeoutSeconds":12}.

Un conteneur qui échoue plusieurs fois à la vérification de l'état de santé est redémarré. Aucun trafic provenant de Server Load Balancer (SLB) n'est routé vers un conteneur qui échoue à cette vérification.

SaeVersion

String

Non

Non

Version de SAE.

Versions prises en charge :

  • v1

  • v2

SecurityGroupId

String

Non

Non

ID du groupe de sécurité.

Aucune

ServiceTags

String

Non

Non

Tags de déploiement progressif configurés pour l'application.

Aucune

SidecarContainersConfig

List

Non

Oui

Liste des informations de configuration des conteneurs.

Pour plus d'informations, consultez Propriétés SidecarContainersConfig.

SlsConfigs

String

Non

Oui

Configuration pour la collecte des journaux de fichiers.

Aucune

Tags

List

Non

Oui

Tags.

Un maximum de 20 tags est pris en charge.

Pour plus d'informations, consultez Syntaxe des tags et Propriétés des tags.

TerminationGracePeriodSeconds

Integer

Non

Non

Délai d'attente pour l'arrêt progressif.

La valeur par défaut est 30. Unité : secondes. Valeurs valides : de 1 à 300.

Timezone

String

Non

Oui

Fuseau horaire.

Valeur par défaut : Asia/Shanghai.

TomcatConfig

String

Non

Non

Configuration du fichier Tomcat.

Définissez la valeur sur "" ou "{}" pour supprimer la configuration :

  • port : numéro de port. Valeurs valides : de 1024 à 65535. Les ports inférieurs à 1024 nécessitent des privilèges root. Étant donné que le conteneur est configuré avec des permissions d'administrateur, spécifiez un numéro de port supérieur à 1024. Si vous ne configurez pas ce paramètre, le port par défaut 8080 est utilisé.

  • contextPath : chemin d'accès. La valeur par défaut est le répertoire racine "/".

  • maxThreads : nombre maximal de connexions dans le pool de connexions. La valeur par défaut est 400.

  • uriEncoding : format d'encodage pour Tomcat, notamment UTF-8, ISO-8859-1, GBK et GB2312. Si vous ne définissez pas ce paramètre, la valeur par défaut ISO-8859-1 est utilisée.

  • useBodyEncodingForUri : indique s'il faut utiliser BodyEncoding for URL. La valeur par défaut est true.

VpcId

String

Non

Non

VPC correspondant au namespace SAE.

Dans SAE, un namespace ne peut être associé qu'à un seul VPC. Cette association ne peut pas être modifiée. Elle est créée lorsque vous créez la première application SAE dans le namespace. Plusieurs namespaces peuvent être associés au même VPC. Si vous ne spécifiez pas ce paramètre, le VPC associé au namespace est utilisé.

VSwitchId

String

Non

Non

vSwitch auquel l'interface réseau élastique (ENI) de l'instance d'application est connectée.

Le vSwitch doit se trouver dans le VPC spécifié. Le vSwitch est associé au namespace EDAS. Si vous ne spécifiez pas ce paramètre, le vSwitch associé au namespace est utilisé.

WarStartOptions

String

Non

Oui

Options de démarrage de l'application dans un package WAR.

La commande de démarrage par défaut de l'application est java $JAVA_OPTS $CATALINA_OPTS -Options org.apache.catalina.startup.Bootstrap "$@" start.

WebContainer

String

Non

Oui

Version de Tomcat requise par le package de déploiement.

Ce paramètre n'est pas pris en charge pour les images.

Syntaxe de SidecarContainersConfig

"SidecarContainersConfig": [
  {
    "CommandArgs": String,
    "AcrInstanceId": String,
    "Memory": Integer,
    "Name": String,
    "EmptyDirDesc": String,
    "Command": String,
    "ImageUrl": String,
    "Cpu": Integer,
    "Envs": String,
    "ConfigMapMountDesc": String
  }
]  

Propriétés de SidecarContainersConfig

Propriété

Type

Obligatoire

Modifiable

Description

Contraintes

Cpu

Integer

Oui

Oui

Nombre de cœurs CPU à allouer au conteneur sidecar.

Aucune

Memory

Integer

Oui

Oui

Quantité de mémoire à allouer au conteneur sidecar.

Aucune

Name

String

Oui

Oui

Nom du conteneur sidecar.

Aucune

AcrInstanceId

String

Non

Oui

ID de l'instance ACR.

Aucune

Command

String

Non

Oui

Commande à exécuter dans le conteneur d'initialisation.

Aucune

CommandArgs

String

Non

Oui

Paramètres de la commande à exécuter dans le conteneur d'initialisation.

Aucune

ConfigMapMountDesc

String

Non

Oui

Description du montage ConfigMap.

Aucune

EmptyDirDesc

String

Non

Oui

Description du montage EMPTYDIR.

Aucune

Envs

String

Non

Oui

Variables d'environnement du conteneur.

Exemple :

[{ "name": "envtmp", "value": "0"}]

ImageUrl

String

Non

Oui

Adresse de l'image.

La configuration d'une adresse d'image est réservée aux applications de type Image.

Syntaxe de InitContainersConfig

"InitContainersConfig": [
  {
    "Command": String,
    "ConfigMapMountDesc": String,
    "ImageUrl": String,
    "CommandArgs": String,
    "Envs": String,
    "Name": String
  }
]  

Propriétés de InitContainersConfig

Propriété

Type

Obligatoire

Modifiable

Description

Contraintes

Name

String

Oui

Oui

Nom du conteneur d'initialisation.

Aucune

Command

String

Non

Oui

Commande à exécuter dans le conteneur d'initialisation.

Aucune

CommandArgs

String

Non

Oui

Paramètres de la commande à exécuter dans le conteneur d'initialisation.

Aucune

ConfigMapMountDesc

String

Non

Non

Description du montage ConfigMap.

Aucune

Envs

String

Non

Oui

Variables d'environnement du conteneur.

Exemple :

[{ "name": "envtmp", "value": "0"}]

ImageUrl

String

Non

Oui

Adresse de l'image.

La configuration d'une adresse d'image est réservée aux applications de type Image.

Syntaxe de Tags

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

Propriétés de Tags

Propriété

Type

Obligatoire

Modifiable

Description

Contraintes

Key

String

Oui

Non

Clé du tag.

La clé du tag doit comporter entre 1 et 128 caractères. Elle ne peut pas commencer par aliyun ou acs:, et ne doit pas contenir http:// ni https://.

Value

String

Non

Non

Valeur du tag.

La valeur du tag peut contenir de 0 à 128 caractères. Elle ne peut pas commencer par aliyun ou acs:, et ne doit pas contenir http:// ni https://.

Valeurs de retour

Fn::GetAtt

  • AppId : ID de l'application.

  • ChangeOrderId : ID de l'ordre de modification. Cet identifiant permet d'interroger l'état d'exécution de la tâche.

Exemples

Scénario 1 : Création d'une application SAE

Créer maintenant

ROSTemplateFormatVersion: '2015-09-01'
Parameters:
  NamespaceId:
    Type: String
    Description: |-
      The ID of the EDAS namespace. The name of the namespace can contain only lowercase letters and hyphens (-). It must start with a lowercase letter.
      You can obtain the namespace from the DescribeNamespaceList operation.
  VpcId:
    Type: String
    AssociationProperty: ALIYUN::ECS::VPC::VPCId
  VSwitchId:
    Type: String
    AssociationProperty: ALIYUN::ECS::VSwitch::VSwitchId
    AssociationPropertyMetadata:
      VpcId: ${VpcId}
  SecurityGroupId:
    Type: String
    AssociationProperty: ALIYUN::ECS::SecurityGroup::SecurityGroupId
    AssociationPropertyMetadata:
      VpcId: ${VpcId}
Resources:
  Application:
    Type: ALIYUN::SAE::Application
    Properties:
      AppName: TestApp
      NamespaceId:
        Ref: NamespaceId
      VpcId:
        Ref: VpcId
      VSwitchId:
        Ref: VSwitchId
      SecurityGroupId:
        Ref: SecurityGroupId
      Cpu: 500
      Memory: 1024
      Replicas: 2
      PackageType: War
      Deploy: true
      Timezone: Asia/Shanghai
Outputs: {}
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Parameters": {
    "NamespaceId": {
      "Type": "String",
      "Description": "The ID of the EDAS namespace. The name of the namespace can contain only lowercase letters and hyphens (-). It must start with a lowercase letter.\nYou can obtain the namespace from the DescribeNamespaceList operation."
    },
    "VpcId": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::VPC::VPCId"
    },
    "VSwitchId": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::VSwitch::VSwitchId",
      "AssociationPropertyMetadata": {
        "VpcId": "${VpcId}"
      }
    },
    "SecurityGroupId": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::SecurityGroup::SecurityGroupId",
      "AssociationPropertyMetadata": {
        "VpcId": "${VpcId}"
      }
    }
  },
  "Resources": {
    "Application": {
      "Type": "ALIYUN::SAE::Application",
      "Properties": {
        "AppName": "TestApp",
        "NamespaceId": {
          "Ref": "NamespaceId"
        },
        "VpcId": {
          "Ref": "VpcId"
        },
        "VSwitchId": {
          "Ref": "VSwitchId"
        },
        "SecurityGroupId": {
          "Ref": "SecurityGroupId"
        },
        "Cpu": 500,
        "Memory": 1024,
        "Replicas": 2,
        "PackageType": "War",
        "Deploy": true,
        "Timezone": "Asia/Shanghai"
      }
    }
  },
  "Outputs": {
  }
}

Scénario 2 : Création d'une application SAE et d'un namespace avec liaison d'une instance SLB

Créer maintenant

ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: Creates an SAE application and a namespace, binds an SLB instance, configures ECS resources and load balancing, and automates the deployment of a containerized application.
  en: Create SAE applications, namespaces, and SLB bindings, configure ECS resources
    with load balancing, and automate the deployment of containerized applications.
Parameters:
  ZoneId:
    Type: String
    AssociationProperty: ALIYUN::ECS::Instance:ZoneId
  VpcId:
    Type: String
    AssociationProperty: ALIYUN::ECS::VPC::VPCId
  VSwitchId:
    Type: String
    AssociationProperty: ALIYUN::ECS::VSwitch::VSwitchId
    AssociationPropertyMetadata:
      VpcId: VpcId
      ZoneId: ZoneId
  SecurityGroupId:
    Type: String
    AssociationProperty: ALIYUN::ECS::SecurityGroup::SecurityGroupId
    AssociationPropertyMetadata:
      VpcId: VpcId
  NamespaceName:
    Type: String
    Description: The namespace name.
    Default: mytest
  NamespaceId:
    Type: String
    Description: The namespace ID.
    Default: mytest
  Description:
    Type: String
    Description: The description of the namespace.
    Default: null
  AppName:
    Type: String
    Description: The application name.
    Default: test
  LoadBalancerSpec:
    Type: String
    Description: The specification of the SLB instance.
    Default: slb.s2.medium
Resources:
  LoadBalancer:
    Type: ALIYUN::SLB::LoadBalancer
    Properties:
      MasterZoneId:
        Ref: ZoneId
      LoadBalancerSpec:
        Ref: LoadBalancerSpec
  Namespace:
    Type: ALIYUN::SAE::Namespace
    Properties:
      NamespaceName:
        Ref: NamespaceName
      NamespaceId:
        Fn::Sub: ${ALIYUN::Region}:${NamespaceId}
      NamespaceDescription:
        Ref: Description
    DependsOn: LoadBalancer
  SaeApp:
    Type: ALIYUN::SAE::Application
    Properties:
      VpcId:
        Ref: VpcId
      VSwitchId:
        Ref: VSwitchId
      SecurityGroupId:
        Ref: SecurityGroupId
      AppName:
        Ref: AppName
      NamespaceId:
        Fn::GetAtt:
        - Namespace
        - NamespaceId
      Cpu: 500
      Memory: 1024
      Replicas: 2
      Deploy: true
      Timezone: Asia/Shanghai
      SaeVersion: v2
      AutoConfig: false

      PackageType: Image
      Jdk: Dragonwell 21
      ImageUrl:
        Fn::Sub: registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:web-springboot-hellosae-v1.0
      ProgrammingLanguage: java
      AppSource: micro_service
    DependsOn:
    - Namespace
  BindSlb:
    Type: ALIYUN::SAE::SlbBinding
    Properties:
      AppId:
        Ref: SaeApp
      Intranet: '[{"port": 80, "targetPort": 8080, "protocol": "TCP"}]'
      InternetSlbId:
        Ref: LoadBalancer
    DependsOn:
    - LoadBalancer
    - SaeApp
Outputs:
  AppId:
    Value:
      Fn::GetAtt:
      - SaeApp
      - AppId
  ChangeOrderId:
    Value:
      Fn::GetAtt:
      - SaeApp
      - ChangeOrderId
  NamespaceId:
    Value:
      Fn::GetAtt:
      - Namespace
      - NamespaceId
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Description": {
    "zh-cn": "Creates an SAE application and a namespace, binds an SLB instance, configures ECS resources and load balancing, and automates the deployment of a containerized application.",
    "en": "Create SAE applications, namespaces, and SLB bindings, configure ECS resources with load balancing, and automate the deployment of containerized applications."
  },
  "Parameters": {
    "ZoneId": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::Instance:ZoneId"
    },
    "VpcId": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::VPC::VPCId"
    },
    "VSwitchId": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::VSwitch::VSwitchId",
      "AssociationPropertyMetadata": {
        "VpcId": "VpcId",
        "ZoneId": "ZoneId"
      }
    },
    "SecurityGroupId": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::SecurityGroup::SecurityGroupId",
      "AssociationPropertyMetadata": {
        "VpcId": "VpcId"
      }
    },
    "NamespaceName": {
      "Type": "String",
      "Description": "The namespace name.",
      "Default": "mytest"
    },
    "NamespaceId": {
      "Type": "String",
      "Description": "The namespace ID.",
      "Default": "mytest"
    },
    "Description": {
      "Type": "String",
      "Description": "The description of the namespace.",
      "Default": null
    },
    "AppName": {
      "Type": "String",
      "Description": "The application name.",
      "Default": "test"
    },
    "LoadBalancerSpec": {
      "Type": "String",
      "Description": "The specification of the SLB instance.",
      "Default": "slb.s2.medium"
    }
  },
  "Resources": {
    "LoadBalancer": {
      "Type": "ALIYUN::SLB::LoadBalancer",
      "Properties": {
        "MasterZoneId": {
          "Ref": "ZoneId"
        },
        "LoadBalancerSpec": {
          "Ref": "LoadBalancerSpec"
        }
      }
    },
    "Namespace": {
      "Type": "ALIYUN::SAE::Namespace",
      "Properties": {
        "NamespaceName": {
          "Ref": "NamespaceName"
        },
        "NamespaceId": {
          "Fn::Sub": "${ALIYUN::Region}:${NamespaceId}"
        },
        "NamespaceDescription": {
          "Ref": "Description"
        }
      },
      "DependsOn": "LoadBalancer"
    },
    "SaeApp": {
      "Type": "ALIYUN::SAE::Application",
      "Properties": {
        "VpcId": {
          "Ref": "VpcId"
        },
        "VSwitchId": {
          "Ref": "VSwitchId"
        },
        "SecurityGroupId": {
          "Ref": "SecurityGroupId"
        },
        "AppName": {
          "Ref": "AppName"
        },
        "NamespaceId": {
          "Fn::GetAtt": [
            "Namespace",
            "NamespaceId"
          ]
        },
        "Cpu": 500,
        "Memory": 1024,
        "Replicas": 2,
        "Deploy": true,
        "Timezone": "Asia/Shanghai",
        "SaeVersion": "v2",
        "AutoConfig": false,
        "PackageType": "Image",
        "Jdk": "Dragonwell 21",
        "ImageUrl": {
          "Fn::Sub": "registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:web-springboot-hellosae-v1.0"
        },
        "ProgrammingLanguage": "java",
        "AppSource": "micro_service"
      },
      "DependsOn": [
        "Namespace"
      ]
    },
    "BindSlb": {
      "Type": "ALIYUN::SAE::SlbBinding",
      "Properties": {
        "AppId": {
          "Ref": "SaeApp"
        },
        "Intranet": "[{\"port\": 80, \"targetPort\": 8080, \"protocol\": \"TCP\"}]",
        "InternetSlbId": {
          "Ref": "LoadBalancer"
        }
      },
      "DependsOn": [
        "LoadBalancer",
        "SaeApp"
      ]
    }
  },
  "Outputs": {
    "AppId": {
      "Value": {
        "Fn::GetAtt": [
          "SaeApp",
          "AppId"
        ]
      }
    },
    "ChangeOrderId": {
      "Value": {
        "Fn::GetAtt": [
          "SaeApp",
          "ChangeOrderId"
        ]
      }
    },
    "NamespaceId": {
      "Value": {
        "Fn::GetAtt": [
          "Namespace",
          "NamespaceId"
        ]
      }
    }
  }
}

Scénario 3 : Déployer une plateforme Dify de production avec SAE

Créer maintenant

ROSTemplateFormatVersion: '2015-09-01'
Description:
  zh-cn: Deploys a production Dify platform using Serverless App Engine.
  en: Deploys a production Dify platform using Serverless App Engine.
Parameters:
  CommonName:
    Type: String
    Default: Dify
  NamespaceName:
    Type: String
    Label:
      en: Namespace Name
      zh-cn: Namespace Name
    Description:
      zh-cn: The namespace name. Only lowercase letters and numbers are supported.
      en: The namespace name. Only lowercase letters and numbers are supported.
    AllowedPattern: '^[a-z0-9]+$'
    AssociationProperty: AutoCompleteInput
    AssociationPropertyMetadata:
      Length: 3
      Prefix: dify
      CharacterClasses:
        - Class: lowercase
          min: 2
        - Class: "number"
          min: 1
  ZoneId1:
    Type: String
    AssociationProperty: 'ALIYUN::ECS::Instance::ZoneId'
    AssociationPropertyMetadata:
      ExclusiveTo:
        - ZoneId2
    Label:
      en: Availability Zone 1
      zh-cn: Availability Zone 1
  ZoneId2:
    Type: String
    AssociationProperty: 'ALIYUN::ECS::Instance::ZoneId'
    AssociationPropertyMetadata:
      ExclusiveTo:
        - ZoneId1
    Label:
      en: Availability Zone 2
      zh-cn: Availability Zone 2
  InstanceType:
    Type: String
    AssociationProperty: 'ALIYUN::ECS::Instance::InstanceType'
    AssociationPropertyMetadata:
      InstanceChargeType: PostPaid
      SystemDiskCategory: cloud_essd
      ZoneId: ${ZoneId1}
    Label:
      en: Instance Type
      zh-cn: Instance Type
  ADBPGAccount:
    Default: dify
    Type: String
    Label:
      zh-cn: DB Account
      en: DB Account
  ADBPGPassword:
    NoEcho: true
    Type: String
    Label:
      zh-cn: DB Account Password
      en: DB Account Password
    AssociationProperty: ALIYUN::RDS::Instance::AccountPassword
  InstancePassword:
    Type: String
    Label:
      en: Logon Password
      zh-cn: Logon Password
    Description:
      en: 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 are ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
      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 are ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/
    AssociationProperty: ALIYUN::ECS::Instance::Password
  RedisInstancePassword:
    Type: String
    Label:
      en: Instance Password
      zh-cn: Instance Password
    Description:
      en: The Redis password for Dify. The password must be 8 to 32 characters in length and can contain only uppercase letters, lowercase letters, and digits. Do not use other characters.
      zh-cn: The Redis password for Dify. The password must be 8 to 32 characters in length and can contain only uppercase letters, lowercase letters, and digits. Do not use other characters.
    ConstraintDescription:
      en: The Redis password for Dify. The password must be 8 to 32 characters in length and can contain only uppercase letters, lowercase letters, and digits. Do not use other characters.
      zh-cn: The Redis password for Dify. The password must be 8 to 32 characters in length and can contain only uppercase letters, lowercase letters, and digits. Do not use other characters.
    AllowedPattern: ^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?\d)[A-Za-z0-9]{8,32}$
    MinLength: '8'
    MaxLength: '32'
    NoEcho: true
  DBInstanceClass:
    Type: String
    Label:
      en: Instance Type
      zh-cn: Instance Type
    Default: pg.n4m.2c.2m
    Required: true
    AssociationProperty: ALIYUN::RDS::Instance::InstanceType
    AssociationPropertyMetadata:
      ZoneId: ${ZoneId}
      EngineVersion: '17.0'
      Engine: PostgreSQL
      Category: HighAvailability
      InstanceChargeType: Postpaid
      DBInstanceStorageType: cloud_essd
      CommodityCode: bards
  PostgreSQLPassword:
    Type: String
    NoEcho: true
    Label:
      en: Database Account Password
      zh-cn: Database Account Password
    AssociationProperty: ALIYUN::RDS::Instance::AccountPassword
  PostgreSQLUserName:
    Type: String
    Label:
      en: Database Account
      zh-cn: Database Account
    # This rule applies to MySQL 5.7 and 8.0.
    AllowedPattern: ^(?!dbo\b|login\b|admin\b|administrator\b|adminsys\b|alimail\b|aliyun\b|apache\b|appadmin\b|apsara\b|aurora\b|bulkadmin\b|cangjie\b|cdn\b|client\b|cm\b|dataengine\b|dayu\b|dba\b|dbcreator\b|developer\b|diskadmin\b|distribution\b|dns\b|download\b|eagleye\b|f5\b|faq\b|fuxi\b|galaxy\b|gongcao\b|gongming\b|groupon\b|ha\b|help\b|host\b|hostmaster\b|houyi\b|hr\b|info\b|information_schema\b|kuafu\b|lvs\b|manager\b|master\b|meituan\b|model\b|monitor\b|msdb\b|mssqld\b|mssqlsystemresource\b|mysql\b|nas\b|net\b|netops\b|netweb\b|news\b|no-reply\b|ntp\b|nuwa\b|nvwa\b|operator\b|opr\b|ops\b|opsdb\b|oracle\b|pangu\b|pe\b|post\b|postmaster\b|processadmin\b|public\b|qq\b|replicator\b|reply\b|root\b|sa\b|sales\b|san\b|security\b|securityadmin\b|serveradmin\b|services\b|setupadmin\b|shennong\b|siteops\b|sqlengine\b|sqlonline\b|squid\b|ssladmin\b|support\b|sys\b|sysadmin\b|syslog\b|system\b|taoyun\b|tempdb\b|test\b|tianyun\b|wangwang\b|eb\b|webmaster\b|webnet\b|xtrabak\b|youchao\b|yum\b|yunti\b|zhongkui\b|database\b|add\b|except\b|percent\b|all\b|exec\b|plan\b|alter\b|execute\b|precision\b|and\b|exists\b|primary\b|any\b|exit\b|print\b|as\b|fetch\b|proc\b|asc\b|file\b|procedure\b|authorization\b|fillfactor\b|public\b|backup\b|for\b|raiserror\b|begin\b|foreign\b|read\b|between\b|freetext\b|readtext\b|break\b|freetexttable\b|reconfigure\b|browse\b|from\b|references\b|bulk\b|full\b|replication\b|by\b|function\b|restore\b|cascade\b|goto\b|restrict\b|case\b|grant\b|return\b|check\b|group\b|revoke\b|checkpoint\b|having\b|right\b|close\b|holdlock\b|rollback\b|clustered\b|identity\b|rowcount\b|coalesce\b|identity_insert\b|rowguidcol\b|collate\b|identitycol\b|rule\b|column\b|if\b|save\b|commit\b|in\b|schema\b|compute\b|index\b|select\b|constraint\b|inner\b|session_user\b|contains\b|insert\b|set\b|containstable\b|intersect\b|setuser\b|continue\b|into\b|shutdown\b|convert\b|is\b|some\b|create\b|join\b|statistics\b|cross\b|key\b|system_user\b|current\b|kill\b|table\b|current_date\b|left\b|textsize\b|current_time\b|like\b|then\b|current_timestamp\b|lineno\b|to\b|current_user\b|load\b|top\b|cursor\b|national\b|tran\b|database\b|nocheck\b|transaction\b|dbcc\b|nonclustered\b|trigger\b|deallocate\b|not\b|truncate\b|declare\b|null\b|tsequal\b|default\b|nullif\b|union\b|delete\b|of\b|unique\b|deny\b|off\b|update\b|desc\b|offsets\b|updatetext\b|disk\b|on\b|use\b|distinct\b|open\b|user\b|distributed\b|opendatasource\b|values\b|double\b|openquery\b|varying\b|drop\b|openrowset\b|view\b|dummy\b|openxml\b|waitfor\b|dump\b|option\b|when\b|else\b|or\b|where\b|end\b|order\b|while\b|errlvl\b|outer\b|with\b|escape\b|over\b|writetext\b|add\b|analyze\b|asc\b|between\b|blob\b|call\b|change\b|check\b|condition\b|continue\b|cross\b|current_timestamp\b|database\b|day_microsecond\b|dec\b|default\b|desc\b|distinct\b|double\b|each\b|enclosed\b|exit\b|fetch\b|float8\b|foreign\b|goto\b|having\b|hour_minute\b|ignore\b|infile\b|insensitive\b|int1\b|int4\b|interval\b|iterate\b|keys\b|leading\b|like\b|lines\b|localtimestamp\b|longblob\b|low_priority\b|mediumint\b|minute_microsecond\b|modifies\b|no_write_to_binlog\b|on\b|optionally\b|out\b|precision\b|purge\b|read\b|references\b|rename\b|require\b|revoke\b|schema\b|select\b|set\b|spatial\b|sqlexception\b|sql_big_result\b|ssl\b|table\b|tinyblob\b|to\b|true\b|unique\b|update\b|using\b|utc_timestamp\b|varchar\b|when\b|with\b|xor\b|all\b|and\b|asensitive\b|bigint\b|both\b|cascade\b|char\b|collate\b|connection\b|convert\b|current_date\b|current_user\b|databases\b|day_minute\b|decimal\b|delayed\b|describe\b|distinctrow\b|drop\b|else\b|escaped\b|explain\b|float\b|for\b|from\b|grant\b|high_priority\b|hour_second\b|in\b|inner\b|insert\b|int2\b|int8\b|into\b|join\b|kill\b|leave\b|limit\b|load\b|lock\b|longtext\b|match\b|mediumtext\b|minute_second\b|natural\b|null\b|optimize\b|or\b|outer\b|primary\b|raid0\b|reads\b|regexp\b|repeat\b|restrict\b|right\b|schemas\b|sensitive\b|show\b|specific\b|sqlstate\b|sql_calc_found_rows\b|starting\b|terminated\b|tinyint\b|trailing\b|undo\b|unlock\b|usage\b|utc_date\b|values\b|varcharacter\b|where\b|write\b|year_month\b|alter\b|as\b|before\b|binary\b|by\b|case\b|character\b|column\b|constraint\b|create\b|current_time\b|cursor\b|day_hour\b|day_second\b|declare\b|delete\b|deterministic\b|div\b|dual\b|elseif\b|exists\b|false\b|float4\b|force\b|fulltext\b|group\b|hour_microsecond\b|if\b|index\b|inout\b|int\b|int3\b|integer\b|is\b|key\b|label\b|left\b|linear\b|localtime\b|long\b|loop\b|mediumblob\b|middleint\b|mod\b|not\b|numeric\b|option\b|order\b|outfile\b|procedure\b|range\b|real\b|release\b|replace\b|return\b|rlike\b|second_microsecond\b|separator\b|smallint\b|sql\b|sqlwarning\b|sql_small_result\b|straight_join\b|then\b|tinytext\b|trigger\b|union\b|unsigned\b|use\b|utc_time\b|varbinary\b|varying\b|while\b|x509\b|zerofill)([a-zA-Z][a-zA-Z0-9_]{0,30}[a-zA-Z0-9])$
    ConstraintDescription:
      en: The value must be up to 32 characters in length and can contain lowercase letters, uppercase letters, digits, and underscores (_). It must start with a letter and end with a letter or digit. For more information about invalid characters, see <a href="https://www.alibabacloud.com/help/zh/rds/developer-reference/forbidden-keywords" target="_blank">Forbidden keywords table</a>.
      zh-cn: The value must be up to 32 characters in length and can contain lowercase letters, uppercase letters, digits, and underscores (_). It must start with a letter and end with a letter or digit. For more information about invalid characters, see <a href="https://www.alibabacloud.com/help/zh/rds/developer-reference/forbidden-keywords" target="_blank">Forbidden keywords table</a>.
    Default: db_user
Resources:
  Vpc:
    Type: 'ALIYUN::ECS::VPC'
    Properties:
      CidrBlock: 192.168.0.0/16
      VpcName:
        Fn::Sub: ${CommonName}-VPC_HZ
  VSwitch1:
    Type: 'ALIYUN::ECS::VSwitch'
    Properties:
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.1.0/24
      ZoneId:
        Ref: ZoneId1
      VSwitchName:
        Fn::Sub: ${CommonName}-vsw_001
  VSwitch2:
    Type: 'ALIYUN::ECS::VSwitch'
    Properties:
      VpcId:
        Ref: Vpc
      CidrBlock: 192.168.2.0/24
      ZoneId:
        Ref: ZoneId2
      VSwitchName:
        Fn::Sub: ${CommonName}-vsw_002
  Sleep:
    DependsOn:
      - VSwitch1
      - VSwitch2
    Type: ALIYUN::ROS::Sleep
    Properties:
      DeleteDuration: 300
  SecurityGroup:
    Type: 'ALIYUN::ECS::SecurityGroup'
    Properties:
      VpcId:
        Ref: Vpc
      SecurityGroupName:
        Fn::Sub: ${CommonName}-SecurityGroup_1
      SecurityGroupIngress:
        - PortRange: 80/80
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
        - PortRange: 3000/3000
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
        - PortRange: 5001/5001
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
        - PortRange: 5002/5002
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
        - PortRange: 5003/5003
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
        - PortRange: 8080/8080
          Priority: 1
          SourceCidrIp: 0.0.0.0/0
          IpProtocol: tcp
  EcsInstance:
    Type: 'ALIYUN::ECS::InstanceGroup'
    Properties:
      VpcId:
        Ref: Vpc
      ZoneId:
        Ref: ZoneId1
      VSwitchId:
        Ref: VSwitch1
      SecurityGroupId:
        Ref: SecurityGroup
      ImageId: aliyun_3_x64_20G_alibase_
      InstanceName:
        Fn::Sub: ${CommonName}-ecs
      InstanceType:
        Ref: InstanceType
      SystemDiskCategory: cloud_essd
      MaxAmount: 1
      SystemDiskSize: 40
      InternetMaxBandwidthOut: 5
      Password:
        Ref: InstancePassword
  RunCommand:
    Type: ALIYUN::ECS::RunCommand
    Properties:
      CommandContent:
        Fn::Sub:
          |
          #!/bin/sh
          echo "sk-$(openssl rand -hex 16)"
      Type: RunShellScript
      InstanceIds:
        - Ref: EcsInstance
  RunCommand2:
    DependsOn:
      - RunCommand
    Type: ALIYUN::ECS::RunCommand
    Properties:
      CommandContent:
        Fn::Sub:
          |
          #!/bin/sh
          export ROS_DEPLOY=true
          curl -fsSL https://help-static-aliyun-doc.aliyuncs.com/install-script/dify/sae/install.sh | bash
      Type: RunShellScript
      InstanceIds:
        - Ref: EcsInstance
  RedisInstance:
    Type: ALIYUN::REDIS::Instance
    Properties:
      ZoneId:
        Ref: ZoneId1
      SecondaryZoneId:
        Ref: ZoneId2
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch1
      InstanceClass: redis.shard.large.y.ee
      EvictionPolicy: noeviction
      InstanceName:
        Fn::Sub: ${CommonName}-Redis
      EngineVersion: '7.0'
      Password:
        Ref: RedisInstancePassword
  REDISWhitelist:
    Type: ALIYUN::REDIS::Whitelist
    Properties:
      InstanceId:
        Ref: RedisInstance
      SecurityIps: 192.168.0.0/16
  ADBPGInstance:
    Type: ALIYUN::GPDB::DBInstance
    Properties:
      EngineVersion: '7.0'
      VectorConfigurationStatus: True
      InstanceSpec: 4C32G
      ZoneId:
        Ref: ZoneId1
      VSwitchId:
        Ref: VSwitch1
      SegNodeNum: 4
      SegStorageType: cloud_essd
      SegDiskPerformanceLevel: pl1
      StorageSize: 50
      VPCId:
        Ref: Vpc
      SecurityIPList: 192.168.0.0/16
      DBInstanceDescription:
        Fn::Sub: ${CommonName}
      PayType: Postpaid
      DBInstanceCategory: HighAvailability
      DBInstanceMode: StorageElastic
      ProdType: standard
  GPDBAccount:
    Type: ALIYUN::GPDB::Account
    Properties:
      DBInstanceId:
        Fn::GetAtt:
          - ADBPGInstance
          - DBInstanceId
      AccountPassword:
        Ref: ADBPGPassword
      AccountName:
        Ref: ADBPGAccount
  SaeNamespace:
    DependsOn:
      - PostgreSQLInstance
      - RedisInstance
      - ADBPGInstance
      - PluginNas
      - APINas
    Type: ALIYUN::SAE::Namespace
    Properties:
      NamespaceName:
        Ref: NamespaceName
      NamespaceId:
        Fn::Sub: ${ALIYUN::Region}:${NamespaceName}
      VpcId:
        Ref: Vpc
  PostgreSQLInstance:
    Type: ALIYUN::RDS::DBInstance
    Properties:
      ZoneId:
        Ref: ZoneId1
      SlaveZoneIds:
        - Ref: ZoneId2
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch1
      DBInstanceClass:
        Ref: DBInstanceClass
      DBInstanceStorage: 50
      Engine: PostgreSQL
      EngineVersion: '17.0'
      SecurityIPList: 192.168.0.0/16
      Category: HighAvailability
      MasterUserType: Super
      MasterUserPassword:
        Ref: PostgreSQLPassword
      MasterUsername:
        Ref: PostgreSQLUserName
      DBInstanceStorageType: cloud_essd
  DifyDataBase:
    Type: ALIYUN::RDS::Database
    Properties:
      CharacterSetName: utf8
      DBInstanceId:
        Fn::GetAtt:
          - PostgreSQLInstance
          - DBInstanceId
      DBName: dify
  DifySetUpDataBase:
    Type: ALIYUN::RDS::Database
    DependsOn: DifyDataBase
    Properties:
      CharacterSetName: UTF8
      DBInstanceId:
        Fn::GetAtt:
          - PostgreSQLInstance
          - DBInstanceId
      DBName: dify_setups
  RdsAccountPrivilege:
    Type: ALIYUN::RDS::AccountPrivilege
    DependsOn: DifySetUpDataBase
    Properties:
      AccountPrivilege: DBOwner
      DBInstanceId:
        Ref: PostgreSQLInstance
      DBName: dify
      AccountName:
        Ref: PostgreSQLUserName
  NatGateway:
    Type: ALIYUN::VPC::NatGateway
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch1
      NatGatewayName:
        Fn::Sub: ${CommonName}-nat
      InternetChargeType: PayByLcu
      EipBindMode: NAT
  Eip:
    Type: 'ALIYUN::VPC::EIP'
    Properties:
      DeletionProtection: false
      Isp: BGP
      Bandwidth: 200
      InternetChargeType: PayByTraffic
  EipAssociation:
    Type: 'ALIYUN::VPC::EIPAssociation'
    Properties:
      InstanceId:
        Ref: NatGateway
      AllocationId:
        Ref: Eip
  SNat:
    Type: 'ALIYUN::VPC::SnatEntry'
    DependsOn: EipAssociation
    Properties:
      SnatTableId:
        Fn::GetAtt:
          - NatGateway
          - SNatTableId
      SnatEntryName:
        Fn::Sub: ${CommonName}-snat
      SourceVSwitchIds:
        - Ref: VSwitch1
        - Ref: VSwitch2
      SnatIp:
        Fn::GetAtt:
          - Eip
          - EipAddress
  APINas:
    Type: ALIYUN::NAS::FileSystem
    Properties:
      ProtocolType: NFS
      FileSystemType: standard
      DeletionForce: true
      StorageType: Performance
      Description:
        Fn::Sub: ${CommonName}-API-NAS
  APINasMountTarget:
    Type: ALIYUN::NAS::MountTarget
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch1
      NetworkType: Vpc
      AccessGroupName: DEFAULT_VPC_GROUP_NAME
      FileSystemId:
        Ref: APINas
  PluginNas:
    Type: ALIYUN::NAS::FileSystem
    Properties:
      ProtocolType: NFS
      FileSystemType: standard
      DeletionForce: true
      StorageType: Performance
      Description:
        Fn::Sub: ${CommonName}-Plugin-NAS
  PluginNasMountTarget:
    Type: ALIYUN::NAS::MountTarget
    Properties:
      VpcId:
        Ref: Vpc
      VSwitchId:
        Ref: VSwitch1
      NetworkType: Vpc
      AccessGroupName: DEFAULT_VPC_GROUP_NAME
      FileSystemId:
        Ref: PluginNas
  SuperOpsUser:
    Type: 'ALIYUN::RAM::User'
    Properties:
      UserName:
        Fn::Sub: SuperOps-${ALIYUN::StackId}
      Policies:
        - PolicyName:
            'Fn::Join':
              - '-'
              - - DifySuperOpsPolicy
                - Ref: 'ALIYUN::StackName'
          PolicyDocument:
            Version: '1'
            Statement:
              - Effect: Allow
                Action:
                  - 'gpdb:*'
                Resource:
                  - '*'
      PolicyAttachments:
        System:
          - AliyunSTSAssumeRoleAccess
          - AliyunRAMReadOnlyAccess
  AccessKey:
    Type: 'ALIYUN::RAM::AccessKey'
    Properties:
      UserName:
        'Fn::GetAtt':
          - SuperOpsUser
          - UserName
  DifyApiConfigMap:
    Type: ALIYUN::SAE::ConfigMap
    Properties:
      Data:
        MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
        SENTRY_PROFILES_SAMPLE_RATE: '1'
        MARKETPLACE_ENABLED: 'true'
        DB_PORT: '5432'
        VECTOR_STORE: analyticdb
        LOG_LEVEL: INFO
        DB_DATABASE: dify
        REDIS_USE_SSL: 'false'
        STORAGE_LOCAL_PATH: /app/api/storage
        SENTRY_TRACES_SAMPLE_RATE: '1'
        MODE: api
        WEB_API_CORS_ALLOW_ORIGINS: '*'
        RESEND_API_URL: https://api.resend.com
        ANALYTICDB_INSTANCE_ID:
          Fn::GetAtt:
            - ADBPGInstance
            - DBInstanceId
        CODE_EXECUTION_ENDPOINT: http://dify-sandbox:8194
        REDIS_HOST:
          Fn::GetAtt:
            - RedisInstance
            - ConnectionDomain
        REDIS_DB: '0'
        REDIS_PORT: '6379'
        MAIL_TYPE: resend
        ANALYTICDB_REGION_ID:
          Ref: ALIYUN::Region
        MIGRATION_ENABLED: 'true'
        CONSOLE_CORS_ALLOW_ORIGINS: '*'
        PLUGIN_DAEMON_URL: http://dify-plugin-daemon:5002
        STORAGE_TYPE: local
        DB_HOST:
          Fn::GetAtt:
            - PostgreSQLInstance
            - InnerConnectionString
      NamespaceId:
        Ref: SaeNamespace
      Name: dify-api
  DifyApiSecret:
    Type: 'ALIYUN::SAE::Secret'
    Properties:
      NamespaceId:
        Ref: SaeNamespace
      SecretName: dify-api
      SecretType: Opaque
      SecretData:
        ANALYTICDB_ACCOUNT:
          Ref: ADBPGAccount
        ANALYTICDB_KEY_ID:
          Fn::GetAtt:
            - AccessKey
            - AccessKeyId
        ANALYTICDB_KEY_SECRET:
          Fn::GetAtt:
            - AccessKey
            - AccessKeySecret
        ANALYTICDB_NAMESPACE: difyns
        ANALYTICDB_NAMESPACE_PASSWORD:
          Ref: ADBPGPassword
        ANALYTICDB_PASSWORD:
          Ref: ADBPGPassword
        CELERY_BROKER_URL:
          Fn::Sub:
            - redis://:${REDIS_PASSWORD}@${REDIS_HOST}:6379/0
            - REDIS_PASSWORD:
                Ref: RedisInstancePassword
              REDIS_HOST:
                Fn::GetAtt:
                  - RedisInstance
                  - ConnectionDomain
        CODE_EXECUTION_API_KEY: dify-sandbox
        DB_PASSWORD:
          Ref: PostgreSQLPassword
        DB_USERNAME:
          Ref: PostgreSQLUserName
        INNER_API_KEY_FOR_PLUGIN: QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1
        PLUGIN_DAEMON_KEY: lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi
        REDIS_PASSWORD:
          Ref: RedisInstancePassword
        REDIS_USERNAME: default
        RESEND_API_KEY: xxxx
        SECRET_KEY:
          !Base64Decode
          Fn::Jq:
            - First
            - .[0].Output
            - Fn::GetAtt:
                - RunCommand
                - InvokeResults
  DifyWorkerConfigMap:
    Type: ALIYUN::SAE::ConfigMap
    Properties:
      Data:
        MAIL_DEFAULT_SEND_FROM: 'YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)'
        SENTRY_PROFILES_SAMPLE_RATE: '1'
        MARKETPLACE_ENABLED: 'true'
        DB_PORT: '5432'
        VECTOR_STORE: analyticdb
        LOG_LEVEL: INFO
        DB_DATABASE: dify
        REDIS_USE_SSL: 'false'
        STORAGE_LOCAL_PATH: /app/api/storage
        SENTRY_TRACES_SAMPLE_RATE: '1'
        MODE: worker
        WEB_API_CORS_ALLOW_ORIGINS: '*'
        RESEND_API_URL: https://api.resend.com
        ANALYTICDB_INSTANCE_ID:
          Fn::GetAtt:
            - ADBPGInstance
            - DBInstanceId
        REDIS_HOST:
          Fn::GetAtt:
            - RedisInstance
            - ConnectionDomain
        REDIS_DB: '0'
        REDIS_PORT: '6379'
        MAIL_TYPE: resend
        ANALYTICDB_REGION_ID:
          Ref: ALIYUN::Region
        MIGRATION_ENABLED: 'true'
        CONSOLE_CORS_ALLOW_ORIGINS: '*'
        PLUGIN_DAEMON_URL: http://dify-plugin-daemon:5002
        STORAGE_TYPE: local
        DB_HOST:
          Fn::GetAtt:
            - PostgreSQLInstance
            - InnerConnectionString
      NamespaceId:
        Ref: SaeNamespace
      Name: dify-worker

  DifyWorkerSecret:
    Type: 'ALIYUN::SAE::Secret'
    Properties:
      NamespaceId:
        Ref: SaeNamespace
      SecretName: dify-worker
      SecretType: Opaque
      SecretData:
        ANALYTICDB_ACCOUNT:
          Ref: ADBPGAccount
        ANALYTICDB_KEY_ID:
          Fn::GetAtt:
            - AccessKey
            - AccessKeyId
        ANALYTICDB_KEY_SECRET:
          Fn::GetAtt:
            - AccessKey
            - AccessKeySecret
        ANALYTICDB_NAMESPACE: difyns
        ANALYTICDB_NAMESPACE_PASSWORD:
          Ref: ADBPGPassword
        ANALYTICDB_PASSWORD:
          Ref: ADBPGPassword
        CELERY_BROKER_URL:
          Fn::Sub:
            - redis://:${REDIS_PASSWORD}@${REDIS_HOST}:6379/0
            - REDIS_PASSWORD:
                Ref: RedisInstancePassword
              REDIS_HOST:
                Fn::GetAtt:
                  - RedisInstance
                  - ConnectionDomain
        DB_PASSWORD:
          Ref: PostgreSQLPassword
        DB_USERNAME:
          Ref: PostgreSQLUserName
        INNER_API_KEY_FOR_PLUGIN: QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1
        PLUGIN_DAEMON_KEY: lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi
        REDIS_PASSWORD:
          Ref: RedisInstancePassword
        REDIS_USERNAME: default
        RESEND_API_KEY: xxxx
        SECRET_KEY:
          !Base64Decode
          Fn::Jq:
            - First
            - .[0].Output
            - Fn::GetAtt:
                - RunCommand
                - InvokeResults
  DifyPluginDaemonConfigMap:
    Type: 'ALIYUN::SAE::ConfigMap'
    Properties:
      NamespaceId:
        Ref: SaeNamespace
      Name: dify-plugin-daemon
      Data:
        SERVER_PORT: "5002"
        PLUGIN_REMOTE_INSTALLING_HOST: "0.0.0.0"
        REDIS_DB: "0"
        REDIS_HOST:
          Fn::GetAtt:
            - RedisInstance
            - ConnectionDomain
        MARKETPLACE_ENABLED: "true"
        DB_PORT: "5432"
        REDIS_USE_SSL: "false"
        PLUGIN_WORKING_PATH: /app/storage/cwd
        DB_HOST:
          Fn::GetAtt:
            - PostgreSQLInstance
            - InnerConnectionString
        PIP_MIRROR_URL: http://mirrors.aliyun.com/pypi/simple/
        REDIS_PORT: "6379"
        PLUGIN_REMOTE_INSTALLING_PORT: "5003"
        MAX_PLUGIN_PACKAGE_SIZE: "52428800"
        DB_DATABASE: dify_plugin
        DIFY_INNER_API_URL: http://dify-api:5001
  DifyPluginDaemonSecret:
    Type: 'ALIYUN::SAE::Secret'
    Properties:
      NamespaceId:
        Ref: SaeNamespace
      SecretName: dify-plugin-daemon
      SecretType: Opaque
      SecretData:
        DB_PASSWORD:
          Ref: PostgreSQLPassword
        DB_USERNAME:
          Ref: PostgreSQLUserName
        DIFY_INNER_API_KEY: QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1
        REDIS_PASSWORD:
          Ref: RedisInstancePassword
        REDIS_USERNAME: default
        SERVER_KEY: lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi
  DifySandboxConfigMap:
    Type: 'ALIYUN::SAE::ConfigMap'
    Properties:
      NamespaceId:
        Ref: SaeNamespace
      Name: dify-sandbox
      Data:
        GIN_MODE: release
        SANDBOX_PORT: "8194"
  DifySandboxSecret:
    Type: 'ALIYUN::SAE::Secret'
    Properties:
      NamespaceId:
        Ref: SaeNamespace
      SecretName: dify-sandbox
      SecretType: Opaque
      SecretData:
        API_KEY: dify-sandbox
  DifyWebConfigMap:
    Type: 'ALIYUN::SAE::ConfigMap'
    Properties:
      NamespaceId:
        Ref: SaeNamespace
      Name: dify-web
      Data:
        MARKETPLACE_ENABLED: "true"
        MARKETPLACE_URL: https://marketplace.dify.ai
        MARKETPLACE_API_URL: https://marketplace.dify.ai
  DifyNginxConfigMap:
    Type: 'ALIYUN::SAE::ConfigMap'
    Properties:
      NamespaceId:
        Ref: SaeNamespace
      Name: dify-nginx
      Data:
        default.conf: |-
          server {
                  listen 80;
                  server_name _;

                  location /console/api {
                    proxy_pass http://dify-api:5001;
                    include proxy.conf;
                  }

                  location /api {
                    proxy_pass http://dify-api:5001;
                    include proxy.conf;
                  }

                  location /v1 {
                    proxy_pass http://dify-api:5001;
                    include proxy.conf;
                  }

                  location /files {
                    proxy_pass http://dify-api:5001;
                    include proxy.conf;
                  }

                  location /explore {
                    proxy_pass http://dify-web:3000;
                    proxy_set_header Dify-Hook-Url $scheme://$host$request_uri;
                    include proxy.conf;
                  }

                  location /e/ {
                    proxy_pass http://dify-plugin-daemon:5002;
                    proxy_set_header Dify-Hook-Url $scheme://$host$request_uri;
                    include proxy.conf;
                  }

                  location / {
                    proxy_pass http://dify-web:3000;
                    include proxy.conf;
                  }
              }
        nginx.conf: |-
          user  nginx;
              worker_processes  auto;
              pid        /var/run/nginx.pid;

              events {
                  worker_connections  1024;
              }

              http {
                  include       /etc/nginx/mime.types;
                  default_type  application/octet-stream;

                  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                                    '$status $body_bytes_sent "$http_referer" '
                                    '"$http_user_agent" "$http_x_forwarded_for"';

                  sendfile        on;
                  #tcp_nopush     on;

                  keepalive_timeout  65;

                  #gzip  on;
                  client_max_body_size 15M;

                  include /etc/nginx/conf.d/*.conf;
              }
        proxy.conf: |-
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header X-Forwarded-Port $server_port;
          proxy_http_version 1.1;
          proxy_set_header Connection "";
          proxy_buffering off;
          proxy_read_timeout 3600s;
          proxy_send_timeout 3600s;
  DifyApiApp:
    DependsOn:
      - SaeNamespace
      - DifyApiConfigMap
      - DifyApiSecret
      - ADBPGInstance
    Type: 'ALIYUN::SAE::Application'
    Properties:
      AppName: dify-api
      SaeVersion: v2
      AutoConfig: false
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: SecurityGroup
      VSwitchId:
        Fn::Sub:
          - '${VSwitch1},${VSwitch2}'
          - VSwitch1:
              Ref: VSwitch1
            VSwitch2:
              Ref: VSwitch2
      Replicas: 1
      NamespaceId:
        Ref: SaeNamespace
      Cpu: 1000
      Memory: 2048
      PackageType: Image
      ImageUrl:
        Fn::Sub: registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-api-v1.6.0
      ProgrammingLanguage: python
      AppSource: micro_service
      Timezone: Asia/Shanghai
      NasConfigs:
        Fn::Sub:
          - '[{"mountDomain":"${MOUNT_DOMAIN}","mountPath":"/app/api/storage","nasId":"${NAS_ID}","nasPath":"dify-api","readOnly":false,"volumeName":"nas-1"}]'
          - MOUNT_DOMAIN:
              Fn::GetAtt:
                - APINasMountTarget
                - MountTargetDomain
            NAS_ID:
              Fn::GetAtt:
                - APINas
                - FileSystemId
      PvtzDiscoverySvc:
        Fn::Sub:
          - '{"enable":"true","namespaceId":"${REGION_ID}:${NAMESPACE}","portAndProtocol":{"5001:TCP":"5001"},"portProtocols":[],"pvtzDiscoveryName":"${REGION_ID}-${USER_ID}","serviceName":"dify-api.${NAMESPACE}"}'
          - NAMESPACE:
              Ref: NamespaceName
            USER_ID:
              Ref: ALIYUN::TenantId
            REGION_ID:
              Ref: ALIYUN::Region
      Envs:
        Fn::Sub:
          - '[{"name":"APP_WEB_URL"},{"name":"FILES_URL"},{"name":"CODE_MAX_DEPTH","value":"5"},{"name":"CODE_MAX_OBJECT_ARRAY_LENGTH","value":"30"},{"name":"CHECK_UPDATE_URL"},{"name":"CODE_MAX_STRING_ARRAY_LENGTH","value":"30"},{"name":"SERVICE_API_URL"},{"name":"sae-sys-secret-all-dify-api","valueFrom":{"secretRef":{"secretId":${SECRET_ID},"key":""}}},{"name":"CODE_MAX_PRECISION","value":"20"},{"name":"CONSOLE_API_URL"},{"name":"TEMPLATE_TRANSFORM_MAX_LENGTH","value":"80000"},{"name":"CODE_MAX_NUMBER","value":"9223372036854775807"},{"name":"CODE_MAX_NUMBER_ARRAY_LENGTH","value":"1000"},{"name":"CONSOLE_WEB_URL"},{"name":"CODE_MIN_NUMBER","value":"-9223372036854775808"},{"name":"CODE_MAX_STRING_LENGTH","value":"80000"},{"name":"SENTRY_DSN"},{"name":"CODE_EXECUTION_API_KEY","valueFrom":{"secretRef":{"secretId":${SANDBOX_SECRET_ID},"key":"API_KEY"}}},{"name":"sae-sys-configmap-all-dify-api","valueFrom":{"configMapRef":{"configMapId":${CONFIGMAP_ID},"key":""}}}]'
          - CONFIGMAP_ID:
              Fn::GetAtt:
                - DifyApiConfigMap
                - ConfigMapId
            SECRET_ID:
              Fn::GetAtt:
                - DifyApiSecret
                - SecretId
            SANDBOX_SECRET_ID:
              Fn::GetAtt:
                - DifySandboxSecret
                - SecretId
  DifyWorkerApp:
    DependsOn:
      - SaeNamespace
      - DifyWorkerConfigMap
      - DifyWorkerSecret
    Type: 'ALIYUN::SAE::Application'
    Properties:
      AppName: dify-worker
      SaeVersion: v2
      AutoConfig: false
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: SecurityGroup
      VSwitchId:
        Fn::Sub:
          - '${VSwitch1},${VSwitch2}'
          - VSwitch1:
              Ref: VSwitch1
            VSwitch2:
              Ref: VSwitch2
      Replicas: 1
      NamespaceId:
        Ref: SaeNamespace
      Cpu: 1000
      Memory: 2048
      PackageType: Image
      ImageUrl:
        Fn::Sub: registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-api-v1.6.0
      ProgrammingLanguage: python
      AppSource: micro_service
      Timezone: Asia/Shanghai
      NasConfigs:
        Fn::Sub:
          - '[{"mountDomain":"${MOUNT_DOMAIN}","mountPath":"/app/api/storage","nasId":"${NAS_ID}","nasPath":"dify-api","readOnly":false,"volumeName":"nas-1"}]'
          - MOUNT_DOMAIN:
              Fn::GetAtt:
                - APINasMountTarget
                - MountTargetDomain
            NAS_ID:
              Fn::GetAtt:
                - APINas
                - FileSystemId
      Envs:
        Fn::Sub:
          - '[{"name":"sae-sys-secret-all-dify-worker","valueFrom":{"secretRef":{"secretId":${SECRET_ID},"key":""}}},{"name":"sae-sys-configmap-all-dify-worker","valueFrom":{"configMapRef":{"configMapId":${CONFIGMAP_ID},"key":""}}},{"name":"CONSOLE_WEB_URL"}]'
          - CONFIGMAP_ID:
              Fn::GetAtt:
                - DifyWorkerConfigMap
                - ConfigMapId
            SECRET_ID:
              Fn::GetAtt:
                - DifyWorkerSecret
                - SecretId
  DifyPluginDaemonApp:
    DependsOn:
      - SaeNamespace
      - DifyPluginDaemonConfigMap
      - DifyPluginDaemonSecret
    Type: 'ALIYUN::SAE::Application'
    Properties:
      AppName: dify-plugin-daemon
      SaeVersion: v2
      AutoConfig: false
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: SecurityGroup
      VSwitchId:
        Fn::Sub:
          - '${VSwitch1},${VSwitch2}'
          - VSwitch1:
              Ref: VSwitch1
            VSwitch2:
              Ref: VSwitch2
      Replicas: 1
      NamespaceId:
        Ref: SaeNamespace
      Cpu: 1000
      Memory: 2048
      PackageType: Image
      ImageUrl:
        Fn::Sub: registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-plugin-daemon-v0.1.3-local
      ProgrammingLanguage: golang
      AppSource: micro_service
      Timezone: Asia/Shanghai
      NasConfigs:
        Fn::Sub:
          - '[{"mountDomain":"${MOUNT_DOMAIN}","mountPath":"/app/storage","nasId":"${NAS_ID}","nasPath":"dify-plugin-daemon","readOnly":false,"volumeName":"nas-1"}]'
          - MOUNT_DOMAIN:
              Fn::GetAtt:
                - PluginNasMountTarget
                - MountTargetDomain
            NAS_ID:
              Fn::GetAtt:
                - PluginNas
                - FileSystemId
      PvtzDiscoverySvc:
        Fn::Sub:
          - '{"enable":"true","namespaceId":"${REGION_ID}:${NAMESPACE}","portAndProtocol":{"5003:TCP":"5003","5002:TCP":"5002"},"portProtocols":[],"pvtzDiscoveryName":"${REGION_ID}-${USER_ID}","serviceName":"dify-plugin-daemon.${NAMESPACE}"}'
          - NAMESPACE:
              Ref: NamespaceName
            USER_ID:
              Ref: ALIYUN::TenantId
            REGION_ID:
              Ref: ALIYUN::Region
      Envs:
        Fn::Sub:
          - '[{"name":"sae-sys-secret-all-dify-plugin-daemon","valueFrom":{"secretRef":{"secretId":${SECRET_ID},"key":""}}},{"name":"sae-sys-configmap-all-dify-plugin-daemon","valueFrom":{"configMapRef":{"configMapId":${CONFIGMAP_ID},"key":""}}}]'
          - CONFIGMAP_ID:
              Fn::GetAtt:
                - DifyPluginDaemonConfigMap
                - ConfigMapId
            SECRET_ID:
              Fn::GetAtt:
                - DifyPluginDaemonSecret
                - SecretId
  DifySandboxApp:
    DependsOn:
      - SaeNamespace
      - DifySandboxConfigMap
      - DifySandboxSecret
    Type: 'ALIYUN::SAE::Application'
    Properties:
      AppName: dify-sandbox
      SaeVersion: v2
      AutoConfig: false
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: SecurityGroup
      VSwitchId:
        Fn::Sub:
          - '${VSwitch1},${VSwitch2}'
          - VSwitch1:
              Ref: VSwitch1
            VSwitch2:
              Ref: VSwitch2
      Replicas: 1
      NamespaceId:
        Ref: SaeNamespace
      Cpu: 1000
      Memory: 2048
      PackageType: Image
      ImageUrl:
        Fn::Sub: registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-sandbox-v0.2.12
      ProgrammingLanguage: golang
      AppSource: micro_service
      Timezone: Asia/Shanghai
      PvtzDiscoverySvc:
        Fn::Sub:
          - '{"enable":"true","namespaceId":"${REGION_ID}:${NAMESPACE}","portAndProtocol":{"8194:TCP":"8194"},"portProtocols":[],"pvtzDiscoveryName":"${REGION_ID}-${USER_ID}","serviceName":"dify-sandbox.${NAMESPACE}"}'
          - NAMESPACE:
              Ref: NamespaceName
            USER_ID:
              Ref: ALIYUN::TenantId
            REGION_ID:
              Ref: ALIYUN::Region
      Envs:
        Fn::Sub:
          - '[{"name":"sae-sys-secret-all-dify-sandbox","valueFrom":{"secretRef":{"secretId":${SECRET_ID},"key":""}}},{"name":"WORKER_TIMEOUT","value":"15"},{"name":"sae-sys-configmap-all-dify-sandbox","valueFrom":{"configMapRef":{"configMapId":${CONFIGMAP_ID},"key":""}}}]'
          - CONFIGMAP_ID:
              Fn::GetAtt:
                - DifySandboxConfigMap
                - ConfigMapId
            SECRET_ID:
              Fn::GetAtt:
                - DifySandboxSecret
                - SecretId
  DifyWebApp:
    DependsOn:
      - SaeNamespace
      - DifyWebConfigMap
    Type: 'ALIYUN::SAE::Application'
    Properties:
      AppName: dify-web
      SaeVersion: v2
      AutoConfig: false
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: SecurityGroup
      VSwitchId:
        Fn::Sub:
          - '${VSwitch1},${VSwitch2}'
          - VSwitch1:
              Ref: VSwitch1
            VSwitch2:
              Ref: VSwitch2
      Replicas: 1
      NamespaceId:
        Ref: SaeNamespace
      Cpu: 1000
      Memory: 2048
      PackageType: Image
      ImageUrl:
        Fn::Sub: registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-web-v1.6.0
      ProgrammingLanguage: other
      AppSource: micro_service
      Timezone: Asia/Shanghai
      PvtzDiscoverySvc:
        Fn::Sub:
          - '{"enable":"true","namespaceId":"${REGION_ID}:${NAMESPACE}","portAndProtocol":{"3000:TCP":"3000"},"portProtocols":[],"pvtzDiscoveryName":"${REGION_ID}-${USER_ID}","serviceName":"dify-web.${NAMESPACE}"}'
          - NAMESPACE:
              Ref: NamespaceName
            USER_ID:
              Ref: ALIYUN::TenantId
            REGION_ID:
              Ref: ALIYUN::Region
      Envs:
        Fn::Sub:
          - '[{"name":"sae-sys-configmap-all-dify-web","valueFrom":{"configMapRef":{"configMapId":${CONFIGMAP_ID},"key":""}}},{"name":"APP_API_URL"},{"name":"CONSOLE_API_URL"},{"name":"EDITION","value":"SELF_HOSTED"}]'
          - CONFIGMAP_ID:
              Fn::GetAtt:
                - DifyWebConfigMap
                - ConfigMapId
  DifyNginxApp:
    DependsOn:
      - SaeNamespace
      - DifyNginxConfigMap
    Type: 'ALIYUN::SAE::Application'
    Properties:
      AppName: dify-nginx
      SaeVersion: v2
      AutoConfig: false
      VpcId:
        Ref: Vpc
      SecurityGroupId:
        Ref: SecurityGroup
      VSwitchId:
        Fn::Sub:
          - '${VSwitch1},${VSwitch2}'
          - VSwitch1:
              Ref: VSwitch1
            VSwitch2:
              Ref: VSwitch2
      Replicas: 1
      NamespaceId:
        Ref: SaeNamespace
      Cpu: 1000
      Memory: 2048
      PackageType: Image
      ImageUrl:
        Fn::Sub: registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:nginx-v1.23.4
      ProgrammingLanguage: other
      AppSource: micro_service
      Timezone: Asia/Shanghai
      ConfigMapMountDesc:
        Fn::Sub:
          - '[{"MountPath":"/etc/nginx/conf.d/default.conf","ConfigMapId":${CONFIGMAP_ID},"ConfigMapName":"dify-nginx","Key":"default.conf"},{"MountPath":"/etc/nginx/nginx.conf","ConfigMapId":${CONFIGMAP_ID},"ConfigMapName":"dify-nginx","Key":"nginx.conf"},{"MountPath":"/etc/nginx/proxy.conf","ConfigMapId":${CONFIGMAP_ID},"ConfigMapName":"dify-nginx","Key":"proxy.conf"}]'
          - CONFIGMAP_ID:
              Fn::GetAtt:
                - DifyNginxConfigMap
                - ConfigMapId
  InternetClb:
    Type: ALIYUN::SLB::LoadBalancer
    Properties:
      LoadBalancerName:
        Ref: ALIYUN::StackName
      LoadBalancerSpec: slb.s2.medium
      AddressType: internet
  BackendAppBindClb:
    Type: 'ALIYUN::SAE::SlbBinding'
    DependsOn:
      - DifyNginxApp
      - InternetClb
    Properties:
      InternetSlbId:
        Fn::GetAtt:
          - InternetClb
          - LoadBalancerId
      Internet: '[{"port": 80, "targetPort": 80, "protocol": "TCP"}]'
      AppId:
        Fn::GetAtt:
          - DifyNginxApp
          - AppId
Outputs:
  DifyAddress:
    Label:
      zh-cn: Dify service address.
      en: Dify service address.
    Description:
      zh-cn: Dify service address.
      en: Dify service address.
    Value:
      Fn::Sub:
        - http://${ServerAddress}:80
        - ServerAddress:
            Fn::GetAtt:
              - InternetClb
              - IpAddress
  PostgresName:
    Label:
      zh-cn: Postgres username
      en: Postgres username
    Description:
      zh-cn: The username of AnalyticDB for PostgreSQL.
      en: The username of AnalyticDB for PostgreSQL.
    Value:
      Ref: ADBPGAccount
  PostgresPassword:
    Label:
      zh-cn: Postgres password
      en: Postgres password
    Description:
      zh-cn: The password of AnalyticDB for PostgreSQL.
      en: The password of AnalyticDB for PostgreSQL.
    NoEcho: true
    Value:
      Ref: ADBPGPassword
  PostgresConnectionString:
    Label:
      zh-cn: Postgres database address
      en: Postgres database address
    Description:
      zh-cn: The internal endpoint of AnalyticDB for PostgreSQL.
      en: The internal endpoint of AnalyticDB for PostgreSQL.
    Value:
      Fn::GetAtt:
        - ADBPGInstance
        - ConnectionString
  APINasFileSystemId:
    Label:
      zh-cn: API NAS file system
      en: API NAS file system
    Description:
      zh-cn: NAS file system.
      en: NAS file system.
    Value:
      Ref: APINas
  APINasMountTarget:
    Label:
      zh-cn: API NAS mount target
      en: API NAS mount target
    Description:
      zh-cn: NAS mount target.
      en: NAS mount target.
    Value:
      Ref: APINasMountTarget
  PluginNasFileSystemId:
    Label:
      zh-cn: Plugin NAS file system
      en: Plugin NAS file system
    Description:
      zh-cn: NAS file system.
      en: NAS file system.
    Value:
      Ref: PluginNas
  PluginNasMountTarget:
    Label:
      zh-cn: Plugin NAS mount target
      en: Plugin NAS mount target
    Description:
      zh-cn: NAS mount target.
      en: NAS mount target.
    Value:
      Ref: PluginNasMountTarget
  RedisConnectionString:
    Label:
      zh-cn: Redis endpoint
      en: Redis endpoint
    Description:
      zh-cn: Redis endpoint.
      en: Redis endpoint.
    Value:
      Fn::GetAtt:
        - RedisInstance
        - ConnectionDomain
  RedisName:
    Label:
      zh-cn: Redis username
      en: Redis username
    Description:
      zh-cn: The username of Redis.
      en: The username of Redis.
    Value: default
  RedisInstancePassword:
    Label:
      zh-cn: Redis password
      en: Redis password
    Description:
      zh-cn: The password of Redis.
      en: The password of Redis.
    NoEcho: true
    Value:
      Ref: RedisInstancePassword
  PostgreSQLDBName:
    Label:
      zh-cn: Database Name
      en: Database Name
    Description:
      zh-cn: The database name of ApsaraDB RDS for PostgreSQL.
      en: The database name of ApsaraDB RDS for PostgreSQL.
    Value: dify
  PostgreSQLConnectionString:
    Label:
      zh-cn: RDS database address
      en: RDS database address
    Description:
      zh-cn: The internal endpoint of ApsaraDB RDS for PostgreSQL.
      en: The internal endpoint of ApsaraDB RDS for PostgreSQL.
    Value:
      Fn::GetAtt:
        - PostgreSQLInstance
        - InnerConnectionString
  PostgreSQLAccount:
    Label:
      zh-cn: RDS username
      en: RDS username
    Description:
      zh-cn: The username of ApsaraDB RDS for PostgreSQL.
      en: The username of ApsaraDB RDS for PostgreSQL.
    Value:
      Ref: PostgreSQLUserName
  PostgreSQLPassword:
    Label:
      zh-cn: RDS password
      en: RDS password
    Description:
      zh-cn: The password of ApsaraDB RDS for PostgreSQL.
      en: The password of ApsaraDB RDS for PostgreSQL.
    NoEcho: true
    Value:
      Ref: PostgreSQLPassword
  NameSpace:
    Label:
      zh-cn: Namespace
      en: Namespace
    Description:
      zh-cn: Namespace.
      en: Namespace.
    Value:
      Fn::Sub: ${ALIYUN::Region}:${NamespaceName}
  Vpc:
    Label:
      zh-cn: VPC ID
      en: VPC ID
    Description:
      zh-cn: VPC ID.
      en: VPC ID.
    Value:
      Ref: Vpc
  Vsw:
    Label:
      zh-cn: vSwitch ID
      en: vSwitch ID
    Description:
      zh-cn: vSwitch ID.
      en: vSwitch ID.
    Value:
      Ref: VSwitch1
  Sg:
    Label:
      zh-cn: Security Group ID
      en: Security Group ID
    Description:
        zh-cn: Security Group ID.
        en: Security Group ID.
    Value:
        Ref: SecurityGroup
  SecretKey:
    Label:
      zh-cn: Secret Key
      en: Secret Key
    Description:
      zh-cn: Used for secure signatures and encrypting sensitive information in the database.
      en: Used for secure signatures and encrypting sensitive information in the database.
    NoEcho: true
    Value:
      !Base64Decode
        Fn::Jq:
          - First
          - .[0].Output
          - Fn::GetAtt:
              - RunCommand
              - InvokeResults
  dify-nginx:
    Label:
      zh-cn: The application address of dify-nginx
      en: The application address of dify-nginx
    Description:
      zh-cn: The application address of dify-nginx. In the application access settings, view the public endpoint based on SLB access.
      en: The application address of dify-nginx. In the application access settings, view the public endpoint based on SLB access.
    Value:
      Fn::Sub: https://sae.console.alibabacloud.com/${ALIYUN::Region}/app-list/${DifyNginxApp.AppId}/micro-app/base?name=dify-nginx
  ECSInstanceId:
    Label:
      zh-cn: ECS instance ID
      en: ECS instance ID
    Description:
      zh-cn: ECS instance ID. This instance deploys the sample e-commerce system.
      en: ECS instance ID. This instance deploys the sample e-commerce system.
    Value:
      Fn::Select:
        - 0
        - Fn::GetAtt:
            - EcsInstance
            - InstanceIds
  Console@DemoUrl:
    Description:
      zh-cn: The application access domain name, which is the address of the e-commerce system in this solution.
      en: The application access domain name, which is the address of the e-commerce system in this solution.
    Value:
      Fn::Sub:
        - http://${PublicIp}
        - PublicIp:
            Fn::Select:
              - 0
              - Fn::GetAtt:
                  - EcsInstance
                  - PublicIps
Metadata:
  'ALIYUN::ROS::Interface':
    Outputs:
      - DifyAddress
      - ECSInstanceId
      - Console@DemoUrl
      - dify-nginx
      - NameSpace
      - Vpc
      - Vsw
      - Sg
      - PostgreSQLDBName
      - PostgreSQLConnectionString
      - PostgreSQLAccount
      - PostgreSQLPassword
      - PostgresName
      - PostgresPassword
      - PostgresConnectionString
      - APINasFileSystemId
      - APINasMountTarget
      - PluginNasFileSystemId
      - PluginNasMountTarget
      - RedisConnectionString
      - RedisName
      - RedisInstancePassword
      - SecretKey
    ParameterGroups:
      - Parameters:
          - ZoneId1
          - ZoneId2
        Label:
          default:
            en: Availability Zone
            zh-cn: Availability Zone
      - Parameters:
          - InstanceType
          - InstancePassword
        Label:
          default:
            en: Elastic Compute Service (ECS)
            zh-cn: Elastic Compute Service (ECS)
      - Parameters:
          - RedisInstancePassword
        Label:
          default:
            en: ApsaraDB for Tair (compatible with Redis)
            zh-cn: ApsaraDB for Tair (compatible with Redis)
      - Parameters:
          - ADBPGAccount
          - ADBPGPassword
        Label:
          default:
            en: Cloud-native data warehouse AnalyticDB for PostgreSQL
            zh-cn: Cloud-native data warehouse AnalyticDB for PostgreSQL
      - Parameters:
          - DBInstanceClass
          - RdsDatabaseName
          - PostgreSQLUserName
          - PostgreSQLPassword
        Label:
          default:
            en: ApsaraDB RDS for PostgreSQL
            zh-cn: ApsaraDB RDS for PostgreSQL
      - Parameters:
          - NamespaceName
        Label:
          default:
            en: Serverless App Engine (SAE)
            zh-cn: Serverless App Engine (SAE)
    TemplateTags:
      - acs:technical-solution:internet-application-development:Deploy a production Dify platform using Serverless App Engine-tech_solu_251
    Hidden:
      - CommonName
{
  "ROSTemplateFormatVersion": "2015-09-01",
  "Description": {
    "zh-cn": "Deploys a production Dify platform using Serverless App Engine.",
    "en": "Deploy the production environment Dify platform through the Serverless application engine."
  },
  "Parameters": {
    "CommonName": {
      "Type": "String",
      "Default": "Dify"
    },
    "NamespaceName": {
      "Type": "String",
      "Label": {
        "en": "Namespace Name",
        "zh-cn": "Namespace Name"
      },
      "Description": {
        "zh-cn": "The namespace name. Only lowercase letters and numbers are supported.",
        "en": "Namespace name, only lowercase letters and numbers are supported."
      },
      "AllowedPattern": "^[a-z0-9]+$",
      "AssociationProperty": "AutoCompleteInput",
      "AssociationPropertyMetadata": {
        "Length": 3,
        "Prefix": "dify",
        "CharacterClasses": [
          {
            "Class": "lowercase",
            "min": 2
          },
          {
            "Class": "number",
            "min": 1
          }
        ]
      }
    },
    "ZoneId1": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
      "AssociationPropertyMetadata": {
        "ExclusiveTo": [
          "ZoneId2"
        ]
      },
      "Label": {
        "en": "Availability Zone 1",
        "zh-cn": "Availability Zone 1"
      }
    },
    "ZoneId2": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::Instance::ZoneId",
      "AssociationPropertyMetadata": {
        "ExclusiveTo": [
          "ZoneId1"
        ]
      },
      "Label": {
        "en": "Availability Zone 2",
        "zh-cn": "Availability Zone 2"
      }
    },
    "InstanceType": {
      "Type": "String",
      "AssociationProperty": "ALIYUN::ECS::Instance::InstanceType",
      "AssociationPropertyMetadata": {
        "InstanceChargeType": "PostPaid",
        "SystemDiskCategory": "cloud_essd",
        "ZoneId": "${ZoneId1}"
      },
      "Label": {
        "en": "Instance Type",
        "zh-cn": "Instance Type"
      }
    },
    "ADBPGAccount": {
      "Default": "dify",
      "Type": "String",
      "Label": {
        "zh-cn": "DB Account",
        "en": "DB Account"
      }
    },
    "ADBPGPassword": {
      "NoEcho": true,
      "Type": "String",
      "Label": {
        "zh-cn": "DB Account Password",
        "en": "DB Account Password"
      },
      "AssociationProperty": "ALIYUN::RDS::Instance::AccountPassword"
    },
    "InstancePassword": {
      "Type": "String",
      "Label": {
        "en": "Server login Password",
        "zh-cn": "Logon Password"
      },
      "Description": {
        "en": "Server login password, Length 8-30, must contain three(Capital letters, lowercase letters, numbers, ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/ Special symbol in)",
        "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 are ()`~!@#$%^&*_-+=|{}[]:;'<>,.?/"
      },
      "AssociationProperty": "ALIYUN::ECS::Instance::Password"
    },
    "RedisInstancePassword": {
      "Type": "String",
      "Label": {
        "en": "Instance Password",
        "zh-cn": "Instance Password"
      },
      "Description": {
        "en": "The Redis password used by Dify should be 8 to 32 characters. It only supports a combination of upper and lower case English and numbers. Please do not use any other characters.",
        "zh-cn": "The Redis password for Dify. The password must be 8 to 32 characters in length and can contain only uppercase letters, lowercase letters, and digits. Do not use other characters."
      },
      "ConstraintDescription": {
        "en": "The Redis password used by Dify should be 8 to 32 characters. It only supports a combination of upper and lower case English and numbers. Please do not use any other characters.",
        "zh-cn": "The Redis password for Dify. The password must be 8 to 32 characters in length and can contain only uppercase letters, lowercase letters, and digits. Do not use other characters."
      },
      "AllowedPattern": "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?\\d)[A-Za-z0-9]{8,32}$",
      "MinLength": "8",
      "MaxLength": "32",
      "NoEcho": true
    },
    "DBInstanceClass": {
      "Type": "String",
      "Label": {
        "en": "Instance Class",
        "zh-cn": "Instance Type"
      },
      "Default": "pg.n4m.2c.2m",
      "Required": true,
      "AssociationProperty": "ALIYUN::RDS::Instance::InstanceType",
      "AssociationPropertyMetadata": {
        "ZoneId": "${ZoneId}",
        "EngineVersion": "17.0",
        "Engine": "PostgreSQL",
        "Category": "HighAvailability",
        "InstanceChargeType": "Postpaid",
        "DBInstanceStorageType": "cloud_essd",
        "CommodityCode": "bards"
      }
    },
    "PostgreSQLPassword": {
      "Type": "String",
      "NoEcho": true,
      "Label": {
        "en": "Database Account Password",
        "zh-cn": "Database Account Password"
      },
      "AssociationProperty": "ALIYUN::RDS::Instance::AccountPassword"
    },
    "PostgreSQLUserName": {
      "Type": "String",
      "Label": {
        "en": "Database Account",
        "zh-cn": "Database Account"
      },
      "AllowedPattern": "^(?!dbo\\b|login\\b|admin\\b|administrator\\b|adminsys\\b|alimail\\b|aliyun\\b|apache\\b|appadmin\\b|apsara\\b|aurora\\b|bulkadmin\\b|cangjie\\b|cdn\\b|client\\b|cm\\b|dataengine\\b|dayu\\b|dba\\b|dbcreator\\b|developer\\b|diskadmin\\b|distribution\\b|dns\\b|download\\b|eagleye\\b|f5\\b|faq\\b|fuxi\\b|galaxy\\b|gongcao\\b|gongming\\b|groupon\\b|ha\\b|help\\b|host\\b|hostmaster\\b|houyi\\b|hr\\b|info\\b|information_schema\\b|kuafu\\b|lvs\\b|manager\\b|master\\b|meituan\\b|model\\b|monitor\\b|msdb\\b|mssqld\\b|mssqlsystemresource\\b|mysql\\b|nas\\b|net\\b|netops\\b|netweb\\b|news\\b|no-reply\\b|ntp\\b|nuwa\\b|nvwa\\b|operator\\b|opr\\b|ops\\b|opsdb\\b|oracle\\b|pangu\\b|pe\\b|post\\b|postmaster\\b|processadmin\\b|public\\b|qq\\b|replicator\\b|reply\\b|root\\b|sa\\b|sales\\b|san\\b|security\\b|securityadmin\\b|serveradmin\\b|services\\b|setupadmin\\b|shennong\\b|siteops\\b|sqlengine\\b|sqlonline\\b|squid\\b|ssladmin\\b|support\\b|sys\\b|sysadmin\\b|syslog\\b|system\\b|taoyun\\b|tempdb\\b|test\\b|tianyun\\b|wangwang\\b|eb\\b|webmaster\\b|webnet\\b|xtrabak\\b|youchao\\b|yum\\b|yunti\\b|zhongkui\\b|database\\b|add\\b|except\\b|percent\\b|all\\b|exec\\b|plan\\b|alter\\b|execute\\b|precision\\b|and\\b|exists\\b|primary\\b|any\\b|exit\\b|print\\b|as\\b|fetch\\b|proc\\b|asc\\b|file\\b|procedure\\b|authorization\\b|fillfactor\\b|public\\b|backup\\b|for\\b|raiserror\\b|begin\\b|foreign\\b|read\\b|between\\b|freetext\\b|readtext\\b|break\\b|freetexttable\\b|reconfigure\\b|browse\\b|from\\b|references\\b|bulk\\b|full\\b|replication\\b|by\\b|function\\b|restore\\b|cascade\\b|goto\\b|restrict\\b|case\\b|grant\\b|return\\b|check\\b|group\\b|revoke\\b|checkpoint\\b|having\\b|right\\b|close\\b|holdlock\\b|rollback\\b|clustered\\b|identity\\b|rowcount\\b|coalesce\\b|identity_insert\\b|rowguidcol\\b|collate\\b|identitycol\\b|rule\\b|column\\b|if\\b|save\\b|commit\\b|in\\b|schema\\b|compute\\b|index\\b|select\\b|constraint\\b|inner\\b|session_user\\b|contains\\b|insert\\b|set\\b|containstable\\b|intersect\\b|setuser\\b|continue\\b|into\\b|shutdown\\b|convert\\b|is\\b|some\\b|create\\b|join\\b|statistics\\b|cross\\b|key\\b|system_user\\b|current\\b|kill\\b|table\\b|current_date\\b|left\\b|textsize\\b|current_time\\b|like\\b|then\\b|current_timestamp\\b|lineno\\b|to\\b|current_user\\b|load\\b|top\\b|cursor\\b|national\\b|tran\\b|database\\b|nocheck\\b|transaction\\b|dbcc\\b|nonclustered\\b|trigger\\b|deallocate\\b|not\\b|truncate\\b|declare\\b|null\\b|tsequal\\b|default\\b|nullif\\b|union\\b|delete\\b|of\\b|unique\\b|deny\\b|off\\b|update\\b|desc\\b|offsets\\b|updatetext\\b|disk\\b|on\\b|use\\b|distinct\\b|open\\b|user\\b|distributed\\b|opendatasource\\b|values\\b|double\\b|openquery\\b|varying\\b|drop\\b|openrowset\\b|view\\b|dummy\\b|openxml\\b|waitfor\\b|dump\\b|option\\b|when\\b|else\\b|or\\b|where\\b|end\\b|order\\b|while\\b|errlvl\\b|outer\\b|with\\b|escape\\b|over\\b|writetext\\b|add\\b|analyze\\b|asc\\b|between\\b|blob\\b|call\\b|change\\b|check\\b|condition\\b|continue\\b|cross\\b|current_timestamp\\b|database\\b|day_microsecond\\b|dec\\b|default\\b|desc\\b|distinct\\b|double\\b|each\\b|enclosed\\b|exit\\b|fetch\\b|float8\\b|foreign\\b|goto\\b|having\\b|hour_minute\\b|ignore\\b|infile\\b|insensitive\\b|int1\\b|int4\\b|interval\\b|iterate\\b|keys\\b|leading\\b|like\\b|lines\\b|localtimestamp\\b|longblob\\b|low_priority\\b|mediumint\\b|minute_microsecond\\b|modifies\\b|no_write_to_binlog\\b|on\\b|optionally\\b|out\\b|precision\\b|purge\\b|read\\b|references\\b|rename\\b|require\\b|revoke\\b|schema\\b|select\\b|set\\b|spatial\\b|sqlexception\\b|sql_big_result\\b|ssl\\b|table\\b|tinyblob\\b|to\\b|true\\b|unique\\b|update\\b|using\\b|utc_timestamp\\b|varchar\\b|when\\b|with\\b|xor\\b|all\\b|and\\b|asensitive\\b|bigint\\b|both\\b|cascade\\b|char\\b|collate\\b|connection\\b|convert\\b|current_date\\b|current_user\\b|databases\\b|day_minute\\b|decimal\\b|delayed\\b|describe\\b|distinctrow\\b|drop\\b|else\\b|escaped\\b|explain\\b|float\\b|for\\b|from\\b|grant\\b|high_priority\\b|hour_second\\b|in\\b|inner\\b|insert\\b|int2\\b|int8\\b|into\\b|join\\b|kill\\b|leave\\b|limit\\b|load\\b|lock\\b|longtext\\b|match\\b|mediumtext\\b|minute_second\\b|natural\\b|null\\b|optimize\\b|or\\b|outer\\b|primary\\b|raid0\\b|reads\\b|regexp\\b|repeat\\b|restrict\\b|right\\b|schemas\\b|sensitive\\b|show\\b|specific\\b|sqlstate\\b|sql_calc_found_rows\\b|starting\\b|terminated\\b|tinyint\\b|trailing\\b|undo\\b|unlock\\b|usage\\b|utc_date\\b|values\\b|varcharacter\\b|where\\b|write\\b|year_month\\b|alter\\b|as\\b|before\\b|binary\\b|by\\b|case\\b|character\\b|column\\b|constraint\\b|create\\b|current_time\\b|cursor\\b|day_hour\\b|day_second\\b|declare\\b|delete\\b|deterministic\\b|div\\b|dual\\b|elseif\\b|exists\\b|false\\b|float4\\b|force\\b|fulltext\\b|group\\b|hour_microsecond\\b|if\\b|index\\b|inout\\b|int\\b|int3\\b|integer\\b|is\\b|key\\b|label\\b|left\\b|linear\\b|localtime\\b|long\\b|loop\\b|mediumblob\\b|middleint\\b|mod\\b|not\\b|numeric\\b|option\\b|order\\b|outfile\\b|procedure\\b|range\\b|real\\b|release\\b|replace\\b|return\\b|rlike\\b|second_microsecond\\b|separator\\b|smallint\\b|sql\\b|sqlwarning\\b|sql_small_result\\b|straight_join\\b|then\\b|tinytext\\b|trigger\\b|union\\b|unsigned\\b|use\\b|utc_time\\b|varbinary\\b|varying\\b|while\\b|x509\\b|zerofill)([a-zA-Z][a-zA-Z0-9_]{0,30}[a-zA-Z0-9])$",
      "ConstraintDescription": {
        "en": "The value can be up to 32 characters in length and can contain letters, digits, and underscores (_). The value must start with a letter and end with a letter or digit.  For more information about invalid characters, see <a href=\"https://www.alibabacloud.com/help/zh/rds/developer-reference/forbidden-keywords\" target=\"_blank\">Forbidden keywords table</a>.",
        "zh-cn": "The value must be up to 32 characters in length and can contain lowercase letters, uppercase letters, digits, and underscores (_). It must start with a letter and end with a letter or digit. For more information about invalid characters, see <a href=\"https://www.alibabacloud.com/help/zh/rds/developer-reference/forbidden-keywords\" target=\"_blank\">Forbidden keywords table</a>."
      },
      "Default": "db_user"
    }
  },
  "Resources": {
    "Vpc": {
      "Type": "ALIYUN::ECS::VPC",
      "Properties": {
        "CidrBlock": "192.168.0.0/16",
        "VpcName": {
          "Fn::Sub": "${CommonName}-VPC_HZ"
        }
      }
    },
    "VSwitch1": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "VpcId": {
          "Ref": "Vpc"
        },
        "CidrBlock": "192.168.1.0/24",
        "ZoneId": {
          "Ref": "ZoneId1"
        },
        "VSwitchName": {
          "Fn::Sub": "${CommonName}-vsw_001"
        }
      }
    },
    "VSwitch2": {
      "Type": "ALIYUN::ECS::VSwitch",
      "Properties": {
        "VpcId": {
          "Ref": "Vpc"
        },
        "CidrBlock": "192.168.2.0/24",
        "ZoneId": {
          "Ref": "ZoneId2"
        },
        "VSwitchName": {
          "Fn::Sub": "${CommonName}-vsw_002"
        }
      }
    },
    "Sleep": {
      "DependsOn": [
        "VSwitch1",
        "VSwitch2"
      ],
      "Type": "ALIYUN::ROS::Sleep",
      "Properties": {
        "DeleteDuration": 300
      }
    },
    "SecurityGroup": {
      "Type": "ALIYUN::ECS::SecurityGroup",
      "Properties": {
        "VpcId": {
          "Ref": "Vpc"
        },
        "SecurityGroupName": {
          "Fn::Sub": "${CommonName}-SecurityGroup_1"
        },
        "SecurityGroupIngress": [
          {
            "PortRange": "80/80",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          },
          {
            "PortRange": "3000/3000",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          },
          {
            "PortRange": "5001/5001",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          },
          {
            "PortRange": "5002/5002",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          },
          {
            "PortRange": "5003/5003",
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          },
          {
            "PortRange": "8080/8080",
            "Priority": 1,
            "SourceCidrIp": "0.0.0.0/0",
            "IpProtocol": "tcp"
          }
        ]
      }
    },
    "EcsInstance": {
      "Type": "ALIYUN::ECS::InstanceGroup",
      "Properties": {
        "VpcId": {
          "Ref": "Vpc"
        },
        "ZoneId": {
          "Ref": "ZoneId1"
        },
        "VSwitchId": {
          "Ref": "VSwitch1"
        },
        "SecurityGroupId": {
          "Ref": "SecurityGroup"
        },
        "ImageId": "aliyun_3_x64_20G_alibase_",
        "InstanceName": {
          "Fn::Sub": "${CommonName}-ecs"
        },
        "InstanceType": {
          "Ref": "InstanceType"
        },
        "SystemDiskCategory": "cloud_essd",
        "MaxAmount": 1,
        "SystemDiskSize": 40,
        "InternetMaxBandwidthOut": 5,
        "Password": {
          "Ref": "InstancePassword"
        }
      }
    },
    "RunCommand": {
      "Type": "ALIYUN::ECS::RunCommand",
      "Properties": {
        "CommandContent": {
          "Fn::Sub": "#!/bin/sh\necho \"sk-$(openssl rand -hex 16)\"\n"
        },
        "Type": "RunShellScript",
        "InstanceIds": [
          {
            "Ref": "EcsInstance"
          }
        ]
      }
    },
    "RunCommand2": {
      "DependsOn": [
        "RunCommand"
      ],
      "Type": "ALIYUN::ECS::RunCommand",
      "Properties": {
        "CommandContent": {
          "Fn::Sub": "#!/bin/sh\nexport ROS_DEPLOY=true\ncurl -fsSL https://help-static-aliyun-doc.aliyuncs.com/install-script/dify/sae/install.sh | bash\n"
        },
        "Type": "RunShellScript",
        "InstanceIds": [
          {
            "Ref": "EcsInstance"
          }
        ]
      }
    },
    "RedisInstance": {
      "Type": "ALIYUN::REDIS::Instance",
      "Properties": {
        "ZoneId": {
          "Ref": "ZoneId1"
        },
        "SecondaryZoneId": {
          "Ref": "ZoneId2"
        },
        "VpcId": {
          "Ref": "Vpc"
        },
        "VSwitchId": {
          "Ref": "VSwitch1"
        },
        "InstanceClass": "redis.shard.large.y.ee",
        "EvictionPolicy": "noeviction",
        "InstanceName": {
          "Fn::Sub": "${CommonName}-Redis"
        },
        "EngineVersion": "7.0",
        "Password": {
          "Ref": "RedisInstancePassword"
        }
      }
    },
    "REDISWhitelist": {
      "Type": "ALIYUN::REDIS::Whitelist",
      "Properties": {
        "InstanceId": {
          "Ref": "RedisInstance"
        },
        "SecurityIps": "192.168.0.0/16"
      }
    },
    "ADBPGInstance": {
      "Type": "ALIYUN::GPDB::DBInstance",
      "Properties": {
        "EngineVersion": "7.0",
        "VectorConfigurationStatus": true,
        "InstanceSpec": "4C32G",
        "ZoneId": {
          "Ref": "ZoneId1"
        },
        "VSwitchId": {
          "Ref": "VSwitch1"
        },
        "SegNodeNum": 4,
        "SegStorageType": "cloud_essd",
        "SegDiskPerformanceLevel": "pl1",
        "StorageSize": 50,
        "VPCId": {
          "Ref": "Vpc"
        },
        "SecurityIPList": "192.168.0.0/16",
        "DBInstanceDescription": {
          "Fn::Sub": "${CommonName}"
        },
        "PayType": "Postpaid",
        "DBInstanceCategory": "HighAvailability",
        "DBInstanceMode": "StorageElastic",
        "ProdType": "standard"
      }
    },
    "GPDBAccount": {
      "Type": "ALIYUN::GPDB::Account",
      "Properties": {
        "DBInstanceId": {
          "Fn::GetAtt": [
            "ADBPGInstance",
            "DBInstanceId"
          ]
        },
        "AccountPassword": {
          "Ref": "ADBPGPassword"
        },
        "AccountName": {
          "Ref": "ADBPGAccount"
        }
      }
    },
    "SaeNamespace": {
      "DependsOn": [
        "PostgreSQLInstance",
        "RedisInstance",
        "ADBPGInstance",
        "PluginNas",
        "APINas"
      ],
      "Type": "ALIYUN::SAE::Namespace",
      "Properties": {
        "NamespaceName": {
          "Ref": "NamespaceName"
        },
        "NamespaceId": {
          "Fn::Sub": "${ALIYUN::Region}:${NamespaceName}"
        },
        "VpcId": {
          "Ref": "Vpc"
        }
      }
    },
    "PostgreSQLInstance": {
      "Type": "ALIYUN::RDS::DBInstance",
      "Properties": {
        "ZoneId": {
          "Ref": "ZoneId1"
        },
        "SlaveZoneIds": [
          {
            "Ref": "ZoneId2"
          }
        ],
        "VpcId": {
          "Ref": "Vpc"
        },
        "VSwitchId": {
          "Ref": "VSwitch1"
        },
        "DBInstanceClass": {
          "Ref": "DBInstanceClass"
        },
        "DBInstanceStorage": 50,
        "Engine": "PostgreSQL",
        "EngineVersion": "17.0",
        "SecurityIPList": "192.168.0.0/16",
        "Category": "HighAvailability",
        "MasterUserType": "Super",
        "MasterUserPassword": {
          "Ref": "PostgreSQLPassword"
        },
        "MasterUsername": {
          "Ref": "PostgreSQLUserName"
        },
        "DBInstanceStorageType": "cloud_essd"
      }
    },
    "DifyDataBase": {
      "Type": "ALIYUN::RDS::Database",
      "Properties": {
        "CharacterSetName": "utf8",
        "DBInstanceId": {
          "Fn::GetAtt": [
            "PostgreSQLInstance",
            "DBInstanceId"
          ]
        },
        "DBName": "dify"
      }
    },
    "DifySetUpDataBase": {
      "Type": "ALIYUN::RDS::Database",
      "DependsOn": "DifyDataBase",
      "Properties": {
        "CharacterSetName": "UTF8",
        "DBInstanceId": {
          "Fn::GetAtt": [
            "PostgreSQLInstance",
            "DBInstanceId"
          ]
        },
        "DBName": "dify_setups"
      }
    },
    "RdsAccountPrivilege": {
      "Type": "ALIYUN::RDS::AccountPrivilege",
      "DependsOn": "DifySetUpDataBase",
      "Properties": {
        "AccountPrivilege": "DBOwner",
        "DBInstanceId": {
          "Ref": "PostgreSQLInstance"
        },
        "DBName": "dify",
        "AccountName": {
          "Ref": "PostgreSQLUserName"
        }
      }
    },
    "NatGateway": {
      "Type": "ALIYUN::VPC::NatGateway",
      "Properties": {
        "VpcId": {
          "Ref": "Vpc"
        },
        "VSwitchId": {
          "Ref": "VSwitch1"
        },
        "NatGatewayName": {
          "Fn::Sub": "${CommonName}-nat"
        },
        "InternetChargeType": "PayByLcu",
        "EipBindMode": "NAT"
      }
    },
    "Eip": {
      "Type": "ALIYUN::VPC::EIP",
      "Properties": {
        "DeletionProtection": false,
        "Isp": "BGP",
        "Bandwidth": 200,
        "InternetChargeType": "PayByTraffic"
      }
    },
    "EipAssociation": {
      "Type": "ALIYUN::VPC::EIPAssociation",
      "Properties": {
        "InstanceId": {
          "Ref": "NatGateway"
        },
        "AllocationId": {
          "Ref": "Eip"
        }
      }
    },
    "SNat": {
      "Type": "ALIYUN::VPC::SnatEntry",
      "DependsOn": "EipAssociation",
      "Properties": {
        "SnatTableId": {
          "Fn::GetAtt": [
            "NatGateway",
            "SNatTableId"
          ]
        },
        "SnatEntryName": {
          "Fn::Sub": "${CommonName}-snat"
        },
        "SourceVSwitchIds": [
          {
            "Ref": "VSwitch1"
          },
          {
            "Ref": "VSwitch2"
          }
        ],
        "SnatIp": {
          "Fn::GetAtt": [
            "Eip",
            "EipAddress"
          ]
        }
      }
    },
    "APINas": {
      "Type": "ALIYUN::NAS::FileSystem",
      "Properties": {
        "ProtocolType": "NFS",
        "FileSystemType": "standard",
        "DeletionForce": true,
        "StorageType": "Performance",
        "Description": {
          "Fn::Sub": "${CommonName}-API-NAS"
        }
      }
    },
    "APINasMountTarget": {
      "Type": "ALIYUN::NAS::MountTarget",
      "Properties": {
        "VpcId": {
          "Ref": "Vpc"
        },
        "VSwitchId": {
          "Ref": "VSwitch1"
        },
        "NetworkType": "Vpc",
        "AccessGroupName": "DEFAULT_VPC_GROUP_NAME",
        "FileSystemId": {
          "Ref": "APINas"
        }
      }
    },
    "PluginNas": {
      "Type": "ALIYUN::NAS::FileSystem",
      "Properties": {
        "ProtocolType": "NFS",
        "FileSystemType": "standard",
        "DeletionForce": true,
        "StorageType": "Performance",
        "Description": {
          "Fn::Sub": "${CommonName}-Plugin-NAS"
        }
      }
    },
    "PluginNasMountTarget": {
      "Type": "ALIYUN::NAS::MountTarget",
      "Properties": {
        "VpcId": {
          "Ref": "Vpc"
        },
        "VSwitchId": {
          "Ref": "VSwitch1"
        },
        "NetworkType": "Vpc",
        "AccessGroupName": "DEFAULT_VPC_GROUP_NAME",
        "FileSystemId": {
          "Ref": "PluginNas"
        }
      }
    },
    "SuperOpsUser": {
      "Type": "ALIYUN::RAM::User",
      "Properties": {
        "UserName": {
          "Fn::Sub": "SuperOps-${ALIYUN::StackId}"
        },
        "Policies": [
          {
            "PolicyName": {
              "Fn::Join": [
                "-",
                [
                  "DifySuperOpsPolicy",
                  {
                    "Ref": "ALIYUN::StackName"
                  }
                ]
              ]
            },
            "PolicyDocument": {
              "Version": "1",
              "Statement": [
                {
                  "Effect": "Allow",
                  "Action": [
                    "gpdb:*"
                  ],
                  "Resource": [
                    "*"
                  ]
                }
              ]
            }
          }
        ],
        "PolicyAttachments": {
          "System": [
            "AliyunSTSAssumeRoleAccess",
            "AliyunRAMReadOnlyAccess"
          ]
        }
      }
    },
    "AccessKey": {
      "Type": "ALIYUN::RAM::AccessKey",
      "Properties": {
        "UserName": {
          "Fn::GetAtt": [
            "SuperOpsUser",
            "UserName"
          ]
        }
      }
    },
    "DifyApiConfigMap": {
      "Type": "ALIYUN::SAE::ConfigMap",
      "Properties": {
        "Data": {
          "MAIL_DEFAULT_SEND_FROM": "YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)",
          "SENTRY_PROFILES_SAMPLE_RATE": "1",
          "MARKETPLACE_ENABLED": "true",
          "DB_PORT": "5432",
          "VECTOR_STORE": "analyticdb",
          "LOG_LEVEL": "INFO",
          "DB_DATABASE": "dify",
          "REDIS_USE_SSL": "false",
          "STORAGE_LOCAL_PATH": "/app/api/storage",
          "SENTRY_TRACES_SAMPLE_RATE": "1",
          "MODE": "api",
          "WEB_API_CORS_ALLOW_ORIGINS": "*",
          "RESEND_API_URL": "https://api.resend.com",
          "ANALYTICDB_INSTANCE_ID": {
            "Fn::GetAtt": [
              "ADBPGInstance",
              "DBInstanceId"
            ]
          },
          "CODE_EXECUTION_ENDPOINT": "http://dify-sandbox:8194",
          "REDIS_HOST": {
            "Fn::GetAtt": [
              "RedisInstance",
              "ConnectionDomain"
            ]
          },
          "REDIS_DB": "0",
          "REDIS_PORT": "6379",
          "MAIL_TYPE": "resend",
          "ANALYTICDB_REGION_ID": {
            "Ref": "ALIYUN::Region"
          },
          "MIGRATION_ENABLED": "true",
          "CONSOLE_CORS_ALLOW_ORIGINS": "*",
          "PLUGIN_DAEMON_URL": "http://dify-plugin-daemon:5002",
          "STORAGE_TYPE": "local",
          "DB_HOST": {
            "Fn::GetAtt": [
              "PostgreSQLInstance",
              "InnerConnectionString"
            ]
          }
        },
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Name": "dify-api"
      }
    },
    "DifyApiSecret": {
      "Type": "ALIYUN::SAE::Secret",
      "Properties": {
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "SecretName": "dify-api",
        "SecretType": "Opaque",
        "SecretData": {
          "ANALYTICDB_ACCOUNT": {
            "Ref": "ADBPGAccount"
          },
          "ANALYTICDB_KEY_ID": {
            "Fn::GetAtt": [
              "AccessKey",
              "AccessKeyId"
            ]
          },
          "ANALYTICDB_KEY_SECRET": {
            "Fn::GetAtt": [
              "AccessKey",
              "AccessKeySecret"
            ]
          },
          "ANALYTICDB_NAMESPACE": "difyns",
          "ANALYTICDB_NAMESPACE_PASSWORD": {
            "Ref": "ADBPGPassword"
          },
          "ANALYTICDB_PASSWORD": {
            "Ref": "ADBPGPassword"
          },
          "CELERY_BROKER_URL": {
            "Fn::Sub": [
              "redis://:${REDIS_PASSWORD}@${REDIS_HOST}:6379/0",
              {
                "REDIS_PASSWORD": {
                  "Ref": "RedisInstancePassword"
                },
                "REDIS_HOST": {
                  "Fn::GetAtt": [
                    "RedisInstance",
                    "ConnectionDomain"
                  ]
                }
              }
            ]
          },
          "CODE_EXECUTION_API_KEY": "dify-sandbox",
          "DB_PASSWORD": {
            "Ref": "PostgreSQLPassword"
          },
          "DB_USERNAME": {
            "Ref": "PostgreSQLUserName"
          },
          "INNER_API_KEY_FOR_PLUGIN": "QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1",
          "PLUGIN_DAEMON_KEY": "lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi",
          "REDIS_PASSWORD": {
            "Ref": "RedisInstancePassword"
          },
          "REDIS_USERNAME": "default",
          "RESEND_API_KEY": "xxxx",
          "SECRET_KEY": {
            "Fn::Base64Decode": {
              "Fn::Jq": [
                "First",
                ".[0].Output",
                {
                  "Fn::GetAtt": [
                    "RunCommand",
                    "InvokeResults"
                  ]
                }
              ]
            }
          }
        }
      }
    },
    "DifyWorkerConfigMap": {
      "Type": "ALIYUN::SAE::ConfigMap",
      "Properties": {
        "Data": {
          "MAIL_DEFAULT_SEND_FROM": "YOUR EMAIL FROM (eg: no-reply <no-reply@dify.ai>)",
          "SENTRY_PROFILES_SAMPLE_RATE": "1",
          "MARKETPLACE_ENABLED": "true",
          "DB_PORT": "5432",
          "VECTOR_STORE": "analyticdb",
          "LOG_LEVEL": "INFO",
          "DB_DATABASE": "dify",
          "REDIS_USE_SSL": "false",
          "STORAGE_LOCAL_PATH": "/app/api/storage",
          "SENTRY_TRACES_SAMPLE_RATE": "1",
          "MODE": "worker",
          "WEB_API_CORS_ALLOW_ORIGINS": "*",
          "RESEND_API_URL": "https://api.resend.com",
          "ANALYTICDB_INSTANCE_ID": {
            "Fn::GetAtt": [
              "ADBPGInstance",
              "DBInstanceId"
            ]
          },
          "REDIS_HOST": {
            "Fn::GetAtt": [
              "RedisInstance",
              "ConnectionDomain"
            ]
          },
          "REDIS_DB": "0",
          "REDIS_PORT": "6379",
          "MAIL_TYPE": "resend",
          "ANALYTICDB_REGION_ID": {
            "Ref": "ALIYUN::Region"
          },
          "MIGRATION_ENABLED": "true",
          "CONSOLE_CORS_ALLOW_ORIGINS": "*",
          "PLUGIN_DAEMON_URL": "http://dify-plugin-daemon:5002",
          "STORAGE_TYPE": "local",
          "DB_HOST": {
            "Fn::GetAtt": [
              "PostgreSQLInstance",
              "InnerConnectionString"
            ]
          }
        },
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Name": "dify-worker"
      }
    },
    "DifyWorkerSecret": {
      "Type": "ALIYUN::SAE::Secret",
      "Properties": {
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "SecretName": "dify-worker",
        "SecretType": "Opaque",
        "SecretData": {
          "ANALYTICDB_ACCOUNT": {
            "Ref": "ADBPGAccount"
          },
          "ANALYTICDB_KEY_ID": {
            "Fn::GetAtt": [
              "AccessKey",
              "AccessKeyId"
            ]
          },
          "ANALYTICDB_KEY_SECRET": {
            "Fn::GetAtt": [
              "AccessKey",
              "AccessKeySecret"
            ]
          },
          "ANALYTICDB_NAMESPACE": "difyns",
          "ANALYTICDB_NAMESPACE_PASSWORD": {
            "Ref": "ADBPGPassword"
          },
          "ANALYTICDB_PASSWORD": {
            "Ref": "ADBPGPassword"
          },
          "CELERY_BROKER_URL": {
            "Fn::Sub": [
              "redis://:${REDIS_PASSWORD}@${REDIS_HOST}:6379/0",
              {
                "REDIS_PASSWORD": {
                  "Ref": "RedisInstancePassword"
                },
                "REDIS_HOST": {
                  "Fn::GetAtt": [
                    "RedisInstance",
                    "ConnectionDomain"
                  ]
                }
              }
            ]
          },
          "DB_PASSWORD": {
            "Ref": "PostgreSQLPassword"
          },
          "DB_USERNAME": {
            "Ref": "PostgreSQLUserName"
          },
          "INNER_API_KEY_FOR_PLUGIN": "QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1",
          "PLUGIN_DAEMON_KEY": "lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi",
          "REDIS_PASSWORD": {
            "Ref": "RedisInstancePassword"
          },
          "REDIS_USERNAME": "default",
          "RESEND_API_KEY": "xxxx",
          "SECRET_KEY": {
            "Fn::Base64Decode": {
              "Fn::Jq": [
                "First",
                ".[0].Output",
                {
                  "Fn::GetAtt": [
                    "RunCommand",
                    "InvokeResults"
                  ]
                }
              ]
            }
          }
        }
      }
    },
    "DifyPluginDaemonConfigMap": {
      "Type": "ALIYUN::SAE::ConfigMap",
      "Properties": {
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Name": "dify-plugin-daemon",
        "Data": {
          "SERVER_PORT": "5002",
          "PLUGIN_REMOTE_INSTALLING_HOST": "0.0.0.0",
          "REDIS_DB": "0",
          "REDIS_HOST": {
            "Fn::GetAtt": [
              "RedisInstance",
              "ConnectionDomain"
            ]
          },
          "MARKETPLACE_ENABLED": "true",
          "DB_PORT": "5432",
          "REDIS_USE_SSL": "false",
          "PLUGIN_WORKING_PATH": "/app/storage/cwd",
          "DB_HOST": {
            "Fn::GetAtt": [
              "PostgreSQLInstance",
              "InnerConnectionString"
            ]
          },
          "PIP_MIRROR_URL": "http://mirrors.aliyun.com/pypi/simple/",
          "REDIS_PORT": "6379",
          "PLUGIN_REMOTE_INSTALLING_PORT": "5003",
          "MAX_PLUGIN_PACKAGE_SIZE": "52428800",
          "DB_DATABASE": "dify_plugin",
          "DIFY_INNER_API_URL": "http://dify-api:5001"
        }
      }
    },
    "DifyPluginDaemonSecret": {
      "Type": "ALIYUN::SAE::Secret",
      "Properties": {
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "SecretName": "dify-plugin-daemon",
        "SecretType": "Opaque",
        "SecretData": {
          "DB_PASSWORD": {
            "Ref": "PostgreSQLPassword"
          },
          "DB_USERNAME": {
            "Ref": "PostgreSQLUserName"
          },
          "DIFY_INNER_API_KEY": "QaHbTe77CtuXmsfyhR7+vRjI/+XbV1AaFy691iy+kGDv2Jvy0/eAh8Y1",
          "REDIS_PASSWORD": {
            "Ref": "RedisInstancePassword"
          },
          "REDIS_USERNAME": "default",
          "SERVER_KEY": "lYkiYYT6owG+71oLerGzA7GXCgOT++6ovaezWAjpCjf+Sjc3ZtU+qUEi"
        }
      }
    },
    "DifySandboxConfigMap": {
      "Type": "ALIYUN::SAE::ConfigMap",
      "Properties": {
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Name": "dify-sandbox",
        "Data": {
          "GIN_MODE": "release",
          "SANDBOX_PORT": "8194"
        }
      }
    },
    "DifySandboxSecret": {
      "Type": "ALIYUN::SAE::Secret",
      "Properties": {
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "SecretName": "dify-sandbox",
        "SecretType": "Opaque",
        "SecretData": {
          "API_KEY": "dify-sandbox"
        }
      }
    },
    "DifyWebConfigMap": {
      "Type": "ALIYUN::SAE::ConfigMap",
      "Properties": {
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Name": "dify-web",
        "Data": {
          "MARKETPLACE_ENABLED": "true",
          "MARKETPLACE_URL": "https://marketplace.dify.ai",
          "MARKETPLACE_API_URL": "https://marketplace.dify.ai"
        }
      }
    },
    "DifyNginxConfigMap": {
      "Type": "ALIYUN::SAE::ConfigMap",
      "Properties": {
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Name": "dify-nginx",
        "Data": {
          "default.conf": "server {\n        listen 80;\n        server_name _;\n\n        location /console/api {\n          proxy_pass http://dify-api:5001;\n          include proxy.conf;\n        }\n\n        location /api {\n          proxy_pass http://dify-api:5001;\n          include proxy.conf;\n        }\n\n        location /v1 {\n          proxy_pass http://dify-api:5001;\n          include proxy.conf;\n        }\n\n        location /files {\n          proxy_pass http://dify-api:5001;\n          include proxy.conf;\n        }\n\n        location /explore {\n          proxy_pass http://dify-web:3000;\n          proxy_set_header Dify-Hook-Url $scheme://$host$request_uri;\n          include proxy.conf;\n        }\n\n        location /e/ {\n          proxy_pass http://dify-plugin-daemon:5002;\n          proxy_set_header Dify-Hook-Url $scheme://$host$request_uri;\n          include proxy.conf;\n        }\n\n        location / {\n          proxy_pass http://dify-web:3000;\n          include proxy.conf;\n        }\n    }",
          "nginx.conf": "user  nginx;\n    worker_processes  auto;\n    pid        /var/run/nginx.pid;\n\n\n    events {\n        worker_connections  1024;\n    }\n\n\n    http {\n        include       /etc/nginx/mime.types;\n        default_type  application/octet-stream;\n\n        log_format  main  '$remote_addr - $remote_user [$time_local] \"$request\" '\n                          '$status $body_bytes_sent \"$http_referer\" '\n                          '\"$http_user_agent\" \"$http_x_forwarded_for\"';\n\n        sendfile        on;\n        #tcp_nopush     on;\n\n        keepalive_timeout  65;\n\n        #gzip  on;\n        client_max_body_size 15M;\n\n        include /etc/nginx/conf.d/*.conf;\n    }",
          "proxy.conf": "proxy_set_header Host $host;\nproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\nproxy_set_header X-Forwarded-Proto $scheme;\nproxy_set_header X-Forwarded-Port $server_port;\nproxy_http_version 1.1;\nproxy_set_header Connection \"\";\nproxy_buffering off;\nproxy_read_timeout 3600s;\nproxy_send_timeout 3600s;"
        }
      }
    },
    "DifyApiApp": {
      "DependsOn": [
        "SaeNamespace",
        "DifyApiConfigMap",
        "DifyApiSecret",
        "ADBPGInstance"
      ],
      "Type": "ALIYUN::SAE::Application",
      "Properties": {
        "AppName": "dify-api",
        "SaeVersion": "v2",
        "AutoConfig": false,
        "VpcId": {
          "Ref": "Vpc"
        },
        "SecurityGroupId": {
          "Ref": "SecurityGroup"
        },
        "VSwitchId": {
          "Fn::Sub": [
            "${VSwitch1},${VSwitch2}",
            {
              "VSwitch1": {
                "Ref": "VSwitch1"
              },
              "VSwitch2": {
                "Ref": "VSwitch2"
              }
            }
          ]
        },
        "Replicas": 1,
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Cpu": 1000,
        "Memory": 2048,
        "PackageType": "Image",
        "ImageUrl": {
          "Fn::Sub": "registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-api-v1.6.0"
        },
        "ProgrammingLanguage": "python",
        "AppSource": "micro_service",
        "Timezone": "Asia/Shanghai",
        "NasConfigs": {
          "Fn::Sub": [
            "[{\"mountDomain\":\"${MOUNT_DOMAIN}\",\"mountPath\":\"/app/api/storage\",\"nasId\":\"${NAS_ID}\",\"nasPath\":\"dify-api\",\"readOnly\":false,\"volumeName\":\"nas-1\"}]",
            {
              "MOUNT_DOMAIN": {
                "Fn::GetAtt": [
                  "APINasMountTarget",
                  "MountTargetDomain"
                ]
              },
              "NAS_ID": {
                "Fn::GetAtt": [
                  "APINas",
                  "FileSystemId"
                ]
              }
            }
          ]
        },
        "PvtzDiscoverySvc": {
          "Fn::Sub": [
            "{\"enable\":\"true\",\"namespaceId\":\"${REGION_ID}:${NAMESPACE}\",\"portAndProtocol\":{\"5001:TCP\":\"5001\"},\"portProtocols\":[],\"pvtzDiscoveryName\":\"${REGION_ID}-${USER_ID}\",\"serviceName\":\"dify-api.${NAMESPACE}\"}",
            {
              "NAMESPACE": {
                "Ref": "NamespaceName"
              },
              "USER_ID": {
                "Ref": "ALIYUN::TenantId"
              },
              "REGION_ID": {
                "Ref": "ALIYUN::Region"
              }
            }
          ]
        },
        "Envs": {
          "Fn::Sub": [
            "[{\"name\":\"APP_WEB_URL\"},{\"name\":\"FILES_URL\"},{\"name\":\"CODE_MAX_DEPTH\",\"value\":\"5\"},{\"name\":\"CODE_MAX_OBJECT_ARRAY_LENGTH\",\"value\":\"30\"},{\"name\":\"CHECK_UPDATE_URL\"},{\"name\":\"CODE_MAX_STRING_ARRAY_LENGTH\",\"value\":\"30\"},{\"name\":\"SERVICE_API_URL\"},{\"name\":\"sae-sys-secret-all-dify-api\",\"valueFrom\":{\"secretRef\":{\"secretId\":${SECRET_ID},\"key\":\"\"}}},{\"name\":\"CODE_MAX_PRECISION\",\"value\":\"20\"},{\"name\":\"CONSOLE_API_URL\"},{\"name\":\"TEMPLATE_TRANSFORM_MAX_LENGTH\",\"value\":\"80000\"},{\"name\":\"CODE_MAX_NUMBER\",\"value\":\"9223372036854775807\"},{\"name\":\"CODE_MAX_NUMBER_ARRAY_LENGTH\",\"value\":\"1000\"},{\"name\":\"CONSOLE_WEB_URL\"},{\"name\":\"CODE_MIN_NUMBER\",\"value\":\"-9223372036854775808\"},{\"name\":\"CODE_MAX_STRING_LENGTH\",\"value\":\"80000\"},{\"name\":\"SENTRY_DSN\"},{\"name\":\"CODE_EXECUTION_API_KEY\",\"valueFrom\":{\"secretRef\":{\"secretId\":${SANDBOX_SECRET_ID},\"key\":\"API_KEY\"}}},{\"name\":\"sae-sys-configmap-all-dify-api\",\"valueFrom\":{\"configMapRef\":{\"configMapId\":${CONFIGMAP_ID},\"key\":\"\"}}}]",
            {
              "CONFIGMAP_ID": {
                "Fn::GetAtt": [
                  "DifyApiConfigMap",
                  "ConfigMapId"
                ]
              },
              "SECRET_ID": {
                "Fn::GetAtt": [
                  "DifyApiSecret",
                  "SecretId"
                ]
              },
              "SANDBOX_SECRET_ID": {
                "Fn::GetAtt": [
                  "DifySandboxSecret",
                  "SecretId"
                ]
              }
            }
          ]
        }
      }
    },
    "DifyWorkerApp": {
      "DependsOn": [
        "SaeNamespace",
        "DifyWorkerConfigMap",
        "DifyWorkerSecret"
      ],
      "Type": "ALIYUN::SAE::Application",
      "Properties": {
        "AppName": "dify-worker",
        "SaeVersion": "v2",
        "AutoConfig": false,
        "VpcId": {
          "Ref": "Vpc"
        },
        "SecurityGroupId": {
          "Ref": "SecurityGroup"
        },
        "VSwitchId": {
          "Fn::Sub": [
            "${VSwitch1},${VSwitch2}",
            {
              "VSwitch1": {
                "Ref": "VSwitch1"
              },
              "VSwitch2": {
                "Ref": "VSwitch2"
              }
            }
          ]
        },
        "Replicas": 1,
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Cpu": 1000,
        "Memory": 2048,
        "PackageType": "Image",
        "ImageUrl": {
          "Fn::Sub": "registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-api-v1.6.0"
        },
        "ProgrammingLanguage": "python",
        "AppSource": "micro_service",
        "Timezone": "Asia/Shanghai",
        "NasConfigs": {
          "Fn::Sub": [
            "[{\"mountDomain\":\"${MOUNT_DOMAIN}\",\"mountPath\":\"/app/api/storage\",\"nasId\":\"${NAS_ID}\",\"nasPath\":\"dify-api\",\"readOnly\":false,\"volumeName\":\"nas-1\"}]",
            {
              "MOUNT_DOMAIN": {
                "Fn::GetAtt": [
                  "APINasMountTarget",
                  "MountTargetDomain"
                ]
              },
              "NAS_ID": {
                "Fn::GetAtt": [
                  "APINas",
                  "FileSystemId"
                ]
              }
            }
          ]
        },
        "Envs": {
          "Fn::Sub": [
            "[{\"name\":\"sae-sys-secret-all-dify-worker\",\"valueFrom\":{\"secretRef\":{\"secretId\":${SECRET_ID},\"key\":\"\"}}},{\"name\":\"sae-sys-configmap-all-dify-worker\",\"valueFrom\":{\"configMapRef\":{\"configMapId\":${CONFIGMAP_ID},\"key\":\"\"}}},{\"name\":\"CONSOLE_WEB_URL\"}]",
            {
              "CONFIGMAP_ID": {
                "Fn::GetAtt": [
                  "DifyWorkerConfigMap",
                  "ConfigMapId"
                ]
              },
              "SECRET_ID": {
                "Fn::GetAtt": [
                  "DifyWorkerSecret",
                  "SecretId"
                ]
              }
            }
          ]
        }
      }
    },
    "DifyPluginDaemonApp": {
      "DependsOn": [
        "SaeNamespace",
        "DifyPluginDaemonConfigMap",
        "DifyPluginDaemonSecret"
      ],
      "Type": "ALIYUN::SAE::Application",
      "Properties": {
        "AppName": "dify-plugin-daemon",
        "SaeVersion": "v2",
        "AutoConfig": false,
        "VpcId": {
          "Ref": "Vpc"
        },
        "SecurityGroupId": {
          "Ref": "SecurityGroup"
        },
        "VSwitchId": {
          "Fn::Sub": [
            "${VSwitch1},${VSwitch2}",
            {
              "VSwitch1": {
                "Ref": "VSwitch1"
              },
              "VSwitch2": {
                "Ref": "VSwitch2"
              }
            }
          ]
        },
        "Replicas": 1,
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Cpu": 1000,
        "Memory": 2048,
        "PackageType": "Image",
        "ImageUrl": {
          "Fn::Sub": "registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-plugin-daemon-v0.1.3-local"
        },
        "ProgrammingLanguage": "golang",
        "AppSource": "micro_service",
        "Timezone": "Asia/Shanghai",
        "NasConfigs": {
          "Fn::Sub": [
            "[{\"mountDomain\":\"${MOUNT_DOMAIN}\",\"mountPath\":\"/app/storage\",\"nasId\":\"${NAS_ID}\",\"nasPath\":\"dify-plugin-daemon\",\"readOnly\":false,\"volumeName\":\"nas-1\"}]",
            {
              "MOUNT_DOMAIN": {
                "Fn::GetAtt": [
                  "PluginNasMountTarget",
                  "MountTargetDomain"
                ]
              },
              "NAS_ID": {
                "Fn::GetAtt": [
                  "PluginNas",
                  "FileSystemId"
                ]
              }
            }
          ]
        },
        "PvtzDiscoverySvc": {
          "Fn::Sub": [
            "{\"enable\":\"true\",\"namespaceId\":\"${REGION_ID}:${NAMESPACE}\",\"portAndProtocol\":{\"5003:TCP\":\"5003\",\"5002:TCP\":\"5002\"},\"portProtocols\":[],\"pvtzDiscoveryName\":\"${REGION_ID}-${USER_ID}\",\"serviceName\":\"dify-plugin-daemon.${NAMESPACE}\"}",
            {
              "NAMESPACE": {
                "Ref": "NamespaceName"
              },
              "USER_ID": {
                "Ref": "ALIYUN::TenantId"
              },
              "REGION_ID": {
                "Ref": "ALIYUN::Region"
              }
            }
          ]
        },
        "Envs": {
          "Fn::Sub": [
            "[{\"name\":\"sae-sys-secret-all-dify-plugin-daemon\",\"valueFrom\":{\"secretRef\":{\"secretId\":${SECRET_ID},\"key\":\"\"}}},{\"name\":\"sae-sys-configmap-all-dify-plugin-daemon\",\"valueFrom\":{\"configMapRef\":{\"configMapId\":${CONFIGMAP_ID},\"key\":\"\"}}}]",
            {
              "CONFIGMAP_ID": {
                "Fn::GetAtt": [
                  "DifyPluginDaemonConfigMap",
                  "ConfigMapId"
                ]
              },
              "SECRET_ID": {
                "Fn::GetAtt": [
                  "DifyPluginDaemonSecret",
                  "SecretId"
                ]
              }
            }
          ]
        }
      }
    },
    "DifySandboxApp": {
      "DependsOn": [
        "SaeNamespace",
        "DifySandboxConfigMap",
        "DifySandboxSecret"
      ],
      "Type": "ALIYUN::SAE::Application",
      "Properties": {
        "AppName": "dify-sandbox",
        "SaeVersion": "v2",
        "AutoConfig": false,
        "VpcId": {
          "Ref": "Vpc"
        },
        "SecurityGroupId": {
          "Ref": "SecurityGroup"
        },
        "VSwitchId": {
          "Fn::Sub": [
            "${VSwitch1},${VSwitch2}",
            {
              "VSwitch1": {
                "Ref": "VSwitch1"
              },
              "VSwitch2": {
                "Ref": "VSwitch2"
              }
            }
          ]
        },
        "Replicas": 1,
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Cpu": 1000,
        "Memory": 2048,
        "PackageType": "Image",
        "ImageUrl": {
          "Fn::Sub": "registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-sandbox-v0.2.12"
        },
        "ProgrammingLanguage": "golang",
        "AppSource": "micro_service",
        "Timezone": "Asia/Shanghai",
        "PvtzDiscoverySvc": {
          "Fn::Sub": [
            "{\"enable\":\"true\",\"namespaceId\":\"${REGION_ID}:${NAMESPACE}\",\"portAndProtocol\":{\"8194:TCP\":\"8194\"},\"portProtocols\":[],\"pvtzDiscoveryName\":\"${REGION_ID}-${USER_ID}\",\"serviceName\":\"dify-sandbox.${NAMESPACE}\"}",
            {
              "NAMESPACE": {
                "Ref": "NamespaceName"
              },
              "USER_ID": {
                "Ref": "ALIYUN::TenantId"
              },
              "REGION_ID": {
                "Ref": "ALIYUN::Region"
              }
            }
          ]
        },
        "Envs": {
          "Fn::Sub": [
            "[{\"name\":\"sae-sys-secret-all-dify-sandbox\",\"valueFrom\":{\"secretRef\":{\"secretId\":${SECRET_ID},\"key\":\"\"}}},{\"name\":\"WORKER_TIMEOUT\",\"value\":\"15\"},{\"name\":\"sae-sys-configmap-all-dify-sandbox\",\"valueFrom\":{\"configMapRef\":{\"configMapId\":${CONFIGMAP_ID},\"key\":\"\"}}}]",
            {
              "CONFIGMAP_ID": {
                "Fn::GetAtt": [
                  "DifySandboxConfigMap",
                  "ConfigMapId"
                ]
              },
              "SECRET_ID": {
                "Fn::GetAtt": [
                  "DifySandboxSecret",
                  "SecretId"
                ]
              }
            }
          ]
        }
      }
    },
    "DifyWebApp": {
      "DependsOn": [
        "SaeNamespace",
        "DifyWebConfigMap"
      ],
      "Type": "ALIYUN::SAE::Application",
      "Properties": {
        "AppName": "dify-web",
        "SaeVersion": "v2",
        "AutoConfig": false,
        "VpcId": {
          "Ref": "V"Ref": "SecurityGroup"
        },
        "VSwitchId": {
          "Fn::Sub": [
            "${VSwitch1},${VSwitch2}",
            {
              "VSwitch1": {
                "Ref": "VSwitch1"
              },
              "VSwitch2": {
                "Ref": "VSwitch2"
              }
            }
          ]
        },
        "Replicas": 1,
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Cpu": 1000,
        "Memory": 2048,
        "PackageType": "Image",
        "ImageUrl": {
          "Fn::Sub": "registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:dify-web-v1.6.0"
        },
        "ProgrammingLanguage": "other",
        "AppSource": "micro_service",
        "Timezone": "Asia/Shanghai",
        "PvtzDiscoverySvc": {
          "Fn::Sub": [
            "{\"enable\":\"true\",\"namespaceId\":\"${REGION_ID}:${NAMESPACE}\",\"portAndProtocol\":{\"3000:TCP\":\"3000\"},\"portProtocols\":[],\"pvtzDiscoveryName\":\"${REGION_ID}-${USER_ID}\",\"serviceName\":\"dify-web.${NAMESPACE}\"}",
            {
              "NAMESPACE": {
                "Ref": "NamespaceName"
              },
              "USER_ID": {
                "Ref": "ALIYUN::TenantId"
              },
              "REGION_ID": {
                "Ref": "ALIYUN::Region"
              }
            }
          ]
        },
        "Envs": {
          "Fn::Sub": [
            "[{\"name\":\"sae-sys-configmap-all-dify-web\",\"valueFrom\":{\"configMapRef\":{\"configMapId\":${CONFIGMAP_ID},\"key\":\"\"}}},{\"name\":\"APP_API_URL\"},{\"name\":\"CONSOLE_API_URL\"},{\"name\":\"EDITION\",\"value\":\"SELF_HOSTED\"}]",
            {
              "CONFIGMAP_ID": {
                "Fn::GetAtt": [
                  "DifyWebConfigMap",
                  "ConfigMapId"
                ]
              }
            }
          ]
        }
      }
    },
    "DifyNginxApp": {
      "DependsOn": [
        "SaeNamespace",
        "DifyNginxConfigMap"
      ],
      "Type": "ALIYUN::SAE::Application",
      "Properties": {
        "AppName": "dify-nginx",
        "SaeVersion": "v2",
        "AutoConfig": false,
        "VpcId": {
          "Ref": "Vpc"
        },
        "SecurityGroupId": {
          "Ref": "SecurityGroup"
        },
        "VSwitchId": {
          "Fn::Sub": [
            "${VSwitch1},${VSwitch2}",
            {
              "VSwitch1": {
                "Ref": "VSwitch1"
              },
              "VSwitch2": {
                "Ref": "VSwitch2"
              }
            }
          ]
        },
        "Replicas": 1,
        "NamespaceId": {
          "Ref": "SaeNamespace"
        },
        "Cpu": 1000,
        "Memory": 2048,
        "PackageType": "Image",
        "ImageUrl": {
          "Fn::Sub": "registry.${ALIYUN::Region}.aliyuncs.com/sae-serverless-demo/sae-demo:nginx-v1.23.4"
        },
        "ProgrammingLanguage": "other",
        "AppSource": "micro_service",
        "Timezone": "Asia/Shanghai",
        "ConfigMapMountDesc": {
          "Fn::Sub": [
            "[{\"MountPath\":\"/etc/nginx/conf.d/default.conf\",\"ConfigMapId\":${CONFIGMAP_ID},\"ConfigMapName\":\"dify-nginx\",\"Key\":\"default.conf\"},{\"MountPath\":\"/etc/nginx/nginx.conf\",\"ConfigMapId\":${CONFIGMAP_ID},\"ConfigMapName\":\"dify-nginx\",\"Key\":\"nginx.conf\"},{\"MountPath\":\"/etc/nginx/proxy.conf\",\"ConfigMapId\":${CONFIGMAP_ID},\"ConfigMapName\":\"dify-nginx\",\"Key\":\"proxy.conf\"}]",
            {
              "CONFIGMAP_ID": {
                "Fn::GetAtt": [
                  "DifyNginxConfigMap",
                  "ConfigMapId"
                ]
              }
            }
          ]
        }
      }
    },
    "InternetClb": {
      "Type": "ALIYUN::SLB::LoadBalancer",
      "Properties": {
        "LoadBalancerName": {
          "Ref": "ALIYUN::StackName"
        },
        "LoadBalancerSpec": "slb.s2.medium",
        "AddressType": "internet"
      }
    },
    "BackendAppBindClb": {
      "Type": "ALIYUN::SAE::SlbBinding",
      "DependsOn": [
        "DifyNginxApp",
        "InternetClb"
      ],
      "Properties": {
        "InternetSlbId": {
          "Fn::GetAtt": [
            "InternetClb",
            "LoadBalancerId"
          ]
        },
        "Internet": "[{\"port\": 80, \"targetPort\": 80, \"protocol\": \"TCP\"}]",
        "AppId": {
          "Fn::GetAtt": [
            "DifyNginxApp",
            "AppId"
          ]
        }
      }
    }
  },
  "Outputs": {
    "DifyAddress": {
      "Label": {
        "zh-cn": "Dify service address.",
        "en": "Dify service address."
      },
      "Description": {
        "zh-cn": "Dify service address.",
        "en": "Dify service address."
      },
      "Value": {
        "Fn::Sub": [
          "http://${ServerAddress}:80",
          {
            "ServerAddress": {
              "Fn::GetAtt": [
                "InternetClb",
                "IpAddress"
              ]
            }
          }
        ]
      }
    },
    "PostgresName": {
      "Label": {
        "zh-cn": "Postgres username",
        "en": "Postgres username"
      },
      "Description": {
        "zh-cn": "The username of AnalyticDB for PostgreSQL.",
        "en": "The username of AnalyticDB PostgreSQL."
      },
      "Value": {
        "Ref": "ADBPGAccount"
      }
    },
    "PostgresPassword": {
      "Label": {
        "zh-cn": "Postgres password",
        "en": "Postgres password"
      },
      "Description": {
        "zh-cn": "The password of AnalyticDB for PostgreSQL.",
        "en": "The password of AnalyticDB PostgreSQL."
      },
      "NoEcho": true,
      "Value": {
        "Ref": "ADBPGPassword"
      }
    },
    "PostgresConnectionString": {
      "Label": {
        "zh-cn": "Postgres database address",
        "en": "Postgres database address"
      },
      "Description": {
        "zh-cn": "The internal endpoint of AnalyticDB for PostgreSQL.",
        "en": "The internal network connection address of AnalyticDB PostgreSQL."
      },
      "Value": {
        "Fn::GetAtt": [
          "ADBPGInstance",
          "ConnectionString"
        ]
      }
    },
    "APINasFileSystemId": {
      "Label": {
        "zh-cn": "API NAS file system",
        "en": "API NAS file System"
      },
      "Description": {
        "zh-cn": "NAS file system.",
        "en": "NAS file System."
      },
      "Value": {
        "Ref": "APINas"
      }
    },
    "APINasMountTarget": {
      "Label": {
        "zh-cn": "API NAS mount target",
        "en": "API NAS MountTarget"
      },
      "Description": {
        "zh-cn": "NAS mount target.",
        "en": "NAS MountTarget."
      },
      "Value": {
        "Ref": "APINasMountTarget"
      }
    },
    "PluginNasFileSystemId": {
      "Label": {
        "zh-cn": "Plugin NAS file system",
        "en": "API NAS file System"
      },
      "Description": {
        "zh-cn": "NAS file system.",
        "en": "NAS file System."
      },
      "Value": {
        "Ref": "PluginNas"
      }
    },
    "PluginNasMountTarget": {
      "Label": {
        "zh-cn": "Plugin NAS mount target",
        "en": "API NAS MountTarget"
      },
      "Description": {
        "zh-cn": "NAS mount target.",
        "en": "NAS MountTarget."
      },
      "Value": {
        "Ref": "PluginNasMountTarget"
      }
    },
    "RedisConnectionString": {
      "Label": {
        "zh-cn": "Redis endpoint",
        "en": "Redis connection address"
      },
      "Description": {
        "zh-cn": "Redis endpoint.",
        "en": "Redis connection address."
      },
      "Value": {
        "Fn::GetAtt": [
          "RedisInstance",
          "ConnectionDomain"
        ]
      }
    },
    "RedisName": {
      "Label": {
        "zh-cn": "Redis username",
        "en": "Redis username"
      },
      "Description": {
        "zh-cn": "The username of Redis.",
        "en": "The username of Redis."
      },
      "Value": "default"
    },
    "RedisInstancePassword": {
      "Label": {
        "zh-cn": "Redis password",
        "en": "Redis password"
      },
      "Description": {
        "zh-cn": "The password of Redis.",
        "en": "The password of Redis."
      },
      "NoEcho": true,
      "Value": {
        "Ref": "RedisInstancePassword"
      }
    },
    "PostgreSQLDBName": {
      "Label": {
        "zh-cn": "Database Name",
        "en": "DBName"
      },
      "Description": {
        "zh-cn": "The database name of ApsaraDB RDS for PostgreSQL.",
        "en": "The database name of RDS PostgreSQL."
      },
      "Value": "dify"
    },
    "PostgreSQLConnectionString": {
      "Label": {
        "zh-cn": "RDS database address",
        "en": "RDS Database address"
      },
      "Description": {
        "zh-cn": "The internal endpoint of ApsaraDB RDS for PostgreSQL.",
        "en": "The internal network connection address of RDS PostgreSQL."
      },
      "Value": {
        "Fn::GetAtt": [
          "PostgreSQLInstance",
          "InnerConnectionString"
        ]
      }
    },
    "PostgreSQLAccount": {
      "Label": {
        "zh-cn": "RDS username",
        "en": "RDS Account"
      },
      "Description": {
        "zh-cn": "The username of ApsaraDB RDS for PostgreSQL.",
        "en": "The username of RDS PostgreSQL."
      },
      "Value": {
        "Ref": "PostgreSQLUserName"
      }
    },
    "PostgreSQLPassword": {
      "Label": {
        "zh-cn": "RDS password",
        "en": "RDS Password"
      },
      "Description": {
        "zh-cn": "The password of ApsaraDB RDS for PostgreSQL.",
        "en": "The password of RDS PostgreSQL."
      },
      "NoEcho": true,
      "Value": {
        "Ref": "PostgreSQLPassword"
      }
    },
    "NameSpace": {
      "Label": {
        "zh-cn": "Namespace",
        "en": "NameSpace"
      },
      "Description": {
        "zh-cn": "Namespace.",
        "en": "NameSpace."
      },
      "Value": {
        "Fn::Sub": "${ALIYUN::Region}:${NamespaceName}"
      }
    },
    "Vpc": {
      "Label": {
        "zh-cn": "VPC ID",
        "en": "Vpc ID"
      },
      "Description": {
        "zh-cn": "VPC ID.",
        "en": "Vpc ID."
      },
      "Value": {
        "Ref": "Vpc"
      }
    },
    "Vsw": {
      "Label": {
        "zh-cn": "vSwitch ID",
        "en": "Vsw ID"
      },
      "Description": {
        "zh-cn": "vSwitch ID.",
        "en": "Vsw ID."
      },
      "Value": {
        "Ref": "VSwitch1"
      }
    },
    "Sg": {
      "Label": {
        "zh-cn": "Security Group ID",
        "en": "Security Group ID"
      },
      "Description": {
        "zh-cn": "Security Group ID.",
        "en": "Security Group ID."
      },
      "Value": {
        "Ref": "SecurityGroup"
      }
    },
    "SecretKey": {
      "Label": {
        "zh-cn": "Secret Key",
        "en": "Secret Key"
      },
      "Description": {
        "zh-cn": "Used for secure signatures and encrypting sensitive information in the database.",
        "en": "Used for secure signatures and encrypting sensitive information in the database."
      },
      "NoEcho": true,
      "Value": {
        "Fn::Base64Decode": {
          "Fn::Jq": [
            "First",
            ".[0].Output",
            {
              "Fn::GetAtt": [
                "RunCommand",
                "InvokeResults"
              ]
            }
          ]
        }
      }
    },
    "dify-nginx": {
      "Label": {
        "zh-cn": "The application address of dify-nginx",
        "en": "The application address of dify-nginx"
      },
      "Description": {
        "zh-cn": "The application address of dify-nginx. In the application access settings, view the public endpoint based on CLB access.",
        "en": "The application address of dify-nginx,In the application access Settings, based on CLB access, view the public network access address."
      },
      "Value": {
        "Fn::Sub": "https://sae.console.alibabacloud.com/${ALIYUN::Region}/app-list/${DifyNginxApp.AppId}/micro-app/base?name=dify-nginx"
      }
    },
    "ECSInstanceId": {
      "Label": {
        "zh-cn": "ECS instance ID",
        "en": "The application address of dify-nginx"
      },
      "Description": {
        "zh-cn": "ECS instance ID. This instance deploys the sample e-commerce system.",
        "en": "ECS instance ID. This instance deploys the sample e-commerce system."
      },
      "Value": {
        "Fn::Select": [
          0,
          {
            "Fn::GetAtt": [
              "EcsInstance",
              "InstanceIds"
            ]
          }
        ]
      }
    },
    "Console@DemoUrl": {
      "Description": {
        "zh-cn": "The application access domain name, which is the address of the e-commerce system in this solution.",
        "en": "The application accesses the domain name, which is the address of the e-commerce system of this solution."
      },
      "Value": {
        "Fn::Sub": [
          "http://${PublicIp}",
          {
            "PublicIp": {
              "Fn::Select": [
                0,
                {
                  "Fn::GetAtt": [
                    "EcsInstance",
                    "PublicIps"
                  ]
                }
              ]
            }
          }
        ]
      }
    }
  },
  "Metadata": {
    "ALIYUN::ROS::Interface": {
      "Outputs": [
        "DifyAddress",
        "ECSInstanceId",
        "Console@DemoUrl",
        "dify-nginx",
        "NameSpace",
        "Vpc",
        "Vsw",
        "Sg",
        "PostgreSQLDBName",
        "PostgreSQLConnectionString",
        "PostgreSQLAccount",
        "PostgreSQLPassword",
        "PostgresName",
        "PostgresPassword",
        "PostgresConnectionString",
        "APINasFileSystemId",
        "APINasMountTarget",
        "PluginNasFileSystemId",
        "PluginNasMountTarget",
        "RedisConnectionString",
        "RedisName",
        "RedisInstancePassword",
        "SecretKey"
      ],
      "ParameterGroups": [
        {
          "Parameters": [
            "ZoneId1",
            "ZoneId2"
          ],
          "Label": {
            "default": {
              "en": "Availability Zone",
              "zh-cn": "Availability Zone"
            }
          }
        },
        {
          "Parameters": [
            "InstanceType",
            "InstancePassword"
          ],
          "Label": {
            "default": {
              "en": "Elastic Compute Service (ECS)",
              "zh-cn": "Elastic Compute Service (ECS)"
            }
          }
        },
        {
          "Parameters": [
            "RedisInstancePassword"
          ],
          "Label": {
            "default": {
              "en": "ApsaraDB for Tair (compatible with Redis)",
              "zh-cn": "ApsaraDB for Tair (compatible with Redis)"
            }
          }
        },
        {
          "Parameters": [
            "ADBPGAccount",
            "ADBPGPassword"
          ],
          "Label": {
            "default": {
              "en": "Cloud-native data warehouse AnalyticDB for PostgreSQL",
              "zh-cn": "Cloud-native data warehouse AnalyticDB for PostgreSQL"
            }
          }
        },
        {
          "Parameters": [
            "DBInstanceClass",
            "RdsDatabaseName",
            "PostgreSQLUserName",
            "PostgreSQLPassword"
          ],
          "Label": {
            "default": {
              "en": "ApsaraDB RDS for PostgreSQL",
              "zh-cn": "ApsaraDB RDS for PostgreSQL"
            }
          }
        },
        {
          "Parameters": [
            "NamespaceName"
          ],
          "Label": {
            "default": {
              "en": "Serverless App Engine (SAE)",
              "zh-cn": "Serverless App Engine (SAE)"
            }
          }
        }
      ],
      "TemplateTags": [
        "acs:technical-solution:internet-application-development:Deploy a production Dify platform using Serverless App Engine-tech_solu_251"
      ],
      "Hidden": [
        "CommonName"
      ]
    }
  }
}

Pour consulter d'autres exemples, reportez-vous à la rubrique Modèles publics contenant cette ressource.