Skip to content

Commit

Permalink
feat: add an attached cluster example for kind as well (#677)
Browse files Browse the repository at this point in the history
* added a kind example with an oidc module as well

* added more info on credentials

* Update main.tf

just noticed a content-type typo

* Update README.md

just updated some text in the example

* Update README.md

missed an env var update for PRINCIPAL

* Update README.md

and another env var fixup

* skipping commit from contributor's wrong account

* putting back some license and typo fixes

* Update .gitignore

---------

Co-authored-by: Huy Pham <huypham@google.com>
  • Loading branch information
linde and hdp617 authored Jul 24, 2024
1 parent fcaf9cb commit a1ffecf
Show file tree
Hide file tree
Showing 8 changed files with 380 additions and 0 deletions.
55 changes: 55 additions & 0 deletions anthos-attached-clusters/kind/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Sandbox Example to Attach a [kind](https://kind.sigs.k8s.io/) Cluster using Terraform

## Prerequisites
The sample is meant just to provide a local example for experimentation. It assumes an environment where [`kind`](https://kind.sigs.k8s.io/) is available and could otherwise be run on the command line, e.g. `kind create cluster`.

## A note on providers

The other examples and module limit dependancies to terraform core providers, but this example takes advantage of some community supplied [providers](provider.tf). They're widely used for their purpose, but please review and consider.

## Usage

1. Edit the values in the terraform.tfvars file to suit your needs. Descriptions for each variable
can be found in `variables.tf`. Additional optional features are also available and commented out
in the `google_container_attached_cluster` resource in `main.tf`.

If you modify the cluster creation, ensure it meets
[Cluster Prerequisites](https://cloud.google.com/anthos/clusters/docs/multi-cloud/attached/eks/reference/cluster-prerequisites).
1. Initialize Terraform:
```bash
terraform init
```
1. Create and apply the plan:
```bash
terraform apply
```
Terraform may give a warning along the lines of `Warning: Content-Type is not recognized as a text type, got "application/jwk-set+json"` but this is ok and just a side effect of the `http` provider we're using and the content type the cluster returns for the `jwks` content.
1. The process should take about a few short minutes to complete.
1. Set some variables based on the terraform porjects values and use them to generate RBAC for the cluster and credentials to login:
```bash
PROJECT=$(echo google_container_attached_cluster.primary.project | terraform console | tr -d '"')
CLUSTER=$(echo google_container_attached_cluster.primary.name | terraform console | tr -d '"')
KUBECONFIG=$(echo kind_cluster.cluster.kubeconfig_path | terraform console | tr -d '"')
# set this to whomever you'd like to grant access
PRINCIPAL=update.this@example.com
# set this whatever role you intend
ROLE=clusterrole/cluster-admin
gcloud container fleet memberships generate-gateway-rbac --apply \
--kubeconfig ${KUBECONFIG} --context=kind-${CLUSTER} \
--project=${PROJECT} \
--membership=${CLUSTER} \
--role=${ROLE} \
--users=${PRINCIPAL}
gcloud container fleet memberships get-credentials ${CLUSTER} --project ${PROJECT}
kubectl get ns
```
This will allow you to access the cluster using kubectl as you would other GKE Enterprise clusters, regardless of location (ie in GCP, other clouds, or on prem).
123 changes: 123 additions & 0 deletions anthos-attached-clusters/kind/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


// This is an example of how you might use the attached module with a local kind cluster

locals {
cluster_name = "${var.name_prefix}-cluster"
}

resource "kind_cluster" "cluster" {
name = local.cluster_name
node_image = var.kind_node_image

kubeconfig_path = "${path.root}/.tmp/kube/${local.cluster_name}"

wait_for_ready = true

kind_config {
kind = "Cluster"
api_version = "kind.x-k8s.io/v1alpha4"
feature_gates = {
KubeletInUserNamespace : "true"
}
}
}

provider "helm" {
alias = "bootstrap_installer"
kubernetes {
host = kind_cluster.cluster.endpoint
client_certificate = kind_cluster.cluster.client_certificate
client_key = kind_cluster.cluster.client_key
cluster_ca_certificate = kind_cluster.cluster.cluster_ca_certificate
}
}

module "attached_install_manifest" {
source = "../modules/attached-install-manifest"
attached_cluster_name = local.cluster_name
attached_cluster_fleet_project = data.google_project.project.project_id
gcp_location = var.gcp_location
platform_version = var.platform_version
providers = {
helm = helm.bootstrap_installer
}
depends_on = [
kind_cluster.cluster
]
}

data "google_project" "project" {
project_id = var.gcp_project_id
}



module "oidc" {
source = "./oidc"

endpoint = kind_cluster.cluster.endpoint
cluster_ca_certificate = kind_cluster.cluster.cluster_ca_certificate
client_certificate = kind_cluster.cluster.client_certificate
client_key = kind_cluster.cluster.client_key
}


resource "google_container_attached_cluster" "primary" {
name = local.cluster_name
project = data.google_project.project.project_id
location = var.gcp_location
description = "Kind attached cluster example"
distribution = "generic"
platform_version = var.platform_version
oidc_config {
issuer_url = module.oidc.issuer
jwks = module.oidc.jwks
}
fleet {
project = "projects/${data.google_project.project.number}"
}

# Optional:
# logging_config {
# component_config {
# enable_components = ["SYSTEM_COMPONENTS", "WORKLOADS"]
# }
# }

# Optional:
# monitoring_config {
# managed_prometheus_config {
# enabled = true
# }
# }

# Optional:
# authorization {
# admin_users = ["user1@google.com", ]
# admin_groups = ["group1@example.com", "group2@example.com"]
# }

depends_on = [
module.attached_install_manifest
]
}




50 changes: 50 additions & 0 deletions anthos-attached-clusters/kind/oidc/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// this is a local library to manage getting OIDC info from the cluster

data "http" "issuer" {

provider = http-full

url = "${var.endpoint}/.well-known/openid-configuration"
request_headers = {
content-type = "application/json"
}

ca = var.cluster_ca_certificate
client_crt = var.client_certificate
client_key = var.client_key
}

locals {
issuer_json = jsondecode(data.http.issuer.response_body)
}

data "http" "jwks" {

provider = http-full

url = local.issuer_json.jwks_uri
request_headers = {
content-type = "application/json"
}

ca = var.cluster_ca_certificate
client_crt = var.client_certificate
client_key = var.client_key
}

23 changes: 23 additions & 0 deletions anthos-attached-clusters/kind/oidc/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

output "issuer" {
value = local.issuer_json.issuer
}

output "jwks" {
value = base64encode(data.http.jwks.response_body)
}
24 changes: 24 additions & 0 deletions anthos-attached-clusters/kind/oidc/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

terraform {
required_providers {
http-full = {
source = "salrashid123/http-full"
}
}
}

34 changes: 34 additions & 0 deletions anthos-attached-clusters/kind/oidc/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

variable "endpoint" {
type = string
}


variable "cluster_ca_certificate" {
type = string
}

variable "client_certificate" {
type = string
}

variable "client_key" {
type = string
}


24 changes: 24 additions & 0 deletions anthos-attached-clusters/kind/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

terraform {
required_providers {
kind = {
source = "tehcyx/kind"
}
}
}

47 changes: 47 additions & 0 deletions anthos-attached-clusters/kind/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

variable "name_prefix" {
description = "Common prefix to use for generating names"
type = string
}

variable "gcp_project_id" {
description = "The GCP project id where the cluster will be registered"
type = string
}

variable "gcp_location" {
description = "GCP location to create the attached resource in"
type = string
default = "us-west1"
}

variable "platform_version" {
description = "Platform version of the attached cluster resource"
type = string
default = "1.28.0-gke.3"
}


variable "kind_node_image" {
description = "The image used for the kind cluster"
type = string
default = "kindest/node:v1.28.0"
}



0 comments on commit a1ffecf

Please sign in to comment.