Feat(helm): Modify the existing serviceAccount for use by router and lora-controller #1005
Feat(helm): Modify the existing serviceAccount for use by router and lora-controller #1005ghkdwlgns612 wants to merge 2 commits into
Conversation
…nd lora-controller to skip SA/Role/RoleBinding creation Signed-off-by: ghkdwlgns612 <ghkdwlgns612@naver.com>
There was a problem hiding this comment.
Code Review
This pull request adds support for configuring custom service accounts for the router and LoRA controller deployments in the Helm chart, skipping the creation of the default ServiceAccount resources when custom names are provided. The feedback suggests a key improvement: instead of skipping the creation of RBAC roles and role bindings when a custom service account is specified, the chart should still manage and create these RBAC resources but dynamically bind them to the custom service account. This ensures that application-specific permissions are maintained by the chart while allowing integration with externally managed service accounts.
| @@ -1,4 +1,4 @@ | |||
| {{- if .Values.routerSpec.enableRouter -}} | |||
| {{- if and .Values.routerSpec.enableRouter (not .Values.routerSpec.serviceAccountName) -}} | |||
There was a problem hiding this comment.
Decoupling ServiceAccount creation from Role/ClusterRole creation is a standard Helm best practice. In many enterprise environments, the ServiceAccount is pre-created externally (e.g., to associate it with AWS IRSA or GCP Workload Identity), but the Helm chart is still expected to manage and create the application-specific RBAC roles and bindings.
By skipping Role creation when serviceAccountName is set, users are forced to manually define and maintain these complex RBAC rules externally, which is error-prone and hard to maintain during chart upgrades.
Instead, we should always create the Role and RoleBinding resources when the component is enabled, but bind them to the custom serviceAccountName if provided.
{{- if .Values.routerSpec.enableRouter -}}| {{- end }} | ||
|
|
||
| {{- if .Values.loraController.enableLoraController }} | ||
| {{- if and .Values.loraController.enableLoraController (not .Values.loraController.serviceAccountName) }} |
There was a problem hiding this comment.
Similarly for the lora-controller, we should not skip the ClusterRole creation when a custom serviceAccountName is provided. This ensures that the required permissions are still managed by the chart while using the externally provisioned service account.
{{- if .Values.loraController.enableLoraController }}| {{- if and .Values.routerSpec.enableRouter (not .Values.routerSpec.serviceAccountName) -}} | ||
| apiVersion: rbac.authorization.k8s.io/v1 | ||
| kind: RoleBinding | ||
| metadata: | ||
| name: {{ .Release.Name }}-deployment-access-binding | ||
| namespace: {{ .Release.Namespace }} | ||
| subjects: | ||
| - kind: ServiceAccount | ||
| name: {{ .Release.Name }}-router-service-account | ||
| name: {{ printf "%s-router-service-account" .Release.Name }} | ||
| namespace: {{ .Release.Namespace }} | ||
| roleRef: | ||
| kind: Role | ||
| name: {{ .Release.Name }}-reader | ||
| apiGroup: rbac.authorization.k8s.io | ||
| {{- end }} |
There was a problem hiding this comment.
To support using a custom serviceAccountName while still letting the chart manage the RoleBinding, we should keep the RoleBinding enabled and dynamically set the subject's name to the custom service account if provided.
{{- if .Values.routerSpec.enableRouter -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ .Release.Name }}-deployment-access-binding
namespace: {{ .Release.Namespace }}
subjects:
- kind: ServiceAccount
name: {{ .Values.routerSpec.serviceAccountName | default (printf "%s-router-service-account" .Release.Name) }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: Role
name: {{ .Release.Name }}-reader
apiGroup: rbac.authorization.k8s.io
{{- end }}| {{- end }} | ||
|
|
||
| {{- if .Values.loraController.enableLoraController }} | ||
| {{- if and .Values.loraController.enableLoraController (not .Values.loraController.serviceAccountName) }} |
| subjects: | ||
| - kind: ServiceAccount | ||
| name: {{ .Release.Name }}-lora-controller | ||
| name: {{ printf "%s-lora-controller" .Release.Name }} | ||
| namespace: {{ .Release.Namespace }} |
| subjects: | ||
| - kind: ServiceAccount | ||
| name: {{ .Release.Name }}-lora-controller | ||
| name: {{ printf "%s-lora-controller" .Release.Name }} | ||
| namespace: {{ .Release.Namespace }} |
There was a problem hiding this comment.
| - it: should NOT create Role and RoleBinding when custom serviceAccountName is set | ||
| release: | ||
| name: vllm | ||
| set: | ||
| routerSpec: | ||
| enableRouter: true | ||
| serviceAccountName: my-existing-sa | ||
| asserts: | ||
| - hasDocuments: | ||
| count: 0 |
There was a problem hiding this comment.
Since we want to keep the Role and RoleBinding creation enabled and bind them to the custom service account, we should update this test to assert that they are created and bound to the custom service account name.
- it: should create Role and RoleBinding with custom serviceAccountName when specified
release:
name: vllm
set:
routerSpec:
enableRouter: true
serviceAccountName: my-existing-sa
asserts:
- containsDocument:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
name: vllm-reader
template: role.yaml
- containsDocument:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
name: vllm-deployment-access-binding
template: rolebinding.yaml
- equal:
path: subjects[0].name
value: my-existing-sa
documentIndex: 0
template: rolebinding.yaml| - it: should NOT create ClusterRole and ClusterRoleBinding when lora serviceAccountName is set | ||
| release: | ||
| name: vllm | ||
| set: | ||
| routerSpec: | ||
| enableRouter: false | ||
| loraController: | ||
| enableLoraController: true | ||
| serviceAccountName: my-existing-lora-sa | ||
| asserts: | ||
| - hasDocuments: | ||
| count: 0 |
There was a problem hiding this comment.
Update this test to assert that the ClusterRole and ClusterRoleBinding are created and bound to the custom my-existing-lora-sa service account.
- it: should create ClusterRole and ClusterRoleBinding with custom serviceAccountName when specified
release:
name: vllm
set:
routerSpec:
enableRouter: false
loraController:
enableLoraController: true
serviceAccountName: my-existing-lora-sa
asserts:
- equal:
path: metadata.name
value: vllm-lora-controller
documentIndex: 0
template: role.yaml
- equal:
path: metadata.name
value: vllm-lora-controller
documentIndex: 0
template: rolebinding.yaml
- equal:
path: subjects[0].name
value: my-existing-lora-sa
documentIndex: 0
template: rolebinding.yamlSigned-off-by: ghkdwlgns612 <ghkdwlgns612@naver.com>
Summary
I wanted to use pre-existing service accounts directly for the router and lora-controller Deployments.
To support this, when serviceAccountName is explicitly set, the chart now skips creating ServiceAccount, Role/ClusterRole, and RoleBinding/ClusterRoleBinding resources.
Root Cause
The previous Helm templates assumed chart-managed identities and RBAC by default, so they always rendered service-account and RBAC resources when router/lora-controller were enabled. This did not support environments where service accounts and permissions are provisioned externally.
Changes