Todos os produtos
Search
Central de documentação

Resource Orchestration Service:ALIYUN::SAE::Application

Última atualização: Sep 20, 2026

O tipo de recurso ALIYUN::SAE::Application cria uma aplicação do Serverless App Engine (SAE).

Sintaxe

{
  "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
  }
}

Properties

Propriedade

Tipo

Obrigatório

Editável

Descrição

Restrições

AppName

String

Yes

No

O nome da aplicação.

O nome pode ter até 36 caracteres. Deve começar com uma letra e pode conter letras, dígitos e hifens (-).

Cpu

Integer

Yes

Yes

O CPU necessário para cada instância. Apenas especificações predefinidas são aceitas.

Valores válidos:

  • 500

  • 1000

  • 2000

  • 4000

  • 8000

  • 16000

  • 32000

Unidade: millicores.

Memory

Integer

Yes

Yes

A memória necessária para cada instância. Apenas especificações predefinidas são aceitas.

Há correspondência de um para um com o CPU. Atualmente, apenas as seguintes especificações são suportadas:

  • 1024: corresponde a 500 millicores de CPU.

  • 2048: corresponde a 500 e 1000 millicores de CPU.

  • 4096: corresponde a 1000 e 2000 millicores de CPU.

  • 8192: corresponde a 2000 e 4000 millicores de CPU.

  • 16384: corresponde a 4000 e 8000 millicores de CPU.

  • 32768: corresponde a 16000 millicores de CPU.

  • 65536: corresponde a 8000, 16000 e 32000 millicores de CPU.

  • 131072: corresponde a 32000 millicores de CPU.

Unidade: MB.

NamespaceId

String

Yes

No

O ID do namespace do EDAS.

Apenas namespaces cujos nomes contêm letras minúsculas e hifens (-) são aceitos. O nome deve começar com uma letra minúscula.

PackageType

String

Yes

No

O tipo de pacote da aplicação.

Valores válidos:

  • FatJar

  • War

  • Image

Replicas

Integer

Yes

No

O número inicial de instâncias.

None

AcrAssumeRoleArn

String

No

No

O Alibaba Cloud Resource Name (ARN) da função RAM necessária para efetuar pull de imagens entre contas.

Para mais informações, consulte Grant permissions to a RAM role.

AcrInstanceId

String

No

Yes

O ID da instância ACR Enterprise.

None

AppDescription

String

No

No

A descrição da aplicação.

A descrição pode ter até 1024 caracteres.

AppSource

String

No

No

A aplicação de microsserviço.

Valores válidos:

  • micro_service

AssociateEip

Boolean

No

No

Especifica se um EIP deve ser vinculado.

Valores válidos:

  • true: Vincula um EIP.

  • false: Não vincula um EIP.

AutoConfig

Boolean

No

No

Especifica se o ambiente de rede deve ser configurado automaticamente.

Valores válidos:

  • true: O SAE configura automaticamente o ambiente de rede ao criar a aplicação. Os valores de NamespaceId, VpcId, vSwitchId e SecurityGroupId são ignorados.

  • false: Configure manualmente o ambiente de rede ao criar a aplicação no SAE.

Nota

Ao definir este parâmetro como true, os demais valores de NamespaceId informados são ignorados.

BaseAppId

String

No

No

O ID da aplicação base.

None

Command

String

No

Yes

O comando de inicialização da imagem.

O comando deve ser um objeto executável que exista no container. Por exemplo, sleep.

Definir este comando substitui o comando de inicialização original da imagem.

CommandArgs

String

No

Yes

Os parâmetros do comando de inicialização da imagem.

None

ConfigMapMountDesc

String

No

No

A descrição da montagem do ConfigMap.

Use os itens de configuração criados na página Configurations do namespace para injetar informações de configuração no container. Os parâmetros são descritos a seguir:

  • configMapId: O ID da instância do ConfigMap.

  • key: A chave.

  • mountPath: O caminho de montagem.

Nota

Passe o parâmetro sae-sys-configmap-all para montar todas as chaves.

CustomHostAlias

String

No

Yes

O mapeamento de host personalizado no container.

O mapeamento de host personalizado no container. O formato é [{"hostName":"samplehost","ip":"127.0.XX.XX"}] .

  • hostName: O nome de domínio ou hostname.

  • ip: O endereço IP.

Deploy

Boolean

No

No

Especifica se a aplicação deve ser implantada imediatamente.

Valores válidos:

  • true: Implanta imediatamente.

  • false (padrão): Não implanta imediatamente.

EdasContainerVersion

String

No

Yes

O ambiente de execução usado pela aplicação EDAS Pandora.

None

EnableEbpf

String

No

No

