Kong Gateway on GKE offloading to Cloud Run (#2299)

* First working version including certificates and HTTPS.

It uses a mix of self-managed certificates and the CA Service.

* One CR service only behind the ILB

* Functional deployment including auto-configuration

A k8s job configures the root certificate, service and route in the admin
api to reach the CR service via Kong proxy.

* Admin API exposed internally only, and some cleanup

* Some name changes

* README

* Remove data source for the vpc and subnet

* Remove data source for Kubernetes services

* Update README

---------

Co-authored-by: Julio Castillo <jccb@google.com>
This commit is contained in:
Julio Diez
2024-05-29 16:26:25 +02:00
committed by GitHub
parent 0d60e39aee
commit c205a692a3
18 changed files with 921 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
# Kong Gateway on GKE offloading to Cloud Run
<!-- BEGIN TOC -->
- [Introduction](#introduction)
- [Requirements](#requirements)
- [Kong Gateway Configuration](#kong-gateway-configuration)
- [Sample Configuration](#sample-configuration)
- [Variables](#variables)
<!-- END TOC -->
## Introduction
This blueprint deploys the Kong API Gateway on GKE with a workload running on Cloud Run. Usually workloads will run on GKE together with the gateway, but some use cases may benefit from running on Cloud Run like handling spiky workloads or for cost optimization.
## Requirements
This blueprint assumes the GKE cluster already exists. We recommend using the accompanying [Autopilot Cluster Pattern](../autopilot-cluster) to deploy a cluster according to Google's best practices. Once you have the cluster up and running, you can use this blueprint to deploy Kong on it.
## Kong Gateway Configuration
This blueprint deploys Kong following the instructions in the [official documentation](https://docs.konghq.com/gateway/latest/install/kubernetes/proxy/). These instructions configure Kong Gateway to use separate control plane and data plane deployments. You can adjust this configuration by directly modifying the YAML manifests under the [manifest-templates](manifest-templates) directory.
The Cloud Run service is exposed behind an Internal Application Load Balancer to provide a custom domain and an HTTPS certificate to Kong. The LB certificate is managed through [Google Cloud Certificate Authority Service](https://cloud.google.com/certificate-authority-service/docs/ca-service-overview). The CA Service allows you to better integrate Kong with Google Cloud managing your own private PKI.
To ease deployment and use of this blueprint, a kubernetes job is created to automatically configure Kong HTTP routing via its _admin API_ to point to Cloud Run. Once deployed, you can use the following command to get the public IP of the Kong gateway, a LoadBalancer service IP. Simply point your browser to that IP to visit the web page offered by Cloud Run. For a production-ready installation please refer to the [official Kong Gateway documentation](https://docs.konghq.com/gateway/latest/).
```sh
$ kubectl get service --namespace kong kong-dp-kong-proxy
```
## Sample Configuration
Use the following template as a starting point for your terraform.tfvars
```tfvars
created_resources = {
vpc_id = "projects/prj-host/global/networks/cluster-vpc"
subnet_id = "projects/prj-host/regions/europe-west1/subnetworks/cluster-default"
}
credentials_config = {
kubeconfig = {
path = "~/.kube/config"
}
}
prefix = "prj"
service_project = {
project_id = "kong-hello"
}
```
<!-- BEGIN TFDOC -->
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [created_resources](variables.tf#L23) | IDs of the resources created by autopilot cluster to be consumed here. | <code title="object&#40;&#123;&#10; vpc_id &#61; string&#10; subnet_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [credentials_config](variables.tf#L32) | Configure how Terraform authenticates to the cluster. | <code title="object&#40;&#123;&#10; fleet_host &#61; optional&#40;string&#41;&#10; kubeconfig &#61; optional&#40;object&#40;&#123;&#10; context &#61; optional&#40;string&#41;&#10; path &#61; optional&#40;string, &#34;&#126;&#47;.kube&#47;config&#34;&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [prefix](variables.tf#L70) | Prefix used for project names. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L79) | Host project with autopilot cluster. | <code>string</code> | ✓ | |
| [service_project](variables.tf#L90) | Service project for Cloud Run service. | <code title="object&#40;&#123;&#10; billing_account_id &#61; optional&#40;string&#41;&#10; parent &#61; optional&#40;string&#41;&#10; project_id &#61; optional&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [cloudrun_svcname](variables.tf#L17) | Name of the Cloud Run service. | <code>string</code> | | <code>&#34;hello-kong&#34;</code> |
| [custom_domain](variables.tf#L51) | Custom domain for the Load Balancer. | <code>string</code> | | <code>&#34;acme.org&#34;</code> |
| [image](variables.tf#L57) | Container image for Cloud Run services. | <code>string</code> | | <code>&#34;us-docker.pkg.dev&#47;cloudrun&#47;container&#47;hello&#34;</code> |
| [namespace](variables.tf#L63) | Namespace used for Kong cluster resources. | <code>string</code> | | <code>&#34;kong&#34;</code> |
| [region](variables.tf#L84) | Cloud region where resources will be deployed. | <code>string</code> | | <code>&#34;europe-west1&#34;</code> |
| [templates_path](variables.tf#L104) | Path where manifest templates will be read from. Set to null to use the default manifests. | <code>string</code> | | <code>null</code> |
<!-- END TFDOC -->

View File

@@ -0,0 +1,128 @@
/**
* 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.
*/
resource "google_privateca_ca_pool" "default" {
project = var.project_id
name = "Acme-CA-pool"
location = var.region
tier = "ENTERPRISE"
}
resource "google_privateca_certificate_authority" "default" {
project = var.project_id
certificate_authority_id = "Acme-CA"
location = var.region
pool = google_privateca_ca_pool.default.name
config {
subject_config {
subject {
common_name = "Acme-CA"
organization = "Acme"
}
}
x509_config {
ca_options {
is_ca = true
}
key_usage {
base_key_usage {
cert_sign = true
crl_sign = true
}
extended_key_usage {
client_auth = true
server_auth = true
}
}
}
}
lifetime = "31536000s" // 1 year
key_spec {
algorithm = "EC_P256_SHA256"
}
// Disable CA deletion related safe checks for easier cleanup while testing.
deletion_protection = false
skip_grace_period = true
ignore_active_certificates_on_deletion = true
}
# TLS certificate for the ILB
#
resource "tls_private_key" "ilb_cert_key" {
algorithm = "RSA"
rsa_bits = 2048
}
resource "google_privateca_certificate" "ilb_cert" {
project = var.project_id
certificate_authority = google_privateca_certificate_authority.default.certificate_authority_id
location = var.region
pool = google_privateca_ca_pool.default.name
lifetime = "2592000s" // 30 days
name = var.cloudrun_svcname
config {
subject_config {
subject {
common_name = var.custom_domain
organization = "Acme"
}
subject_alt_name {
dns_names = [var.custom_domain]
}
}
x509_config {
ca_options {
is_ca = false
}
key_usage {
base_key_usage {
key_agreement = true
}
extended_key_usage {
server_auth = true
}
}
}
public_key {
format = "PEM"
key = base64encode(tls_private_key.ilb_cert_key.public_key_pem)
}
}
}
# TLS certificate to secure the control plane/data plane Kong communication
#
resource "tls_private_key" "kong" {
algorithm = "ECDSA"
ecdsa_curve = "P384"
}
resource "tls_self_signed_cert" "kong" {
allowed_uses = [
"cert_signing",
"client_auth",
"digital_signature",
"key_encipherment",
"server_auth",
]
private_key_pem = tls_private_key.kong.private_key_pem
validity_period_hours = 365 * 24 // 1 year
is_ca_certificate = true
subject {
common_name = "kong_clustering"
}
}

View File

@@ -0,0 +1,31 @@
/**
* 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.
*/
module "cloud_run" {
source = "../../../../modules/cloud-run-v2"
project_id = module.service-project.project_id
name = var.cloudrun_svcname
region = var.region
containers = {
default = {
image = var.image
}
}
iam = {
"roles/run.invoker" = ["allUsers"]
}
ingress = "INGRESS_TRAFFIC_INTERNAL_LOAD_BALANCER"
}

View File

@@ -0,0 +1,30 @@
/**
* 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.
*/
module "private_dns_ilb" {
source = "../../../../modules/dns"
project_id = var.project_id
name = "dns-ilb"
zone_config = {
domain = format("%s.", var.custom_domain)
private = {
client_networks = [var.created_resources.vpc_id]
}
}
recordsets = {
"A " = { records = [module.ilb-l7.address] }
}
}

View File

@@ -0,0 +1,56 @@
/**
* 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.
*/
module "ilb-l7" {
source = "../../../../modules/net-lb-app-int"
project_id = var.project_id
name = "ilb-l7-cr"
region = var.region
backend_service_configs = {
default = {
project_id = module.service-project.project_id
backends = [{
group = "cr"
}]
health_checks = []
}
}
health_check_configs = {}
neg_configs = {
cr = {
project_id = module.service-project.project_id
cloudrun = {
region = var.region
target_service = {
name = var.cloudrun_svcname
}
}
}
}
protocol = "HTTPS"
ssl_certificates = {
create_configs = {
default = {
certificate = google_privateca_certificate.ilb_cert.pem_certificate
private_key = tls_private_key.ilb_cert_key.private_key_pem
}
}
}
vpc_config = {
network = var.created_resources.vpc_id
subnetwork = var.created_resources.subnet_id
}
}

View File

@@ -0,0 +1,90 @@
/**
* 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.
*/
locals {
wl_templates_path = (
var.templates_path == null
? "${path.module}/manifest-templates"
: pathexpand(var.templates_path)
)
}
resource "kubectl_manifest" "kong-namespace" {
yaml_body = templatefile(
"${local.wl_templates_path}/namespace.yaml", {
kong_namespace = var.namespace
}
)
}
resource "kubectl_manifest" "kong-license" {
yaml_body = templatefile(
"${local.wl_templates_path}/license.yaml", {
kong_namespace = var.namespace
kong_license = "'{}'"
}
)
depends_on = [kubectl_manifest.kong-namespace]
}
resource "kubectl_manifest" "kong-cert" {
yaml_body = templatefile(
"${local.wl_templates_path}/cert.yaml", {
kong_namespace = var.namespace
certificate = base64encode(tls_self_signed_cert.kong.cert_pem)
private_key = base64encode(tls_self_signed_cert.kong.private_key_pem)
}
)
depends_on = [kubectl_manifest.kong-license]
}
resource "helm_release" "kong-cp" { # Kong Gateway control plane release
name = "kong-cp"
repository = "https://charts.konghq.com"
chart = "kong"
namespace = var.namespace
values = [file("${local.wl_templates_path}/values-cp.yaml")]
depends_on = [kubectl_manifest.kong-cert]
}
resource "helm_release" "kong-dp" { # Kong Gateway data plane release
name = "kong-dp"
repository = "https://charts.konghq.com"
chart = "kong"
namespace = var.namespace
values = [file("${local.wl_templates_path}/values-dp.yaml")]
depends_on = [kubectl_manifest.kong-cert]
}
resource "kubectl_manifest" "kong-config" {
yaml_body = templatefile(
"${local.wl_templates_path}/config-proxy.yaml", {
kong_namespace = var.namespace
root_cer = indent(4, google_privateca_certificate_authority.default.pem_ca_certificates[0])
domain = var.custom_domain
}
)
depends_on = [helm_release.kong-cp]
}
resource "kubectl_manifest" "kong-configure" {
yaml_body = templatefile(
"${local.wl_templates_path}/configure-proxy.yaml", {
kong_namespace = var.namespace
}
)
depends_on = [kubectl_manifest.kong-config]
}

View File

@@ -0,0 +1,32 @@
/**
* 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.
*/
module "service-project" {
source = "../../../../modules/project"
name = var.service_project.project_id
prefix = var.prefix
project_create = var.service_project.billing_account_id != null
billing_account = try(var.service_project.billing_account_id, null)
parent = try(var.service_project.parent, null)
services = [
"compute.googleapis.com",
"run.googleapis.com",
]
shared_vpc_service_config = {
host_project = var.project_id
}
skip_delete = true
}

View File

@@ -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.
apiVersion: v1
kind: Secret
metadata:
name: kong-cluster-cert
namespace: "${kong_namespace}"
type: kubernetes.io/tls
data:
tls.crt: "${certificate}"
tls.key: "${private_key}"

View File

@@ -0,0 +1,27 @@
# 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.
apiVersion: v1
kind: ConfigMap
metadata:
name: config-proxy
namespace: "${kong_namespace}"
data:
config-proxy.sh: |-
#!/bin/sh
apk add curl jq
ADMIN_IP="$(nslookup kong-cp-kong-admin.${kong_namespace}.svc.cluster.local | awk '/^Address: / { print $2 }')"
CERT_ID="$(curl -s http://$ADMIN_IP:8001/ca_certificates -F cert='${root_cer}' | jq .id)"
curl -s http://$ADMIN_IP:8001/services -H 'Content-Type: application/json' -d '{"name":"acme","protocol":"https","host":"${domain}","port":443,"path":"/","tls_verify":true,"ca_certificates":['$CERT_ID']}'
curl -s http://$ADMIN_IP:8001/routes -H 'Content-Type: application/json' -d '{"name":"acme","paths":["/"],"service":{"name":"acme"}}'

View File

@@ -0,0 +1,40 @@
# 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.
apiVersion: batch/v1
kind: Job
metadata:
name: configure-proxy
namespace: "${kong_namespace}"
spec:
suspend: false
completions: 1
template:
spec:
restartPolicy: Never
volumes:
- name: config-proxy-volume
configMap:
defaultMode: 0700
name: config-proxy
containers:
- name: configure-proxy
image: alpine
volumeMounts:
- name: config-proxy-volume
mountPath: /tmp
command:
- /bin/sh
- -c
- /tmp/config-proxy.sh

View File

@@ -0,0 +1,22 @@
# 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.
apiVersion: v1
kind: Secret
metadata:
name: kong-enterprise-license
namespace: "${kong_namespace}"
type: Opaque
stringData:
license: "${kong_license}"

View File

@@ -0,0 +1,18 @@
# 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.
apiVersion: v1
kind: Namespace
metadata:
name: "${kong_namespace}"

View File

@@ -0,0 +1,86 @@
# 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.
#env:
# log_level: debug
# Do not use Kong Ingress Controller
ingressController:
enabled: false
image:
repository: kong/kong-gateway
tag: "3.6.1.4"
# Mount the secret created earlier
secretVolumes:
- kong-cluster-cert
env:
# This is a control_plane node
role: control_plane
# These certificates are used for control plane / data plane communication
cluster_cert: /etc/secrets/kong-cluster-cert/tls.crt
cluster_cert_key: /etc/secrets/kong-cluster-cert/tls.key
# Database
# CHANGE THESE VALUES
database: postgres
pg_database: kong
pg_user: kong
pg_password: demo123
pg_host: kong-cp-postgresql.kong.svc.cluster.local
pg_ssl: "on"
# Kong Manager password
password: kong_admin_password
# This is for testing purposes only
# DO NOT DO THIS IN PRODUCTION
# Your cluster needs a way to create PersistantVolumeClaims
# if this option is enabled
postgresql:
enabled: true
auth:
password: demo123
# Enterprise functionality
enterprise:
enabled: true
license_secret: kong-enterprise-license
# The control plane serves the Admin API
admin:
enabled: true
http:
enabled: true
# Clustering endpoints are required in hybrid mode
cluster:
enabled: true
tls:
enabled: true
clustertelemetry:
enabled: true
tls:
enabled: true
# Optional features
manager:
enabled: false
# These roles will be served by different Helm releases
proxy:
enabled: false

View File

@@ -0,0 +1,58 @@
# 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.
#env:
# log_level: debug
# Do not use Kong Ingress Controller
ingressController:
enabled: false
image:
repository: kong/kong-gateway
tag: "3.6.1.4"
# Mount the secret created earlier
secretVolumes:
- kong-cluster-cert
env:
# data_plane nodes do not have a database
role: data_plane
database: "off"
# Tell the data plane how to connect to the control plane
cluster_control_plane: kong-cp-kong-cluster.kong.svc.cluster.local:8005
cluster_telemetry_endpoint: kong-cp-kong-clustertelemetry.kong.svc.cluster.local:8006
# Configure control plane / data plane authentication
lua_ssl_trusted_certificate: /etc/secrets/kong-cluster-cert/tls.crt
cluster_cert: /etc/secrets/kong-cluster-cert/tls.crt
cluster_cert_key: /etc/secrets/kong-cluster-cert/tls.key
# Enterprise functionality
enterprise:
enabled: true
license_secret: kong-enterprise-license
# The data plane handles proxy traffic only
proxy:
enabled: true
# These roles are served by the kong-cp deployment
admin:
enabled: false
manager:
enabled: false

View File

@@ -0,0 +1,55 @@
/**
* 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.
*/
data "google_client_config" "identity" {
count = var.credentials_config.fleet_host != null ? 1 : 0
}
provider "kubectl" {
config_path = (
var.credentials_config.kubeconfig == null
? null
: pathexpand(var.credentials_config.kubeconfig.path)
)
config_context = try(
var.credentials_config.kubeconfig.context, null
)
host = (
var.credentials_config.fleet_host == null
? null
: var.credentials_config.fleet_host
)
token = try(data.google_client_config.identity.0.access_token, null)
}
provider "helm" {
kubernetes {
config_path = (
var.credentials_config.kubeconfig == null
? null
: pathexpand(var.credentials_config.kubeconfig.path)
)
config_context = try(
var.credentials_config.kubeconfig.context, null
)
host = (
var.credentials_config.fleet_host == null
? null
: var.credentials_config.fleet_host
)
token = try(data.google_client_config.identity.0.access_token, null)
}
}

View File

@@ -0,0 +1,108 @@
/**
* 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 "cloudrun_svcname" {
description = "Name of the Cloud Run service."
type = string
default = "hello-kong"
}
variable "created_resources" {
description = "IDs of the resources created by autopilot cluster to be consumed here."
type = object({
vpc_id = string
subnet_id = string
})
nullable = false
}
variable "credentials_config" {
description = "Configure how Terraform authenticates to the cluster."
type = object({
fleet_host = optional(string)
kubeconfig = optional(object({
context = optional(string)
path = optional(string, "~/.kube/config")
}))
})
nullable = false
validation {
condition = (
(var.credentials_config.fleet_host != null) !=
(var.credentials_config.kubeconfig != null)
)
error_message = "Exactly one of fleet host or kubeconfig must be set."
}
}
variable "custom_domain" {
description = "Custom domain for the Load Balancer."
type = string
default = "acme.org"
}
variable "image" {
description = "Container image for Cloud Run services."
type = string
default = "us-docker.pkg.dev/cloudrun/container/hello"
}
variable "namespace" {
description = "Namespace used for Kong cluster resources."
type = string
nullable = false
default = "kong"
}
variable "prefix" {
description = "Prefix used for project names."
type = string
validation {
condition = var.prefix != ""
error_message = "Prefix cannot be empty."
}
}
variable "project_id" {
description = "Host project with autopilot cluster."
type = string
}
variable "region" {
description = "Cloud region where resources will be deployed."
type = string
default = "europe-west1"
}
variable "service_project" {
description = "Service project for Cloud Run service."
type = object({
billing_account_id = optional(string)
parent = optional(string)
project_id = optional(string)
})
nullable = false
validation {
condition = var.service_project.billing_account_id != null || var.service_project.project_id != null
error_message = "At least one of billing_account_id or project_id should be set."
}
}
variable "templates_path" {
description = "Path where manifest templates will be read from. Set to null to use the default manifests."
type = string
default = null
}

View File

@@ -0,0 +1,27 @@
# 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
#
# https://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_version = ">= 1.7.4"
required_providers {
google = {
source = "hashicorp/google"
version = ">= 5.29.1, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 5.29.1, < 6.0.0" # tftest
}
}
}

View File

@@ -0,0 +1,22 @@
# 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
#
# https://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 {
kubectl = {
source = "gavinbunney/kubectl"
version = ">= 1.7.0"
}
}
}