In the Container Service for Kubernetes console, a graphical interface is provided to guide you through the process of creating a managed Kubernetes cluster. However, it can be cumbersome to use the console to create large numbers of managed clusters. Using Terrafrom can help you solve these problems. This topic describes how to quickly deploy a managed Kubernetes cluster by using Terraform.

Create a managed Kubernetes cluster

In alicloud_cs_managed_kubernetes, a Terraform resource document for Alibaba Cloud managed Kubernetes clusters, you can see the parameters provided by the resource. Resource parameters are divided into input arguments and output attributes. The Argument Reference section lists the required and optional arguments and their characteristics. For example, name and name_prefix are two required arguments, but they are mutually exclusive and cannot be specified simultaneously. If the name argument is specified, the name value will be used as the cluster name. If the name_prefix argument is specified, a cluster name starting with the prefix specified by name_prefix will be automatically generated.

  1. Compile a cluster description by referring to the Argument Reference section in the preceding document. The code is as follows:
    provider "alicloud" {
    }
    # The default resource name.
    variable "name" {
      default = "my-first-kubernetes-demo"
    }
    # The name of the Log Service project.
    variable "log_project_name" {
      default = "my-first-kubernetes-sls-demo"
    }
    # The zone.
    data "alicloud_zones" default {
      available_resource_creation = "VSwitch"
    }
    # The ECS instance specifications of the worker node.
    data "alicloud_instance_types" "default" {
      availability_zone    = data.alicloud_zones.default.zones[0].id
      cpu_core_count       = 2
      memory_size          = 4
      kubernetes_node_role = "Worker"
    }
    #The VPC.
    resource "alicloud_vpc" "default" {
      name       = var.name
      cidr_block = "10.1.0.0/21"
    }
    # The VSwitch.
    resource "alicloud_vswitch" "default" {
      name              = var.name
      vpc_id            = alicloud_vpc.default.id
      cidr_block        = "10.1.1.0/24"
      availability_zone = data.alicloud_zones.default.zones[0].id
    }
    # The Log Service project.
    resource "alicloud_log_project" "log" {
      name        = var.log_project_name
      description = "created by terraform for managedkubernetes cluster"
    }
    # The managed Kubernetes cluster.
    resource "alicloud_cs_managed_kubernetes" "default" {
      # The prefix of the Kubernetes cluster name. It is mutually exclusive with the name argument. If the name_prefix argument is specified, Terraform will use it to create a unique cluster name. Default value: Terraform-Creation.
      name_prefix               = var.name
      # The zone where the new Kubernetes cluster will be located.
      availability_zone         = data.alicloud_zones.default.zones[0].id
      # The VSwitches of the new Kubernetes cluster. Specify the IDs of one or more VSwitches. The VSwitches must be in the zone specified by availability_zone.
      vswitch_ids               = [alicloud_vswitch.default.id]
      # Specify whether to create a new NAT gateway when creating the Kubernetes cluster. Default value: true.
      new_nat_gateway           = true
      # The ECS instance type of the worker node. Specify one type for a cluster deployed in a single zone or three types for a cluster deployed across multiple zones. You can use the instance_types data source to obtain available instance types for Kubernetes master nodes.
      worker_instance_types     = [data.alicloud_instance_types.default.instance_types[0].id]
      # The total number of worker nodes in the Kubernetes cluster. Default value: 3. Maximum value: 50.
      worker_number             = 2
      # The password used to log on to the cluster node through SSH. You must specify one of the password, key_name, and kms_encrypted_password fields.
      password                  = "Yourpassword1234"
      # The CIDR block for the pod network. When cluster_network_type is set to flannel, you must set this argument. It cannot be the same as the VPC CIDR block or the CIDR block used by the Kubernetes cluster in the VPC, and cannot be modified after creation. Maximum number of hosts allowed in the cluster: 256.
      pod_cidr                  = "172.20.0.0/16"
      # The CIDR block for the service network. It cannot be the same as the VPC CIDR block or the CIDR block used by the Kubernetes cluster in the VPC, and cannot be modified after creation.
      service_cidr              = "172.21.0.0/20"
      # Specify whether to install CloudMonitor for the Kubernetes node.
      install_cloud_monitor     = true
      # Specify whether to create an Internet-facing SLB instance for the API server. Default value: false.
      slb_internet_enabled      = true
      # The system disk type of the worker node. Valid values: cloud_ssd and cloud_efficiency. Default value: cloud_efficiency.
      worker_disk_category      = "cloud_efficiency"
      # The data disk type of the worker node. The valid values are cloud_ssd and cloud_efficiency. If this argument is not specified, no data disk will be created.
      worker_data_disk_category = "cloud_ssd"
      # The data disk size of the worker node. Unit: GB. Valid values: 20 to 32768. Default value: 40.
      worker_data_disk_size     = 200
      # The log configuration.
      log_config {
        # The log collection type. Only Log Service is supported.
        type    = "SLS"
        # The name of the Log Service project. Cluster logs will be exported to this project.
        project = alicloud_log_project.log.name
      }
    }             
  2. Save the preceding configuration as a main.tf description file. Run the terraform init and terraform apply commands in the current directory of the file.
    1. Run the terraform init command to initialize Terraform configuration files.
      $ terraform init
      
      Initializing provider plugins...
      - Checking for available provider plugins on https://releases.hashicorp.com...
      - Downloading plugin for provider "alicloud" (1.26.0)...
      
      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.
    2. Run the terraform apply command to create resources.
      $ terraform apply
      
      An execution plan has been generated and is shown below.
      Resource actions are indicated with the following symbols:
        + create
      
      Terraform will perform the following actions:
      
        # alicloud_cs_managed_kubernetes.default will be created
        + resource "alicloud_cs_managed_kubernetes" "default" {
            + availability_zone           = "cn-hangzhou-b"
            + force_update                = false
            + id                          = (known after apply)
            + install_cloud_monitor       = true
            + name                        = (known after apply)
            + name_prefix                 = "my-first-kubernetes-demo"
            + new_nat_gateway             = true
            + password                    = (sensitive value)
            + pod_cidr                    = "172.20.0.0/16"
            + security_group_id           = (known after apply)
            + service_cidr                = "172.21.0.0/20"
            + slb_internet_enabled        = true
            + vpc_id                      = (known after apply)
            + vswitch_ids                 = (known after apply)
            + worker_data_disk_category   = "cloud_ssd"
            + worker_data_disk_size       = 200
            + worker_disk_category        = "cloud_efficiency"
            + worker_disk_size            = 40
            + worker_instance_charge_type = "PostPaid"
            + worker_instance_types       = [
                + "ecs.n1.medium",
              ]
            + worker_nodes                = (known after apply)
            + worker_number               = 2
      
            + log_config {
                + project = "my-first-kubernetes-sls-demo"
                + type    = "SLS"
              }
          }
      
        # alicloud_log_project.log will be created
        + resource "alicloud_log_project" "log" {
            + description = "created by terraform for managedkubernetes cluster"
            + id          = (known after apply)
            + name        = "my-first-kubernetes-sls-demo"
          }
      
        # alicloud_vpc.default will be created
        + resource "alicloud_vpc" "default" {
            + cidr_block        = "10.1.0.0/21"
            + id                = (known after apply)
            + name              = "my-first-kubernetes-demo"
            + resource_group_id = (known after apply)
            + route_table_id    = (known after apply)
            + router_id         = (known after apply)
            + router_table_id   = (known after apply)
          }
      
        # alicloud_vswitch.default will be created
        + resource "alicloud_vswitch" "default" {
            + availability_zone = "cn-hangzhou-b"
            + cidr_block        = "10.1.1.0/24"
            + id                = (known after apply)
            + name              = "my-first-kubernetes-demo"
            + vpc_id            = (known after apply)
          }
      
      Plan: 4 to add, 0 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. The terraform init command will download required provider plug-ins. The terraform apply command will figure out the operations to be performed based on the main.tf file. The preceding log shows that a resource named alicloud_cs_managed_kubernetes.k8s will be created. You must enter yes to confirm the operation. After you confirm the operation, it takes about five minutes to create the resource. Terraform will then generate log entries similar to the following ones:
    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_vpc.default: Creating...
    alicloud_log_project.log: Creating...
    alicloud_log_project.log: Creation complete after 1s [id=my-first-kubernetes-sls-demo]
    alicloud_vpc.default: Creation complete after 6s [id=vpc-bp1830x557ktabq******]
    alicloud_vswitch.default: Creating...
    alicloud_vswitch.default: Creation complete after 5s [id=vsw-bp1vb35pc7bvc0e*****]
    alicloud_cs_managed_kubernetes.default: Creating...
    alicloud_cs_managed_kubernetes.default: Still creating... [10s elapsed]
    alicloud_cs_managed_kubernetes.default: Still creating... [20s elapsed]
    alicloud_cs_managed_kubernetes.default: Still creating... [30s elapsed]
    alicloud_cs_managed_kubernetes.default: Still creating... [40s elapsed]
    alicloud_cs_managed_kubernetes.default: Still creating... [50s elapsed]
    ......
    alicloud_cs_managed_kubernetes.k8s: Creation complete after 6m5s (ID: cc54df7d990a24ed18c1e0ebacd36418c)
    
    Apply complete! Resources: 4 added, 0 changed, 0 destroyed.                       
  4. When the Apply complete! Resources: 4 added message appears, the cluster is created. You can also log on to the console to view this cluster.

