Skip to content
This repository has been archived by the owner on Mar 29, 2023. It is now read-only.

Commit

Permalink
Merge pull request #56 from gruntwork-io/yori-default-service-account
Browse files Browse the repository at this point in the history
Allow overriding the default service account on the default node pool of GKE
  • Loading branch information
yorinasub17 authored Aug 20, 2019
2 parents ea5c97e + b1b99dc commit abc5aae
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defaults: &defaults
KUBERGRUNT_VERSION: v0.3.9
HELM_VERSION: v2.11.0
MODULE_CI_VERSION: v0.13.3
TERRAFORM_VERSION: 0.12.1
TERRAFORM_VERSION: 0.12.6
TERRAGRUNT_VERSION: NONE
PACKER_VERSION: NONE
GOLANG_VERSION: 1.11.2
Expand Down
18 changes: 9 additions & 9 deletions examples/gke-basic-tiller/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ resource "null_resource" "tiller_tls_certs" {
# Use environment variables for Kubernetes credentials to avoid leaking into the logs
environment = {
KUBECTL_SERVER_ENDPOINT = data.template_file.gke_host_endpoint.rendered
KUBECTL_CA_DATA = base64encode(data.template_file.cluster_ca_certificate.rendered)
KUBECTL_TOKEN = data.template_file.access_token.rendered
KUBECTL_CA_DATA = base64encode(data.template_file.cluster_ca_certificate.rendered)
KUBECTL_TOKEN = data.template_file.access_token.rendered
}
}
}
Expand All @@ -292,12 +292,12 @@ resource "null_resource" "tiller_tls_certs" {
module "tiller" {
source = "github.com/gruntwork-io/terraform-kubernetes-helm.git//modules/k8s-tiller?ref=v0.5.0"

tiller_tls_gen_method = "none"
tiller_service_account_name = kubernetes_service_account.tiller.metadata[0].name
tiller_tls_gen_method = "none"
tiller_service_account_name = kubernetes_service_account.tiller.metadata[0].name
tiller_service_account_token_secret_name = kubernetes_service_account.tiller.default_secret_name
tiller_tls_secret_name = local.tls_secret_name
namespace = local.tiller_namespace
tiller_image_version = local.tiller_version
tiller_tls_secret_name = local.tls_secret_name
namespace = local.tiller_namespace
tiller_image_version = local.tiller_version

# Kubergrunt will store the private key under the key "tls.pem" in the corresponding Secret resource, which will be
# accessed as a file when mounted into the container.
Expand All @@ -316,8 +316,8 @@ resource "null_resource" "wait_for_tiller" {
# Use environment variables for Kubernetes credentials to avoid leaking into the logs
environment = {
KUBECTL_SERVER_ENDPOINT = data.template_file.gke_host_endpoint.rendered
KUBECTL_CA_DATA = base64encode(data.template_file.cluster_ca_certificate.rendered)
KUBECTL_TOKEN = data.template_file.access_token.rendered
KUBECTL_CA_DATA = base64encode(data.template_file.cluster_ca_certificate.rendered)
KUBECTL_TOKEN = data.template_file.access_token.rendered
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions examples/gke-public-cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ module "gke_cluster" {

subnetwork = module.vpc_network.public_subnetwork
cluster_secondary_range_name = module.vpc_network.public_subnetwork_secondary_range_name

alternative_default_service_account = var.override_default_node_pool_service_account ? module.gke_service_account.email : null
}

# ---------------------------------------------------------------------------------------------------------------------
Expand Down
11 changes: 11 additions & 0 deletions examples/gke-public-cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,14 @@ variable "vpc_secondary_cidr_block" {
type = string
default = "10.7.0.0/16"
}

# ---------------------------------------------------------------------------------------------------------------------
# TEST PARAMETERS
# These parameters are only used during testing and should not be touched.
# ---------------------------------------------------------------------------------------------------------------------

variable "override_default_node_pool_service_account" {
description = "When true, this will use the service account that is created for use with the default node pool that comes with all GKE clusters"
type = bool
default = false
}
18 changes: 9 additions & 9 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,8 @@ resource "null_resource" "tiller_tls_certs" {
# Use environment variables for Kubernetes credentials to avoid leaking into the logs
environment = {
KUBECTL_SERVER_ENDPOINT = data.template_file.gke_host_endpoint.rendered
KUBECTL_CA_DATA = base64encode(data.template_file.cluster_ca_certificate.rendered)
KUBECTL_TOKEN = data.template_file.access_token.rendered
KUBECTL_CA_DATA = base64encode(data.template_file.cluster_ca_certificate.rendered)
KUBECTL_TOKEN = data.template_file.access_token.rendered
}
}
}
Expand All @@ -311,12 +311,12 @@ resource "null_resource" "tiller_tls_certs" {
module "tiller" {
source = "github.com/gruntwork-io/terraform-kubernetes-helm.git//modules/k8s-tiller?ref=v0.5.0"

tiller_tls_gen_method = "none"
tiller_service_account_name = kubernetes_service_account.tiller.metadata[0].name
tiller_tls_gen_method = "none"
tiller_service_account_name = kubernetes_service_account.tiller.metadata[0].name
tiller_service_account_token_secret_name = kubernetes_service_account.tiller.default_secret_name
tiller_tls_secret_name = local.tls_secret_name
namespace = local.tiller_namespace
tiller_image_version = local.tiller_version
tiller_tls_secret_name = local.tls_secret_name
namespace = local.tiller_namespace
tiller_image_version = local.tiller_version

# Kubergrunt will store the private key under the key "tls.pem" in the corresponding Secret resource, which will be
# accessed as a file when mounted into the container.
Expand All @@ -335,8 +335,8 @@ resource "null_resource" "wait_for_tiller" {
# Use environment variables for Kubernetes credentials to avoid leaking into the logs
environment = {
KUBECTL_SERVER_ENDPOINT = data.template_file.gke_host_endpoint.rendered
KUBECTL_CA_DATA = base64encode(data.template_file.cluster_ca_certificate.rendered)
KUBECTL_TOKEN = data.template_file.access_token.rendered
KUBECTL_CA_DATA = base64encode(data.template_file.cluster_ca_certificate.rendered)
KUBECTL_TOKEN = data.template_file.access_token.rendered
}
}
}
Expand Down
15 changes: 15 additions & 0 deletions modules/gke-cluster/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ resource "google_container_cluster" "cluster" {

initial_node_count = 1

# If we have an alternative default service account to use, set on the node_config so that the default node pool can
# be created successfully.
dynamic "node_config" {
# Ideally we can do `for_each = var.alternative_default_service_account != null ? [object] : []`, but due to a
# terraform bug, this doesn't work. See https://github.com/hashicorp/terraform/issues/21465. So we simulate it using
# a for expression.
for_each = [
for x in [var.alternative_default_service_account] : x if var.alternative_default_service_account != null
]

content {
service_account = node_config.value
}
}

# ip_allocation_policy.use_ip_aliases defaults to true, since we define the block `ip_allocation_policy`
ip_allocation_policy {
// Choose the range, but let GCP pick the IPs within the range
Expand Down
54 changes: 30 additions & 24 deletions modules/gke-cluster/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -110,38 +110,44 @@ variable "master_authorized_networks_config" {
}]
EOF
type = list(any)
default = []
type = list(any)
default = []
}

variable "maintenance_start_time" {
description = "Time window specified for daily maintenance operations in RFC3339 format"
type = string
default = "05:00"
type = string
default = "05:00"
}

variable "stub_domains" {
description = "Map of stub domains and their resolvers to forward DNS queries for a certain domain to an external DNS server"
type = map(string)
default = {}
type = map(string)
default = {}
}

variable "non_masquerade_cidrs" {
description = "List of strings in CIDR notation that specify the IP address ranges that do not use IP masquerading."
type = list(string)
default = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
type = list(string)
default = ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]
}

variable "ip_masq_resync_interval" {
description = "The interval at which the agent attempts to sync its ConfigMap file from the disk."
type = string
default = "60s"
type = string
default = "60s"
}

variable "ip_masq_link_local" {
description = "Whether to masquerade traffic to the link-local prefix (169.254.0.0/16)."
type = bool
default = false
type = bool
default = false
}

variable "alternative_default_service_account" {
description = "Alternative Service Account to be used by the Node VMs. If not specified, the default compute Service Account will be used. Provide if the default Service Account is no longer available."
type = string
default = null
}

# ---------------------------------------------------------------------------------------------------------------------
Expand All @@ -151,36 +157,36 @@ variable "ip_masq_link_local" {

variable "enable_kubernetes_dashboard" {
description = "Whether to enable the Kubernetes Web UI (Dashboard). The Web UI requires a highly privileged security account."
type = bool
default = false
type = bool
default = false
}

variable "enable_legacy_abac" {
description = "Whether to enable legacy Attribute-Based Access Control (ABAC). RBAC has significant security advantages over ABAC."
type = bool
default = false
type = bool
default = false
}

variable "enable_network_policy" {
description = "Whether to enable Kubernetes NetworkPolicy on the master, which is required to be enabled to be used on Nodes."
type = bool
default = true
type = bool
default = true
}

variable "basic_auth_username" {
description = "The username used for basic auth; set both this and `basic_auth_password` to \"\" to disable basic auth."
type = string
default = ""
type = string
default = ""
}

variable "basic_auth_password" {
description = "The password used for basic auth; set both this and `basic_auth_username` to \"\" to disable basic auth."
type = string
default = ""
type = string
default = ""
}

variable "enable_client_certificate_authentication" {
description = "Whether to enable authentication by x509 certificates. With ABAC disabled, these certificates are effectively useless."
type = bool
default = false
type = bool
default = false
}
17 changes: 14 additions & 3 deletions test/gke_cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,24 @@ func TestGKECluster(t *testing.T) {
t.Parallel()

var testcases = []struct {
testName string
exampleFolder string
testName string
exampleFolder string
overrideDefaultSA bool
}{
{
"PublicCluster",
"gke-public-cluster",
false,
},
{
"PrivateCluster",
"gke-private-cluster",
false,
},
{
"PublicClusterWithCustomSA",
"gke-public-cluster",
true,
},
}

Expand Down Expand Up @@ -65,7 +73,10 @@ func TestGKECluster(t *testing.T) {
uniqueID := random.UniqueId()
project := gcp.GetGoogleProjectIDFromEnvVar(t)
region := gcp.GetRandomRegion(t, project, nil, nil)
gkeClusterTerratestOptions := createTestGKEClusterTerraformOptions(t, uniqueID, project, region,gkeClusterTerraformModulePath)
gkeClusterTerratestOptions := createTestGKEClusterTerraformOptions(t, uniqueID, project, region, gkeClusterTerraformModulePath)
if testCase.overrideDefaultSA {
gkeClusterTerratestOptions.Vars["override_default_node_pool_service_account"] = "1"
}
test_structure.SaveString(t, workingDir, "uniqueID", uniqueID)
test_structure.SaveString(t, workingDir, "project", project)
test_structure.SaveString(t, workingDir, "region", region)
Expand Down

0 comments on commit abc5aae

Please sign in to comment.