Skip to content

Commit 1abd030

Browse files
authored
Better support for KUBECONFIG file authentication (cloudposse/terraform-aws-components#1034)
1 parent 68b7829 commit 1abd030

File tree

2 files changed

+54
-18
lines changed

2 files changed

+54
-18
lines changed

src/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ components:
8080
| <a name="input_kube_exec_auth_enabled"></a> [kube\_exec\_auth\_enabled](#input\_kube\_exec\_auth\_enabled) | If `true`, use the Kubernetes provider `exec` feature to execute `aws eks get-token` to authenticate to the EKS cluster.<br>Disabled by `kubeconfig_file_enabled`, overrides `kube_data_auth_enabled`. | `bool` | `true` | no |
8181
| <a name="input_kube_exec_auth_role_arn"></a> [kube\_exec\_auth\_role\_arn](#input\_kube\_exec\_auth\_role\_arn) | The role ARN for `aws eks get-token` to use | `string` | `""` | no |
8282
| <a name="input_kube_exec_auth_role_arn_enabled"></a> [kube\_exec\_auth\_role\_arn\_enabled](#input\_kube\_exec\_auth\_role\_arn\_enabled) | If `true`, pass `kube_exec_auth_role_arn` as the role ARN to `aws eks get-token` | `bool` | `true` | no |
83-
| <a name="input_kubeconfig_context"></a> [kubeconfig\_context](#input\_kubeconfig\_context) | Context to choose from the Kubernetes kube config file | `string` | `""` | no |
83+
| <a name="input_kubeconfig_context"></a> [kubeconfig\_context](#input\_kubeconfig\_context) | Context to choose from the Kubernetes config file.<br>If supplied, `kubeconfig_context_format` will be ignored. | `string` | `""` | no |
84+
| <a name="input_kubeconfig_context_format"></a> [kubeconfig\_context\_format](#input\_kubeconfig\_context\_format) | A format string to use for creating the `kubectl` context name when<br>`kubeconfig_file_enabled` is `true` and `kubeconfig_context` is not supplied.<br>Must include a single `%s` which will be replaced with the cluster name. | `string` | `""` | no |
8485
| <a name="input_kubeconfig_exec_auth_api_version"></a> [kubeconfig\_exec\_auth\_api\_version](#input\_kubeconfig\_exec\_auth\_api\_version) | The Kubernetes API version of the credentials returned by the `exec` auth plugin | `string` | `"client.authentication.k8s.io/v1beta1"` | no |
8586
| <a name="input_kubeconfig_file"></a> [kubeconfig\_file](#input\_kubeconfig\_file) | The Kubernetes provider `config_path` setting to use when `kubeconfig_file_enabled` is `true` | `string` | `""` | no |
8687
| <a name="input_kubeconfig_file_enabled"></a> [kubeconfig\_file\_enabled](#input\_kubeconfig\_file\_enabled) | If `true`, configure the Kubernetes provider with `kubeconfig_file` and use that kubeconfig file for authenticating to the EKS cluster | `bool` | `false` | no |

src/provider-helm.tf

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,35 @@ variable "kubeconfig_file_enabled" {
2121
type = bool
2222
default = false
2323
description = "If `true`, configure the Kubernetes provider with `kubeconfig_file` and use that kubeconfig file for authenticating to the EKS cluster"
24+
nullable = false
2425
}
2526

2627
variable "kubeconfig_file" {
2728
type = string
2829
default = ""
2930
description = "The Kubernetes provider `config_path` setting to use when `kubeconfig_file_enabled` is `true`"
31+
nullable = false
3032
}
3133

3234
variable "kubeconfig_context" {
3335
type = string
3436
default = ""
35-
description = "Context to choose from the Kubernetes kube config file"
37+
description = <<-EOT
38+
Context to choose from the Kubernetes config file.
39+
If supplied, `kubeconfig_context_format` will be ignored.
40+
EOT
41+
nullable = false
42+
}
43+
44+
variable "kubeconfig_context_format" {
45+
type = string
46+
default = ""
47+
description = <<-EOT
48+
A format string to use for creating the `kubectl` context name when
49+
`kubeconfig_file_enabled` is `true` and `kubeconfig_context` is not supplied.
50+
Must include a single `%s` which will be replaced with the cluster name.
51+
EOT
52+
nullable = false
3653
}
3754

3855
variable "kube_data_auth_enabled" {
@@ -42,6 +59,7 @@ variable "kube_data_auth_enabled" {
4259
If `true`, use an `aws_eks_cluster_auth` data source to authenticate to the EKS cluster.
4360
Disabled by `kubeconfig_file_enabled` or `kube_exec_auth_enabled`.
4461
EOT
62+
nullable = false
4563
}
4664

4765
variable "kube_exec_auth_enabled" {
@@ -51,48 +69,62 @@ variable "kube_exec_auth_enabled" {
5169
If `true`, use the Kubernetes provider `exec` feature to execute `aws eks get-token` to authenticate to the EKS cluster.
5270
Disabled by `kubeconfig_file_enabled`, overrides `kube_data_auth_enabled`.
5371
EOT
72+
nullable = false
5473
}
5574

5675
variable "kube_exec_auth_role_arn" {
5776
type = string
5877
default = ""
5978
description = "The role ARN for `aws eks get-token` to use"
79+
nullable = false
6080
}
6181

6282
variable "kube_exec_auth_role_arn_enabled" {
6383
type = bool
6484
default = true
6585
description = "If `true`, pass `kube_exec_auth_role_arn` as the role ARN to `aws eks get-token`"
86+
nullable = false
6687
}
6788

6889
variable "kube_exec_auth_aws_profile" {
6990
type = string
7091
default = ""
7192
description = "The AWS config profile for `aws eks get-token` to use"
93+
nullable = false
7294
}
7395

7496
variable "kube_exec_auth_aws_profile_enabled" {
7597
type = bool
7698
default = false
7799
description = "If `true`, pass `kube_exec_auth_aws_profile` as the `profile` to `aws eks get-token`"
100+
nullable = false
78101
}
79102

80103
variable "kubeconfig_exec_auth_api_version" {
81104
type = string
82105
default = "client.authentication.k8s.io/v1beta1"
83106
description = "The Kubernetes API version of the credentials returned by the `exec` auth plugin"
107+
nullable = false
84108
}
85109

86110
variable "helm_manifest_experiment_enabled" {
87111
type = bool
88112
default = false
89113
description = "Enable storing of the rendered manifest for helm_release so the full diff of what is changing can been seen in the plan"
114+
nullable = false
90115
}
91116

92117
locals {
93118
kubeconfig_file_enabled = var.kubeconfig_file_enabled
94-
kube_exec_auth_enabled = local.kubeconfig_file_enabled ? false : var.kube_exec_auth_enabled
95-
kube_data_auth_enabled = local.kube_exec_auth_enabled ? false : var.kube_data_auth_enabled
119+
kubeconfig_file = local.kubeconfig_file_enabled ? var.kubeconfig_file : ""
120+
kubeconfig_context = !local.kubeconfig_file_enabled ? "" : (
121+
length(var.kubeconfig_context) != 0 ? var.kubeconfig_context : (
122+
length(var.kubeconfig_context_format) != 0 ? format(var.kubeconfig_context_format, local.eks_cluster_id) : ""
123+
)
124+
)
125+
126+
kube_exec_auth_enabled = local.kubeconfig_file_enabled ? false : var.kube_exec_auth_enabled
127+
kube_data_auth_enabled = local.kube_exec_auth_enabled ? false : var.kube_data_auth_enabled
96128

97129
# Eventually we might try to get this from an environment variable
98130
kubeconfig_exec_auth_api_version = var.kubeconfig_exec_auth_api_version
@@ -107,10 +139,11 @@ locals {
107139
] : []
108140

109141
# Provide dummy configuration for the case where the EKS cluster is not available.
110-
certificate_authority_data = try(module.eks.outputs.eks_cluster_certificate_authority_data, "")
142+
certificate_authority_data = local.kubeconfig_file_enabled ? null : try(module.eks.outputs.eks_cluster_certificate_authority_data, null)
143+
cluster_ca_certificate = local.kubeconfig_file_enabled ? null : try(base64decode(local.certificate_authority_data), null)
111144
# Use coalesce+try to handle both the case where the output is missing and the case where it is empty.
112145
eks_cluster_id = coalesce(try(module.eks.outputs.eks_cluster_id, ""), "missing")
113-
eks_cluster_endpoint = try(module.eks.outputs.eks_cluster_endpoint, "")
146+
eks_cluster_endpoint = local.kubeconfig_file_enabled ? null : try(module.eks.outputs.eks_cluster_endpoint, "")
114147
}
115148

116149
data "aws_eks_cluster_auth" "eks" {
@@ -121,15 +154,16 @@ data "aws_eks_cluster_auth" "eks" {
121154
provider "helm" {
122155
kubernetes {
123156
host = local.eks_cluster_endpoint
124-
cluster_ca_certificate = base64decode(local.certificate_authority_data)
157+
cluster_ca_certificate = local.cluster_ca_certificate
125158
token = local.kube_data_auth_enabled ? one(data.aws_eks_cluster_auth.eks[*].token) : null
126-
# The Kubernetes provider will use information from KUBECONFIG if it exists, but if the default cluster
127-
# in KUBECONFIG is some other cluster, this will cause problems, so we override it always.
128-
config_path = local.kubeconfig_file_enabled ? var.kubeconfig_file : ""
129-
config_context = var.kubeconfig_context
159+
# It is too confusing to allow the Kubernetes provider to use environment variables to set authentication
160+
# in this module because we have so many options, so we override environment variables like `KUBE_CONFIG_PATH`
161+
# in all cases. People can still use environment variables by setting TF_VAR_kubeconfig_file.
162+
config_path = local.kubeconfig_file
163+
config_context = local.kubeconfig_context
130164

131165
dynamic "exec" {
132-
for_each = local.kube_exec_auth_enabled && length(local.certificate_authority_data) > 0 ? ["exec"] : []
166+
for_each = local.kube_exec_auth_enabled && local.certificate_authority_data != null ? ["exec"] : []
133167
content {
134168
api_version = local.kubeconfig_exec_auth_api_version
135169
command = "aws"
@@ -146,15 +180,16 @@ provider "helm" {
146180

147181
provider "kubernetes" {
148182
host = local.eks_cluster_endpoint
149-
cluster_ca_certificate = base64decode(local.certificate_authority_data)
183+
cluster_ca_certificate = local.cluster_ca_certificate
150184
token = local.kube_data_auth_enabled ? one(data.aws_eks_cluster_auth.eks[*].token) : null
151-
# The Kubernetes provider will use information from KUBECONFIG if it exists, but if the default cluster
152-
# in KUBECONFIG is some other cluster, this will cause problems, so we override it always.
153-
config_path = local.kubeconfig_file_enabled ? var.kubeconfig_file : ""
154-
config_context = var.kubeconfig_context
185+
# It is too confusing to allow the Kubernetes provider to use environment variables to set authentication
186+
# in this module because we have so many options, so we override environment variables like `KUBE_CONFIG_PATH`
187+
# in all cases. People can still use environment variables by setting TF_VAR_kubeconfig_file.
188+
config_path = local.kubeconfig_file
189+
config_context = local.kubeconfig_context
155190

156191
dynamic "exec" {
157-
for_each = local.kube_exec_auth_enabled && length(local.certificate_authority_data) > 0 ? ["exec"] : []
192+
for_each = local.kube_exec_auth_enabled && local.certificate_authority_data != null ? ["exec"] : []
158193
content {
159194
api_version = local.kubeconfig_exec_auth_api_version
160195
command = "aws"

0 commit comments

Comments
 (0)