Ativa o monitoramento de aplicações não Java com base na tecnologia eBPF.

Valores válidos:

  • true: Ativar.

  • false: Desativar. Este é o valor padrão.

EnableNewArms

Boolean

No

No

Especifica se o novo recurso Arms deve ser ativado.

Valores válidos:

  • true: Ativar

  • false: Desativar

EnableSidecarResourceIsolated

Boolean

No

Yes

Especifica se o isolamento de recursos deve ser ativado para o container sidecar.

Valores válidos:

  • true: Isola os recursos.

  • false: Não isola os recursos.

Envs

String

No

Yes

As variáveis de ambiente do container.

O formato do parâmetro de variável de ambiente do container é: [{"name":"envtmp","value":"0"}].

  • name: O nome da variável de ambiente.

  • value: O valor da variável de ambiente ou uma referência a uma variável de ambiente.

ImagePullSecrets

String

No

No

O ID do secret correspondente.

None

ImageUrl

String

No

Yes

O endereço da imagem.

O endereço de imagem só pode ser configurado para aplicações do tipo Image.

InitContainersConfig

List

No

Yes

A lista de configurações de init container.

Para mais informações, consulte InitContainersConfig properties.

JarStartArgs

String

No

Yes

Os parâmetros para iniciar a aplicação em um pacote JAR.

O comando de inicialização padrão da aplicação é $JAVA_HOME/bin/java $JarStartOptions -jar $CATALINA_OPTS "$package_path" $JarStartArgs.

JarStartOptions

String

No

Yes

As opções para iniciar a aplicação em um pacote JAR.

O comando de inicialização padrão da aplicação é $JAVA_HOME/bin/java $JarStartOptions -jar $CATALINA_OPTS "$package_path" $JarStartArgs.

Jdk

String

No

Yes

A versão do JDK da qual o pacote de implantação depende.

A imagem não suporta este parâmetro.

KafkaConfigs

String

No

No

O resumo das configurações para coleta de logs no Kafka.

Os parâmetros são descritos a seguir:

  • kafkaEndpoint: O endpoint de service da API do Kafka.

  • kafkaInstanceId: O ID da instância do Kafka.

  • kafkaConfigs: O resumo das configurações de um ou mais logs. Para mais informações sobre os valores válidos, consulte o parâmetro de requisição KafkaConfigs neste tópico.

Liveness

String

No

Yes

A verificação de integridade do container. Um container que falha na verificação é reiniciado.

Apenas comandos executados no container são suportados. Exemplo: {"exec":{"command":["sleep","5s"]},"initialDelaySeconds":10,"timeoutSeconds":11}.

MicroRegistration

String

No

No

Selecione o registro de service Nacos.

Valores válidos:

  • 0: Nacos integrado ao SAE.

  • 1: Nacos criado pelo usuário.

  • 2: MSE Commercial Nacos.

MicroRegistrationConfig

String

No

No

As informações de configuração do registro de service.

None

MountDesc

String

No

Yes

A descrição de montagem.

None

MountHost

String

No

Yes

O destino de montagem do sistema de arquivos NAS no VPC.

None

NasConfigs

String

No

No

As configurações para montar um sistema de arquivos NAS.

Os parâmetros são descritos a seguir:

  • mountPath: O caminho de montagem no container.

  • readOnly: Se o valor for false, você terá permissões de leitura e escrita.

  • nasId: O ID do NAS.

  • mountDomain: O endereço do destino de montagem no container. Para mais informações, consulte DescribeMountTargets.

  • nasPath: O caminho relativo do arquivo NAS.

NasId

String

No

Yes

O ID do sistema de arquivos NAS montado.

O sistema de arquivos NAS deve ter uma cota de destino de montagem disponível, ou seu destino de montagem deve estar em um vSwitch no VPC. Se você não especificar este parâmetro, mas especificar o parâmetro MountDesc, um sistema de arquivos NAS será automaticamente adquirido e montado no vSwitch do VPC.

NewSaeVersion

String

No

No

A nova versão do SAE.

Valores válidos:

  • lite

  • std

  • pro

OssAkId

String

No

No

O AccessKey ID para operações de leitura e escrita no OSS.

None

OssAkSecret

String

No

No

O AccessKey secret para operações de leitura e escrita no OSS.

None

OssMountDescs

List

No

No

A descrição da montagem do OSS.

Os parâmetros são descritos a seguir:

  • bucketName: O nome do bucket.

  • bucketPath: O diretório ou objeto OSS criado no OSS. Se o diretório de montagem do OSS não existir, uma exceção será gerada.

  • mountPath: O caminho do container no SAE. Se o caminho existir, ele será substituído. Se não existir, será criado.

  • readOnly: Especifica se o caminho do container tem permissão somente leitura para os recursos do diretório montado. Valores válidos:

    • true: Permissão somente leitura.

    • false: Permissões de leitura e escrita.

