Skip to content

Commit 6501fd8

Browse files
authored
feat(kubectl): Generate kubeconfig dynamically (#62)
1 parent f9c3929 commit 6501fd8

File tree

4 files changed

+60
-47
lines changed

4 files changed

+60
-47
lines changed

modules/kubectl-wrapper/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ module "kubectl" {
3131
| create\_cmd\_triggers | List of any additional triggers for the create command execution. | map | `<map>` | no |
3232
| enabled | Flag to optionally disable usage of this module. | bool | `"true"` | no |
3333
| gcloud\_sdk\_version | The gcloud sdk version to download. | string | `"281.0.0"` | no |
34+
| internal\_ip | Use internal ip for the cluster endpoint. | bool | `"false"` | no |
3435
| kubectl\_create\_command | The kubectl command to create resources. | string | n/a | yes |
3536
| kubectl\_destroy\_command | The kubectl command to destroy resources. | string | n/a | yes |
3637
| module\_depends\_on | List of modules or resources this module depends on. | list | `<list>` | no |
3738
| project\_id | The project ID hosting the cluster. Optional if use_existing_context is true. | string | `""` | no |
39+
| service\_account\_key\_file | Path to service account key file to auth as for running `gcloud container clusters get-credentials`. | string | `""` | no |
3840
| skip\_download | Whether to skip downloading gcloud (assumes gcloud and kubectl is already available outside the module) | bool | `"true"` | no |
3941
| upgrade | Whether to upgrade gcloud at runtime | bool | `"true"` | no |
4042
| use\_existing\_context | Use existing kubecontext to auth kube-api. | bool | `"false"` | no |

modules/kubectl-wrapper/main.tf

+11-25
Original file line numberDiff line numberDiff line change
@@ -15,36 +15,22 @@
1515
*/
1616

1717
locals {
18-
cluster_endpoint = "https://${data.google_container_cluster.primary.0.endpoint}"
19-
cluster_ca_certificate = data.google_container_cluster.primary.0.master_auth.0.cluster_ca_certificate
20-
token = data.google_client_config.default.0.access_token
21-
create_cmd = var.use_existing_context ? var.kubectl_create_command : "${local.cluster_endpoint} ${local.token} ${local.cluster_ca_certificate} ${var.kubectl_create_command}"
22-
destroy_cmd = var.use_existing_context ? var.kubectl_destroy_command : "${local.cluster_endpoint} ${local.token} ${local.cluster_ca_certificate} ${var.kubectl_destroy_command}"
23-
}
24-
25-
data "google_container_cluster" "primary" {
26-
count = var.enabled && ! var.use_existing_context ? 1 : 0
27-
name = var.cluster_name
28-
project = var.project_id
29-
location = var.cluster_location
30-
}
31-
32-
data "google_client_config" "default" {
33-
count = var.enabled && ! var.use_existing_context ? 1 : 0
18+
base_cmd = "${var.cluster_name} ${var.cluster_location} ${var.project_id} ${var.internal_ip} ${var.use_existing_context}"
3419
}
3520

3621
module "gcloud_kubectl" {
37-
source = "../.."
38-
module_depends_on = var.module_depends_on
39-
additional_components = var.additional_components
40-
skip_download = var.skip_download
41-
gcloud_sdk_version = var.gcloud_sdk_version
42-
enabled = var.enabled
43-
upgrade = var.upgrade
22+
source = "../.."
23+
module_depends_on = var.module_depends_on
24+
additional_components = var.additional_components
25+
skip_download = var.skip_download
26+
gcloud_sdk_version = var.gcloud_sdk_version
27+
enabled = var.enabled
28+
upgrade = var.upgrade
29+
service_account_key_file = var.service_account_key_file
4430

4531
create_cmd_entrypoint = "${path.module}/scripts/kubectl_wrapper.sh"
46-
create_cmd_body = local.create_cmd
32+
create_cmd_body = "${local.base_cmd} ${var.kubectl_create_command}"
4733
create_cmd_triggers = var.create_cmd_triggers
4834
destroy_cmd_entrypoint = "${path.module}/scripts/kubectl_wrapper.sh"
49-
destroy_cmd_body = local.destroy_cmd
35+
destroy_cmd_body = "${local.base_cmd} ${var.kubectl_destroy_command}"
5036
}

modules/kubectl-wrapper/scripts/kubectl_wrapper.sh

+36-22
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,47 @@ if [ "$#" -lt 3 ]; then
2121
exit 1
2222
fi
2323

24-
HOST=$1
25-
TOKEN=$2
26-
CA_CERTIFICATE=$3
24+
CLUSTER_NAME=$1
25+
LOCATION=$2
26+
PROJECT_ID=$3
27+
INTERNAL=$4
28+
USE_EXISTING_CONTEXT=$5
2729

28-
shift 3
30+
shift 5
2931

30-
RANDOM_ID="${RANDOM}_${RANDOM}"
31-
export TMPDIR="/tmp/kubectl_wrapper_${RANDOM_ID}"
32+
if $USE_EXISTING_CONTEXT ;then
3233

33-
function cleanup {
34-
rm -rf "${TMPDIR}"
35-
}
36-
trap cleanup EXIT
34+
"$@"
3735

38-
mkdir "${TMPDIR}"
36+
else
3937

40-
export KUBECONFIG="${TMPDIR}/config"
38+
RANDOM_ID="${RANDOM}_${RANDOM}"
39+
export TMPDIR="/tmp/kubectl_wrapper_${RANDOM_ID}"
4140

42-
# shellcheck disable=SC1117
43-
base64 --help | grep "\--decode" && B64_ARG="--decode" || B64_ARG="-d"
44-
echo "${CA_CERTIFICATE}" | base64 ${B64_ARG} > "${TMPDIR}/ca_certificate"
41+
function cleanup {
42+
rm -rf "${TMPDIR}"
43+
}
44+
trap cleanup EXIT
4545

46-
kubectl config set-cluster kubectl-wrapper --server="${HOST}" --certificate-authority="${TMPDIR}/ca_certificate" --embed-certs=true 1>/dev/null
47-
rm -f "${TMPDIR}/ca_certificate"
48-
kubectl config set-context kubectl-wrapper --cluster=kubectl-wrapper --user=kubectl-wrapper --namespace=default 1>/dev/null
49-
kubectl config set-credentials kubectl-wrapper --token="${TOKEN}" 1>/dev/null
50-
kubectl config use-context kubectl-wrapper 1>/dev/null
51-
kubectl version 1>/dev/null
46+
mkdir "${TMPDIR}"
5247

53-
"$@"
48+
export KUBECONFIG="${TMPDIR}/config"
49+
50+
LOCATION_TYPE=$(grep -o "-" <<< "${LOCATION}" | wc -l)
51+
52+
CMD="gcloud container clusters get-credentials ${CLUSTER_NAME} --project ${PROJECT_ID}"
53+
54+
if [[ $LOCATION_TYPE -eq 2 ]] ;then
55+
CMD+=" --zone ${LOCATION}"
56+
else
57+
CMD+=" --region ${LOCATION}"
58+
fi
59+
60+
if $INTERNAL ;then
61+
CMD+=" --internal-ip"
62+
fi
63+
64+
$CMD
65+
66+
"$@"
67+
fi

modules/kubectl-wrapper/variables.tf

+11
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,14 @@ variable "use_existing_context" {
8787
type = bool
8888
default = false
8989
}
90+
91+
variable "internal_ip" {
92+
description = "Use internal ip for the cluster endpoint."
93+
type = bool
94+
default = false
95+
}
96+
97+
variable "service_account_key_file" {
98+
description = "Path to service account key file to auth as for running `gcloud container clusters get-credentials`."
99+
default = ""
100+
}

0 commit comments

Comments
 (0)