使用Terraform管理SAE应用

Serverless 应用引擎 SAE(Serverless App Engine)是面向应用的Serverless PaaS平台,向上抽象了应用的概念。将应用部署至SAE后,您无需管理和维护集群与服务器,可以专注于设计和构建应用程序,将其部署在SAE。除通过控制台、API、插件、CI/CD部署外,您还可以通过Terraform来部署SAE应用。本文介绍如何通过Terraform自动创建、自定义创建以及删除SAE应用。

前提条件

  • 安装Terraform。支持Terraform 0.13及以上版本。
  • 配置阿里云账号信息。

    选择一种阿里云认证方式,为Terraform的执行提供认证信息。本文以环境变量认证方式为例:

    export ALICLOUD_ACCESS_KEY="************"
    export ALICLOUD_SECRET_KEY="************"
    export ALICLOUD_REGION="cn-hangzhou"
    说明 为保障数据安全性,建议您按需为RAM用户授予SAE资源的操作权限。具体操作,请参见为RAM用户授权

背景信息

Terraform的alicloud_sae_application资源提供一系列参数来管理SAE应用。本文通过介绍创建和删除应用的多种方式,说明部分参数的用法,展示如何通过Terraform管理云资源。更多信息,请参见alicloud_sae_application

说明

目前不支持通过Terraform更新应用。

创建应用

SAE支持镜像部署和代码包部署。其中代码包支持JAR包、WAR包和PHP ZIP包。创建应用时,您可以按需选择以下方式配置专有网络:

  • 自动配置:SAE将自动帮您配置命名空间、VPC、vSwitch及安全组等。命名空间为默认命名空间。

  • 自定义配置:您需要为创建的应用配置所需的命名空间、VPC、vSwitch及安全组等。

自动配置

本示例以在华东1(杭州)地域下创建应用为例,介绍如何通过镜像方式自动部署应用。

  1. 创建一个用于存放Terraform资源的项目文件夹,命名为terraform
  2. 执行以下命令,进入项目目录。
    cd terraform
  3. 创建名为main.tf的配置文件。内容如下。

    terraform {
      required_providers {
        alicloud = {
          source  = "hashicorp/alicloud"
          version = "1.156.0"
        }
      }
    }
    
    resource "alicloud_sae_application" "auto" {
      count           = 1
      app_name        = var.app_name
      app_description = var.app_description
      auto_config     = true 
      image_url       = var.image_url
      package_type    = var.package_type
      timezone        = "Asia/Beijing"
      replicas        = var.replicas
      cpu             = var.cpu
      memory          = var.memory
    }
    
    # 应用名称
    variable "app_name" {
      description = "The name of the application"
      type        = string
    }
    
    # 应用描述
    variable "app_description" {
      default     = "description created by Terraform"
      description = "The description of the application"
      type        = string
    }
    
    # 应用部署类型
    variable "package_type" {
      default     = "Image"
      description = "The package type of the application"
      type        = string
    }
    
    # 实例CPU规格
    variable "cpu" {
      default     = "500"
      description = "The cpu of the application, in unit of millicore"
      type        = string
    }
    
    # 实例内存规格
    variable "memory" {
      default     = "1024"
      description = "The memory of the application, in unit of MB"
      type        = string
    }
    
    # 镜像地址
    variable "image_url" {
      description = "The image url of the application, like `registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-slim:0.9`"
      type        = string
    }
    
    # 应用实例数
    variable "replicas" {
      default     = "1"
      description = "The replicas of the application"
      type        = string
    }
    
    output "app_id" {
      description = "The id of the application"
      value       = alicloud_sae_application.auto.0.id
    }
    
    output "app_name" {
      description = "The name of the application"
      value       = var.app_name
    }
  4. 执行以下命令,初始化配置。
    terraform init
  5. 依次执行以下命令,创建SAE应用。

    1. 执行以下命令,执行配置文件。

      terraform apply
    2. 根据提示依次输入应用的各项信息。

      • app_name:应用名称。输入auto-app-1

      • image_url:镜像地址。输入registry.cn-hangzhou.aliyuncs.com/****/****:01

        您可以登录容器镜像服务控制台,在目标实例仓库的基本信息页面查看镜像地址。格式如下:

        registry.<regionId>.aliyuncs.com/<命令空间名称>/<镜像仓库名称>:<镜像版本号>

      预期输出:

      ...
      
      Plan: 1 to add, 0 to change, 0 to destroy.
      
      Changes to Outputs:
        + app_id   = (known after apply)
        + app_name = "auto-app-1"
      alicloud_sae_application.auto[0]: Creating...
      ...
      alicloud_sae_application.auto[0]: Creation complete after 59s [id=f8e2f217-8788-41e0-85d1-ce96105b****]
      
      Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
      
      Outputs:
      
      app_id = "f8e2f217-8788-41e0-85d1-ce96105b****"
      app_name = "auto-app-1"

    如果输出代码符合预期输出,说明已成功创建以镜像部署的应用。

