Rancher Terraform

The Rancher Terraform Provider allows administrators to create and manage RKE2 guest clusters using Terraform.

Deployment

Prerequisites

  • The Kubernetes cluster is built on top of Harvester VMs.
  • The Harvester VMs that run as guest Kubernetes nodes are in the same namespace.

Deploy Guest Clusters Using the Rancher Terraform Provider

  1. Create an API key.

    On the Rancher UI, go to Account & API Keys > Create API key > Create.

    Create API Key Access & Secret Keys

  2. Obtain the Harvester cluster ID.

    On the Rancher UI, go to Virtualization Management > Manage > Related Resources > Mgmt Cluster Name.

    Harvester Cluster ID

  3. Obtain the kubeconfig for the Harvester Cloud Provider and the Harvester CSI Driver.

    • UI
    • Shell

    On the Rancher UI, go to Virtualization Management. Locate the target Harvester cluster in the list and then select > Download KubeConfig.

    Download Kubeconfig

    1. # Generate harvester cloud provider kubeconfig
    2. RANCHER_SERVER_URL="<RANCHER_SERVER_URL>" # Pure server URL like https://192.168.0.181:6443
    3. RANCHER_ACCESS_KEY="<RANCHER_ACCESS_KEY>"
    4. RANCHER_SECRET_KEY="<RANCHER_SECRET_KEY>"
    5. HARVESTER_CLUSTER_ID="<HARVESTER_CLUSTER_ID>"
    6. CLUSTER_NAME="rke2-demo"
    7. curl -k -X POST ${RANCHER_SERVER_URL}/k8s/clusters/${HARVESTER_CLUSTER_ID}/v1/harvester/kubeconfig \
    8. -H 'Content-Type: application/json' \
    9. -u ${RANCHER_ACCESS_KEY}:${RANCHER_SECRET_KEY} \
    10. -d '{"clusterRoleName": "harvesterhci.io:cloudprovider", "namespace": "default", "serviceAccountName": "'${CLUSTER_NAME}'"}' | xargs | sed 's/\\n/\n/g' > ${CLUSTER_NAME}-kubeconfig
  4. Prepare a provider.tf file with the following content:

    1. terraform {
    2. required_providers {
    3. rancher2 = {
    4. source = "rancher/rancher2"
    5. version = "4.2.0"
    6. }
    7. }
    8. }
    9. # Configure the Rancher2 provider to admin
    10. provider "rancher2" {
    11. api_url = "<api_url>" # API Endpoint on Account & API Keys page
    12. access_key = "<access_key>"
    13. secret_key = "<secret_key>"
    14. insecure = true # Set to true if the Rancher server uses a self-signed certificate
    15. }
  5. Prepare a main.tf file with the following content:

    1. # Get imported harvester cluster info
    2. data "rancher2_cluster_v2" "harv" {
    3. name = "<harvester_cluster_name_in_rancher>"
    4. }
    5. # Create a new Cloud Credential for an imported Harvester cluster
    6. resource "rancher2_cloud_credential" "harv-cred" {
    7. name = "harv-cred"
    8. harvester_credential_config {
    9. cluster_id = data.rancher2_cluster_v2.harv.cluster_v1_id
    10. cluster_type = "imported"
    11. kubeconfig_content = data.rancher2_cluster_v2.harv.kube_config
    12. }
    13. }
    14. # Create a new rancher2 machine config v2 using harvester node_driver
    15. resource "rancher2_machine_config_v2" "rke2-machine" {
    16. generate_name = "rke2-machine"
    17. harvester_config {
    18. vm_namespace = "default"
    19. cpu_count = "2"
    20. memory_size = "4"
    21. disk_info = <<EOF
    22. {
    23. "disks": [{
    24. "imageName": "default/<vmimage-name>",
    25. "size": 15,
    26. "bootOrder": 1
    27. }]
    28. }
    29. EOF
    30. network_info = <<EOF
    31. {
    32. "interfaces": [{
    33. "networkName": "default/<network-name>"
    34. }]
    35. }
    36. EOF
    37. ssh_user = "<ssh_user>"
    38. user_data = <<EOF
    39. package_update: true
    40. packages:
    41. - qemu-guest-agent
    42. - iptables
    43. runcmd:
    44. - - systemctl
    45. - enable
    46. - '--now'
    47. - qemu-guest-agent.service
    48. EOF
    49. }
    50. }
    51. resource "rancher2_cluster_v2" "rke2-demo" {
    52. name = "rke2-demo"
    53. kubernetes_version = "v1.28.10+rke2r1"
    54. rke_config {
    55. machine_pools {
    56. name = "pool1"
    57. cloud_credential_secret_name = rancher2_cloud_credential.harv-cred.id
    58. control_plane_role = true
    59. etcd_role = true
    60. worker_role = true
    61. quantity = 1
    62. machine_config {
    63. kind = rancher2_machine_config_v2.rke2-machine.kind
    64. name = rancher2_machine_config_v2.rke2-machine.name
    65. }
    66. }
    67. machine_selector_config {
    68. config = yamlencode({
    69. cloud-provider-config = file("${path.module}/rke2-demo-kubeconfig")
    70. cloud-provider-name = "harvester"
    71. })
    72. }
    73. machine_global_config = <<EOF
    74. cni: "calico"
    75. disable-kube-proxy: false
    76. etcd-expose-metrics: false
    77. EOF
    78. upgrade_strategy {
    79. control_plane_concurrency = "1"
    80. worker_concurrency = "1"
    81. }
    82. etcd {
    83. snapshot_schedule_cron = "0 */5 * * *"
    84. snapshot_retention = 5
    85. }
    86. chart_values = <<EOF
    87. harvester-cloud-provider:
    88. clusterName: rke2-demo
    89. cloudConfigPath: /var/lib/rancher/rke2/etc/config-files/cloud-provider-config
    90. EOF
    91. }
    92. }
  6. Run terraform init.

  7. Run terraform apply.