Skip to content

feat(helm/provisioner): add support for provisioner keys, add note re psk #15122

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions helm/provisioner/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{{/*
Deprecation notices:
*/}}

{{- if .Values.provisionerDaemon.pskSecretName }}
* Provisioner Daemon PSKs are no longer recommended for use with external
provisioners. Consider migrating to scoped provisioner keys instead. For more
information, see: https://coder.com/docs/admin/provisioners#authentication
{{- end }}

Enjoy Coder! Please create an issue at https://github.com/coder/coder if you run
into any problems! :)
12 changes: 12 additions & 0 deletions helm/provisioner/templates/_coder.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,23 @@ args:
env:
- name: CODER_PROMETHEUS_ADDRESS
value: "0.0.0.0:2112"
{{- if and (empty .Values.provisionerDaemon.pskSecretName) (empty .Values.provisionerDaemon.keySecretName) }}
{{ fail "Either provisionerDaemon.pskSecretName or provisionerDaemon.keySecretName must be specified." }}
{{- end }}
{{- if .Values.provisionerDaemon.pskSecretName }}
- name: CODER_PROVISIONER_DAEMON_PSK
valueFrom:
secretKeyRef:
name: {{ .Values.provisionerDaemon.pskSecretName | quote }}
key: psk
{{- end }}
{{- if and .Values.provisionerDaemon.keySecretName .Values.provisionerDaemon.keySecretKey }}
- name: CODER_PROVISIONER_DAEMON_KEY
valueFrom:
secretKeyRef:
name: {{ .Values.provisionerDaemon.keySecretName | quote }}
key: {{ .Values.provisionerDaemon.keySecretKey | quote }}
{{- end }}
{{- if include "provisioner.tags" . }}
- name: CODER_PROVISIONERD_TAGS
value: {{ include "provisioner.tags" . }}
Expand Down
12 changes: 12 additions & 0 deletions helm/provisioner/tests/chart_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ var testCases = []testCase{
name: "provisionerd_psk",
expectedError: "",
},
{
name: "provisionerd_key",
expectedError: "",
},
{
name: "provisionerd_psk_and_key",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it ever sensible to accept both? I think we can only accept one or other as the authentication credential

Copy link
Member Author

@johnstcn johnstcn Oct 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you're correct:

error: cannot provide both provisioner key --key and pre-shared key --psk

I can remove this test and add a check in the Helm chart, but I'd worry about logic drift.

expectedError: "",
},
{
name: "provisionerd_no_psk_or_key",
expectedError: `Either provisionerDaemon.pskSecretName or provisionerDaemon.keySecretName must be specified.`,
},
{
name: "extra_templates",
expectedError: "",
Expand Down
137 changes: 137 additions & 0 deletions helm/provisioner/tests/testdata/provisionerd_key.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
# Source: coder-provisioner/templates/coder.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: coder-provisioner
app.kubernetes.io/part-of: coder-provisioner
app.kubernetes.io/version: 0.1.0
helm.sh/chart: coder-provisioner-0.1.0
name: coder-provisioner
---
# Source: coder-provisioner/templates/rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: coder-provisioner-workspace-perms
rules:
- apiGroups: [""]
resources: ["pods"]
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- apps
resources:
- deployments
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
---
# Source: coder-provisioner/templates/rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: "coder-provisioner"
subjects:
- kind: ServiceAccount
name: "coder-provisioner"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: coder-provisioner-workspace-perms
---
# Source: coder-provisioner/templates/coder.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: coder-provisioner
app.kubernetes.io/part-of: coder-provisioner
app.kubernetes.io/version: 0.1.0
helm.sh/chart: coder-provisioner-0.1.0
name: coder-provisioner
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/name: coder-provisioner
template:
metadata:
annotations: {}
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: coder-provisioner
app.kubernetes.io/part-of: coder-provisioner
app.kubernetes.io/version: 0.1.0
helm.sh/chart: coder-provisioner-0.1.0
spec:
containers:
- args:
- provisionerd
- start
command:
- /opt/coder
env:
- name: CODER_PROMETHEUS_ADDRESS
value: 0.0.0.0:2112
- name: CODER_PROVISIONER_DAEMON_KEY
valueFrom:
secretKeyRef:
key: provisionerd-key
name: coder-provisionerd-key
- name: CODER_PROVISIONERD_TAGS
value: clusterType=k8s,location=auh
- name: CODER_URL
value: http://coder.default.svc.cluster.local
image: ghcr.io/coder/coder:latest
imagePullPolicy: IfNotPresent
lifecycle: {}
name: coder
ports: null
resources: {}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: null
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
volumeMounts: []
restartPolicy: Always
serviceAccountName: coder-provisioner
terminationGracePeriodSeconds: 600
volumes: []
10 changes: 10 additions & 0 deletions helm/provisioner/tests/testdata/provisionerd_key.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
coder:
image:
tag: latest
provisionerDaemon:
pskSecretName: ""
keySecretName: "coder-provisionerd-key"
keySecretKey: "provisionerd-key"
tags:
location: auh
clusterType: k8s
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
coder:
image:
tag: latest
provisionerDaemon:
pskSecretName: ""
keySecretName: ""
tags:
location: auh
clusterType: k8s
142 changes: 142 additions & 0 deletions helm/provisioner/tests/testdata/provisionerd_psk_and_key.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
---
# Source: coder-provisioner/templates/coder.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: coder-provisioner
app.kubernetes.io/part-of: coder-provisioner
app.kubernetes.io/version: 0.1.0
helm.sh/chart: coder-provisioner-0.1.0
name: coder-provisioner
---
# Source: coder-provisioner/templates/rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: coder-provisioner-workspace-perms
rules:
- apiGroups: [""]
resources: ["pods"]
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- apps
resources:
- deployments
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
---
# Source: coder-provisioner/templates/rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: "coder-provisioner"
subjects:
- kind: ServiceAccount
name: "coder-provisioner"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: coder-provisioner-workspace-perms
---
# Source: coder-provisioner/templates/coder.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: coder-provisioner
app.kubernetes.io/part-of: coder-provisioner
app.kubernetes.io/version: 0.1.0
helm.sh/chart: coder-provisioner-0.1.0
name: coder-provisioner
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/name: coder-provisioner
template:
metadata:
annotations: {}
labels:
app.kubernetes.io/instance: release-name
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: coder-provisioner
app.kubernetes.io/part-of: coder-provisioner
app.kubernetes.io/version: 0.1.0
helm.sh/chart: coder-provisioner-0.1.0
spec:
containers:
- args:
- provisionerd
- start
command:
- /opt/coder
env:
- name: CODER_PROMETHEUS_ADDRESS
value: 0.0.0.0:2112
- name: CODER_PROVISIONER_DAEMON_PSK
valueFrom:
secretKeyRef:
key: psk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: any reason why this is called psk instead of provisionerd-psk?

Copy link
Member Author

@johnstcn johnstcn Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The key name is currently hard-coded in _coder.tpl:

- name: CODER_PROVISIONER_DAEMON_PSK
  valueFrom:
    secretKeyRef:
      name: {{ .Values.provisionerDaemon.pskSecretName | quote }}
      key: psk
{{- if include "provisioner.tags" . }}

This wasn't changed as part of this PR. I can add a separate PR to allow customizing the key name, if required.

name: coder-provisionerd-psk
- name: CODER_PROVISIONER_DAEMON_KEY
valueFrom:
secretKeyRef:
key: provisionerd-key
name: coder-provisionerd-key
- name: CODER_PROVISIONERD_TAGS
value: clusterType=k8s,location=auh
- name: CODER_URL
value: http://coder.default.svc.cluster.local
image: ghcr.io/coder/coder:latest
imagePullPolicy: IfNotPresent
lifecycle: {}
name: coder
ports: null
resources: {}
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: null
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
volumeMounts: []
restartPolicy: Always
serviceAccountName: coder-provisioner
terminationGracePeriodSeconds: 600
volumes: []
10 changes: 10 additions & 0 deletions helm/provisioner/tests/testdata/provisionerd_psk_and_key.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
coder:
image:
tag: latest
provisionerDaemon:
pskSecretName: "coder-provisionerd-psk"
keySecretName: "coder-provisionerd-key"
keySecretKey: "provisionerd-key"
tags:
location: auh
clusterType: k8s
20 changes: 17 additions & 3 deletions helm/provisioner/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,25 @@ coder:
# provisionerDaemon -- Provisioner Daemon configuration options
provisionerDaemon:
# provisionerDaemon.pskSecretName -- The name of the Kubernetes secret that contains the
# Pre-Shared Key (PSK) to use to authenticate with Coder. The secret must be in the same namespace
# as the Helm deployment, and contain an item called "psk" which contains the pre-shared key.
# Pre-Shared Key (PSK) to use to authenticate with Coder. The secret must be
# in the same namespace as the Helm deployment, and contain an item called
# "psk" which contains the pre-shared key.
# NOTE: We no longer recommend using PSKs. Please consider using provisioner
# keys instead. They have a number of benefits, including the ability to
# rotate them easily.
pskSecretName: "coder-provisioner-psk"

# provisionerDaemon.tags -- Tags to filter provisioner jobs by
# provisionerDaemon.keySecretName -- The name of the Kubernetes
# secret that contains a provisioner key to use to authenticate with Coder.
# See: https://coder.com/docs/admin/provisioners#authentication
keySecretName: ""
# provisionerDaemon.keySecretKey -- The key of the Kubernetes
# secret specified in provisionerDaemon.keySecretName that contains
# the provisioner key. Defaults to "key".
keySecretKey: "key"

# provisionerDaemon.tags -- Tags to filter provisioner jobs by.
# See: https://coder.com/docs/admin/provisioners#provisioner-tags
tags:
{}
# location: usa
Expand Down
Loading