Modify a managed Kubernetes cluster

Terraform providers provide the ability to modify certain arguments. In normal cases, arguments of resources that are not marked ForceNew can all be modified.

  1. The following code shows how to modify arguments with comments explaining the modifications:
    resource "alicloud_cs_managed_kubernetes" "default" {
      # Change the cluster name to test-managed-kubernetes-updated.
      name = "test-managed-kubernetes-updated"
      availability_zone         = data.alicloud_zones.default.zones[0].id
      vswitch_ids               = [alicloud_vswitch.default.id]
      new_nat_gateway           = true
      worker_instance_types     = [data.alicloud_instance_types.default.instance_types[0].id]
      # Set worker_numbers to 3 to add a worker node.
      worker_number             = 3
      password                  = "Yourpassword1234"
      pod_cidr                  = "172.20.0.0/16"
      service_cidr              = "172.21.0.0/20"
      install_cloud_monitor     = true
      slb_internet_enabled      = true
      worker_disk_category      = "cloud_efficiency"
      worker_data_disk_category = "cloud_ssd"
      worker_data_disk_size     = 200
      log_config {
        type    = "SLS"
        project = alicloud_log_project.log.name
      }
      # Export the cluster connection configuration file to the /tmp directory.
      kube_config = "/tmp/config"
      # Export the certificate related files of the cluster to the /tmp directory.
      client_cert = "/tmp/client-cert.pem"
      client_key = "/tmp/client-key.pem"
      cluster_ca_cert = "/tmp/cluster-ca-cert.pem"
    }                    
  2. Similarly, you can use the terraform apply command to modify a cluster. After running the command, the following log output is displayed. Type yes and press the Enter key to change the cluster name to test-managed-kubernetes-updated, scale out the number of worker nodes to 3, and export the certificate and connection files to the /tmp directory.
    $ terraform apply
    alicloud_cs_managed_kubernetes.k8s: Refreshing state... (ID: cc54df7d990a24ed18c1e0ebacd36418c)
    
    An execution plan has been generated and is shown below.
    Resource actions are indicated with the following symbols:
      ~ update in-place
    
    Terraform will perform the following actions:
    
      ~ alicloud_cs_managed_kubernetes.k8s
          client_cert:      "" => "/tmp/client-cert.pem"
          client_key:       "" => "/tmp/client-key.pem"
          cluster_ca_cert:  "" => "/tmp/cluster-ca-cert.pem"
          kube_config:      "" => "/tmp/config"
          name:             "test-managed-kubernetes" => "test-managed-kubernetes-updated"
          worker_numbers.0: "2" => "3"
    
    
    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: yes
    
    alicloud_cs_managed_kubernetes.k8s: Modifying... (ID: cc54df7d990a24ed18c1e0ebacd36418c)
      client_cert:      "" => "/tmp/client-cert.pem"
      client_key:       "" => "/tmp/client-key.pem"
      cluster_ca_cert:  "" => "/tmp/cluster-ca-cert.pem"
      kube_config:      "" => "/tmp/config"
      name:             "test-managed-kubernetes" => "test-managed-kubernetes-updated"
      worker_numbers.0: "2" => "3"
    alicloud_cs_managed_kubernetes.k8s: Still modifying... (ID: cc54df7d990a24ed18c1e0ebacd36418c, 10s elapsed)
    alicloud_cs_managed_kubernetes.k8s: Still modifying... (ID: cc54df7d990a24ed18c1e0ebacd36418c, 20s elapsed)
    alicloud_cs_managed_kubernetes.k8s: Still modifying... (ID: cc54df7d990a24ed18c1e0ebacd36418c, 30s elapsed)
    ......
    alicloud_cs_managed_kubernetes.k8s: Modifications complete after 4m4s (ID: cc54df7d990a24ed18c1e0ebacd36418c)
    
    Apply complete! Resources: 0 added, 1 changed, 0 destroyed.                       
  3. After the terraform apply command is run, the cluster information displayed in the console indicates that the cluster has reached the desired state. On the local machine, you can use the exported kubectl configuration file to connect to the created cluster.