This topic describes how to use Terraform to create an ACK managed cluster.
You can run the sample code in this tutorial directly from the OpenAPI Portal.
Prerequisites
-
ACK activated. If not, see Activate ACK via Terraform.
-
Your Alibaba Cloud account must have full permissions on all resources. If the credentials of your Alibaba Cloud account are leaked, you may face significant security risks. We recommend that you use a Resource Access Management (RAM) user and create an AccessKey for the RAM user. For more information, see Create a RAM user and Create an AccessKey.
-
Attach the following least privilege policy to the RAM user that you use to run Terraform commands. This policy grants the RAM user permissions to manage the resources in this example. For more information, see Manage RAM user permissions.
This permission policy allows the RAM user to create, view, and delete VPCs, vSwitches, and ACK clusters.
{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "vpc:CreateVpc", "vpc:CreateVSwitch", "cs:CreateCluster", "vpc:DescribeVpcAttribute", "vpc:DescribeVSwitchAttributes", "vpc:DescribeRouteTableList", "vpc:DescribeNatGateways", "cs:DescribeTaskInfo", "cs:DescribeClusterDetail", "cs:GetClusterCerts", "cs:CheckControlPlaneLogEnable", "cs:CreateClusterNodePool", "cs:DescribeClusterNodePoolDetail", "cs:ModifyClusterNodePool", "vpc:DeleteVpc", "vpc:DeleteVSwitch", "cs:DeleteCluster", "cs:DeleteClusterNodepool" ], "Resource": "*" } ] } -
Prepare a Terraform runtime environment. You can use Terraform in one of the following ways:
-
Use Terraform in Terraform Explorer: Alibaba Cloud provides an online Terraform environment that you can use without installation. This method is ideal for quickly testing and debugging Terraform at no cost.
-
Use Terraform to quickly create resources: Alibaba Cloud Cloud Shell has Terraform pre-installed and its credentials configured. You can run Terraform commands directly in Cloud Shell. This method provides a quick, cost-effective way to use Terraform.
-
Use Terraform in Resource Orchestration Service (ROS): ROS provides a managed service for Terraform. You can create Terraform-based templates to define resources on Alibaba Cloud, AWS, or Azure and configure resource parameters and dependencies.
-
Install and configure Terraform on your on-premises machine: This method is suitable for scenarios with poor network connectivity or where a custom development environment is required.
ImportantMake sure that your Terraform version is 0.12.28 or later. To check the version, run the
terraform --versioncommand. -
Resources
Some resources used in this example incur fees. To avoid unwanted charges, delete these resources when you no longer need them.
-
alicloud_zones: Queries availability zones.
-
alicloud_instance_types: Queries ECS instance types that meet specified criteria.
-
alicloud_vpc: Creates a VPC.
-
alicloud_vswitch: Creates one or more vSwitches to divide a VPC into subnets.
-
alicloud_cs_managed_kubernetes: Creates an ACK managed cluster.
-
alicloud_cs_kubernetes_node_pool: Creates a node pool for an ACK managed cluster.
Generate Terraform configuration from the console
If you have specific configuration needs not covered in the examples, you can export the Terraform configuration directly from the ACK console.
Log on to the ACK console. In the left navigation pane, click Clusters.
On the Clusters page, click Cluster Templates.
-
In the dialog box, select a cluster type, click Create, and then configure the cluster details on the Cluster Configurations page.
-
After you complete the configuration, go to the Confirm step and click Console-to-Code in the upper-right corner.
-
In the sidebar, click the Terraform tab to view and copy the auto-generated HCL code.
Create an ACK managed cluster with Terway
This example creates an ACK managed cluster that includes a regular node pool, a managed node pool, and an auto-scaling node pool. By default, several add-ons are installed on the cluster, such as Terway (network add-on), csi-plugin (storage add-on), csi-provisioner (storage add-on), loongcollector (logging add-on), Nginx Ingress Controller, ack-arms-prometheus (monitoring add-on), and ack-node-problem-detector (node diagnostics add-on).
-
Create a working directory, create a configuration file named main.tf in the working directory, and then copy the following code into main.tf.
provider "alicloud" { region = var.region_id } variable "region_id" { type = string default = "cn-shenzhen" } variable "cluster_spec" { type = string description = "The specifications for the Kubernetes cluster. This can be empty. Valid values: ack.standard: Standard managed clusters; ack.pro.small: Professional managed clusters." default = "ack.pro.small" } # The availability zones for the vSwitches. variable "availability_zone" { description = "The availability zones for the vSwitches." default = ["cn-shenzhen-c", "cn-shenzhen-e", "cn-shenzhen-f"] } # A list of existing vSwitch IDs. variable "node_vswitch_ids" { description = "A list of existing vSwitch IDs for Terway nodes." type = list(string) default = [] } # A list of CIDR blocks for creating new vSwitches. variable "node_vswitch_cidrs" { description = "A list of CIDR blocks for creating new vSwitches when 'node_vswitch_ids' is not specified." type = list(string) default = ["172.16.0.0/23", "172.16.2.0/23", "172.16.4.0/23"] } # The configuration of the Terway network add-on. If empty, new Terway vSwitches are created based on terway_vswitch_cidrs by default. variable "terway_vswitch_ids" { description = "List of existing pod vswitch ids for terway." type = list(string) default = [] } # The CIDR blocks for creating vSwitches for Terway when terway_vswitch_ids is not specified. variable "terway_vswitch_cidrs" { description = "List of cidr blocks used to create several new vswitches when 'terway_vswitch_ids' is not specified." type = list(string) default = ["172.16.208.0/20", "172.16.224.0/20", "172.16.240.0/20"] } # The ECS instance types for worker nodes. variable "worker_instance_types" { description = "The ECS instance types for worker nodes." default = ["ecs.g6.2xlarge", "ecs.g6.xlarge"] } # The add-ons to install on the ACK cluster. Includes Terway (network), csi-plugin (storage), csi-provisioner (storage), loongcollector (logging), Nginx Ingress Controller, ack-arms-prometheus (monitoring), and ack-node-problem-detector (node diagnostics). variable "cluster_addons" { type = list(object({ name = string config = string })) default = [ { "name" = "terway-eniip", "config" = "", }, { "name" = "loongcollector", "config" = "{\"IngressDashboardEnabled\":\"true\"}", }, { "name" = "nginx-ingress-controller", "config" = "{\"IngressSlbNetworkType\":\"internet\"}", }, { "name" = "arms-prometheus", "config" = "", }, { "name" = "ack-node-problem-detector", "config" = "{\"sls_project_name\":\"\"}", }, { "name" = "csi-plugin", "config" = "", }, { "name" = "csi-provisioner", "config" = "", } ] } # The name prefix for the ACK managed cluster. variable "k8s_name_prefix" { description = "The name prefix for the managed Kubernetes cluster." default = "tf-ack-shenzhen" } # Default resource names. locals { k8s_name_terway = substr(join("-", [var.k8s_name_prefix, "terway"]), 0, 63) k8s_name_flannel = substr(join("-", [var.k8s_name_prefix, "flannel"]), 0, 63) k8s_name_ask = substr(join("-", [var.k8s_name_prefix, "ask"]), 0, 63) new_vpc_name = "tf-vpc-172-16" new_vsw_name_azD = "tf-vswitch-azD-172-16-0" new_vsw_name_azE = "tf-vswitch-azE-172-16-2" new_vsw_name_azF = "tf-vswitch-azF-172-16-4" nodepool_name = "default-nodepool" managed_nodepool_name = "managed-node-pool" autoscale_nodepool_name = "autoscale-node-pool" log_project_name = "log-for-${local.k8s_name_terway}" } # ECS instance configuration for nodes. Queries for ECS instance types that meet the CPU and memory requirements. data "alicloud_instance_types" "default" { cpu_core_count = 8 memory_size = 32 availability_zone = var.availability_zone[0] kubernetes_node_role = "Worker" } # VPC. resource "alicloud_vpc" "default" { vpc_name = local.new_vpc_name cidr_block = "172.16.0.0/12" } # Node vSwitches. resource "alicloud_vswitch" "vswitches" { count = length(var.node_vswitch_ids) > 0 ? 0 : length(var.node_vswitch_cidrs) vpc_id = alicloud_vpc.default.id cidr_block = element(var.node_vswitch_cidrs, count.index) zone_id = element(var.availability_zone, count.index) } # The vSwitches for pods. resource "alicloud_vswitch" "terway_vswitches" { count = length(var.terway_vswitch_ids) > 0 ? 0 : length(var.terway_vswitch_cidrs) vpc_id = alicloud_vpc.default.id cidr_block = element(var.terway_vswitch_cidrs, count.index) zone_id = element(var.availability_zone, count.index) } # ACK managed cluster. resource "alicloud_cs_managed_kubernetes" "default" { name = local.k8s_name_terway # The name of the Kubernetes cluster. cluster_spec = var.cluster_spec # Creates a professional managed cluster. vswitch_ids = split(",", join(",", alicloud_vswitch.vswitches.*.id)) # The vSwitches for the node pool. Specify one or more vSwitch IDs. The vSwitches must be in the specified availability zones. pod_vswitch_ids = split(",", join(",", alicloud_vswitch.terway_vswitches.*.id)) # Pod vSwitches. new_nat_gateway = true # Specifies whether to create a new nat gateway when you create the Kubernetes cluster. Default value: true. service_cidr = "10.11.0.0/16" # The Service CIDR block, required when using Flannel networking. It must not overlap with the VPC CIDR block or that of another Kubernetes cluster in the same VPC. This parameter cannot be changed after the cluster is created. The cluster supports a maximum of 256 nodes. slb_internet_enabled = true # Specifies whether to create an Internet-facing load balancer for the API server. Default value: false. enable_rrsa = true control_plane_log_components = ["apiserver", "kcm", "scheduler", "ccm"] # Control plane logs. dynamic "addons" { # Add-on configuration. for_each = var.cluster_addons content { name = lookup(addons.value, "name", var.cluster_addons) config = lookup(addons.value, "config", var.cluster_addons) } } } # Regular node pool. resource "alicloud_cs_kubernetes_node_pool" "default" { cluster_id = alicloud_cs_managed_kubernetes.default.id # The ID of the Kubernetes cluster. node_pool_name = local.nodepool_name # The name of the node pool. vswitch_ids = split(",", join(",", alicloud_vswitch.vswitches.*.id)) # The vSwitches for the node pool. Specify one or more vSwitch IDs. The vSwitches must be in the specified availability zones. instance_types = var.worker_instance_types instance_charge_type = "PostPaid" desired_size = 2 # The desired number of nodes in the node pool. install_cloud_monitor = true # Specifies whether to install CloudMonitor on the nodes. system_disk_category = "cloud_efficiency" system_disk_size = 100 image_type = "AliyunLinux" data_disks { # Data disk configuration for the node. category = "cloud_essd" # The category of the data disk. size = 120 # The size of the data disk. } } # Create a managed node pool. resource "alicloud_cs_kubernetes_node_pool" "managed_node_pool" { cluster_id = alicloud_cs_managed_kubernetes.default.id # The ID of the Kubernetes cluster. node_pool_name = local.managed_nodepool_name # The name of the node pool. vswitch_ids = split(",", join(",", alicloud_vswitch.vswitches.*.id)) # The vSwitches for the node pool. Specify one or more vSwitch IDs. The vSwitches must be in the specified availability zones. desired_size = 0 # The desired number of nodes in the node pool. management { auto_repair = true auto_upgrade = true max_unavailable = 1 } instance_types = var.worker_instance_types instance_charge_type = "PostPaid" install_cloud_monitor = true system_disk_category = "cloud_efficiency" system_disk_size = 100 image_type = "AliyunLinux" data_disks { category = "cloud_essd" size = 120 } } # Create an auto-scaling node pool. The node pool can be scaled out to a maximum of 10 nodes and must have at least 1 node. resource "alicloud_cs_kubernetes_node_pool" "autoscale_node_pool" { cluster_id = alicloud_cs_managed_kubernetes.default.id node_pool_name = local.autoscale_nodepool_name vswitch_ids = split(",", join(",", alicloud_vswitch.vswitches.*.id)) scaling_config { min_size = 1 max_size = 10 } instance_types = var.worker_instance_types install_cloud_monitor = true # Specifies whether to install CloudMonitor on the nodes. system_disk_category = "cloud_efficiency" system_disk_size = 100 image_type = "AliyunLinux3" data_disks { # Data disk configuration for the node. category = "cloud_essd" # The category of the data disk. size = 120 # The size of the data disk. } } -
Run the following command to initialize the Terraform runtime environment.
terraform initExpected output:
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. -
Create an execution plan and preview the changes.
terraform plan -
Run the following command to create the cluster.
terraform applyType
yeswhen prompted and press Enter. The following output indicates that the ACK cluster is created: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.default: Creation complete after 5m48s [id=ccb53e72ec6c447c990762800********] ... Apply complete! Resources: 11 added, 0 changed, 0 destroyed. -
Verify the results
Terraform show
Run the following command to view the details of the resources created by Terraform.
terraform showACK console
Log on to the ACK console to view the created cluster.
Resource cleanup
When you no longer need the resources created or managed by Terraform, run the terraform destroy command to release them and avoid charges. For more information about the terraform destroy command, see Common commands.
terraform destroy