Skip to content

Commit

Permalink
Merge pull request #273 from mmontan/custom-gcr-project
Browse files Browse the repository at this point in the history
Add a parameter 'registry_project_id' to the GKE module templates
  • Loading branch information
morgante committed Oct 18, 2019
2 parents 838b7ca + e71ef10 commit 4815c7a
Show file tree
Hide file tree
Showing 23 changed files with 102 additions and 19 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ In either case, upgrading to module version `v1.0.0` will trigger a recreation o
| project\_id | The project ID to host the cluster in (required) | string | n/a | yes |
| region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no |
| regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no |
| registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no |
| remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no |
| service\_account | The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created. | string | `""` | no |
| stub\_domains | Map of stub domains and their resolvers to forward DNS queries for a certain domain to an external DNS server | map(list(string)) | `<map>` | no |
Expand Down Expand Up @@ -228,6 +229,9 @@ following project roles:
- roles/iam.serviceAccountUser
- roles/resourcemanager.projectIamAdmin (only required if `service_account` is set to `create`)

Additionally, if `service_account` is set to `create` and `grant_registry_access` is requested, the service account requires the following role on the `registry_project_id` project:
- roles/resourcemanager.projectIamAdmin

### Enable APIs
In order to operate with the Service Account you must activate the following APIs on the project where the Service Account was created:

Expand Down
3 changes: 3 additions & 0 deletions autogen/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ following project roles:
- roles/iam.serviceAccountUser
- roles/resourcemanager.projectIamAdmin (only required if `service_account` is set to `create`)

Additionally, if `service_account` is set to `create` and `grant_registry_access` is requested, the service account requires the following role on the `registry_project_id` project:
- roles/resourcemanager.projectIamAdmin

### Enable APIs
In order to operate with the Service Account you must activate the following APIs on the project where the Service Account was created:

Expand Down
2 changes: 1 addition & 1 deletion autogen/sa.tf
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ resource "google_project_iam_member" "cluster_service_account-monitoring_viewer"

resource "google_project_iam_member" "cluster_service_account-gcr" {
count = var.create_service_account && var.grant_registry_access ? 1 : 0
project = var.project_id
project = var.registry_project_id == "" ? var.project_id : var.registry_project_id
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.cluster_service_account[0].email}"
}
Expand Down
6 changes: 6 additions & 0 deletions autogen/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ variable "grant_registry_access" {
default = false
}

variable "registry_project_id" {
type = string
description = "Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project."
default = ""
}

