Service Mesh (ASM) supports using Terraform Kubernetes Provider to operate custom resources in ASM or modify mesh features starting from version 1.22.6.109. This topic introduces how to use Terraform to create or modify ASM custom resources through two examples.
Prerequisites
A kubectl client is connected to the ACK cluster. For more information, see Get a cluster kubeconfig and connect to the cluster using kubectl.
(Optional) Terraform is installed and configured locally.
You can also use Cloud Shell to perform all the operations demonstrated in this topic. Before you start, switch the Terraform version to ensure that the Terraform version is greater than 0.14.
(Optional) The tfk8s tool is installed.
Preparations
Before starting the demonstration process, we recommend that you create an empty directory as the Terraform project directory and create a provider.tf file in the directory with the following content.
provider "kubernetes" {
config_path = "~/.kube/config"
}This configuration file specifies the kubeconfig used by the Terraform Kubernetes Provider.
The complete directory structure in this topic is as follows:
terraform-Project # Terraform project directory
├── asmmeshconfig.tf # Scenario 2 tf file
├── virtualservice.tf # Scenario 1 tf file
├── provider.tf # provider file
└── resources # Used to store resource files, such as yaml, json, etc.
└── demo.yaml # Scenario 1 resource fileAfter the provider.tf file is created, initialize the Terraform project.
terraform initScenario 1: Use Terraform to create a VirtualService resource
Create a VirtualService resource file named
demo.yamlin the resources directory.apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: my-productpage-rule namespace: istio-system spec: hosts: - productpage.prod.svc.cluster.local # ignores rule namespace http: - timeout: 5s route: - destination: host: productpage.prod.svc.cluster.localCreate virtualservice.tf.
resource "kubernetes_manifest" "virtualservice_demo" { manifest = yamldecode(file("./resources/demo.yaml")) }Check the changes to Terraform resources.
terraform planExpected output:
Create and verify the resource.
Create the resource.
terraform apply --auto-approveVerify the resource.
kubectl get VirtualService -n istio-systemExpected output:
NAME GATEWAYS HOSTS AGE my-productpage-rule ["productpage.prod.svc.cluster.local"] 77s
(Optional) Clean up the resource.
terraform destroy -target=kubernetes_manifest.virtualservice_demo --auto-approve
Scenario 2: Modify the ASMMeshConfig resource to control mesh features
This scenario demonstrates how to modify an existing ASMMeshConfig resource to disable the default service mesh feature that rewrites health checks for Pods.
Import the ASMMeshConfig resource.
Use the tfk8s tool
Generate asmmeshconfig.tf.
kubectl get asmmeshconfig default -o yaml | tfk8s --strip -o asmmeshconfig.tfThe above command will directly generate the
asmmeshconfig.tffile with the expected content as follows.resource "kubernetes_manifest" "asmmeshconfig_default" { manifest = { "apiVersion" = "istio.alibabacloud.com/v1beta1" "kind" = "ASMMeshConfig" "metadata" = { "name" = "default" } "spec" = { "accessLogConfiguration" = {} "ambientConfiguration" = { "enabled" = false "redirectMode" = "" "waypoint" = {} "ztunnel" = {} } "cniConfiguration" = { "enabled" = true "excludeNamespaces" = "istio-system,kube-system" "repair" = {} } "enableGatewayAPI" = true "gatewayAPIInferenceExtension" = {} "ingressControllerMode" = "OFF" "ingressSelector" = "ingressgateway1" "ingressService" = "istio-ingressgateway1" "sidecarInjectorWebhookConfiguration" = {} "smcEnabled" = false } } }Import the ASMMeshConfig resource into the terraform state.
terraform import kubernetes_manifest.asmmeshconfig_default "apiVersion=istio.alibabacloud.com/v1beta1,name=default,kind=ASMMeshConfig"Expected output:
Import successful! The resources that were imported are shown above. These resources are now in your Terraform state and will henceforth be managed by Terraform. ╷ │ Warning: Apply needed after 'import' │ │ Please run apply after a successful import to realign the resource state to the configuration in Terraform. ╵Execute the
terraform applycommand to align the Terraform and Kubernetes resource states.terraform apply --auto-approvePartial expected output:
... # kubernetes_manifest.asmmeshconfig_default will be updated in-place ~ resource "kubernetes_manifest" "asmmeshconfig_default" { + manifest = { + apiVersion = "istio.alibabacloud.com/v1beta1" + kind = "ASMMeshConfig" + metadata = { + annotations = null + creationTimestamp = null ...
Use the terraform command
Import the ASMMeshConfig resource into the state.
terraform import kubernetes_manifest.asmmeshconfig_default "apiVersion=istio.alibabacloud.com/v1beta1,name=default,kind=ASMMeshConfig"Expected output:
Import successful! The resources that were imported are shown above. These resources are now in your Terraform state and will henceforth be managed by Terraform. ╷ │ Warning: Apply needed after 'import' │ │ Please run apply after a successful import to realign the resource state to the configuration in Terraform. ╵Generate asmmeshconfig.tf.
terraform show -no-color > asmmeshconfig.tfExpected file content:
resource "kubernetes_manifest" "asmmeshconfig_default" { object = { apiVersion = "istio.alibabacloud.com/v1beta1" kind = "ASMMeshConfig" metadata = { annotations = null creationTimestamp = null deletionGracePeriodSeconds = null deletionTimestamp = null finalizers = null generateName = null generation = null labels = null managedFields = null name = "default" namespace = null ownerReferences = null resourceVersion = null selfLink = null uid = null } spec = { accessLogConfiguration = {} adaptiveSchedulerConfiguration = {} ambientConfiguration = { redirectMode = "" waypoint = {} ztunnel = {} } cniConfiguration = { enabled = true repair = {} } localityLbSetting = { enabled = true } } } }Change
objecttomanifestin the asmmeshconfig.tf file and remove parameters withnullvalues. The following is the adjusted content of asmmeshconfig.tf.resource "kubernetes_manifest" "asmmeshconfig_default" { manifest = { apiVersion = "istio.alibabacloud.com/v1beta1" kind = "ASMMeshConfig" metadata = { name = "default" } spec = { accessLogConfiguration = {} adaptiveSchedulerConfiguration = {} ambientConfiguration = { redirectMode = "" waypoint = {} ztunnel = {} } cniConfiguration = { enabled = true repair = {} } localityLbSetting = { enabled = true } } } }Execute the
terraform applycommand to align the Terraform and Kubernetes resource states.terraform apply --auto-approvePartial expected output:
... # kubernetes_manifest.asmmeshconfig_default will be updated in-place ~ resource "kubernetes_manifest" "asmmeshconfig_default" { + manifest = { + apiVersion = "istio.alibabacloud.com/v1beta1" + kind = "ASMMeshConfig" + metadata = { + annotations = null + creationTimestamp = null ...
The parameters of terraform import in the steps above are explained as follows:
Parameter
Description
kubernetes_manifest
Terraform resource type, corresponding to the resource type in
asmmeshconfig.tf.asmmeshconfig_default
Terraform resource name, corresponding to the resource name in
asmmeshconfig.tf.apiVersion
The API version registered in the Kubernetes CRD. You can view the apiVersion of the resource by executing
kubectl get ${resource type} ${resource name}.kind
The resource type registered in the Kubernetes CRD. You can view the kind of the resource by executing
kubectl get ${resource type} ${resource name}.name
The name of the ASMMeshConfig resource to be imported, which is
defaultin this case. Since the ASMMeshConfig resource is a cluster-level Kubernetes resource, no namespace is specified here. For namespace-level resources, you can specify the namespace usingnamespace=${resource namespace}.Edit asmmeshconfig.tf to add the value of
spec.sidecarInjectorWebhookConfiguration.rewriteAppHTTPProbefield asfalseto disable the default service mesh feature that rewrites health checks for Pods.resource "kubernetes_manifest" "asmmeshconfig_default" { manifest = { "apiVersion" = "istio.alibabacloud.com/v1beta1" "kind" = "ASMMeshConfig" "metadata" = { "name" = "default" } "spec" = { "accessLogConfiguration" = {} "ambientConfiguration" = { "enabled" = false "redirectMode" = "" "waypoint" = {} "ztunnel" = {} } "cniConfiguration" = { "enabled" = true "excludeNamespaces" = "istio-system,kube-system" "repair" = {} } "enableGatewayAPI" = true "gatewayAPIInferenceExtension" = {} "ingressControllerMode" = "OFF" "ingressSelector" = "ingressgateway1" "ingressService" = "istio-ingressgateway1" "sidecarInjectorWebhookConfiguration" = { "rewriteAppHTTPProbe" = false } "smcEnabled" = false } } }Check the changes.
terraform planExpected output:
kubernetes_manifest.asmmeshconfig_default: Refreshing state... 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: # kubernetes_manifest.asmmeshconfig_default will be updated in-place ~ resource "kubernetes_manifest" "asmmeshconfig_default" { ~ manifest = { ~ spec = { ~ sidecarInjectorWebhookConfiguration = { + rewriteAppHTTPProbe = false } # (9 unchanged attributes hidden) } # (3 unchanged attributes hidden) } ~ object = { ~ spec = { ~ sidecarInjectorWebhookConfiguration = { + rewriteAppHTTPProbe = false } # (9 unchanged attributes hidden) } # (3 unchanged attributes hidden) } } Plan: 0 to add, 1 to change, 0 to destroy.NoteIf the changes in
manifestandobjectare inconsistent, it indicates that the Kubernetes resource has been modified through other means, and the actual state of the Kubernetes resource is different from the state recorded by Terraform. You can executeterraform refreshto update Terraform's state.Apply the changes.
terraform apply --auto-approveExpected output:
kubernetes_manifest.asmmeshconfig_default: Modifying... kubernetes_manifest.asmmeshconfig_default: Modifications complete after 1s ... Apply complete! Resources: 0 added, 1 changed, 0 destroyed.