PageSourceSearch

https://docs-spectrocloud.netlify.app/assets/js/2e40ffb5.11628bc2.js

js docs-spectrocloud.netlify.app collected 2026-10-03 10:40:31 UTC 49,624 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkspectro_cloud_docs=self.webpackChunkspectro_cloud_docs||[]).push([["10968"],{507112:function(e,t,r){r.r(t),r.d(t,{frontMatter:()=>a,toc:()=>c,default:()=>h,metadata:()=>s,assets:()=>i,contentTitle:()=>l});var s=JSON.parse('{"id":"tutorials/getting-started/palette/vmware/deploy-manage-k8s-cluster-tf","title":"Cluster Management with Terraform","description":"Learn how to deploy and update a Palette host cluster to VMware vSphere with Terraform.","source":"@site/docs/docs-content/tutorials/getting-started/palette/vmware/deploy-manage-k8s-cluster-tf.md","sourceDirName":"tutorials/getting-started/palette/vmware","slug":"/tutorials/getting-started/palette/vmware/deploy-manage-k8s-cluster-tf","permalink":"/tutorials/getting-started/palette/vmware/deploy-manage-k8s-cluster-tf","draft":false,"unlisted":false,"editUrl":"https://github.com/spectrocloud/librarium/blob/master/docs/docs-content/tutorials/getting-started/palette/vmware/deploy-manage-k8s-cluster-tf.md","tags":[{"inline":true,"label":"getting-started","permalink":"/tags/getting-started"},{"inline":true,"label":"vmware","permalink":"/tags/vmware"},{"inline":true,"label":"terraform","permalink":"/tags/terraform"},{"inline":true,"label":"tutorial","permalink":"/tags/tutorial"}],"version":"current","lastUpdatedAt":1777826507000,"sidebarPosition":50,"frontMatter":{"sidebar_label":"Cluster Management with Terraform","title":"Cluster Management with Terraform","description":"Learn how to deploy and update a Palette host cluster to VMware vSphere with Terraform.","icon":"","hide_table_of_contents":false,"sidebar_position":50,"toc_max_heading_level":2,"tags":["getting-started","vmware","terraform","tutorial"]},"sidebar":"tutorialSidebar","previous":{"title":"Deploy Cluster Profile Updates","permalink":"/tutorials/getting-started/palette/vmware/update-k8s-cluster"},"next":{"title":"Scale, Upgrade, and Secure Clusters","permalink":"/tutorials/getting-started/palette/vmware/scale-secure-cluster"}}'),n=r(474848),o=r(884429);let a={sidebar_label:"Cluster Management with Terraform",title:"Cluster Management with Terraform",description:"Learn how to deploy and update a Palette host cluster to VMware vSphere with Terraform.",icon:"",hide_table_of_contents:!1,sidebar_position:50,toc_max_heading_level:2,tags:["getting-started","vmware","terraform","tutorial"]},l,i={},c=[{value:"\u{1F9D1}\u200D\u{1F680} Back at Spacetastic HQ",id:"-back-at-spacetastic-hq",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Set Up Local Environment",id:"set-up-local-environment",level:2},{value:"Resources Review",id:"resources-review",level:2},{value:"Provider",id:"provider",level:4},{value:"Cluster Profile",id:"cluster-profile",level:4},{value:"Data Resources",id:"data-resources",level:4},{value:"Cluster",id:"cluster",level:4},{value:"Terraform Tests",id:"terraform-tests",level:2},{value:"Input Variables",id:"input-variables",level:2},{value:"Deploy the Cluster",id:"deploy-the-cluster",level:2},{value:"Verify the Application",id:"verify-the-application",level:3},{value:"Version Cluster Profiles",id:"version-cluster-profiles",level:2},{value:"Roll Back Cluster Profiles",id:"roll-back-cluster-profiles",level:2},{value:"Cleanup",id:"cleanup",level:2},{value:"Wrap-Up",id:"wrap-up",level:2},{value:"\u{1F9D1}\u200D\u{1F680} Catch up with Spacetastic",id:"-catch-up-with-spacetastic",level:2}];function d(e){let t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components},{PartialsComponent:s,TabItem:a,Tabs:l}=t;return s||p("PartialsComponent",!0),a||p("TabItem",!0),l||p("Tabs",!0),(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs",children:"Spectro Cloud Terraform"})," provider\nallows you to create and manage Palette resources using Infrastructure as Code (IaC). With IaC, you can automate the\nprovisioning of resources, collaborate on changes, and maintain a single source of truth for your infrastru
1cture."]}),"\n",(0,n.jsx)(t.p,{children:"This tutorial will teach you how to use Terraform to deploy and update a VMware vSphere host cluster. You will learn how\nto create two versions of a cluster profile with different demo applications, update the deployed cluster with the new\ncluster profile version, and then perform a rollback. The concepts you learn about in the Getting Started section are\ncentered around a fictional case study company, Spacetastic Ltd."}),"\n",(0,n.jsx)(t.h2,{id:"-back-at-spacetastic-hq",children:"\u{1F9D1}\u200D\u{1F680} Back at Spacetastic HQ"}),"\n",(0,n.jsx)(s,{category:"getting-started",name:"spacetastic-deploy-cluster-tf-intro"}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsx)(t.p,{children:"To complete this tutorial, you will need the following items in place:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Follow the steps described in the ",(0,n.jsx)(t.a,{href:"/tutorials/getting-started/palette/vmware/setup",children:"Set up Palette with VMware"})," guide to authenticate Palette for use with\nyour VMware vSphere account."]}),"\n",(0,n.jsxs)(t.li,{children:["Follow the steps described in the ",(0,n.jsx)(t.a,{href:"/tutorials/getting-started/palette/vmware/deploy-pcg",children:"Deploy a PCG"})," tutorial to deploy a VMware vSphere Private Cloud\nGateway (PCG)."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://www.docker.com/products/docker-desktop/",children:"Docker Desktop"})," or ",(0,n.jsx)(t.a,{href:"https://podman.io/docs/installation",children:"Podman"}),"\ninstalled if you choose to follow along using the tutorial container."]}),"\n",(0,n.jsxs)(t.li,{children:["If you choose to clone the repository instead of using the tutorial container, make sure you have the following\nsoftware installed:","\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli",children:"Terraform"})," v1.9.0 or greater"]}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://git-scm.com/downloads",children:"Git"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://kubernetes.io/docs/tasks/tools/",children:"Kubectl"})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"set-up-local-environment",children:"Set Up Local Environment"}),"\n",(0,n.jsx)(s,{category:"getting-started",name:"setup-local-environment"}),"\n",(0,n.jsx)(t.p,{children:"Navigate to the folder that contains the tutorial code."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"cd terraform/getting-started-deployment-tf\n"})}),"\n",(0,n.jsx)(t.h2,{id:"resources-review",children:"Resources Review"}),"\n",(0,n.jsx)(t.p,{children:"To help you get started with Terraform, the tutorial code is structured to support deploying a cluster to either AWS,\nAzure, GCP, or VMware vSphere. Before you deploy a host cluster to VMware vSphere, review the following files in the\nfolder structure."}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:(0,n.jsx)(t.strong,{children:"File"})}),(0,n.jsx)(t.th,{children:(0,n.jsx)(t.strong,{children:"Description"})})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"provider.tf"})}),(0,n.jsx)(t.td,{children:"This file contains the Terraform providers that are used to support the deployment of the cluster."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"inputs.tf"})}),(0,n.jsx)(t.td,{children:"This file contains all the Terraform variables required for the deployment logic."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"data.tf"})}),(0,n.jsx)(t.td,{children:"This file contains all the query resources that perform read actions."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"cluster_profiles.tf"})}),(0,n.jsx)(t.td,{children:"This file contains the cluster profile definitions for each cloud provider."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"cluster
1s.tf"})}),(0,n.jsx)(t.td,{children:"This file has the cluster configurations required to deploy a host cluster to one of the cloud providers."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"terraform.tfvars"})}),(0,n.jsx)(t.td,{children:"Use this file to target a specific cloud provider and customize the deployment. This is the only file you must modify."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"ippool.tf"})}),(0,n.jsx)(t.td,{children:"This file contains the configuration required for VMware deployments that use static IP placement."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"ssh-key.tf"})}),(0,n.jsx)(t.td,{children:"This file has the SSH key resource definition required for Azure and VMware deployments."})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.strong,{children:"outputs.tf"})}),(0,n.jsxs)(t.td,{children:["This file contains the content that will be displayed in the terminal after a successful Terraform ",(0,n.jsx)(t.code,{children:"apply"})," action."]})]})]})]}),"\n",(0,n.jsx)(t.p,{children:"The following section reviews the core Terraform resources more closely."}),"\n",(0,n.jsx)(t.h4,{id:"provider",children:"Provider"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.strong,{children:"provider.tf"})," file contains the Terraform providers used in the tutorial and their respective versions. This\ntutorial uses four providers:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs",children:"Spectro Cloud"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://registry.terraform.io/providers/hashicorp/tls/latest",children:"TLS"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://registry.terraform.io/providers/hashicorp/vsphere/latest",children:"vSphere"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://registry.terraform.io/providers/hashicorp/local/latest",children:"Local"})}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["Note how the project name is specified in the ",(0,n.jsx)(t.code,{children:'provider "spectrocloud" {}'})," block. You can change the target project by\nmodifying the value of the ",(0,n.jsx)(t.code,{children:"palette-project"})," variable in the ",(0,n.jsx)(t.strong,{children:"terraform.tfvars"})," file."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-hcl",children:'terraform {\n  required_providers {\n    spectrocloud = {\n      version = ">= 0.20.6"\n      source  = "spectrocloud/spectrocloud"\n    }\n\n    tls = {\n      source  = "hashicorp/tls"\n      version = "4.0.4"\n    }\n\n    vsphere = {\n      source  = "hashicorp/vsphere"\n      version = ">= 2.6.1"\n    }\n\n    local = {\n      source  = "hashicorp/local"\n      version = "2.4.1"\n    }\n  }\n\n  required_version = ">= 1.9"\n}\n\nprovider "spectrocloud" {\n  project_name = var.palette-project\n}\n'})}),"\n",(0,n.jsx)(t.h4,{id:"cluster-profile",children:"Cluster Profile"}),"\n",(0,n.jsxs)(t.p,{children:["The next file you should become familiar with is the ",(0,n.jsx)(t.strong,{children:"cluster_profiles.tf"})," file. The ",(0,n.jsx)(t.code,{children:"spectrocloud_cluster_profile"}),"\nresource allows you to create a cluster profile and customize its layers. You can specify the packs and versions to use\nor add a manifest or Helm chart."]}),"\n",(0,n.jsxs)(t.p,{children:["The cluster profile resource is declared eight times in the ",(0,n.jsx)(t.strong,{children:"cluster-profiles.tf"})," file, with each pair of resources\nbeing designated for a specific provider. In this tutorial, two versions of the VMware vSphere cluster profile are\ndeployed: version ",(0,n.jsx)(t.code,{children:"1.0.0"})," deploys the ",(0,n.jsx)(t.a,{href:"https://github.com/spectrocloud/hello-universe",children:"Hello Universe"})," pack, while\nversion ",(0,n.jsx)(t.code,{children:"1.1.0"})," deploys the ",(0,n.jsx)(t.a,{href:"https://www.kubecost.com/",children:"Kubecost"})," pack along with the\n",(0,n.jsx)(t.a,{href:"https://github.com/spectrocloud/hello-universe",children:"Hello Universe"})," application."]}),"\n",(0,n.jsxs)(t.p,{children:["The cluster profiles also include layers for the Operating System (OS), Kubernetes, container network interface,\ncontainer storage interface, and load balancer implementation for bare-metal cluster
1s. The first ",(0,n.jsx)(t.code,{children:"pack {}"})," block in the\nlist equates to the bottom layer of the cluster profile. Ensure you define the bottom layer of the cluster profile - the\nOS layer - first in the list of ",(0,n.jsx)(t.code,{children:"pack {}"})," blocks, as the order in which you arrange the contents of the ",(0,n.jsx)(t.code,{children:"pack {}"})," blocks\nplays an important role in the cluster profile creation. The table below displays the packs deployed in each version of\nthe cluster profile."]}),"\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:(0,n.jsx)(t.strong,{children:"Pack Type"})}),(0,n.jsx)(t.th,{children:(0,n.jsx)(t.strong,{children:"Pack Name"})}),(0,n.jsx)(t.th,{children:(0,n.jsx)(t.strong,{children:"Version"})}),(0,n.jsx)(t.th,{children:(0,n.jsx)(t.strong,{children:"Cluster Profile v1.0.0"})}),(0,n.jsx)(t.th,{children:(0,n.jsx)(t.strong,{children:"Cluster Profile v1.1.0"})})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"OS"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"ubuntu-vsphere"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"22.04"})}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Kubernetes"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"kubernetes"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"1.32.3"})}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Network"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"cni-calico"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"3.29.3"})}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Storage"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"csi-vsphere-csi"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"3.3.1"})}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"Load Balancer"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"lb-metallb-helm"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"0.14.9"})}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"App Services"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"hellouniverse"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"1.2.0"})}),(0,n.jsx)(t.td,{children:"\u2705"}),(0,n.jsx)(t.td,{children:"\u2705"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:"App Services"}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"cost-analyzer"})}),(0,n.jsx)(t.td,{children:(0,n.jsx)(t.code,{children:"1.103.3"})}),(0,n.jsx)(t.td,{children:"\u274C"}),(0,n.jsx)(t.td,{children:"\u2705"})]})]})]}),"\n",(0,n.jsxs)(t.p,{children:["The Hello Universe pack has two configured ",(0,n.jsx)(t.a,{href:"/glossary-all#presets",children:"presets"}),". The first preset deploys a\nstandalone frontend application, while the second one deploys a three-tier application with a frontend, API server, and\nPostgres database. This tutorial deploys the three-tier version of the\n",(0,n.jsx)(t.a,{href:"https://github.com/spectrocloud/hello-universe",children:"Hello Universe"})," pack. The preset selection in the Terraform code is\nspecified within the Hello Universe pack block with the ",(0,n.jsx)(t.code,{children:"values"})," field and by using the ",(0,n.jsx)(t.strong,{children:"values-3tier.yaml"})," file.\nBelow is an example of version ",(0,n.jsx)(t.code,{children:"1.0.0"})," of the VMware vSphere cluster profile Terraform resource."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-hcl",children:'resource "spectrocloud_cluster_profile" "vmware-profile" {\n  count = var.deploy-vmware ? 1 : 0\n\n  name        = "tf-vmware-profile"\n  description = "A basic cluster profile for VMware"\n  tags        = concat(var.tags, ["env:VMware"])\n  cloud       = "vsphere"\n  type        = "cluster"\n  version     = "1.0.0"\n\n  pack {\n    name   = data.spectrocloud_pack.vmware_ubuntu.name\n    tag    = data.spectrocloud_pack.vmware_ubuntu.version\n    uid    = data.spectrocloud_pack.vmware_ubuntu.id\n    values = data.spectrocloud_pack.vmware_ubuntu.values\n    type   = "spectro"\n  }\n\n  pack {\n    name   = data.spectrocloud_pack.vmware_k8s.name\n    tag    = data.spectrocloud_pack.vmware_k8s.version\n    uid    = data.spectrocloud_pack.vmware_k8s.id\n    values = data.spectrocloud_pack.vmware_k8s.values\n    type   = "spectro"\n  }\n\n  pack {\n    name   = data.spectrocloud_pack.vmware_cni.name\n    tag    = data.spectrocloud_pack.vmware_cni.version\n    uid    = data.spectrocloud_pack.vmware_cni.id\n    values = data.spectrocloud_pack.vmware_cni.values\n    type   = "spectro"\n  }\n\n  pack {\n    name   = data.spectrocloud_pack.vmware_csi.name\n    tag    = data.spectrocloud_pack.vmware_csi.version\n    uid    = data.spectrocloud_pack.vmware_csi.id\n    values = data.spectrocloud_pack.vmware_csi.values\n    type   = "spectro"\n  }\n\n  pack {\n    name   = data.spectrocloud_pack.vmware_metallb.name\n    tag    = data.spectrocloud_pack.vmware_metallb.version\n    uid    = data.spectrocloud_pack.vmware_metallb.id\n    values = replace(data.spectrocloud_pack.vmware_metallb.values, "192.168.10.0/24", var.metallb_ip)\n    type   = "oci"\n  }\n\n  pack {\n    name = data.spectrocloud_pack.hellouniverse.name\n    tag  = data.spectrocloud_pack.hellouniverse.version\n    uid  = data.spectrocloud_pack.hellouniverse.id\n    values = templatefile("manifests/values-3tier.yaml", {\n      namespace   = var.app_namespace,\n      port        = var.app_port,\n      replicas    = var.replicas_number,\n      db_password = base64encode(var.db_password),\n      auth_token  = base64encode(var.auth_token)\n    })\n    type = "oci"\n  }\n}\n'})}),"\n",(0,n.jsx)(t.h4,{id:"data-resources",children:"Data Resources"}),"\n",(0,n.jsxs)(t.p,{children:["Each ",(0,n.jsx)(t.code,{children:"pack {}"})," block contains references to a data resource.\n",(0,n.jsx)(t.a,{href:"https://developer.hashicorp.com/terraform/language/data-sources",children:"Data resources"})," are used to perform read actions in\nTerraform. The Spectro Cloud Terraform provider exposes several data resources to help you make your Terraform code more\ndynamic. The data resource used in the cluster profile is ",(0,n.jsx)(t.code,{children:"spectrocloud_pack"}),". This resource enables you to query\nPalette for information about a specific pack, such as its unique ID, registry ID, available versions, and YAML values."]}),"\n",(0,n.jsxs)(t.p,{children:["Below is the data resource used to query Palette for information about the Kubernetes pack for version ",(0,n.jsx)(t.code,{children:"1.28.13"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-hcl",children:'data "spectrocloud_pack" "vmware_k8s" {\n  name         = "kubernetes"\n  version      = "1.32.3"\n  registry_uid = data.spectrocloud_registry.public_registry.id\n}\n'})}),"\n",(0,n.jsxs)(t.p,{children:["Using the data resource helps you avoid manually entering the parameter values required by the cluster profile's\n",(0,n.jsx)(t.code,{children:"pack {}"})," block."]}),"\n",(0,n.jsx)(t.h4,{id:"cluster",children:"Cluster"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.strong,{children:"cluster
1s.tf"})," file contains the definitions required for deploying a host cluster to one of the infrastructure\nproviders. To create a VMware vSphere host cluster, you must set the ",(0,n.jsx)(t.code,{children:"deploy-vmware"})," variable in the\n",(0,n.jsx)(t.strong,{children:"terraform.tfvars"})," file to true."]}),"\n",(0,n.jsxs)(t.p,{children:["When deploying a cluster using Terraform, you must provide the same parameters as those available in the Palette UI for\nthe cluster deployment step, such as the instance size and number of nodes. You can learn more about each parameter by\nreviewing the\n",(0,n.jsx)(t.a,{href:"https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs/resources/cluster_vsphere",children:"VMware vSphere cluster resource"}),"\ndocumentation."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-hcl",children:'resource "spectrocloud_cluster_vsphere" "vmware-cluster" {\n  count = var.deploy-vmware ? 1 : 0\n\n  name             = "vmware-cluster"\n  tags             = concat(var.tags, ["env:vmware"])\n  cloud_account_id = data.spectrocloud_cloudaccount_vsphere.account[0].id\n\n  cloud_config {\n    ssh_keys              = [local.ssh_public_key]\n    datacenter            = var.datacenter_name\n    folder                = var.folder_name\n    static_ip             = var.deploy-vmware-static # If true, the cluster will use static IP placement. If false, the cluster will use DDNS.\n    network_search_domain = var.search_domain\n  }\n\n  cluster_profile {\n    id = var.deploy-vmware && var.deploy-vmware-kubecost ? resource.spectrocloud_cluster_profile.vmware-profile-kubecost[0].id : resource.spectrocloud_cluster_profile.vmware-profile[0].id\n  }\n\n  scan_policy {\n    configuration_scan_schedule = "0 0 * * SUN"\n    penetration_scan_schedule   = "0 0 * * SUN"\n    conformance_scan_schedule   = "0 0 1 * *"\n  }\n\n  machine_pool {\n    name                    = "control-plane-pool"\n    count                   = 1\n    control_plane           = true\n    control_plane_as_worker = true\n\n    instance_type {\n      cpu          = 4\n      disk_size_gb = 60\n      memory_mb    = 8000\n    }\n\n    placement {\n      cluster       = var.vsphere_cluster\n      datastore     = var.datastore_name\n      network       = var.network_name\n      resource_pool = var.resource_pool_name\n      # Required for static IP placement.\n      static_ip_pool_id = var.deploy-vmware-static ? resource.spectrocloud_privatecloudgateway_ippool.ippool[0].id : null\n    }\n\n  }\n\n  machine_pool {\n    name          = "worker-pool"\n    count         = 1\n    control_plane = false\n\n    instance_type {\n      cpu          = 4\n      disk_size_gb = 60\n      memory_mb    = 8000\n    }\n\n    placement {\n      cluster       = var.vsphere_cluster\n      datastore     = var.datastore_name\n      network       = var.network_name\n      resource_pool = var.resource_pool_name\n      # Required for static IP placement.\n      static_ip_pool_id = var.deploy-vmware-static ? resource.spectrocloud_privatecloudgateway_ippool.ippool[0].id : null\n    }\n  }\n}\n'})}),"\n",(0,n.jsx)(t.h2,{id:"terraform-tests",children:"Terraform Tests"}),"\n",(0,n.jsx)(t.p,{children:"Before starting the cluster deployment, test the Terraform code to ensure the resources will be provisioned correctly."}),"\n",(0,n.jsxs)(t.p,{children:["Issue the following command in your terminal to initialize Terraform. The ",(0,n.jsx)(t.code,{children:"init"})," command initializes the working\ndirectory that contains the Terraform files."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"terraform init\n"})}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-text",metastring:"hideClipboard",children:"Terraform has been successfully initialized!\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Next, issue the ",(0,n.jsx)(t.code,{children:"terraform test"})," command to start the tests."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"terraform test\n"})}),"\n",(0,n.jsx)(t.p,{children:"A successful test execution will output the following."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-text",metastring:"hideClipboard",children:"Success! 16 passed, 0 failed.\n"})}),"\n",(0,n.jsx)(t.h2,{id:"input-variables",children:"Input Variables"}),"\n",(0,n.jsxs)(t.p,{children:["To deploy a cluster using Terraform, you must first modify the ",(0,n.jsx)(t.strong,{children:"terraform.tfvars"})," file. Open it in the editor of your\nchoice. The tutorial container includes the editor ",(0,n.jsx)(t.a,{href:"https://www.nano-editor.org",children:"Nano"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["The file is structured with different sections. Each provider has a section with variables that need to be filled 
1in,\nidentified by the placeholder ",(0,n.jsx)(t.code,{children:"REPLACE_ME"}),". Additionally, there is a toggle variable named ",(0,n.jsx)(t.code,{children:"deploy-<cloud-provider>"}),"\navailable for each provider, which you can use to select the deployment environment."]}),"\n",(0,n.jsxs)(t.p,{children:["In the ",(0,n.jsx)(t.strong,{children:"Palette Settings"})," section, modify the name of the ",(0,n.jsx)(t.code,{children:"palette-project"})," variable if you wish to deploy to a\nPalette project different from the default one."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-hcl",metastring:"{4}",children:'#####################\n# Palette Settings\n#####################\npalette-project = "Default" # The name of your project in Palette.\n'})}),"\n",(0,n.jsxs)(t.p,{children:["Next, in the ",(0,n.jsx)(t.strong,{children:"Hello Universe Configuration"})," section, provide values for the database password and authentication token\nfor the Hello Universe pack. For example, you can use the value ",(0,n.jsx)(t.code,{children:"password"})," for the database password and the default\ntoken provided in the\n",(0,n.jsx)(t.a,{href:"https://github.com/spectrocloud/hello-universe/tree/main?tab=readme-ov-file#reverse-proxy-with-kubernetes",children:"Hello Universe"}),"\nrepository for the authentication token."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-hcl",metastring:"{7-8}",children:'##############################\n# Hello Universe Configuration\n##############################\napp_namespace   = "hello-universe" # The namespace in which the application will be deployed.\napp_port        = 8080             # The cluster port number on which the service will listen for incoming traffic.\nreplicas_number = 1                # The number of pods to be created.\ndb_password     = "REPLACE ME"     # The database password to connect to the API database.\nauth_token      = "REPLACE ME"     # The auth token for the API connection.\n'})}),"\n",(0,n.jsxs)(t.p,{children:["Locate the VMware vSphere provider section and change ",(0,n.jsx)(t.code,{children:"deploy-vmware = false"})," to ",(0,n.jsx)(t.code,{children:"deploy-vmware = true"}),". Additionally,\nreplace all occurrences of ",(0,n.jsx)(t.code,{children:"REPLACE_ME"})," with the required variable values."]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"metallb_ip"})," - Range of IP addresses for your MetalLB load balancer. If using static IP placement, this range must be\nincluded in the PCG static IP pool range."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"pcg_name"})," - Name of the PCG that will be used to deploy the Palette cluster."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"datacenter_name"})," - Name of the data center in vSphere."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"folder_name"})," - Name of the folder in vSphere."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"search_domain"})," - Name of the network search domain."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"vsphere_cluster"})," - Name of the cluster as it appears in vSphere."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"datastore_name"})," - Name of the datastore as it appears in vSphere."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"network_name"})," - Name of the network as it appears in vSphere."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"resource_pool_name"})," - Name of the resource pool as it appears in vSphere."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"ssh_key"})," - Path to a public SSH key. If not provided, a new key pair will be created."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"ssh_key_private"})," - Path to a private SSH key. If not provided, a new key pair will be created."]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-hcl",metastring:"{4,7-15}",children:'############################\n# VMware Deployment Settings\n############################\ndeploy-vmware          = false # Set to true to deploy to VMware.\ndeploy-vmware-kubecost = false # Set to true to deploy to VMware and include Kubecost to your cluster profile.\n\nmetallb_ip         = "REPLACE ME"\npcg_name           = "REPLACE ME"\ndatacenter_name    = "REPLACE ME"\nfolder_name        = "REPLACE ME"\nsearch_domain      = "REPLACE ME"\nvsphere_cluster    = "REPLACE ME"\ndatastore_name     = "REPLACE ME"\nnet
1work_name       = "REPLACE ME"\nresource_pool_name = "REPLACE ME"\nssh_key            = ""\nssh_key_private    = ""\n'})}),"\n",(0,n.jsx)(t.admonition,{type:"info",children:(0,n.jsxs)(t.p,{children:["If you deployed the PCG using static IP placement, you must create an\n",(0,n.jsx)(t.a,{href:"/clusters/pcg/manage-pcg/create-manage-node-pool",children:"IPAM pool"})," before deploying clusters. Set the\n",(0,n.jsx)(t.code,{children:"deploy-vmware-static"})," variable to true and provide the required values for the variables under the ",(0,n.jsx)(t.strong,{children:"Static IP Pool\nVariables"})," section."]})}),"\n",(0,n.jsx)(t.p,{children:"When you are done making the required changes, save the file."}),"\n",(0,n.jsx)(t.h2,{id:"deploy-the-cluster",children:"Deploy the Cluster"}),"\n",(0,n.jsxs)(t.p,{children:["Before starting the cluster provisioning, export your ",(0,n.jsx)(t.a,{href:"/tutorials/getting-started/palette/vmware/setup#create-a-palette-api-key",children:"Palette API key"})," as an\nenvironment variable. This step allows the Terraform code to authenticate with the Palette API."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"export SPECTROCLOUD_APIKEY=<Your-Spectro-Cloud-API-key>\n"})}),"\n",(0,n.jsx)(t.admonition,{type:"warning",children:(0,n.jsxs)(t.p,{children:["Before deploying the resources, ensure that there are no active clusters named ",(0,n.jsx)(t.code,{children:"vmware-cluster"})," or cluster profiles\nnamed ",(0,n.jsx)(t.code,{children:"tf-vmware-profile"})," in your Palette project."]})}),"\n",(0,n.jsxs)(t.p,{children:["Issue the ",(0,n.jsx)(t.code,{children:"plan"})," command to preview the resources that Terraform will create."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"terraform plan\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The output indicates that six new resources will be created: two versions of the VMware vSphere cluster profile, the\nhost cluster, and the files associated with the SSH key pair if you have not provided one. The host cluster will use\nversion ",(0,n.jsx)(t.code,{children:"1.0.0"})," of the cluster profile."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"Plan: 6 to add, 0 to change, 0 to destroy.\n"})}),"\n",(0,n.jsxs)(t.p,{children:["To deploy the resources, use the ",(0,n.jsx)(t.code,{children:"apply"})," command."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"terraform apply -auto-approve\n"})}),"\n",(0,n.jsxs)(t.p,{children:["To check that the cluster profile was created correctly, log in to ",(0,n.jsx)(t.a,{href:"https://console.spectrocloud.com",children:"Palette"}),", and\nclick ",(0,n.jsx)(t.strong,{children:"Profiles"})," from the left ",(0,n.jsx)(t.strong,{children:"Main Menu"}),". Locate the cluster profile named ",(0,n.jsx)(t.code,{children:"tf-vmware-profile"}),". Click on the\ncluster profile to review its layers and versions."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"A view of the cluster profile",src:r(331927).A+"",width:"2888",height:"1670"})}),"\n",(0,n.jsxs)(t.p,{children:["You can also check the cluster creation process by selecting ",(0,n.jsx)(t.strong,{children:"Clusters"})," from the left ",(0,n.jsx)(t.strong,{children:"Main Menu"}),"."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Update the cluster",src:r(326492).A+"",width:"2890",height:"1652"})}),"\n",(0,n.jsx)(t.p,{children:"Select your cluster to review its details page, which contains the status, cluster profile, event logs, and more."}),"\n",(0,n.jsxs)(t.p,{children:["The cluster deployment may take 15 to 30 minutes depending on the cloud provider, cluster profile, cluster size, and the\nnode pool configurations provided. You can learn more about the deployment progress by reviewing the event log. Click on\nthe ",(0,n.jsx)(t.strong,{children:"Events"})," tab to check the log."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Update the cluster",src:r(227474).A+"",width:"2896",height:"1938"})}),"\n",(0,n.jsx)(t.h3,{id:"verify-the-application",children:"Verify the Application"}),"\n",(0,n.jsxs)(t.p,{children:["In Palette, navigate to the left ",(0,n.jsx)(t.strong,{children:"Main Menu"}
1)," and select ",(0,n.jsx)(t.strong,{children:"Clusters"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["Select your cluster to view its ",(0,n.jsx)(t.strong,{children:"Overview"})," tab. When the application is deployed and ready for network traffic,\nindicated in the ",(0,n.jsx)(t.strong,{children:"Services"})," field, Palette exposes the service URL. Click on the URL for port ",(0,n.jsx)(t.strong,{children:":8080"})," to access the\nHello Universe application."]}),"\n",(0,n.jsx)(t.admonition,{type:"warning",children:(0,n.jsx)(t.p,{children:"It can take up to three minutes for DNS to properly resolve the public load balancer URL. We recommend waiting a few\nmoments before clicking on the service URL to prevent the browser from caching an unresolved DNS request."})}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Deployed application",src:r(608337).A+"",width:"2532",height:"2198"})}),"\n",(0,n.jsx)(t.p,{children:"Welcome to the Spacetastic astronomy education platform. Feel free to explore the pages and learn more about space. The\nstatistics page offers information on visitor counts on your deployed service."}),"\n",(0,n.jsx)(t.h2,{id:"version-cluster-profiles",children:"Version Cluster Profiles"}),"\n",(0,n.jsx)(t.p,{children:"Palette supports the creation of multiple cluster profile versions using the same profile name. This provides you with\nbetter change visibility and control over the layers in your host clusters. Profile versions are commonly used for\nadding or removing layers and pack configuration updates."}),"\n",(0,n.jsxs)(t.p,{children:["The version number of a given profile must be unique and use the semantic versioning format ",(0,n.jsx)(t.code,{children:"major.minor.patch"}),". In this\ntutorial, you used Terraform to deploy two versions of a VMware vSphere cluster profile. The snippet below displays a\nsegment of the Terraform cluster profile resource version ",(0,n.jsx)(t.code,{children:"1.0.0"})," that was deployed."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-hcl",metastring:"{4,9}",children:'resource "spectrocloud_cluster_profile" "vmware-profile" {\n  count = var.deploy-vmware ? 1 : 0\n\n  name        = "tf-vmware-profile"\n  description = "A basic cluster profile for VMware"\n  tags        = concat(var.tags, ["env:VMware"])\n  cloud       = "vsphere"\n  type        = "cluster"\n  version     = "1.0.0"\n'})}),"\n",(0,n.jsxs)(t.p,{children:["Open the ",(0,n.jsx)(t.strong,{children:"terraform.tfvars"})," file, set the ",(0,n.jsx)(t.code,{children:"deploy-vmware-kubecost"})," variable to true, and save the file. Once applied,\nthe host cluster will use version ",(0,n.jsx)(t.code,{children:"1.1.0"})," of the cluster profile with the Kubecost pack."]}),"\n",(0,n.jsxs)(t.p,{children:["The snippet below displays the segment of the Terraform resource that creates the cluster profile version ",(0,n.jsx)(t.code,{children:"1.1.0"}),". Note\nhow the name ",(0,n.jsx)(t.code,{children:"tf-vmware-profile"})," is the same as in the first cluster profile resource, but the version is different."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-hcl",metastring:"{4,9}",children:'resource "spectrocloud_cluster_profile" "vmware-profile-kubecost" {\n  count = var.deploy-vmware ? 1 : 0\n\n  name        = "tf-vmware-profile"\n  description = "A basic cluster profile for VMware with Kubecost"\n  tags        = concat(var.tags, ["env:VMware"])\n  cloud       = "vsphere"\n  type        = "cluster"\n  version     = "1.1.0"\n'})}),"\n",(0,n.jsx)(t.p,{children:"In the terminal window, issue the following command to plan the changes."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"terraform plan\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The output states that one resource will be modified. The deployed cluster will now use version ",(0,n.jsx)(t.code,{children:"1.1.0"})," of the cluster\nprofile."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-text",metastring:"hideClipboard",children:"Plan: 0 to add, 1 to change, 0 to destroy.\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Issue the ",(0,n.jsx)(t.code,{children:"apply"})," command to deploy the changes."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"terraform apply -auto-approve\n"})}),"\n",(0,n.jsx)(t.p,{children:"Palette will now reconcile the current state of your workloads with the desired state specified by the new cluster\nprofile version."}),"\n",(0,n.jsxs)(t.p,{children:["To visualize the reconciliation behavior, log in to ",(0,n.jsx)(t.a,{href:"https://console.spectrocloud.com",children:"Palette"}
1),", and click ",(0,n.jsx)(t.strong,{children:"Clusters"}),"\nfrom the left ",(0,n.jsx)(t.strong,{children:"Main Menu"}),"."]}),"\n",(0,n.jsxs)(t.p,{children:["Select the cluster named ",(0,n.jsx)(t.code,{children:"vmware-cluster"}),". Click on the ",(0,n.jsx)(t.strong,{children:"Events"})," tab. Note how a cluster reconciliation action was\ntriggered due to cluster profile changes."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Image that shows the cluster profile reconciliation behavior",src:r(596893).A+"",width:"2888",height:"1930"})}),"\n",(0,n.jsxs)(t.p,{children:["Next, click on the ",(0,n.jsx)(t.strong,{children:"Profile"})," tab. Observe that the cluster is now using version ",(0,n.jsx)(t.code,{children:"1.1.0"})," of the ",(0,n.jsx)(t.code,{children:"tf-vmware-profile"}),"\ncluster profile."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Image that shows the new cluster profile version with Kubecost",src:r(303123).A+"",width:"2888",height:"1930"})}),"\n",(0,n.jsxs)(t.p,{children:["Once the changes have been completed, Palette marks the cluster layers with a green status indicator. Click the\n",(0,n.jsx)(t.strong,{children:"Overview"})," tab to verify that the Kubecost pack was successfully deployed."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Image that shows the cluster with Kubecost",src:r(575127).A+"",width:"2894",height:"1936"})}),"\n",(0,n.jsxs)(t.p,{children:["Next, download the ",(0,n.jsx)(t.a,{href:"/clusters/cluster-management/kubeconfig",children:"kubeconfig"})," file for your cluster from the\nPalette UI. This file enables you and other users to issue ",(0,n.jsx)(t.code,{children:"kubectl"})," commands against the host cluster."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Image that shows the cluster&#39;s kubeconfig file location",src:r(790043).A+"",width:"2886",height:"1928"})}),"\n",(0,n.jsxs)(t.p,{children:["Open a new terminal window and set the environment variable ",(0,n.jsx)(t.code,{children:"KUBECONFIG"})," to point to the kubeconfig file you downloaded."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"export KUBECONFIG=~/Downloads/admin.vmware-cluster.kubeconfig\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Forward the Kubecost UI to your local network. The Kubecost dashboard is not exposed externally by default, so the\ncommand below will allow you to access it locally on port ",(0,n.jsx)(t.strong,{children:"9090"}),". If port 9090 is already taken, you can choose a\ndifferent one."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"kubectl port-forward --namespace kubecost deployment/cost-analyzer-cost-analyzer 9090\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Open your browser window and navigate to ",(0,n.jsx)(t.code,{children:"http://localhost:9090"}),". The Kubecost UI provides you with a variety of cost\ninformation about your cluster."]}),"\n",(0,n.jsxs)(t.p,{children:["To use Kubecost in VMware vSphere clusters, you must enable the\n",(0,n.jsx)(t.a,{href:"https://docs.kubecost.com/architecture/pricing-sources-matrix#cloud-provider-on-demand-api",children:"custom pricing"})," option in\nthe Kubecost UI and manually set the monthly cluster costs."]}),"\n",(0,n.jsxs)(t.p,{children:["Read more about ",(0,n.jsx)(t.a,{href:"https://docs.kubecost.com/using-kubecost/navigating-the-kubecost-ui",children:"Navigating the Kubecost UI"})," to\nmake the most of the cost analyzer pack."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Image that shows the Kubecost UI",src:r(630180).A+"",width:"3244",height:"2144"})}),"\n",(0,n.jsxs)(t.p,{children:["Once you are done exploring the Kubecost dashboard, stop the ",(0,n.jsx)(t.code,{children:"kubectl port-forward"})," command by closing the terminal\nwindow it is executing from."]}),"\n",(0,n.jsx)(t.h2,{id:"roll-back-cluster-profiles",children:"Roll Back Cluster Profiles"}),"\n",(0,n.jsx)(t.p,{children:"One of the key advantages of using cluster profile versions is that they make it possible to maintain a copy of\npreviously known working states. The ability to roll back to a previously working cluster profile in one action shortens\nthe time to recovery in the event of an incident."}),"\n",(0,n.jsx)(t.p,{children:"The process of rolling back to a previous version using Terraform is similar to the process of applying a new version."}),"\n",(0,n.jsxs)(t.p,{children:["Open the ",(0,n.jsx)(t.strong,{children:"terraform.tfvars"})," file, set the ",(0,n.jsx)(t.code,{children:"deploy-vmware-kubecost"})," variable to false, and save the file. Once applied,\nthis action will make the active cluster use version ",(0,n.jsx)(t.strong,{children:"1.0.0"})," of the cluster profile again."]}),"\n",(0,n.jsx)(t.p,{children:"In the terminal window, issue the following command to plan the changes."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"terraform plan\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The output states that the deployed cluster will now use version ",(0,n.jsx)(t.code,{children:"1.0.0"})," of the cluster profile."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-text",metastring:"hideClipboard",children:"Plan: 0 to add, 1 to change, 0 to destroy.\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Issue the ",(0,n.jsx)(t.code,{children:"apply"})," command to deploy the changes."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"terraform apply -auto-approve\n"})}),"\n",(0,n.jsxs)(t.p,{children:["Palette now makes the changes required for the cluster to return to the state specified in version ",(0,n.jsx)(t.code,{children:"1.0.0"})," of your\ncluster profile. Once your changes have completed, Palette marks your layers with the green status indicator."]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Image that shows the cluster using version 1.0.0 of the cluster profile",src:r(336659).A+"",width:"2886",height:"1928"})}),"\n",(0,n.jsx)(t.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,n.jsxs)(t.p,{children:["Use the following steps to clean up the resources you created for the tutorial. Use the ",(0,n.jsx)(t.code,{children:"destroy"})," command to remove all\nthe resources you created through Terraform."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"terraform destroy --auto-approve\n"})}),"\n",(0,n.jsxs)(t.p,{children:["A successful execution of ",(0,n.jsx)(t.code,{children:"terraform destroy"})," will output the following."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"Destroy complete! Resources: 6 destroyed.\n"})}
1),"\n",(0,n.jsx)(s,{category:"clusters",name:"force-delete-callout"}),"\n",(0,n.jsxs)(t.p,{children:["If you are using the tutorial container, type ",(0,n.jsx)(t.code,{children:"exit"})," in your terminal session and press the ",(0,n.jsx)(t.strong,{children:"Enter"})," key. Next, issue\nthe following command to stop and remove the container."]}),"\n",(0,n.jsxs)(l,{children:[(0,n.jsx)(a,{label:"Docker",value:"docker",children:(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"docker stop tutorialContainer && \\\ndocker rmi --force ghcr.io/spectrocloud/tutorials:1.3.0\n"})})}),(0,n.jsx)(a,{label:"Podman",value:"podman",children:(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-shell",children:"podman stop tutorialContainer && \\\npodman rmi --force ghcr.io/spectrocloud/tutorials:1.3.0\n"})})})]}),"\n",(0,n.jsx)(t.h2,{id:"wrap-up",children:"Wrap-Up"}),"\n",(0,n.jsx)(t.p,{children:"In this tutorial, you learned how to create different versions of a cluster profile using Terraform. You deployed a host\nVMware vSphere cluster and then updated it to use a different version of a cluster profile. Finally, you learned how to\nperform cluster profile roll backs."}),"\n",(0,n.jsxs)(t.p,{children:["We encourage you to check out the ",(0,n.jsx)(t.a,{href:"/tutorials/getting-started/palette/vmware/scale-secure-cluster",children:"Scale, Upgrade, and Secure Clusters"})," tutorial to learn how\nto perform common Day-2 operations on your deployed clusters."]}),"\n",(0,n.jsx)(t.h2,{id:"-catch-up-with-spacetastic",children:"\u{1F9D1}\u200D\u{1F680} Catch up with Spacetastic"}),"\n",(0,n.jsx)(s,{category:"getting-started",name:"spacetastic-deploy-cluster-tf-end"})]})}function h(e={}){let{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}function p(e,t){throw Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},608337:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-k8s-cluster_hello-universe-with-api-383d5c0d85757604c4422ab8ee388765.webp"},326492:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-manage-k8s-cluster-tf_create_cluster-74dd13114468453b54fe5f1ee520a005.webp"},227474:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-manage-k8s-cluster-tf_event_log-5b80e8be3e496e291c3b22a1a9d53640.webp"},331927:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-manage-k8s-cluster-tf_profile_review-00cce1eff46022b2c80bb2475830b415.webp"},790043:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-manage-k8s-cluster_kubeconfig-1b702e0dae6637033c1c94e4d979f2ad.webp"},630180:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-manage-k8s-cluster_kubecost-7e65633ec4605de30c965e758a5e54dc.webp"},303123:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-manage-k8s-cluster_profile-with-cluster-5e4ced2df8bcf59d912c01758bf2a77d.webp"},575127:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-manage-k8s-cluster_profile-with-kubecost-0fa197644f5fa9bcecc7aa0f1d309d29.webp"},336659:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-manage-k8s-cluster_profile-without-kubecost-35b8e573898af7c89a7e756c6fb39b85.webp"},596893:function(e,t,r){r.d(t,{A:()=>s});let s=r.p+"assets/images/getting-started_deploy-manage-k8s-cluster_reconciliation-8e9df2e3c5c24accf35a24db71de56f6.webp"},884429:function(e,t,r){r.d(t,{R:()=>a,x:()=>l});var s=r(296540);let n={},o=s.createContext(n);function a(e){let t=s.useContext(o);return s.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.