PackageUrl

String

No

Yes

O endereço do pacote de implantação.

Este parâmetro é válido quando PackageType está definido como War ou FatJar.

PackageVersion

String

No

Yes

O número de versão do pacote implantado.

Este parâmetro é obrigatório quando PackageType está definido como War ou FatJar.

Php

String

No

No

A versão do PHP da qual o pacote de implantação PHP depende.

None.

PhpArmsConfigLocation

String

No

No

O caminho de montagem para monitoramento de aplicações PHP. Certifique-se de que o servidor PHP carregue o arquivo de configuração a partir deste caminho.

Não é necessário se preocupar com o conteúdo da configuração. O SAE renderiza automaticamente o arquivo de configuração correto.

PhpConfig

String

No

No

O conteúdo do arquivo de configuração PHP.

None

PhpConfigLocation

String

No

No

O caminho de montagem para a configuração de inicialização da aplicação PHP.

Certifique-se de que o servidor PHP seja iniciado usando este arquivo de configuração.

PostStart

String

No

Yes

O script a executar após a inicialização do container.

O script a executar após a inicialização do container. Exemplo: {"exec":{"command":"cat","/etc/group"}}.

PreStop

String

No

Yes

O script a executar antes da exclusão do container.

O script a executar antes da exclusão do container. Exemplo: {"exec":{"command":"cat","/etc/group"}}.

ProgrammingLanguage

String

No

No

A linguagem de programação da stack de tecnologia da aplicação.

Valores válidos:

  • java: Linguagem Java.

  • php: Linguagem PHP.

  • other: Múltiplas linguagens, como Python, C++, Go e Node.js.

PvtzDiscoverySvc

String

No

No

Ativa o registro e a descoberta de service K8s.

Os parâmetros são descritos a seguir:

  • serviceName: O nome do service. O formato é Custom-Namespace ID. O sufixo -Namespace ID não pode ser personalizado. Especifique o sufixo com base no namespace da aplicação. Por exemplo, ao selecionar o namespace padrão na região China (Beijing), o sufixo é -cn-beijing-default.

  • namespaceId: O ID do namespace.

  • portProtocols: As portas e os protocolos. O número da porta deve estar no intervalo [1, 65535]. Os protocolos suportados são TCP e UDP.

  • portAndProtocol: A porta e o protocolo. O número da porta deve estar no intervalo [1, 65535]. Os protocolos suportados são TCP e UDP. O parâmetro portProtocols é recomendado. Ao definir portProtocols, somente portProtocols tem efeito.

  • enable: Ativa o registro e a descoberta de service K8s.

Python

String

No

No

O ambiente Python.

PYTHON 3.9.15 é suportado.

PythonModules

String

No

No

Dependências de módulos para instalação personalizada.

Por padrão, as dependências definidas no arquivo requirements.txt no diretório raiz são instaladas. Se não houver configuração ou pacote de software personalizado disponível, especifique as dependências a serem instaladas.

Readiness

String

No

Yes

O script de verificação do status de inicialização da aplicação.

O script de verificação do status de inicialização da aplicação. Exemplo: {"exec":{"command":["sleep","6s"]},"initialDelaySeconds":15,"timeoutSeconds":12}.

Um container que falha na verificação de integridade múltiplas vezes é reiniciado. Nenhum tráfego do Server Load Balancer (SLB) é roteado para um container que falha na verificação de integridade.

SaeVersion

String

No

No

A versão do SAE.

Versões suportadas:

  • v1

  • v2

SecurityGroupId

String

No

No

O ID do grupo de segurança.

None

ServiceTags

String

No

No

As tags de canary configuradas para a aplicação.

None

SidecarContainersConfig

List

No

Yes

A lista de informações de configuração do container.

Para mais informações, consulte SidecarContainersConfig properties.

SlsConfigs

String

No

Yes

A configuração para coleta de log de arquivo.

None

Tags

List

No

Yes

As tags.

O máximo de 20 tags é suportado.

Para mais informações, consulte Tags syntax e Tags properties.

TerminationGracePeriodSeconds

Integer

No

No

O período de tempo limite para encerramento gracioso.

O valor padrão é 30. Unidade: segundos. Valores válidos: 1 a 300.

Timezone

String

No

Yes

O fuso horário.

Valor padrão: Asia/Shanghai.

TomcatConfig

String

No

No

A configuração do arquivo Tomcat.

