From a77c2a72f24cdce521a1047f56e89bd785110534 Mon Sep 17 00:00:00 2001 From: Aleksei Krugliak Date: Sun, 1 Sep 2024 15:17:55 +0400 Subject: [PATCH] added simple-template --- .pre-commit-config.yaml | 8 +- .terraform.lock.hcl | 55 -------- README.md | 102 ++------------- demo-namespace.tf | 6 - get-credentials.sh | 2 - simple-template/README.md | 128 +++++++++++++++++++ simple-template/demo-namespace.tf | 6 + simple-template/get-credentials.sh | 9 ++ gke.tf => simple-template/gke.tf | 20 ++- outputs.tf => simple-template/outputs.tf | 5 +- providers.tf => simple-template/providers.tf | 8 -- variables.tf => simple-template/variables.tf | 13 +- simple-template/versions.tf | 16 +++ vpc.tf => simple-template/vpc.tf | 0 versions.tf | 14 -- 15 files changed, 197 insertions(+), 195 deletions(-) delete mode 100644 .terraform.lock.hcl delete mode 100644 demo-namespace.tf delete mode 100755 get-credentials.sh create mode 100644 simple-template/README.md create mode 100644 simple-template/demo-namespace.tf create mode 100755 simple-template/get-credentials.sh rename gke.tf => simple-template/gke.tf (68%) rename outputs.tf => simple-template/outputs.tf (81%) rename providers.tf => simple-template/providers.tf (56%) rename variables.tf => simple-template/variables.tf (64%) create mode 100644 simple-template/versions.tf rename vpc.tf => simple-template/vpc.tf (100%) delete mode 100644 versions.tf diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d629c01..1361207 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -3,8 +3,12 @@ repos: rev: "v0.16.0" hooks: - id: terraform-docs-go - args: ["markdown", "table", "--output-file", "README.md", "."] + args: ["markdown", "table", "--output-file", "README.md", "./simple-template"] + - id: terraform-docs-go + args: ["markdown", "table", "--output-file", "README.md", "./private-cluster-module"] + - id: terraform-docs-go + args: ["markdown", "table", "--output-file", "README.md", "./bucket"] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - - id: trailing-whitespace \ No newline at end of file + - id: trailing-whitespace diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl deleted file mode 100644 index 7d9dc26..0000000 --- a/.terraform.lock.hcl +++ /dev/null @@ -1,55 +0,0 @@ -# This file is maintained automatically by "tofu init". -# Manual edits may be lost in future updates. - -provider "registry.opentofu.org/hashicorp/google" { - version = "5.27.0" - constraints = "~> 5.27.0" - hashes = [ - "h1:cMRlEcTObLOVpFx09v3osbNtKayr2IIJFuhsRPdfrT4=", - "zh:10dee695387df836c8f2a7e7f4609e3d3d910e8070cebf91bdd4e4449237191b", - "zh:260a2bf30a5e0cbbb2a331a74561886df3d380be26beeb1f50a3cab829208eed", - "zh:2a87013cb2a408b2d494e2e7a938d2c6df7ed85156a6fe6be47a84390c3e3162", - "zh:443aa9b0637de3e20ff901a5e2e431d82bac80067eca3256d8792b4d069a9018", - "zh:4eb358ad15b756993b36fa7ef70507b9ad3fefa7869ac6d483a83a9f8beaa5f7", - "zh:5e8657fca3376d3b8f57aaa2ebf0575974f0d3af7448ad456ceae8364322362b", - "zh:8bcf6fa7adcc375ffb293dc72ba4e1ee8ad39fbadf11d901bd413fa01de836c6", - "zh:965d6df9bf7f0d85e0f61a9d7e5afdd389219e8b339ed241646ac292aedc839e", - "zh:c573e6c6e84691bf1c7736c238290441b2be40038972230dcaa7adc48b74b316", - "zh:eac4f56c4f3ddaead0a55d3b2016391578fdf3dea060b2ed32ac80974cd46b1d", - ] -} - -provider "registry.opentofu.org/hashicorp/helm" { - version = "2.14.0" - hashes = [ - "h1:K1yXsEeNhW/7YVSvsv55UaFSx4hHeKB1giPuQUKmFfQ=", - "zh:1c84ca8c274564c46497e89055139c7af64c9e1a8dd4f1cd4c68503ac1322fb8", - "zh:211a763173934d30c2e49c0cc828b1e34a528b0fdec8bf48d2bb3afadd4f9095", - "zh:3dca0b703a2f82d3e283a9e9ca6259a3b9897b217201f3cddf430009a1ca00c9", - "zh:40c5cfd48dcef54e87129e19d31c006c2e3309ee6c09d566139eaf315a59a369", - "zh:6f23c00ca1e2663e2a208a7491aa6dbe2604f00e0af7e23ef9323206e8f2fc81", - "zh:77f8cfc4888600e0d12da137bbdb836de160db168dde7af26c2e44cf00cbf057", - "zh:97b99c945eafa9bafc57c3f628d496356ea30312c3df8dfac499e0f3ff6bf0c9", - "zh:a01cfc53e50d5f722dc2aabd26097a8e4d966d343ffd471034968c2dc7a8819d", - "zh:b69c51e921fe8c91e38f4a82118d0b6b0f47f6c71a76f506fde3642ecbf39911", - "zh:fb8bfc7b8106bef58cc5628c024103f0dd5276d573fe67ac16f343a2b38ecee8", - ] -} - -provider "registry.opentofu.org/hashicorp/kubernetes" { - version = "2.29.0" - constraints = "~> 2.29.0" - hashes = [ - "h1:WcfXWA92IBkzQCGSv05Yb8Lped8kp7RRJEQIWG5nDTY=", - "zh:2467de940f98ef5d3ed977a0f6b797962cd9ae6210ef706b8f6e6db23a0b3b99", - "zh:480a2ccc9e1f3a444b6ebf836d87061002be00c54482be7180e090dddc47809e", - "zh:4ce04ba31734813d6636b51b2346b8262253264033be2775d66e8298551c2dde", - "zh:56b94fcd5ba65cae892fd64e831838369ae4615582c314eee73fa2e513689991", - "zh:5a7e858dc3600e542182abcec9079e2f8741d1ba72114e87668ef64679e7191a", - "zh:905b6eb78f19bd80b22c688af06130353977f77f313738c8e0cfc524e8550d4c", - "zh:ccf5c3e7383d11785a735a0ce7751e4ff394b133aa5085857139eaec1d9a54c1", - "zh:eb4e72d3abf937c283f702342eb1fc820b3dbfc743b1e24c84c3604c8fca1988", - "zh:eea59cd51ef366269231cbfa5b77fc3b9fbebecfd6bca8dff27e5abd96188d92", - "zh:f026a8b4fa2ca566c3d6cd9bfdd0dd58c0631e3d945b98a8ced0943aa27dd4bd", - ] -} diff --git a/README.md b/README.md index 6cea871..b5c83b3 100644 --- a/README.md +++ b/README.md @@ -1,95 +1,19 @@ -# How to use repo +# Terraform GKE clusters templates -1. Create `terraform.tfvars` file with a few variables -```shell -project = "gcp-project" -region = "europe-west1" -environment_name = "demo" -``` +Hello everyone! I'm glad to see you here. +This is a repository with a few examples of GKE clusters that you can create in your own GCP project. +Feel free to use this code in sandboxes for testing purposes. -2. Create cluster -All commands will be applied via Terraform 1.7.0 and via OpenTofu, the same version. +Also, I'm adding links to this repository in my articles on [my Medium](https://medium.com/@ksemele) and other places. -Here are OpenTofu commands. -```shell -tofu init -tofu apply -``` +## How to use this repo -3. Get the credentials for the new cluster (configure kubeconfig) +You can see a few directories in this repo: +* [bucket](https://github.com/ksemele/tf-gke-test/tree/main/bucket) - terraform code for creating google bucket for storing remote state +* [simple-template](https://github.com/ksemele/tf-gke-test/tree/main/simple-template) - Simple GKE example. Usually it's enough for any of my tests. +* [private-cluster-module](https://github.com/ksemele/tf-gke-test/tree/main/private-cluster-module) - GKE created by `beta-private-cluster-update-variant` module. Creates GKE cluster with a private network. -You can see all useful commands and links in the output: +Each directory contains its own readme with all needed commands to reproduce the example. +--- -```shell -tofu output -``` - -There is a manual command: - -```shell -gcloud container clusters get-credentials $(tofu output -raw kubernetes_cluster_name) --region $(tofu output -raw zone) --project $(tofu output -raw project) -``` - -Or just use `./get-credentials.sh` - -4. Destroy all resources - -```shell -tofu destroy -``` - - -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | ~>1.7.0 | -| [google](#requirement\_google) | ~>5.27.0 | -| [kubernetes](#requirement\_kubernetes) | ~>2.29.0 | - -## Providers - -| Name | Version | -|------|---------| -| [google](#provider\_google) | 5.27.0 | -| [kubernetes](#provider\_kubernetes) | 2.29.0 | - -## Modules - -No modules. - -## Resources - -| Name | Type | -|------|------| -| [google_compute_network.vpc](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network) | resource | -| [google_compute_subnetwork.subnet](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_subnetwork) | resource | -| [google_container_cluster.primary](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster) | resource | -| [google_container_node_pool.primary_nodes](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_node_pool) | resource | -| [google_project_service.service_networking](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_service) | resource | -| [kubernetes_namespace.demo-cluster](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | -| [google_client_config.primary](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/client_config) | data source | - -## Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [environment\_name](#input\_environment\_name) | n/a | `string` | `"demo"` | no | -| [project](#input\_project) | Google Project to create resources in | `string` | `"demo"` | no | -| [region](#input\_region) | The region to host the cluster in | `string` | `"us-central1"` | no | -| [vpc\_host\_project](#input\_vpc\_host\_project) | Host Project where virtual network exists | `string` | `"demo"` | no | -| [zone](#input\_zone) | The region to host the cluster in | `string` | `"us-central1-b"` | no | - -## Outputs - -| Name | Description | -|------|-------------| -| [gcloud\_gke\_get\_creds](#output\_gcloud\_gke\_get\_creds) | Command to get GKE credentials | -| [gcloud\_gke\_link](#output\_gcloud\_gke\_link) | GKE web ui link | -| [gcloud\_vpc\_link](#output\_gcloud\_vpc\_link) | VPC web ui link | -| [kubernetes\_cluster\_host](#output\_kubernetes\_cluster\_host) | GKE Cluster Host | -| [kubernetes\_cluster\_name](#output\_kubernetes\_cluster\_name) | GKE Cluster Name | -| [project](#output\_project) | GCloud Project ID | -| [region](#output\_region) | GCloud Region | -| [zone](#output\_zone) | GCloud Project ID | - +❤️ I'm very thankful to [Altenar](https://altenar.com) who sponsored me in this project. diff --git a/demo-namespace.tf b/demo-namespace.tf deleted file mode 100644 index fd20be8..0000000 --- a/demo-namespace.tf +++ /dev/null @@ -1,6 +0,0 @@ -resource "kubernetes_namespace" "demo-cluster" { - metadata { - name = "demo-cluster" - } - depends_on = [google_container_node_pool.primary_nodes] -} diff --git a/get-credentials.sh b/get-credentials.sh deleted file mode 100755 index ff284a1..0000000 --- a/get-credentials.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -gcloud container clusters get-credentials $(tofu output -raw kubernetes_cluster_name) --region $(tofu output -raw zone) --project $(tofu output -raw project) diff --git a/simple-template/README.md b/simple-template/README.md new file mode 100644 index 0000000..082b7e2 --- /dev/null +++ b/simple-template/README.md @@ -0,0 +1,128 @@ +# simple-template + +## What is created ty thah template + +This example is using local state. +You need an empty google project for tests. + +1. VPC network with one subnet +2. GKE cluster with an external endpoint and services network (be careful with that!) +3. Workload nodepool with one node +3. Namespace `this-is-demo-cluster` + +## How to use the code + +1. Create a `terraform.tfvars` file with a few variables + +```shell +project = "your-gcp-project" +``` +`region`, `zone` and `environment_name` are optional + +2. Create the cluster + +All commands will be applied via Terraform 1.8.0 or via OpenTofu, the same version. +I use alias `t` for the commands. + +```shell +t init +t apply +``` + +3. Get the credentials for the new cluster (configure kubeconfig) + +You can see all useful commands and links in the output: + +```shell +t output +``` + +There is a manual command: + +```shell +gcloud container clusters get-credentials $(t output -raw kubernetes_cluster_name) --zone $(t output -raw zone) --project $(t output -raw project) +``` + +Or just use `./get-credentials.sh` + +4. Destroy all resources + +```shell +t destroy +``` + +## Additional info + +Some manual tests. + +### terraform +✅ create cluster
+✅ `./get-credentials.sh`
+✅ manual cred command
+✅ output `gcloud_gke_get_creds` command
+✅ create simple nginx pod `kubectl run nginx --image=nginx:latest -n default && kubectl get po -w`
+✅ `flux install && kubectl get po -n flux-system -w`
+✅ destroy cluster + +### opentofu +✅ create cluster
+✅ `./get-credentials.sh`
+✅ manual cred command
+✅ output `gcloud_gke_get_creds` command
+✅ create simple nginx pod `kubectl run nginx --image=nginx:latest -n default && kubectl get po -w`
+✅ `flux install && kubectl get po -n flux-system -w`
+✅ destroy cluster + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | ~>1.8.0 | +| [google](#requirement\_google) | ~>5.42.0 | +| [kubernetes](#requirement\_kubernetes) | ~>2.32.0 | + +## Providers + +| Name | Version | +|------|---------| +| [google](#provider\_google) | 5.42.0 | +| [kubernetes](#provider\_kubernetes) | 2.32.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [google_compute_network.vpc](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network) | resource | +| [google_compute_subnetwork.subnet](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_subnetwork) | resource | +| [google_container_cluster.primary](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_cluster) | resource | +| [google_container_node_pool.primary_nodes](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/container_node_pool) | resource | +| [google_project_service.service_networking](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_service) | resource | +| [kubernetes_namespace.this-is-demo-cluster](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) | resource | +| [google_client_config.primary](https://registry.terraform.io/providers/hashicorp/google/latest/docs/data-sources/client_config) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [project](#input\_project) | Google Project to create resources in | `string` | `"demo"` | no | +| [region](#input\_region) | The region to host the cluster in | `string` | `"us-central1"` | no | +| [zone](#input\_zone) | The region to host the cluster in | `string` | `"us-central1-b"` | no | + +## Outputs + +| Name | Description | +|------|-------------| +| [gcloud\_gke\_get\_creds](#output\_gcloud\_gke\_get\_creds) | Command to get GKE credentials | +| [gcloud\_gke\_link](#output\_gcloud\_gke\_link) | GKE web ui link | +| [gcloud\_vpc\_link](#output\_gcloud\_vpc\_link) | VPC web ui link | +| [kubernetes\_cluster\_host](#output\_kubernetes\_cluster\_host) | GKE Cluster Host | +| [kubernetes\_cluster\_name](#output\_kubernetes\_cluster\_name) | GKE Cluster Name | +| [project](#output\_project) | GCloud Project ID | +| [region](#output\_region) | GCloud Region | +| [zone](#output\_zone) | GCloud Project ID | + diff --git a/simple-template/demo-namespace.tf b/simple-template/demo-namespace.tf new file mode 100644 index 0000000..6a41365 --- /dev/null +++ b/simple-template/demo-namespace.tf @@ -0,0 +1,6 @@ +resource "kubernetes_namespace" "this-is-demo-cluster" { + metadata { + name = "this-is-demo-cluster" + } + depends_on = [google_container_node_pool.primary_nodes] +} diff --git a/simple-template/get-credentials.sh b/simple-template/get-credentials.sh new file mode 100755 index 0000000..51f4256 --- /dev/null +++ b/simple-template/get-credentials.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if grep -H "opentofu.org" .terraform.lock.hcl > /dev/null; then + echo "trying to read tofu state" + gcloud container clusters get-credentials $(tofu output -raw kubernetes_cluster_name) --zone $(tofu output -raw zone) --project $(tofu output -raw project) +else + echo "trying to read terraform state" + gcloud container clusters get-credentials $(terraform output -raw kubernetes_cluster_name) --zone $(terraform output -raw zone) --project $(terraform output -raw project) +fi diff --git a/gke.tf b/simple-template/gke.tf similarity index 68% rename from gke.tf rename to simple-template/gke.tf index f0b2c54..5c70ff6 100644 --- a/gke.tf +++ b/simple-template/gke.tf @@ -1,5 +1,9 @@ +locals { + cluster_name = "${var.project}-gke" +} + resource "google_container_cluster" "primary" { - name = "${var.project}-gke" + name = local.cluster_name location = var.zone # We can't create a cluster with no node pool defined, but we want to only use @@ -10,10 +14,16 @@ resource "google_container_cluster" "primary" { network = google_compute_network.vpc.name subnetwork = google_compute_subnetwork.subnet.name - deletion_protection = false # Use this only for study purposess - depends_on = [google_compute_network.vpc, google_compute_subnetwork.subnet] + deletion_protection = false # Use this only for testing purposess! + depends_on = [ + google_compute_network.vpc, + google_compute_subnetwork.subnet + ] } +# You can use only the default pool for your experiments, but in that confuguration +# you have more flexibility. Even Prometheus or Flux doesn't run in the default node. +# That's why I suppose to use a separate node pool. resource "google_container_node_pool" "primary_nodes" { name = google_container_cluster.primary.name location = var.zone @@ -36,8 +46,8 @@ resource "google_container_node_pool" "primary_nodes" { preemptible = true machine_type = "n2-standard-8" tags = [ - "${var.environment_name}-k8s-${var.region}", - "${var.environment_name}-k8s-${var.region}-nodes" + "${local.cluster_name}-${var.region}", + "${local.cluster_name}-${var.region}-nodes" ] metadata = { disable-legacy-endpoints = "true" diff --git a/outputs.tf b/simple-template/outputs.tf similarity index 81% rename from outputs.tf rename to simple-template/outputs.tf index e0bfc6f..e3f8a3a 100644 --- a/outputs.tf +++ b/simple-template/outputs.tf @@ -20,12 +20,13 @@ output "kubernetes_cluster_name" { output "kubernetes_cluster_host" { description = "GKE Cluster Host" + sensitive = true value = google_container_cluster.primary.endpoint } output "gcloud_gke_get_creds" { description = "Command to get GKE credentials" - value = "gcloud container clusters get-credentials ${google_container_cluster.primary.name} --region ${google_container_cluster.primary.location} --project ${var.project}" + value = "gcloud container clusters get-credentials ${google_container_cluster.primary.name} --zone ${google_container_cluster.primary.location} --project ${var.project}" } output "gcloud_vpc_link" { @@ -35,5 +36,5 @@ output "gcloud_vpc_link" { output "gcloud_gke_link" { description = "GKE web ui link" - value = "https://console.cloud.google.com/kubernetes/clusters/details/${var.region}/${var.project}-gke/details?project=${var.project}" + value = "https://console.cloud.google.com/kubernetes/clusters/details/${var.region}/${local.cluster_name}/details?project=${var.project}" } diff --git a/providers.tf b/simple-template/providers.tf similarity index 56% rename from providers.tf rename to simple-template/providers.tf index 53f8469..0e4e72a 100644 --- a/providers.tf +++ b/simple-template/providers.tf @@ -10,11 +10,3 @@ provider "kubernetes" { token = data.google_client_config.primary.access_token cluster_ca_certificate = base64decode(google_container_cluster.primary.master_auth.0.cluster_ca_certificate) } - -provider "helm" { - kubernetes { - host = "https://${google_container_cluster.primary.endpoint}" - token = data.google_client_config.primary.access_token - cluster_ca_certificate = base64decode(google_container_cluster.primary.master_auth.0.cluster_ca_certificate) - } -} diff --git a/variables.tf b/simple-template/variables.tf similarity index 64% rename from variables.tf rename to simple-template/variables.tf index 0fa062e..8e1dc40 100644 --- a/variables.tf +++ b/simple-template/variables.tf @@ -1,20 +1,9 @@ variable "project" { + type = string description = "Google Project to create resources in" - type = string default = "demo" } -variable "vpc_host_project" { - description = "Host Project where virtual network exists" - type = string - default = "demo" -} - -variable "environment_name" { - type = string - default = "demo" -} - variable "region" { type = string description = "The region to host the cluster in" diff --git a/simple-template/versions.tf b/simple-template/versions.tf new file mode 100644 index 0000000..549f18e --- /dev/null +++ b/simple-template/versions.tf @@ -0,0 +1,16 @@ +terraform { + required_version = "~>1.8.0" + + required_providers { + # https://github.com/hashicorp/terraform-provider-google + google = { + source = "hashicorp/google" + version = "~>5.42.0" + } + # https://github.com/hashicorp/terraform-provider-kubernetes + kubernetes = { + source = "hashicorp/kubernetes" + version = "~>2.32.0" + } + } +} diff --git a/vpc.tf b/simple-template/vpc.tf similarity index 100% rename from vpc.tf rename to simple-template/vpc.tf diff --git a/versions.tf b/versions.tf deleted file mode 100644 index 014623e..0000000 --- a/versions.tf +++ /dev/null @@ -1,14 +0,0 @@ -terraform { - required_version = "~>1.7.0" - - required_providers { - google = { - source = "hashicorp/google" # https://github.com/hashicorp/terraform-provider-google - version = "~>5.27.0" - } - kubernetes = { - source = "hashicorp/kubernetes" # https://github.com/hashicorp/terraform-provider-kubernetes - version = "~>2.29.0" - } - } -}