{"id":691,"date":"2018-09-24T08:39:24","date_gmt":"2018-09-24T05:39:24","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/2018\/09\/24\/terraform-kubernetes-provider\/"},"modified":"2018-09-24T08:39:24","modified_gmt":"2018-09-24T05:39:24","slug":"terraform-kubernetes-provider","status":"publish","type":"post","link":"https:\/\/upcloud.com\/global\/blog\/terraform-kubernetes-provider\/","title":{"rendered":"What is Terraform Kubernetes provider and how to use it"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">As <a href=\"https:\/\/kubernetes.io\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes<\/a> continues to dominate the container orchestration space in the technology industry, infrastructure automation products are all expanding their feature sets to include a method to connect to and configure Kubernetes so it can be managed along with the other resources you are already managing with your choice of automation tool.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As a leading infrastructure-as-code product, <a href=\"https:\/\/upcloud.com\/global\/blog\/upcloud-verified-terraform-provider\">Terraform<\/a> has a connector called the <a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">Kubernetes provider<\/a>. Let\u2019s take a look at what you can do with it.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/signup.upcloud.com\/\">Test hosting on UpCloud!<\/a><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Can the Kubernetes provider build a cluster?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">No, the provider will not build and deploy a Kubernetes cluster. The Kubernetes provider requires a cluster to be up and running before you can use it. If you are wanting Terraform to build and deploy a Kubernetes cluster in the public cloud, you would use the cloud-specific provider. An example would be using the <a href=\"https:\/\/github.com\/UpCloudLtd\/terraform-provider-upcloud\" target=\"_blank\" rel=\"noopener noreferrer\">Terraform Provider from UpCloud<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Simple scenario for the Terraform Kubernetes provider<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A simple but common use case for interacting with Kubernetes using the Terraform Kubernetes provider is to create a namespace, deploying an application as a pod, and then exposing it as a service. Below are examples of the configuration that you would use for Terraform.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 1: Configure the provider<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The easiest way to handle credentials is to create a default kube configuration pointing to your cluster. The default location for this file is <tt>~\/.kube\/config<\/tt>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to have it included in your Terraform instance, it would look like this:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">provider \"kubernetes\" {\n  host = \"https:\/\/1.2.3.4\"\n\n  username = \"AccountNameWithAccess\"\n  password = \"GuessMe!\"\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 2: Deploy NGINX in a pod<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">resource \"kubernetes_pod\" \"nginx\" {\n  metadata {\n    name = \"nginx-example\"\n    labels {\n      App = \"nginx\"\n    }\n  }\n\n  spec {\n    container {\n      image = \"nginx:1.15.2\"\n      name  = \"example\"\n\n      port {\n        container_port = 80\n      }\n    }\n  }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Step 3: Create a service to expose NGINX externally<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">resource \"kubernetes_service\" \"nginx\" {\n  metadata {\n    name = \"nginx-example\"\n  }\n  spec {\n    selector {\n      App = \"${kubernetes_pod.nginx.metadata.0.labels.App}\"\n    }\n    port {\n      port = 80\n      target_port = 80\n    }\n\n    type = \"LoadBalancer\"\n  }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will also want the Terraform <tt>apply<\/tt> command to output the load balancer\u2019s IP, so add this to the bottom of the script before running it. If you replace both instances of \u201cip\u201d with \u201chostname\u201d, it will provide a hostname if one is set.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">output \"lb_ip\" {\n  value = \"${kubernetes_service.nginx.load_balancer_ingress.0.ip}\"\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Any configuration that is passed into the container instances uses a <a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/r\/config_map.html\" target=\"_blank\" rel=\"noopener noreferrer\">config_map<\/a>, which is not the best way to treat things that are sensitive. If the container instances need to have sensitive information that you don\u2019t want to expose to the entire cluster in order to successfully operate, then the Kubernetes provider has a mechanism to handle <a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/r\/secret.html\" target=\"_blank\" rel=\"noopener noreferrer\">secrets<\/a>. These secrets are most often certificates, API Keys, and credentials used to access services.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Persistent storage<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The scenario above does not define any persistent volumes\u2014It is strictly ephemeral storage. In reality, many applications (like databases) require data to persist between restarts of a container runtime.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Kubernetes provider has all the functionality required to create a <a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/r\/storage_class.html\" target=\"_blank\" rel=\"noopener noreferrer\">storage class<\/a> to define where <a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/r\/persistent_volume.html\" target=\"_blank\" rel=\"noopener noreferrer\">persistent volumes<\/a> can be created, and the ability to <a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/r\/persistent_volume_claim.html\" target=\"_blank\" rel=\"noopener noreferrer\">claim<\/a> those volumes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Scaling and quotas<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Kubernetes\u2019 largest strength is handling the orchestration of multiple instances of an application across multiple nodes. To manage these capabilities, there are multiple resources available.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/r\/horizontal_pod_autoscaler.html\" target=\"_blank\" rel=\"noopener noreferrer\">Horizontal Pod Autoscaler<\/a> sets the minimum and maximum number of replicas that should be run of any given pod. The Kubernetes cluster will scale based on CPU usage of containers.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There is a resource to activate the <a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/r\/replication_controller.html\" target=\"_blank\" rel=\"noopener noreferrer\">Replication Controller<\/a>, which will enforce the rules as they have been defined. (Too many pods and some will be killed, too few and some will be started.) Typically, the replication controller regularly runs against the cluster as is, but there are instances where you want immediate action, like when you increase the maximum number via the autoscaler resource.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/r\/limit_range.html\" target=\"_blank\" rel=\"noopener noreferrer\">Limits<\/a> and <a href=\"https:\/\/www.terraform.io\/docs\/providers\/kubernetes\/r\/resource_quota.html\" target=\"_blank\" rel=\"noopener noreferrer\">quotas<\/a> can be used to limit the amount of resources that are consumed by individual namespaces. These resources are memory, CPU, and disk. Once there are limits in place, all pods that are started within that namespace will need to fit in within the defined quota.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Terraform Kubernetes provider provides all the features necessary to manage all the Kubernetes clusters in your environment\u2014across as many cloud providers as you want.<\/p>\n\n\n\n<div class=\"panel panel-primary\">\n<div class=\"panel-heading\">Guest post by Vince Power<\/div>\n<div class=\"panel-body\"><small>Vince Power is a Solution Architect who has a focus on cloud adoption and technology implementations using open source-based technologies. He has extensive experience with core computing and networking (IaaS), identity and access management (IAM), application platforms (PaaS), and continuous delivery.<\/small><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>As a leading infrastructure-as-code product, Terraform has a connector called the Kubernetes provider. Let\u2019s take a look at what you can do with it.<\/p>\n","protected":false},"author":3,"featured_media":60514,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_relevanssi_hide_post":"","_relevanssi_hide_content":"","_relevanssi_pin_for_all":"","_relevanssi_pin_keywords":"","_relevanssi_unpin_keywords":"","_relevanssi_related_keywords":"","_relevanssi_related_include_ids":"","_relevanssi_related_exclude_ids":"","_relevanssi_related_no_append":"","_relevanssi_related_not_related":"","_relevanssi_related_posts":"769,256,625,325,673,3892","_relevanssi_noindex_reason":"Blocked by a filter function","footnotes":""},"categories":[94],"tags":[],"class_list":["post-691","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guest-stories"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/posts\/691","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=691"}],"version-history":[{"count":0,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/posts\/691\/revisions"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=691"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/categories?post=691"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tags?post=691"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}