Defina o valor como "" ou "{}" para excluir a configuração:

  • port: O número da porta. Valores válidos: 1024 a 65535. Portas menores que 1024 exigem permissões de root. Como o container é configurado com permissões de administrador, especifique um número de porta maior que 1024. Se este parâmetro não for configurado, a porta padrão 8080 é utilizada.

  • contextPath: O caminho de acesso. O valor padrão é o diretório raiz "/".

  • maxThreads: O número máximo de conexões no pool de conexões. O valor padrão é 400.

  • uriEncoding: O formato de codificação do Tomcat, incluindo UTF-8, ISO-8859-1, GBK e GB2312. Se este parâmetro não for definido, o valor padrão ISO-8859-1 é utilizado.

  • useBodyEncodingForUri: Especifica se deve ser usado BodyEncoding for URL. O valor padrão é true.

VpcId

String

No

No

O VPC correspondente ao namespace do SAE.

No SAE, um namespace pode ser vinculado a apenas um VPC, e esse vínculo não pode ser alterado. Ele é criado quando você cria a primeira aplicação SAE no namespace. Múltiplos namespaces podem ser vinculados ao mesmo VPC. Se este parâmetro não for especificado, o VPC vinculado ao namespace é utilizado.

VSwitchId

String

No

No

O vSwitch ao qual a interface de rede elástica (ENI) da instância da aplicação está conectada.

O vSwitch deve estar no VPC especificado e está vinculado ao namespace do EDAS. Se este parâmetro não for especificado, o vSwitch vinculado ao namespace é utilizado.

WarStartOptions

String

No

Yes

As opções para iniciar a aplicação em um pacote WAR.

O comando de inicialização padrão da aplicação é java $JAVA_OPTS $CATALINA_OPTS -Options org.apache.catalina.startup.Bootstrap "$@" start.

WebContainer

String

No

Yes

A versão do Tomcat da qual o pacote de implantação depende.

A imagem não suporta este parâmetro.

Sintaxe de SidecarContainersConfig

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

Propriedades de SidecarContainersConfig

Property

Type

Required

Editable

Description

Constraints

Cpu

Integer

Yes

Yes

O número de núcleos de CPU a serem alocados para o sidecar container.

None

Memory

Integer

Yes

Yes

A quantidade de memória a ser alocada para o sidecar container.

None

Name

String

Yes

Yes

O nome do sidecar container.

None

AcrInstanceId

String

No

Yes

O ID da instância ACR.

None

Command

String

No

Yes

O comando a ser executado no init container.

None

CommandArgs

String

No

Yes

Os parâmetros do comando a ser executado no init container.

None

ConfigMapMountDesc

String

No

Yes

A descrição de montagem do ConfigMap.

None

EmptyDirDesc

String

No

Yes

A descrição de montagem EMPTYDIR.

None

Envs

String

No

Yes

As variáveis de ambiente do container.

Exemplo:

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

ImageUrl

String

No

Yes

O endereço da imagem.

É possível configure um endereço de imagem somente para aplicações do tipo Image.

Sintaxe de InitContainersConfig

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

Propriedades de InitContainersConfig

Property

Type

Required

Editable

Description

Constraints

Name

String

Yes

Yes

O nome do init container.

None

Command

String

No

Yes

O comando a ser executado no init container.

None

CommandArgs

String

No

Yes

Os parâmetros do comando a ser executado no init container.

None

ConfigMapMountDesc

String

No

No

A descrição de montagem do ConfigMap.

None

Envs

String

No

Yes

As variáveis de ambiente do container.

Exemplo:

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

ImageUrl

String

No

Yes

O endereço da imagem.

É possível configure um endereço de imagem somente para aplicações do tipo Image.

Sintaxe de Tags

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

Propriedades de Tags

Property

Type

Required

Editable

Description

Constraints

Key

String

Yes

No

A chave da tag.

O comprimento da chave da tag deve ser de 1 a 128 caracteres. Não pode começar com aliyun ou acs:, e não pode conter http:// ou https://.

Value

String

No

No

O valor da tag.

O comprimento do valor da tag deve ser de 0 a 128 caracteres. Não pode começar com aliyun ou acs:, e não pode conter http:// ou https://.

Valores de retorno

Fn::GetAtt

  • AppId: O ID da aplicação.

  • ChangeOrderId: O ID da ordem de alteração. Use este ID para consultar o status de execução da tarefa.

Exemplos

Cenário 1: Crie uma aplicação SAE

Criar agora

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": {
  }
}

Cenário 2: Crie uma aplicação SAE e um namespace, e vincule uma instância SLB

Criar agora

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

Cenário 3: Implante uma plataforma Dify de produção usando SAE

Criar agora

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

Para mais exemplos, consulte Modelos públicos que contêm este recurso.