Q:

Terraform: starting a GKE cluster and Ingress app with one apply

I am fairly new to Terraform and am attempting to set-up a GCP GKE cluster and then connect it to an Ingress application. I was able to successfully do so following this tutorial: https://www.youtube.com/watch?v=Vcv6GapxUCI. Here is a link to the Github repo from the tutorial if you would like to see how the main.tf file is structured: https://github.com/alexandarp/terraform-gke.
However, this method involves using Terraform to create the GKE cluster first then separately use the gcloud command line command to get the cluster credentials and then run several “kubectl apply” commands to create the Ingress application from a set of .yaml files. So basically, it becomes a two-step process of creating the GKE cluster and then separately creating an Ingress application.
My question is: is it possible to do both steps using only one “terraform apply” command? That is, have one Terraform file that both creates the GKE cluster and then also creates the Ingress application as well?  Again, I am fairly new to Terraform, so if this is out of the scope of its capabilities, I understand! Any direction on where to move with this problem would be greatly appreciated!

A:

Yes, use provider "kubernetes" {}
See a working example below for your reference. In this example, I am creating an example namespace using resource "kubernetes_namespace" "example" {}.
You will be using resource "kubernetes_deployment" "example" {} and resource "kubernetes_service" "example" {}. See the docs here for more details.

main.tf

provider "google" {
  credentials = file("account.json")
  project     = "my-project-id"
  region      = "us-central1"
}

# Create GKE Cluster
resource "google_container_cluster" "primary" {
  name               = "marcellus-wallace"
  location           = "us-central1-a"
  initial_node_count = 1

  master_auth {
    username = ""
    password = ""

    client_certificate_config {
      issue_client_certificate = false
    }
  }

  node_config {
    oauth_scopes = [
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
    ]

    metadata = {
      disable-legacy-endpoints = "true"
    }

    labels = {
      foo = "bar"
    }

    tags = ["foo", "bar"]
  }

  timeouts {
    create = "30m"
    update = "40m"
  }
}

data "google_client_config" "default" {}

data "google_container_cluster" "my_cluster" {
  name     = "${google_container_cluster.primary.name}"
  location = "us-central1-a"
}

# Kubernetes Provider
provider "kubernetes" {
  config_context_cluster = "${google_container_cluster.primary.name}"
  load_config_file       = false
  host                   = "https://${data.google_container_cluster.my_cluster.endpoint}"
  token                  = "${data.google_client_config.default.access_token}"
  cluster_ca_certificate = "${base64decode(data.google_container_cluster.my_cluster.master_auth.0.cluster_ca_certificate)}"
}

# Deploy resources on GKE
resource "kubernetes_namespace" "example" {
  metadata {
    annotations = {
      name = "example-annotation"
    }

    labels = {
      mylabel = "label-value"
    }

    name = "terraform-example-namespace"
  }
}