自定义配置:镜像部署

本示例以在华东1(杭州)地域下创建应用为例,介绍如何通过镜像方式自定义部署应用。

  1. 创建一个用于存放Terraform资源的项目文件夹,命名为terraform
  2. 执行以下命令,进入项目目录。
    cd terraform
  3. 创建名为main.tf的配置文件。内容如下。

    terraform {
      required_providers {
        alicloud = {
          source  = "hashicorp/alicloud"
          version = "~> 1.163.0"
        }
      }
    }
    
    # 命名空间信息
    resource "alicloud_sae_namespace" "default" {
      namespace_description = var.namespace_description
      namespace_id          = var.namespace_id
      namespace_name        = var.namespace_name
    }
    
    # 命名空间描述
    variable "namespace_description" {
      description = "Namespace Description"
      default     = "a namespace"
    }
    # 命名空间名称
    variable "namespace_name" {
      description = "Namespace Name"
      type = string
    }
    # 命名空间ID
    variable "namespace_id" {
      description = "Namespace ID"
      type = string
    }
    
    output "namespace_id" {
      value = var.namespace_id
      description = "Namespace ID"
    }
    
    # VPC和安全组
    resource "alicloud_security_group" "sg" {
      name        = var.name
      description = var.description
      vpc_id      = module.vpc.VPC_ID
    }
    
    resource "alicloud_security_group_rule" "sg_rule" {
      type              = "ingress"
      ip_protocol       = "tcp"
      nic_type          = "intranet"
      policy            = "accept"
      port_range        = var.port_range
      priority          = 1
      security_group_id = alicloud_security_group.sg.id
      cidr_ip           = var.cidr_ip
    }
    
    module "vpc" {
      source  = "git::github.com/kubevela-contrib/terraform-modules.git//alibaba/vswitch"
      zone_id = var.zone_id
    }
    
    variable "name" {
      default     = "tf"
      description = "The name of the security group rule"
      type        = string
    }
    
    variable "description" {
      default     = "The description of the security group rule"
      description = "The description of the security group rule"
      type        = string
    }
    
    # 端口范围
    variable "port_range" {
      default     = "1/65535"
      description = "The port range of the security group rule"
      type        = string
    }
    
    # CIDR地址
    variable "cidr_ip" {
      description = "cidr blocks used to create a new security group rule"
      type        = string
      default     = "0.0.0.0/0"
    }
    
    # 地域内可用区
    variable "zone_id" {
      description = "Availability Zone ID"
      type        = string
      default     = "cn-hongkong-b"
    }
    
    resource "alicloud_sae_application" "manual" {
      app_name          = var.app_name
      app_description   = var.app_description
      deploy            = true
      image_url         = var.image_url
      namespace_id      = alicloud_sae_namespace.default.id
      vswitch_id        = module.vpc.VSWITCH_ID
      vpc_id            = module.vpc.VPC_ID
      security_group_id = alicloud_security_group.sg.id
      package_type      = var.package_type
      timezone          = "Asia/Beijing"
      replicas          = var.replicas
      cpu               = var.cpu
      memory            = var.memory
    
    # 环境变量设置
      envs="[{'name':'envtmp','value':'0'},{'name':'envtmp2','value':'0'}]"
    # 自定义Host映射
      custom_host_alias = "[{hostName:'samplehost',ip:'127.0.0.1'},{'hostName':'example.com','ip':'128.0.X.X'}]"
    # 应用健康检查
      liveness = "{'httpGet':{'path':'/','port':80,'scheme':'HTTP'},'initialDelaySeconds':20,'periodSeconds':10,'timeoutSeconds':1}"
      readiness = "{'httpGet':{'path':'/','port':80,'scheme':'HTTP'},'initialDelaySeconds':20,'periodSeconds':10,'timeoutSeconds':1}"
    
    # 容器启动后执行脚本
      post_start ="{'exec':{'command':['sh','-c','echo hello > /tmp/hello.txt']}}"
    # 容器停止前执行脚本
      pre_stop = "{'exec':{'command':['sh','-c','echo hello']}}"
    # 优雅下线超时时间
      termination_grace_period_seconds = 50
    # 自动开启应用弹性策略
      auto_enable_application_scaling_rule = true
    # 最小存活实例数
      min_ready_instances = 1
    }
    # 应用日志采集到SLS
    variable "slsConfig" {
      default = "[{"logDir":"","logType":"stdout"},{"logDir":"/home/admin/logs/*.log"}]"
      description = "The config of sls log collect"
      type        = string
    }
    # 应用名称
    variable "app_name" {
      description = "The name of the application"
      type        = string
    }
    # 应用描述
    variable "app_description" {
      default     = "description created by Terraform"
      description = "The description of the application"
      type        = string
    }
    # 应用部署方式
    variable "package_type" {
      default     = "Image"
      description = "The package type of the application"
      type        = string
    }
    
    # 实例CPU规格
    variable "cpu" {
      default     = "500"
      description = "The cpu of the application, in unit of millicore"
      type        = string
    }
    # 实例内存规格
    variable "memory" {
      default     = "1024"
      description = "The memory of the application, in unit of MB"
      type        = string
    }
    # 镜像地址
    variable "image_url" {
      description = "The image url of the application, like `registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-slim:0.9`"
      type        = string
    }
    # 应用实例数
    variable "replicas" {
      default     = "1"
      description = "The replicas of the application"
      type        = string
    }
    
    output "app_id" {
      description = "The id of the application"
      value       = alicloud_sae_application.manual.id
    }
    
    output "app_name" {
      description = "The name of the application"
      value       = var.app_name
    }
  4. 执行以下命令,初始化配置。
    terraform init
  5. 依次执行以下命令,以镜像方式创建应用。

    1. 执行以下命令,部署应用。

      terraform apply
    2. 根据提示依次输入应用的各项信息。

      • app_name:应用名称。输入manual-image

      • namespace_name:命名空间名称。输入demo

      • namespace_id:命名空间ID。输入cn-hangzhou:demo

      • image_url:镜像地址。输入registry.cn-hangzhou.aliyuncs.com/****/****:01

        您可以登录容器镜像服务控制台,在目标实例仓库的基本信息页面查看镜像地址。格式如下:

        registry.<regionId>.aliyuncs.com/<命令空间名称>/<镜像仓库名称>:<镜像版本号>

      预期输出:

      ...
      
      Plan: 6 to add, 0 to change, 0 to destroy.
      
      Changes to Outputs:
        + app_id       = (known after apply)
        + app_name     = "manual-image"
        + namespace_id = "cn-hangzhou:demo"
      alicloud_sae_namespace.default: Creating...
      ...
      alicloud_sae_application.manual: Creation complete after 1m58s [id=af34c033-fc5a-4147-8baf-87c71d3a****]
      
      Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
      
      Outputs:
      
      app_id = "af34c033-fc5a-4147-8baf-87c71d3a****"
      app_name = "manual-image"
      namespace_id = "cn-hangzhou:demo"

    如果输出代码符合预期输出,说明已成功创建以镜像部署的应用。

自定义配置:JAR包部署

本示例以在华东1(杭州)地域下创建应用为例,介绍如何通过JAR包方式自定义部署应用。

  1. 创建一个用于存放Terraform资源的项目文件夹,命名为terraform
  2. 执行以下命令,进入项目目录。
    cd terraform
  3. 创建名为main.tf的配置文件。内容如下。

    terraform {
      required_providers {
        alicloud = {
          source  = "hashicorp/alicloud"
          version = "~> 1.163.0"
        }
      }
    }
    
    # 命名空间
    resource "alicloud_sae_namespace" "default" {
      namespace_description = var.namespace_description
      namespace_id          = var.namespace_id
      namespace_name        = var.namespace_name
    }
    
    # 命名空间描述
    variable "namespace_description" {
      description = "Namespace Description"
      default     = "a namespace"
    }
    
    # 命名空间名称
    variable "namespace_name" {
      description = "Namespace Name"
      type = string
    }
    # 命名空间ID
    variable "namespace_id" {
      description = "Namespace ID"
      type = string
    }
    
    
    output "namespace_id" {
      value = var.namespace_id
      description = "Namespace ID"
    }
    
    # VPC和安全组
    resource "alicloud_security_group" "sg" {
      name        = var.name
      description = var.description
      vpc_id      = module.vpc.VPC_ID
    }
    
    resource "alicloud_security_group_rule" "sg_rule" {
      type              = "ingress"
      ip_protocol       = "tcp"
      nic_type          = "intranet"
      policy            = "accept"
      port_range        = var.port_range
      priority          = 1
      security_group_id = alicloud_security_group.sg.id
      cidr_ip           = var.cidr_ip
    }
    
    module "vpc" {
      source  = "git::github.com/kubevela-contrib/terraform-modules.git//alibaba/vswitch"
      zone_id = var.zone_id
    }
    
    variable "name" {
      default     = "tf"
      description = "The name of the security group rule"
      type        = string
    }
    
    variable "description" {
      default     = "The description of the security group rule"
      description = "The description of the security group rule"
      type        = string
    }
    # 端口范围
    variable "port_range" {
      default     = "1/65535"
      description = "The port range of the security group rule"
      type        = string
    }
    # 安全组IP地址
    variable "cidr_ip" {
      description = "cidr blocks used to create a new security group rule"
      type        = string
      default     = "0.0.0.0/0"
    }
    # 地域内可用区
    variable "zone_id" {
      description = "Availability Zone ID"
      type        = string
      default     = "cn-hongkong-b"
    }
    
    resource "alicloud_sae_application" "manual" {
      app_name          = var.app_name
      app_description   = var.app_description
      deploy            = true
    
      package_version = "12132111"
      package_url     = "https://****.oss-ap-southeast-1.aliyuncs.com/javacommon-0.0.1-SNAPSHOT.jar"
      jdk             = "Open JDK 8"
    
      namespace_id      = alicloud_sae_namespace.default.id
      vswitch_id        = module.vpc.VSWITCH_ID
      vpc_id            = module.vpc.VPC_ID
      security_group_id = alicloud_security_group.sg.id
      package_type      = var.package_type
      timezone          = "Asia/Beijing"
      replicas          = var.replicas
      cpu               = var.cpu
      memory            = var.memory
    }
    # 应用名称
    variable "app_name" {
      description = "The name of the application"
      type        = string
    }
    # 应用描述
    variable "app_description" {
      default     = "description created by Terraform"
      description = "The description of the application"
      type        = string
    }
    # 应用部署方式
    variable "package_type" {
      default     = "FatJar"
      description = "The package type of the application"
      type        = string
    }
    # 实例CPU规格
    variable "cpu" {
      default     = "500"
      description = "The cpu of the application, in unit of millicore"
      type        = string
    }
    # 实例内存规格
    variable "memory" {
      default     = "1024"
      description = "The memory of the application, in unit of MB"
      type        = string
    }
    
    # 应用实例数
    variable "replicas" {
      default     = "1"
      description = "The replicas of the application"
      type        = string
    }
    
    output "app_id" {
      description = "The id of the application"
      value       = alicloud_sae_application.manual.id
    }
    
    output "app_name" {
      description = "The name of the application"
      value       = var.app_name
    }
                            
  4. 执行以下命令,初始化配置。
    terraform init
  5. 依次执行以下命令,以JAR包方式创建应用。

    1. 执行以下命令,部署应用。

      terraform apply
    2. 根据提示依次输入应用的各项信息。

      • app_name:应用名称。输入manual-jar

      • namespace_name:命名空间名称。输入demo

      • namespace_id:命名空间ID。输入cn-hangzhou:demo

      预期输出:

      Plan: 6 to add, 0 to change, 0 to destroy.
      
      Changes to Outputs:
        + app_id       = (known after apply)
        + app_name     = "manual-jar"
        + namespace_id = "cn-hangzhou:demo"
      alicloud_sae_namespace.default: Creating...
      ...
      alicloud_sae_application.manual: Creation complete after 1m46s [id=724b681e-e9e4-4891-b426-f16d7b78****]
      
      Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
      
      Outputs:
      
      app_id = "724b681e-e9e4-4891-b426-f16d7b78****"
      app_name = "manual-jar"
      namespace_id = "cn-hangzhou:demo"

    如果输出代码符合预期输出,说明已成功创建以JAR包部署的应用。

删除应用

本文以在华东1(杭州)地域下自动创建的应用auto-app-1为例,介绍如何删除应用。

  1. 在目标项目目录内执行以下命令,运行配置文件。
    terraform destroy
  2. 根据提示依次输入应用的各项信息,删除应用。

    • app_name:输入auto-app-1

    • image_url:输入registry.cn-hangzhou.aliyuncs.com/****/****:01

      镜像地址格式如下:

      registry.<regionId>.aliyuncs.com/<命令空间名称>/<镜像仓库名称>:<镜像版本号>

      您可以登录容器镜像服务控制台,在目标实例仓库的基本信息页面,查看镜像地址。

    预期输出:

    alicloud_sae_application.auto[0]: Refreshing state... [id=599a843b-f11d-456e-b934-dc9fdf99****]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      - destroy
    
    Terraform will perform the following actions:
    
      # alicloud_sae_application.auto[0] will be destroyed
      - resource "alicloud_sae_application" "auto" {
          - app_description                  = "description created by Terraform" -> null
          - app_name                         = "auto-app-1" -> null
    ...
        }
    
    Plan: 0 to add, 0 to change, 1 to destroy.
    
    Changes to Outputs:
      - app_id   = "599a843b-f11d-456e-b934-dc9fdf99****" -> null
      - app_name = "auto-app-1" -> null
    alicloud_sae_application.auto[0]: Destroying... [id=599a843b-f11d-456e-b934-dc9fdf99****]
    alicloud_sae_application.auto[0]: Destruction complete after 5s
    
    Destroy complete! Resources: 1 destroyed.

    如果输出代码符合预期输出,说明已成功删除应用auto-app-1

更多信息