variable "service_account" {
type = string
description = "The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created."
Expand Down
5 changes: 3 additions & 2 deletions examples/workload_metadata_config/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ module "gke" {
subnetwork = var.subnetwork
ip_range_pods = var.ip_range_pods
ip_range_services = var.ip_range_services
create_service_account = false
service_account = var.compute_engine_service_account
create_service_account = true
grant_registry_access = true
registry_project_id = var.registry_project_id
enable_private_endpoint = true
enable_private_nodes = true
master_ipv4_cidr_block = "172.16.0.0/28"
Expand Down
5 changes: 2 additions & 3 deletions examples/workload_metadata_config/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ variable "ip_range_services" {
description = "The secondary ip range to use for pods"
}

variable "compute_engine_service_account" {
description = "Service account to associate to the nodes in the cluster"
variable "registry_project_id" {
description = "Project name for the GCR registry"
}

4 changes: 4 additions & 0 deletions modules/beta-private-cluster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ In either case, upgrading to module version `v1.0.0` will trigger a recreation o
| project\_id | The project ID to host the cluster in (required) | string | n/a | yes |
| region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no |
| regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no |
| registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no |
| remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no |
| resource\_usage\_export\_dataset\_id | The dataset id for which network egress metering for this cluster will be enabled. If enabled, a daemonset will be created in the cluster to meter network egress traffic. | string | `""` | no |
| sandbox\_enabled | (Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` and `node_version` = `1.12.7-gke.17` or later to use it). | bool | `"false"` | no |
Expand Down Expand Up @@ -258,6 +259,9 @@ following project roles:
- roles/iam.serviceAccountUser
- roles/resourcemanager.projectIamAdmin (only required if `service_account` is set to `create`)

Additionally, if `service_account` is set to `create` and `grant_registry_access` is requested, the service account requires the following role on the `registry_project_id` project:
- roles/resourcemanager.projectIamAdmin

### Enable APIs
In order to operate with the Service Account you must activate the following APIs on the project where the Service Account was created:

Expand Down
2 changes: 1 addition & 1 deletion modules/beta-private-cluster/sa.tf
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ resource "google_project_iam_member" "cluster_service_account-monitoring_viewer"

resource "google_project_iam_member" "cluster_service_account-gcr" {
count = var.create_service_account && var.grant_registry_access ? 1 : 0
project = var.project_id
project = var.registry_project_id == "" ? var.project_id : var.registry_project_id
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.cluster_service_account[0].email}"
}
Expand Down
6 changes: 6 additions & 0 deletions modules/beta-private-cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ variable "grant_registry_access" {
default = false
}

variable "registry_project_id" {
type = string
description = "Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project."
default = ""
}

variable "service_account" {
type = string
description = "The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created."
Expand Down
4 changes: 4 additions & 0 deletions modules/beta-public-cluster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ In either case, upgrading to module version `v1.0.0` will trigger a recreation o
| project\_id | The project ID to host the cluster in (required) | string | n/a | yes |
| region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no |
| regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no |
| registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no |
| remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no |
| resource\_usage\_export\_dataset\_id | The dataset id for which network egress metering for this cluster will be enabled. If enabled, a daemonset will be created in the cluster to meter network egress traffic. | string | `""` | no |
| sandbox\_enabled | (Beta) Enable GKE Sandbox (Do not forget to set `image_type` = `COS_CONTAINERD` and `node_version` = `1.12.7-gke.17` or later to use it). | bool | `"false"` | no |
Expand Down Expand Up @@ -249,6 +250,9 @@ following project roles:
- roles/iam.serviceAccountUser
- roles/resourcemanager.projectIamAdmin (only required if `service_account` is set to `create`)

Additionally, if `service_account` is set to `create` and `grant_registry_access` is requested, the service account requires the following role on the `registry_project_id` project:
- roles/resourcemanager.projectIamAdmin

### Enable APIs
In order to operate with the Service Account you must activate the following APIs on the project where the Service Account was created:

Expand Down
2 changes: 1 addition & 1 deletion modules/beta-public-cluster/sa.tf
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ resource "google_project_iam_member" "cluster_service_account-monitoring_viewer"

resource "google_project_iam_member" "cluster_service_account-gcr" {
count = var.create_service_account && var.grant_registry_access ? 1 : 0
project = var.project_id
project = var.registry_project_id == "" ? var.project_id : var.registry_project_id
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.cluster_service_account[0].email}"
}
Expand Down
6 changes: 6 additions & 0 deletions modules/beta-public-cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ variable "grant_registry_access" {
default = false
}

variable "registry_project_id" {
type = string
description = "Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project."
default = ""
}

variable "service_account" {
type = string
description = "The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created."
Expand Down
4 changes: 4 additions & 0 deletions modules/private-cluster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ In either case, upgrading to module version `v1.0.0` will trigger a recreation o
| project\_id | The project ID to host the cluster in (required) | string | n/a | yes |
| region | The region to host the cluster in (optional if zonal cluster / required if regional) | string | `"null"` | no |
| regional | Whether is a regional cluster (zonal cluster if set false. WARNING: changing this after cluster creation is destructive!) | bool | `"true"` | no |
| registry\_project\_id | Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project. | string | `""` | no |
| remove\_default\_node\_pool | Remove default node pool while setting up the cluster | bool | `"false"` | no |
| service\_account | The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created. | string | `""` | no |
| stub\_domains | Map of stub domains and their resolvers to forward DNS queries for a certain domain to an external DNS server | map(list(string)) | `<map>` | no |
Expand Down Expand Up @@ -237,6 +238,9 @@ following project roles:
- roles/iam.serviceAccountUser
- roles/resourcemanager.projectIamAdmin (only required if `service_account` is set to `create`)

Additionally, if `service_account` is set to `create` and `grant_registry_access` is requested, the service account requires the following role on the `registry_project_id` project:
- roles/resourcemanager.projectIamAdmin

### Enable APIs
In order to operate with the Service Account you must activate the following APIs on the project where the Service Account was created:

Expand Down
2 changes: 1 addition & 1 deletion modules/private-cluster/sa.tf
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ resource "google_project_iam_member" "cluster_service_account-monitoring_viewer"

resource "google_project_iam_member" "cluster_service_account-gcr" {
count = var.create_service_account && var.grant_registry_access ? 1 : 0
project = var.project_id
project = var.registry_project_id == "" ? var.project_id : var.registry_project_id
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.cluster_service_account[0].email}"
}
Expand Down
6 changes: 6 additions & 0 deletions modules/private-cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,12 @@ variable "grant_registry_access" {
default = false
}

variable "registry_project_id" {
type = string
description = "Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project."
default = ""
}

variable "service_account" {
type = string
description = "The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created."
Expand Down
2 changes: 1 addition & 1 deletion sa.tf
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ resource "google_project_iam_member" "cluster_service_account-monitoring_viewer"

resource "google_project_iam_member" "cluster_service_account-gcr" {
count = var.create_service_account && var.grant_registry_access ? 1 : 0
project = var.project_id
project = var.registry_project_id == "" ? var.project_id : var.registry_project_id
role = "roles/storage.objectViewer"
member = "serviceAccount:${google_service_account.cluster_service_account[0].email}"
}
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/shared/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -79,3 +79,6 @@ output "service_account" {
value = module.example.service_account
}

output "registry_project_id" {
value = var.registry_project_id
}
4 changes: 4 additions & 0 deletions test/fixtures/shared/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ variable "compute_engine_service_account" {
description = "The email address of the service account to associate with the GKE cluster"
}

variable "registry_project_id" {
description = "Project to use for granting access to the GCR registry, if requested"
}

18 changes: 9 additions & 9 deletions test/fixtures/workload_metadata_config/example.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
module "example" {
source = "../../../examples/workload_metadata_config"

project_id = var.project_id
cluster_name_suffix = "-${random_string.suffix.result}"
region = var.region
zones = slice(var.zones, 0, 1)
network = google_compute_network.main.name
subnetwork = google_compute_subnetwork.main.name
ip_range_pods = google_compute_subnetwork.main.secondary_ip_range[0].range_name
ip_range_services = google_compute_subnetwork.main.secondary_ip_range[1].range_name
compute_engine_service_account = var.compute_engine_service_account
project_id = var.project_id
cluster_name_suffix = "-${random_string.suffix.result}"
region = var.region
zones = slice(var.zones, 0, 1)
network = google_compute_network.main.name
subnetwork = google_compute_subnetwork.main.name
ip_range_pods = google_compute_subnetwork.main.secondary_ip_range[0].range_name
ip_range_services = google_compute_subnetwork.main.secondary_ip_range[1].range_name
registry_project_id = var.registry_project_id
}
18 changes: 18 additions & 0 deletions test/integration/workload_metadata_config/controls/gcloud.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
# limitations under the License.

project_id = attribute('project_id')
registry_project_id = attribute('registry_project_id')
location = attribute('location')
cluster_name = attribute('cluster_name')
service_account = attribute('service_account')

control "gcloud" do
title "Google Compute Engine GKE configuration"
Expand Down Expand Up @@ -55,4 +57,20 @@
end
end
end

describe command("gcloud projects get-iam-policy #{registry_project_id} --format=json") do
its(:exit_status) { should eq 0 }
its(:stderr) { should eq '' }

let!(:iam) do
if subject.exit_status == 0
JSON.parse(subject.stdout)
else
{}
end
end
it "has expected registry roles" do
expect(iam['bindings']).to include("members" => ["serviceAccount:#{service_account}"], "role" => "roles/storage.objectViewer")
end
end
end
6 changes: 6 additions & 0 deletions test/integration/workload_metadata_config/inspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ attributes:
- name: project_id
required: true
type: string
- name: service_account
required: true
type: string
- name: registry_project_id
required: false
type: string
3 changes: 3 additions & 0 deletions test/setup/make_source.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ echo "#!/usr/bin/env bash" > ../source.sh
project_id=$(terraform output project_id)
echo "export TF_VAR_project_id='$project_id'" >> ../source.sh

# We use the same project for registry project in the tests.
echo "export TF_VAR_registry_project_id='$project_id'" >> ../source.sh

sa_json=$(terraform output sa_key)
# shellcheck disable=SC2086
echo "export SERVICE_ACCOUNT_JSON='$(echo $sa_json | base64 --decode)'" >> ../source.sh
Expand Down
6 changes: 6 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,12 @@ variable "grant_registry_access" {
default = false
}

variable "registry_project_id" {
type = string
description = "Project holding the Google Container Registry. If empty, we use the cluster project. If grant_registry_access is true, storage.objectViewer role is assigned on this project."
default = ""
}

variable "service_account" {
type = string
description = "The service account to run nodes as if not overridden in `node_pools`. The create_service_account variable default value (true) will cause a cluster-specific service account to be created."
Expand Down

0 comments on commit 4815c7a

Please sign in to comment.