使用Terraform管理ASM实例

Terraform是HashiCorp公司提供的一种开源的云上资源编排工具,用于安全高效地预览,配置和管理云基础架构和资源,帮助开发者自动化地创建、更新阿里云基础设施资源。本文介绍如何使用Terraform创建和删除ASM实例。

前提条件

  • 已在本地安装和配置Terraform。具体操作,请参见在本地安装和配置Terraform

  • 已配置阿里云账号信息。创建环境变量,用于存放身份认证和地域信息。

    export ALICLOUD_ACCESS_KEY="************" #替换为您的AccessKey ID信息。
    export ALICLOUD_SECRET_KEY="************" #替换为您的AccessKey Secret信息。
    export ALICLOUD_REGION="cn-beijing"    #替换为您的地域ID。
    说明

    为提高权限管理的灵活性和安全性,建议您创建名为Terraform的RAM用户,并为该RAM用户创建AccessKey和授权。具体操作,请参见创建RAM用户为RAM用户授权

背景信息

关于Terraform的详细介绍,请参见terraform

创建ASM实例

  1. 在本地创建名为main.tf的配置文件。

    • 若您没有专有网络和虚拟交换机,您需要使用以下内容创建main.tf文件。

      terraform {
        required_providers {
          alicloud = {
            source = "aliyun/alicloud"
          }
        }
      }
      
      variable "k8s_name_prefix" {
        description = "The name prefix used to create Service Mesh (ASM)."
        default     = "tf-asm"
      }
      
      resource "random_uuid" "this" {}
      
      # 默认的资源名称及配置。
      locals {
        # 服务网格名称。
        mesh_name = substr(join("-", [var.k8s_name_prefix, random_uuid.this.result]), 0, 63)
        # 服务网格的规格,可以选择三种规格:standard: 标准版(免费),enterprise:企业版,ultimate:旗舰版。
        mesh_spec = "enterprise"
        # 专有网络名称。
        new_vpc_name = "vpc-for-${local.mesh_name}"
        # 虚拟交换机名称。
        new_vsw_name = "vsw-for-${local.mesh_name}"
      }
      
      # 可以创建虚拟交换机的AZ。
      data "alicloud_zones" "default" {
        available_resource_creation = "VSwitch"
      }
      # 专有网络。
      resource "alicloud_vpc" "default" {
        vpc_name = local.new_vpc_name
      }
      # 虚拟交换机。
      resource "alicloud_vswitch" "default" {
        vpc_id       = alicloud_vpc.default.id
        cidr_block   = cidrsubnet(alicloud_vpc.default.cidr_block, 8, 2)
        zone_id      = data.alicloud_zones.default.zones.0.id
        vswitch_name = local.new_vsw_name
      }
      # 查询可以创建的服务网格版本。
      data "alicloud_service_mesh_versions" "default" {
        edition = local.mesh_spec == "standard" ? "Default" : "Pro"
      }
      # 选择可创建的第一个版本作为创建新服务网格使用的版本。
      locals {
        mesh_version = split(":", data.alicloud_service_mesh_versions.default.ids[0])[1]
      }
      # 服务网格ASM实例。
      resource "alicloud_service_mesh_service_mesh" "default" {
        # 服务网格名称。
        service_mesh_name = local.mesh_name
        # 服务网格的网络配置。
        network {
          # 专有网络ID。
          vpc_id        = alicloud_vpc.default.id
          # 虚拟交换机ID。
          vswitche_list = [alicloud_vswitch.default.id]
        }
        # 服务网格的版本。
        version = local.mesh_version
        # 服务网格的API Server和Pilot负载均衡配置。
        load_balancer {
          # 是否使用eip暴露服务网格API Server负载均衡。
          api_server_public_eip = true
        }
      
        # 服务网格的实例配置Mesh Config。
        mesh_config {
          # 将访问日志采集到阿里云日志服务。
          access_log {
            enabled = true
          }
      
          # 启用控制面日志采集,需开通阿里云日志服务。
          control_plane_log {
            enabled = true
          }
      
          # 启用ARMS链路追踪。
          tracing = true
      
          # 如果启用链路追踪,设置采样百分比。
          pilot {
            trace_sampling = 100
          }
      
          # 开启采集Prometheus监控指标。
          telemetry = true
      
          # 启用网格拓扑(需要开启Prometheus)。
          kiali {
            enabled = true
          }
      
          # 启用网格审计,需要开通阿里云日志服务。
          audit {
            enabled = true
          }
        }
        # 服务网格的规格,可以选择三种规格:standard: 标准版(免费),enterprise:企业版,ultimate:旗舰版。
        cluster_spec = local.mesh_spec
      }

      在main.tf文件中根据实际情况自定义以下参数,其他参数值会使用OpenAPI自动拉取获取。

      参数

      描述

      mesh_name

      自定义服务网格名称。

      mesh_spec

      设置服务网格规格,可选:

      • standard:标准版(免费)。

      • enterprise:企业版。

      • ultimate:旗舰版。

      new_vpc_name

      自定义专有网络名称。

      new_vsw_name

      自定义虚拟交换机名称。

      api_server_public_eip

      是否使用EIP暴露服务网格API Server负载均衡,可选:

      • true:使用EIP暴露服务网格API Server负载均衡。

      • false:不使用EIP暴露服务网格API Server负载均衡。

    • 若您已有专有网络和虚拟交换机,您需要使用以下内容创建main.tf文件。

      重要

      专有网络、虚拟交换机需要和Terraform的身份认证信息处于同一地域,否则将识别不到专有网络和虚拟交换机。

      terraform {
        required_providers {
          alicloud = {
            source = "aliyun/alicloud"
          }
        }
      }
      
      variable "asm_name_prefix" {
        description = "The name prefix used to create Service Mesh (ASM)."
        default     = "tf-asm"
      }
      
      resource "random_uuid" "this" {}
      
      # 默认的资源名称及配置。
      locals {
        # 服务网格名称。
        mesh_name = substr(join("-", [var.asm_name_prefix, random_uuid.this.result]), 0, 63)
        # 服务网格的规格,可以选择三种规格:standard: 标准版(免费),enterprise:企业版,ultimate:旗舰版。
        mesh_spec = "enterprise"
        # 已有专有网络名称。
        vpc_name = "vpc-luying-hangzhou1"
        # 已有虚拟交换机名称。
        vsw_name = "vsw-luying-hangzhou1"
      }
      
      # 专有网络。
      data "alicloud_vpcs" "default" {
        name_regex = local.vpc_name # 已经存在的vpc名称。
      }
      # 虚拟交换机。
      data "alicloud_vswitches" "default" {
        vpc_id = data.alicloud_vpcs.default.ids[0]
      }
      locals {
        exist_vswitch_ids = [for vsw in data.alicloud_vswitches.default.vswitches : vsw.id if vsw.name == local.vsw_name]
      }
      # 查询可以创建的服务网格版本。
      data "alicloud_service_mesh_versions" "default" {
        edition = local.mesh_spec == "standard" ? "Default" : "Pro"
      }
      # 选择可创建的第一个版本作为创建新服务网格使用的版本。
      locals {
        mesh_version = split(":", data.alicloud_service_mesh_versions.default.ids[0])[1]
      }
      # 服务网格ASM实例。
      resource "alicloud_service_mesh_service_mesh" "default" {
        # 服务网格名称。
        service_mesh_name = local.mesh_name
        # 服务网格的网络配置。
        network {
          # 专有网络ID。
          vpc_id        =  data.alicloud_vpcs.default.ids[0]
          # 虚拟交换机ID。
          vswitche_list = [local.exist_vswitch_ids[0]]
        }
        # 服务网格的版本。
        version = local.mesh_version
        # 服务网格的API Server和Pilot负载均衡配置。
        load_balancer {
          # 是否使用eip暴露服务网格API Server负载均衡。
          api_server_public_eip = true
        }
      
        # 服务网格的实例配置Mesh Config。
        mesh_config {
          # 将访问日志采集到阿里云日志服务。
          access_log {
            enabled = true
          }
      
          # 启用控制面日志采集,需开通阿里云日志服务。
          control_plane_log {
            enabled = true
          }
      
          # 启用ARMS链路追踪。
          tracing = true
      
          # 如果启用链路追踪,设置采样百分比。
          pilot {
            trace_sampling = 100
          }
      
          # 开启采集Prometheus监控指标。
          telemetry = true
      
          # 启用网格拓扑(需要开启Prometheus)。
          kiali {
            enabled = true
          }
      
          # 启用网格审计,需要开通阿里云日志服务。
          audit {
            enabled = true
          }
        }
        # 服务网格的规格,可以选择三种规格:standard: 标准版(免费),enterprise:企业版,ultimate:旗舰版。
        cluster_spec = local.mesh_spec
      }

      在main.tf文件中根据实际情况自定义以下参数,其他参数值会使用OpenAPI自动拉取获取。

      参数

      描述

      mesh_name

      自定义服务网格名称。

      mesh_spec

      设置服务网格规格,可选:

      • standard:标准版(免费)。

      • enterprise:企业版。

      • ultimate:旗舰版。

      vpc_name

      输入已有专有网络名称。

      vsw_name

      输入已有虚拟交换机名称。

      api_server_public_eip

      是否使用EIP暴露服务网格API Server负载均衡,可选:

      • true:使用EIP暴露服务网格API Server负载均衡。

      • false:不使用EIP暴露服务网格API Server负载均衡。

  2. 执行以下命令,初始化Terraform运行环境。

    terraform init

    预期输出:

    Initializing the backend...
    
    Initializing provider plugins...
    - Finding aliyun/alicloud versions matching "1.166.0"...
    - Finding latest version of hashicorp/random...
    ...
    
    Terraform has been successfully initialized!
    
    You may now begin working with Terraform. Try running "terraform plan" to see
    any changes that are required for your infrastructure. All Terraform commands
    should now work.
    
    If you ever set or change modules or backend configuration for Terraform,
    rerun this command to reinitialize your working directory. If you forget, other
    commands will detect it and remind you to do so if necessary.
  3. 执行以下命令,生成Terraform资源规划。

    terraform plan

    预期输出:

    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      + create
    
    Terraform will perform the following actions:
    ...
    Plan: 2 to add, 0 to change, 0 to destroy.
  4. 执行以下命令,使用main.tf文件创建ASM实例。

    terraform apply

    预期输出:

    alicloud_service_mesh_service_mesh.example: Refreshing state...
    ...
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value:                    

    Enter a value参数右侧输入yes,预期返回以下内容:

    ...
    alicloud_service_mesh_service_mesh.default: Creating...
    alicloud_service_mesh_service_mesh.default: Still creating... [10s elapsed]
    ...
    alicloud_service_mesh_service_mesh.example: Creation complete after 2m42s [id=**********]
    
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

