Resource Definitions

Driver

Capability

Flavor

Resource Type

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:

  1. 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.

  2. 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 &quot;my-workload-1&quot;<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 &quot;my-workload-2&quot;<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 &quot;my-workload-1&quot;<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 &quot;my-workload-2&quot;<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
      }
    })
  }
}


Top