Propagate Id
Propagate Class
This example demonstrates how ID propagation through Resource References can be used to create a new instance of a resource for another resource. It involves provisioning a k8s-service-account resource for every workload resource provisioned.
How the example works
This example is made up of two Resource Definitions: one workload and two k8s-service-account Resource Definition. Both Resource Definitions use the humanitec/template  driver.
A resource of type workload is automatically provisioned for each Workload in an Application in Humanitec. The workload will have the ID of modules.<workload id> and a class of default. This means that if an Application contains two workloads called workload-one and workload-two, two workload resources will be provisioned, one with ID modules.workload-one and the other with ID modules.workload-two.
The def-workload.yaml Resource Definition has a reference to a k8s-service-account resource. The Resource Reference does not specify either the class or the ID of the resource. This means that the k8s-service-account resource is provisioned with the same ID and class as the Workload.
Run the example
Prerequisites
See the prerequisites section in the README at the root of this repository.
In addition, the environment variable HUMANITEC_APP should be set to example-propagate-class.
Cost
This example will result in a single Pod being deployed to a Kubernetes Cluster.
Deploy the example
- 
Create a new Application:
humctl create app "${HUMANITEC_APP}" - 
Register the Resource Definitions:
mkdir resource-definitions cp def-*.yaml ./resource-definitions humctl apply -f ./resource-definitions - 
Deploy the Score Workload:
humctl score deploy --org "${HUMANITEC_ORG}" --app "${HUMANITEC_APP}" --env "${HUMANITEC_ENV}" --token "${HUMANITEC_TOKEN} 
Clean up the example
- 
Delete the Application
humctl delete app "${HUMANITEC_APP}" - 
Delete the Resource Definitions
humctl delete -f ./resource-definitions rm -rf ./resource-definitions 
score.yaml
(view on GitHub )
:
apiVersion: score.dev/v1b1
metadata:
  name: example-workload
containers:
  busybox:
    image: busybox:latest
    command:
      - /bin/sh
    args:
      - "-c"
      # This will output all of the environment variables in the container to
      # STDOUT every 15 seconds. This can be seen in the container logs in the
      # Humanitec UI.
      - "while true; do set; sleep 15; done"
Resource Definitions
def-k8s-service-account.yaml
(view on GitHub )
:
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: example-k8s-service-account
entity:
  criteria:
    - app_id: example-propagate-id
  driver_inputs:
    values:
      res_id: ${context.res.id}
      templates:
        init: |
          name: {{ .driver.values.res_id | splitList "." | last }}-sa
        outputs: |
          name: {{ .init.name }}
        manifests: |
          service-account.yaml:
            location: namespace
            data: |
              apiVersion: v1
              kind: ServiceAccount
              metadata:
                name: {{ .init.name }}
  driver_type: humanitec/template
  name: example-k8s-service-account
  type: k8s-service-account
def-workload.yaml
(view on GitHub )
:
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: example-workload
entity:
  criteria:
    - app_id: example-propagate-id
  driver_inputs:
    values:
      templates:
        outputs: |
          update: 
          - op: add
            path: /spec/serviceAccountName
            {{/*
              The resource reference does not specify ID or class so the ID and
              class of the workload being provisioned will be used.
            *//}
            value: ${resources.k8s-service-account.outputs.name}
  driver_type: humanitec/template
  name: example-workload
  type: workload
def-k8s-service-account.tf
(view on GitHub )
:
resource "humanitec_resource_definition" "example-k8s-service-account" {
  driver_type = "humanitec/template"
  id          = "example-k8s-service-account"
  name        = "example-k8s-service-account"
  type        = "k8s-service-account"
  driver_inputs = {
    values_string = jsonencode({
      "res_id" = "$${context.res.id}"
      "templates" = {
        "init"      = "name: {{ .driver.values.res_id | splitList \".\" | last }}-sa\n"
        "outputs"   = "name: {{ .init.name }}\n"
        "manifests" = <<END_OF_TEXT
service-account.yaml:
  location: namespace
  data: |
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: {{ .init.name }}
END_OF_TEXT
      }
    })
  }
}
resource "humanitec_resource_definition_criteria" "example-k8s-service-account_criteria_0" {
  resource_definition_id = resource.humanitec_resource_definition.example-k8s-service-account.id
  app_id                 = "example-propagate-id"
}
def-workload.tf
(view on GitHub )
:
resource "humanitec_resource_definition" "example-workload" {
  driver_type = "humanitec/template"
  id          = "example-workload"
  name        = "example-workload"
  type        = "workload"
  driver_inputs = {
    values_string = jsonencode({
      "templates" = {
        "outputs" = <<END_OF_TEXT
update: 
- op: add
  path: /spec/serviceAccountName
  {{/*
    The resource reference does not specify ID or class so the ID and
    class of the workload being provisioned will be used.
  *//}
  value: $${resources.k8s-service-account.outputs.name}
END_OF_TEXT
      }
    })
  }
}
resource "humanitec_resource_definition_criteria" "example-workload_criteria_0" {
  resource_definition_id = resource.humanitec_resource_definition.example-workload.id
  app_id                 = "example-propagate-id"
}