删除ASM实例

使用Terraform删除指定ASM实例时,您必须进入到与main.tf文件相同的目录下后,才能执行命令删除该实例。

进入与main.tf文件相同的目录下,执行以下命令,删除ASM实例。

terraform destroy

预期输出:

...
Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: 

Enter a value参数右侧输入yes,预期返回以下内容:

...
Destroy complete! Resources: 2 destroyed.

修改ASM实例属性

您可以通过修改tf文件中的属性定义,并执行terraform apply将变更应用到ASM实例,本文以修改http10_enabled属性为例,演示如何通过terraform修改ASM实例属性。

  1. 此处以“已有专有网络和虚拟交换机”场景的tf文件为例,修改服务网格资源的mesh_config.pilot.http10_enabledtrue

    terraform {
      required_providers {
        alicloud = {
          source = "aliyun/alicloud"
        }
      }
    }
    
    variable "asm_name_prefix" {
      description = "The name prefix used to create Service Mesh (ASM)."
      default     = "tf-asm"
    }
    
    resource "random_uuid" "this" {}
    
    # 默认的资源名称及配置。
    locals {
      # 服务网格名称。
      mesh_name = substr(join("-", [var.asm_name_prefix, random_uuid.this.result]), 0, 63)
      # 服务网格的规格,可以选择三种规格:standard: 标准版(免费),enterprise:企业版,ultimate:旗舰版。
      mesh_spec = "enterprise"
      # 已有专有网络名称。
      vpc_name = "prod-hz-vpc"
      # 已有虚拟交换机名称。
      vsw_name = "prod-hz-vpc-default"
    }
    
    # 专有网络。
    data "alicloud_vpcs" "default" {
      name_regex = local.vpc_name # 已经存在的vpc名称。
    }
    # 虚拟交换机。
    data "alicloud_vswitches" "default" {
      vpc_id = data.alicloud_vpcs.default.ids[0]
    }
    locals {
      exist_vswitch_ids = [for vsw in data.alicloud_vswitches.default.vswitches : vsw.id if vsw.name == local.vsw_name]
    }
    # 查询可以创建的服务网格版本。
    data "alicloud_service_mesh_versions" "default" {
      edition = local.mesh_spec == "standard" ? "Default" : "Pro"
    }
    # 选择可创建的第一个版本作为创建新服务网格使用的版本。
    locals {
      mesh_version = split(":", data.alicloud_service_mesh_versions.default.ids[0])[1]
    }
    # 服务网格ASM实例。
    resource "alicloud_service_mesh_service_mesh" "default" {
      # 服务网格名称。
      service_mesh_name = local.mesh_name
      # 服务网格的网络配置。
      network {
        # 专有网络ID。
        vpc_id        =  data.alicloud_vpcs.default.ids[0]
        # 虚拟交换机ID。
        vswitche_list = [local.exist_vswitch_ids[0]]
      }
      # 服务网格的版本。
      version = local.mesh_version
      # 服务网格的API Server和Pilot负载均衡配置。
      load_balancer {
        # 是否使用eip暴露服务网格API Server负载均衡。
        api_server_public_eip = true
      }
    
      # 服务网格的实例配置Mesh Config。
      mesh_config {
        # 将访问日志采集到阿里云日志服务。
        access_log {
          enabled = true
        }
    
        # 启用控制面日志采集,需开通阿里云日志服务。
        control_plane_log {
          enabled = true
          project = "mesh-log-cab09b566d4a64c1fa05271d5365495f1"
        }
    
        # 启用ARMS链路追踪。
        tracing = true
    
        # 如果启用链路追踪,设置采样百分比。
        pilot {
          trace_sampling = 100
          http10_enabled = true 
        }
    
        # 开启采集Prometheus监控指标。
        telemetry = true
    
        # 启用网格拓扑(需要开启Prometheus)。
        kiali {
          enabled = true
        }
    
        # 启用网格审计,需要开通阿里云日志服务。
        audit {
          enabled = true
        }
      }
      # 服务网格的规格,可以选择三种规格:standard: 标准版(免费),enterprise:企业版,ultimate:旗舰版。
      cluster_spec = local.mesh_spec
    }
    
  2. 执行terraform apply,观察到该字段发生变更,符合预期。

    terraform apply
    random_uuid.this: Refreshing state... [id=6ab24265-2381-dad9-3be5-351329c5665a]
    data.alicloud_vpcs.default: Reading...
    data.alicloud_service_mesh_versions.default: Reading...
    data.alicloud_service_mesh_versions.default: Read complete after 1s [id=605899410]
    data.alicloud_vpcs.default: Read complete after 1s [id=2909606812]
    data.alicloud_vswitches.default: Reading...
    data.alicloud_vswitches.default: Read complete after 0s [id=866499268]
    alicloud_service_mesh_service_mesh.default: Refreshing state... [id=cab09b566d4a64c1fa05271d5365495f1]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      ~ update in-place
    
    Terraform will perform the following actions:
    
      # alicloud_service_mesh_service_mesh.default will be updated in-place
      ~ resource "alicloud_service_mesh_service_mesh" "default" {
            id                = "cab09b566d4a64c1fa05271d5365495f1"
            # (6 unchanged attributes hidden)
    
          ~ mesh_config {
                # (5 unchanged attributes hidden)
    
              ~ pilot {
                  ~ http10_enabled = false -> true
                    # (1 unchanged attribute hidden)
                }
    
                # (7 unchanged blocks hidden)
            }
    
            # (2 unchanged blocks hidden)
        }
    
    Plan: 0 to add, 1 to change, 0 to destroy.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value:
  3. 输入yes应用变更

    ......省略无关内容......
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    alicloud_service_mesh_service_mesh.default: Modifying... [id=cab09b566d4a64c1fa05271d5365495f1]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=cab09b566d4a64c1fa05271d5365495f1, 10s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=cab09b566d4a64c1fa05271d5365495f1, 20s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=cab09b566d4a64c1fa05271d5365495f1, 30s elapsed]
    alicloud_service_mesh_service_mesh.default: Modifications complete after 37s [id=cab09b566d4a64c1fa05271d5365495f1]

