Serviceaccount
This section contains example Resource Definitions using the Template Driver for provisioning Kubernetes ServiceAccounts for your Workloads.
The solution consists of a combination of two Resource Definitions of type workload
and k8s-service-account
.
The workload
Resource Type is an implicit Type which is automatically referenced for any Deployment.
This workload
Resource Definition adds the serviceAccountName
item to the Pod spec and references a k8s-service-account
type Resource , causing it to be provisioned. The k8s-service-account
Resource Definition generates the Kubernetes manifest for the actual ServiceAccount.
The examples demonstrates two alternative approaches:
-
Providing a separate Kubernetes ServiceAccount for each Workload
This approach lets you fine tune the permissions obtained via the ServiceAccount for each Workload, but create more objects in the Resource Graph and on the cluster.
-
Providing a single Kubernetes ServiceAccount for all Workloads in the same Application Environment
This approach results in unified permissions for each Workload and less objects in the Resource Graph and on the cluster
For option 1, a Resource Graph for Workloads using those Resource Definitions will look like this:
flowchart LR
workloadVirtual1[Workload "my-workload-1"<br/>defined via Score] -.-> workload1(id: modules.my-workload-1<br/>type: workload<br/>class: default)
workload1 --> serviceAccount1(id: modules.my-workload-1<br/>type: k8s-service-account<br/>class: default)
workloadVirtual2[Workload "my-workload-2"<br/>defined via Score] -.-> workload2(id: modules.my-workload-2<br/>type: workload<br/>class: default)
workload2 --> serviceAccount2(id: modules.my-workload-2<br/>type: k8s-service-account<br/>class: default)
classDef dotted stroke-dasharray: 5 5;
class workloadVirtual1,workloadVirtual2 dotted
For option 2, a Resource Graph for Workloads using those Resource Definitions will look like this:
flowchart LR
workloadVirtual1[Workload "my-workload-1"<br/>defined via Score] -.-> workload1(id: modules.my-workload-1<br/>type: workload<br/>class: default)
workload1 --> serviceAccount(id: ksa<br/>type: k8s-service-account<br/>class: default)
workloadVirtual2[Workload "my-workload-2"<br/>defined via Score] -.-> workload2(id: modules.my-workload-2<br/>type: workload<br/>class: default)
workload2 --> serviceAccount
classDef dotted stroke-dasharray: 5 5;
class workloadVirtual1,workloadVirtual2 dotted
Check the code in the Resource Definitions to activate the option you wish to use.
In both cases, the resource id
is used in the k8s-service-account
Resource Definition to derive the name of the Kubernetes ServiceAccount.
Resource Definitions
serviceaccount-k8ssa-def.yaml
(view on GitHub )
:
# This Resource Defintion provisions a Kubernetes ServiceAccount
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: serviceaccount-k8s-service-account
entity:
driver_type: humanitec/template
name: serviceaccount-k8s-service-account
type: k8s-service-account
driver_inputs:
values:
res_id: ${context.res.id}
templates:
init: |
res_id: {{ .driver.values.res_id }}
{{- $res_name := .driver.values.res_id | splitList "." | last }}
name: {{ $res_name | toRawJson }}
outputs: |
name: {{ .init.name }}
manifests: |
service-account.yaml:
location: namespace
data:
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .init.name }}
annotations:
hum-res: {{ .init.res_id }}
serviceaccount-workload-def.yaml
(view on GitHub )
:
# This Resource Definition adds a Kubernetes ServiceAccount to a Workload
# Note the inline comments on adjusting the setup
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: serviceaccount-workload
entity:
driver_type: humanitec/template
name: serviceaccount-workload
type: workload
driver_inputs:
values:
templates:
outputs: |
update:
- op: add
path: /spec/serviceAccountName
# Option 1: separate ServiceAccount per workload. Using the current workload's ID by not specifying an ID
value: ${resources.k8s-service-account.outputs.name}
# Option 2: single ServiceAccount for all workloads. Specifying a fixed ID, e.g. "ksa"
# value: ${resources.k8s-service-account#ksa.outputs.name}
serviceaccount-k8ssa-def.tf
(view on GitHub )
:
resource "humanitec_resource_definition" "serviceaccount-k8s-service-account" {
driver_type = "humanitec/template"
id = "serviceaccount-k8s-service-account"
name = "serviceaccount-k8s-service-account"
type = "k8s-service-account"
driver_inputs = {
values_string = jsonencode({
"res_id" = "$${context.res.id}"
"templates" = {
"init" = <<END_OF_TEXT
res_id: {{ .driver.values.res_id }}
{{- $res_name := .driver.values.res_id | splitList "." | last }}
name: {{ $res_name | toRawJson }}
END_OF_TEXT
"outputs" = "name: {{ .init.name }}\n"
"manifests" = <<END_OF_TEXT
service-account.yaml:
location: namespace
data:
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .init.name }}
annotations:
hum-res: {{ .init.res_id }}
END_OF_TEXT
}
})
}
}
serviceaccount-workload-def.tf
(view on GitHub )
:
resource "humanitec_resource_definition" "serviceaccount-workload" {
driver_type = "humanitec/template"
id = "serviceaccount-workload"
name = "serviceaccount-workload"
type = "workload"
driver_inputs = {
values_string = jsonencode({
"templates" = {
"outputs" = <<END_OF_TEXT
update:
- op: add
path: /spec/serviceAccountName
# Option 1: separate ServiceAccount per workload. Using the current workload's ID by not specifying an ID
value: $${resources.k8s-service-account.outputs.name}
# Option 2: single ServiceAccount for all workloads. Specifying a fixed ID, e.g. "ksa"
# value: $${resources.k8s-service-account#ksa.outputs.name}
END_OF_TEXT
}
})
}
}