Skip to content

Commit 486d17a

Browse files
feat: add autopilot confidential nodes example (#2289)
Co-authored-by: Andrew Peabody <[email protected]>
1 parent e89d29b commit 486d17a

File tree

25 files changed

+386
-0
lines changed

25 files changed

+386
-0
lines changed

build/int.cloudbuild.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,21 @@ steps:
481481
- verify test-confidential-safer-cluster
482482
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
483483
args: ['/bin/bash', '-c', 'cft test run TestConfidentialSaferCluster --stage teardown --verbose']
484+
- id: apply test-confidential-autopilot-private
485+
waitFor:
486+
- init-all
487+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
488+
args: ['/bin/bash', '-c', 'cft test run TestConfidentialAutopilotPrivate --stage apply --verbose']
489+
- id: verify test-confidential-autopilot-private
490+
waitFor:
491+
- apply test-confidential-autopilot-private
492+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
493+
args: ['/bin/bash', '-c', 'cft test run TestConfidentialAutopilotPrivate --stage verify --verbose']
494+
- id: teardown test-confidential-autopilot-private
495+
waitFor:
496+
- verify test-confidential-autopilot-private
497+
name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS'
498+
args: ['/bin/bash', '-c', 'cft test run TestConfidentialAutopilotPrivate --stage teardown --verbose']
484499
tags:
485500
- 'ci'
486501
- 'integration'
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Confidential Autopilot Private Cluster
2+
3+
This example illustrates how to create an Autopilot cluster with beta features,
4+
using Confidential GKE nodes and a Customer Managed Encryption Keys (CMEK).
5+
6+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
7+
## Inputs
8+
9+
| Name | Description | Type | Default | Required |
10+
|------|-------------|------|---------|:--------:|
11+
| project\_id | The project ID to host the cluster in | `string` | n/a | yes |
12+
| region | The region to host the cluster in | `string` | `"us-central1"` | no |
13+
14+
## Outputs
15+
16+
| Name | Description |
17+
|------|-------------|
18+
| cluster\_name | Cluster name |
19+
| kms\_key | CMEK used for disk and database encryption |
20+
| kubernetes\_endpoint | The cluster endpoint |
21+
| location | Cluster location (region if regional cluster, zone if zonal cluster) |
22+
| master\_kubernetes\_version | Kubernetes version of the master |
23+
| network\_name | The name of the VPC being created |
24+
| region | The region in which the cluster resides |
25+
| service\_account | The service account to default running nodes as if not overridden in `node_pools`. |
26+
| subnet\_names | The names of the subnet being created |
27+
| zones | List of zones in which the cluster resides |
28+
29+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
30+
31+
To provision this example, run the following from within this directory:
32+
- `terraform init` to get the plugins
33+
- `terraform plan` to see the infrastructure plan
34+
- `terraform apply` to apply the infrastructure build
35+
- `terraform destroy` to destroy the built infrastructure
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
locals {
18+
cluster_type = "confidential-autopilot-private"
19+
network_name = "confidential-autopilot-private-network"
20+
subnet_name = "confidential-autopilot-private-subnet"
21+
master_auth_subnetwork = "confidential-autopilot-master-subnet"
22+
pods_range_name = "ip-range-pods-confidential-autopilot"
23+
svc_range_name = "ip-range-svc-confidential-autopilot"
24+
subnet_names = [for subnet_self_link in module.gcp-network.subnets_self_links : split("/", subnet_self_link)[length(split("/", subnet_self_link)) - 1]]
25+
}
26+
27+
data "google_project" "main" {
28+
project_id = var.project_id
29+
}
30+
31+
resource "random_string" "suffix" {
32+
length = 4
33+
special = false
34+
upper = false
35+
}
36+
37+
module "kms" {
38+
source = "terraform-google-modules/kms/google"
39+
version = "~> 4.0"
40+
41+
project_id = var.project_id
42+
key_protection_level = "HSM"
43+
location = var.region
44+
keyring = "keyring-${random_string.suffix.result}"
45+
keys = ["key"]
46+
prevent_destroy = false
47+
}
48+
49+
resource "google_kms_crypto_key_iam_member" "main" {
50+
crypto_key_id = values(module.kms.keys)[0]
51+
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
52+
member = "serviceAccount:service-${data.google_project.main.number}@compute-system.iam.gserviceaccount.com"
53+
}
54+
55+
module "gke" {
56+
source = "terraform-google-modules/kubernetes-engine/google//modules/beta-autopilot-private-cluster"
57+
version = "~> 36.0"
58+
59+
project_id = var.project_id
60+
name = "${local.cluster_type}-cluster"
61+
regional = true
62+
region = var.region
63+
network = module.gcp-network.network_name
64+
subnetwork = local.subnet_names[index(module.gcp-network.subnets_names, local.subnet_name)]
65+
ip_range_pods = local.pods_range_name
66+
ip_range_services = local.svc_range_name
67+
release_channel = "REGULAR"
68+
enable_vertical_pod_autoscaling = true
69+
enable_private_endpoint = true
70+
enable_private_nodes = true
71+
network_tags = [local.cluster_type]
72+
deletion_protection = false
73+
boot_disk_kms_key = values(module.kms.keys)[0]
74+
enable_confidential_nodes = true
75+
76+
database_encryption = [
77+
{
78+
"key_name" : values(module.kms.keys)[0],
79+
"state" : "ENCRYPTED"
80+
}
81+
]
82+
83+
depends_on = [google_kms_crypto_key_iam_member.main]
84+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
module "gcp-network" {
18+
source = "terraform-google-modules/network/google"
19+
version = "~> 10.0"
20+
21+
project_id = var.project_id
22+
network_name = local.network_name
23+
24+
subnets = [
25+
{
26+
subnet_name = local.subnet_name
27+
subnet_ip = "10.0.0.0/17"
28+
subnet_region = var.region
29+
subnet_private_access = true
30+
},
31+
{
32+
subnet_name = local.master_auth_subnetwork
33+
subnet_ip = "10.60.0.0/17"
34+
subnet_region = var.region
35+
},
36+
]
37+
38+
secondary_ranges = {
39+
(local.subnet_name) = [
40+
{
41+
range_name = local.pods_range_name
42+
ip_cidr_range = "192.168.0.0/18"
43+
},
44+
{
45+
range_name = local.svc_range_name
46+
ip_cidr_range = "192.168.64.0/18"
47+
},
48+
]
49+
}
50+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
output "kubernetes_endpoint" {
18+
description = "The cluster endpoint"
19+
sensitive = true
20+
value = module.gke.endpoint
21+
}
22+
23+
output "cluster_name" {
24+
description = "Cluster name"
25+
value = module.gke.name
26+
}
27+
28+
output "location" {
29+
description = "Cluster location (region if regional cluster, zone if zonal cluster)"
30+
value = module.gke.location
31+
}
32+
33+
output "master_kubernetes_version" {
34+
description = "Kubernetes version of the master"
35+
value = module.gke.master_version
36+
}
37+
38+
output "service_account" {
39+
description = "The service account to default running nodes as if not overridden in `node_pools`."
40+
value = module.gke.service_account
41+
}
42+
43+
output "network_name" {
44+
description = "The name of the VPC being created"
45+
value = module.gcp-network.network_name
46+
}
47+
48+
output "subnet_names" {
49+
description = "The names of the subnet being created"
50+
value = module.gcp-network.subnets_names
51+
}
52+
53+
output "region" {
54+
description = "The region in which the cluster resides"
55+
value = module.gke.region
56+
}
57+
58+
output "zones" {
59+
description = "List of zones in which the cluster resides"
60+
value = module.gke.zones
61+
}
62+
63+
output "kms_key" {
64+
description = "CMEK used for disk and database encryption"
65+
value = values(module.kms.keys)[0]
66+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
variable "project_id" {
18+
description = "The project ID to host the cluster in"
19+
type = string
20+
}
21+
22+
variable "region" {
23+
description = "The region to host the cluster in"
24+
type = string
25+
default = "us-central1"
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
terraform {
18+
required_providers {
19+
google = {
20+
source = "hashicorp/google"
21+
}
22+
kubernetes = {
23+
source = "hashicorp/kubernetes"
24+
}
25+
}
26+
required_version = ">= 1.3"
27+
}

metadata.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ spec:
6868
examples:
6969
- name: autopilot_private_firewalls
7070
location: examples/autopilot_private_firewalls
71+
- name: confidential_autopilot_private
72+
location: examples/confidential_autopilot_private
7173
- name: confidential_safer_cluster
7274
location: examples/confidential_safer_cluster
7375
- name: deploy_service

modules/auth/metadata.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ spec:
3434
examples:
3535
- name: autopilot_private_firewalls
3636
location: examples/autopilot_private_firewalls
37+
- name: confidential_autopilot_private
38+
location: examples/confidential_autopilot_private
3739
- name: confidential_safer_cluster
3840
location: examples/confidential_safer_cluster
3941
- name: deploy_service

modules/beta-autopilot-private-cluster/metadata.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ spec:
3434
examples:
3535
- name: autopilot_private_firewalls
3636
location: examples/autopilot_private_firewalls
37+
- name: confidential_autopilot_private
38+
location: examples/confidential_autopilot_private
3739
- name: confidential_safer_cluster
3840
location: examples/confidential_safer_cluster
3941
- name: deploy_service

0 commit comments

Comments
 (0)