添加或移除Kubernetes集群

您可以通过修改tf文件中的cluster_ids数组,将希望加入ASM管理的集群ID追加至数组,将希望从ASM移除的集群ID从数组中移除,并执行terraform apply将变更应用到ASM实例。

  1. 此处以添加集群一个集群到asm为例,修改服务网格资源的cluster_ids,在数组种追加集群ID:

    ......省略无关内容......
    # 服务网格ASM实例。
    resource "alicloud_service_mesh_service_mesh" "default" {
      # 服务网格名称。
      service_mesh_name = local.mesh_name
      # 服务网格的网络配置。
      network {
        # 专有网络ID。
        vpc_id        =  data.alicloud_vpcs.default.ids[0]
        # 虚拟交换机ID。
        vswitche_list = [local.exist_vswitch_ids[0]]
      }
      # 服务网格的版本。
      version = local.mesh_version
      # 服务网格的API Server和Pilot负载均衡配置。
      load_balancer {
        # 是否使用eip暴露服务网格API Server负载均衡。
        api_server_public_eip = true
      }
      cluster_ids = [
        "c94a1a1d968e04c55861b8747********" # 新增集群ID到数组
      ]
      ......省略无关内容......
    }
    ......省略无关内容......
  2. 执行terraform apply,观察到数据面集群ID数组发生变更,符合预期

    random_uuid.this: Refreshing state... [id=6ab24265-2381-dad9-3be5-351329c5665a]
    data.alicloud_service_mesh_versions.default: Reading...
    data.alicloud_vpcs.default: Reading...
    data.alicloud_vpcs.default: Read complete after 1s [id=2909606812]
    data.alicloud_vswitches.default: Reading...
    data.alicloud_vswitches.default: Read complete after 0s [id=866499268]
    data.alicloud_service_mesh_versions.default: Read complete after 1s [id=3077056360]
    alicloud_service_mesh_service_mesh.default: Refreshing state... [id=c71fe2f2301234701b2e4116397426342]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      ~ update in-place
    
    Terraform will perform the following actions:
    
      # alicloud_service_mesh_service_mesh.default will be updated in-place
      ~ resource "alicloud_service_mesh_service_mesh" "default" {
          ~ cluster_ids       = [
              + "c94a1a1d968e04c55861b8747********",
            ]
            id                = "c71fe2f2301234701b2e4116397426342"
            tags              = {}
            # (6 unchanged attributes hidden)
        }
    
    Plan: 0 to add, 1 to change, 0 to destroy.
    
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: 
  3. 输入yes应用变更

    ......省略无关内容......
    Do you want to perform these actions?
      Terraform will perform the actions described above.
      Only 'yes' will be accepted to approve.
    
      Enter a value: yes
    
    alicloud_service_mesh_service_mesh.default: Modifying... [id=c71fe2f2301234701b2e4116397426342]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 10s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 20s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 30s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 40s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 50s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 1m0s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 1m10s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 1m20s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 1m30s elapsed]
    alicloud_service_mesh_service_mesh.default: Still modifying... [id=c71fe2f2301234701b2e4116397426342, 1m40s elapsed]
    alicloud_service_mesh_service_mesh.default: Modifications complete after 1m44s [id=c71fe2f2301234701b2e4116397426342]
    
    Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

Terraform管理的ASM资源

ASM支持通过Terraform管理以下Resource和Data Source:

类型

名称

描述

Resources

alicloud_service_mesh_service_mesh

管理ASM实例。

alicloud_service_mesh_user_permission

配置ASM实例权限。

Data Sources

alicloud_service_mesh_service_meshes

列举所有的ASM实例。

alicloud_service_mesh_versions

列举所有可用的服务网格版本。

terraform apply看到字段被删除时的处理方式

为了简化操作,ASM的部分属性即使创建时不指定,服务端也会分配默认值,这个特性类似于terraform的Computed属性标签,但是若将这些属性设置为Computed,则会使得这些值无法被改为空(字符串类型无法改为空字符串,数值类型无法改为0,布尔类型无法改为false)。为了允许这些属性被改为空值,ASM Terraform Registry不能将这些属性设置为Computed。在您执行terraform apply时,由于服务端返回了这些属性,而tf文件中未显式声明,terraform会认为您希望删除这些值,此时,若您不希望置空这些属性,则应当根据提示手动将它们补充到tf文件中,再执行terraform apply