Resource Graph Patterns

Pattern name

Resource Type

Propagate Class

Propagate Class

This example demonstrates how Resource classes can be propagate via Resource References. It involves having a single Resource Definition that can be parameterized by referencing another Resource.

How the example works

This example is made up of 3 Resource Definitions: one s3 and two config Resource Definitions. To keep the examples as simple as possible, the humanitec/echo driver is used.

The s3 Resource Definition def-s3.yaml is configured to match to two classes one and two. It outputs its bucket output based on the Resource Reference ${resources.config#example.outputs.name}. This Resource Reference will cause a new resource to be provisioned and be replaced with the name output of that newly provisioned resource. As the Resource Definition only defines the type of the resource (config) and the ID of the resource (example), the class that the new resource will be provisioned with will be the same as the class of the s3 resource.

The one config Resource Definition (def-config-one.yaml) is configured to match the class one and the other def-config-two.yaml matches the class two.

The score.yaml file depends on a resource of type s3 bucket with a class of one. It outputs the bucket name in the environment variable BUCKET_NAME.

This means that an S3 bucket will be provisioned via the def-s3.yaml Resource Definition and the bucket name will be pulled from the Resource Definition def-config-one.yaml is configured to match the class one and so will be name-01.

If the class on the s3 resource is changed to two then the bucket name will be pulled from the Resource Definition def-config-two.yaml is configured to match the class two and so will be name-02.

Run the demo

Prerequisites

See the prerequisites section in the README at the root of this section.

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

  1. Create a new app:

    humctl create app "${HUMANITEC_APP}"
    
  2. Register the resource definitions:

    mkdir resource-definitions
    cp def-*.yaml ./resource-definitions
    humctl apply -f ./resource-definitions
    
  3. Create the Resource Classes

    While not technically required, it is recommended to explicitly create Resource Classes for types used by developers in Score.

    humctl api post "/orgs/${HUMANITEC_ORG}/resources/types/s3/classes" \
    -d '{
    "id": "one",
    "description": "Sample Resource Class one"
    }'
    
    humctl api post "/orgs/${HUMANITEC_ORG}/resources/types/s3/classes" \
    -d '{
    "id": "two",
    "description": "Sample Resource Class two"
    }'
    
  4. Deploy the Score workload:

    humctl score deploy --org "${HUMANITEC_ORG}" --app "${HUMANITEC_APP}" --env "${HUMANITEC_ENV}" --token "${HUMANITEC_TOKEN}
    

Play with the demo

  1. In the Humanitec UI, visit the running deployment and look in the container logs for the line starting with BUCKET_NAME. It should have a value of name-01

  2. Change the class of the s3 resource in the score.yaml file from one to two.

  3. Redeploy the Score file:

    humctl score deploy --org "${HUMANITEC_ORG}" --app "${HUMANITEC_APP}" --env "${HUMANITEC_ENV}"--token "${HUMANITEC_TOKEN}
    
  4. In the Humanitec UI, visit the running deployment and look in the container logs for the line starting with BUCKET_NAME. It should now have a value of name-02

Clean up the example

  1. Delete the Application:

    humctl delete app "${HUMANITEC_APP}"
    
  2. 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

    variables:
      BUCKET_NAME: ${resources.my-s3.bucket}

    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"

resources:
  my-s3:
    type: s3
    # Change the class to "two" 
    class: one

Resource Definitions


def-config-one.yaml ( view on GitHub ) :

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: example-config-one
entity:
  criteria:
    - class: one
      res_id: example
      app_id: example-propagate-class
  driver_inputs:
    values:
      name: name-01
  driver_type: humanitec/echo
  name: example-config-one
  type: config


def-config-two.yaml ( view on GitHub ) :

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: example-config-two
entity:
  criteria:
    - class: two
      res_id: example
      app_id: example-propagate-class
  driver_inputs:
    values:
      name: name-02
  driver_type: humanitec/echo
  name: example-config-two
  type: config


def-s3.yaml ( view on GitHub ) :

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: example-s3
entity:
  criteria:
    - class: one
      app_id: example-propagate-class
    - class: two
      app_id: example-propagate-class
  driver_inputs:
    values:
      bucket: ${resources.config#example.outputs.name}
  driver_type: humanitec/echo
  name: example-s3
  type: s3


def-config-one.tf ( view on GitHub ) :

resource "humanitec_resource_definition" "example-config-one" {
  driver_type = "humanitec/echo"
  id          = "example-config-one"
  name        = "example-config-one"
  type        = "config"
  driver_inputs = {
    values_string = jsonencode({
      "name" = "name-01"
    })
  }
}

resource "humanitec_resource_definition_criteria" "example-config-one_criteria_0" {
  resource_definition_id = resource.humanitec_resource_definition.example-config-one.id
  class                  = "one"
  res_id                 = "example"
  app_id                 = "example-propagate-class"
}


def-config-two.tf ( view on GitHub ) :

resource "humanitec_resource_definition" "example-config-two" {
  driver_type = "humanitec/echo"
  id          = "example-config-two"
  name        = "example-config-two"
  type        = "config"
  driver_inputs = {
    values_string = jsonencode({
      "name" = "name-02"
    })
  }
}

resource "humanitec_resource_definition_criteria" "example-config-two_criteria_0" {
  resource_definition_id = resource.humanitec_resource_definition.example-config-two.id
  class                  = "two"
  res_id                 = "example"
  app_id                 = "example-propagate-class"
}


def-s3.tf ( view on GitHub ) :

resource "humanitec_resource_definition" "example-s3" {
  driver_type = "humanitec/echo"
  id          = "example-s3"
  name        = "example-s3"
  type        = "s3"
  driver_inputs = {
    values_string = jsonencode({
      "bucket" = "$${resources.config#example.outputs.name}"
    })
  }
}

resource "humanitec_resource_definition_criteria" "example-s3_criteria_0" {
  resource_definition_id = resource.humanitec_resource_definition.example-s3.id
  class                  = "one"
  app_id                 = "example-propagate-class"
}

resource "humanitec_resource_definition_criteria" "example-s3_criteria_1" {
  resource_definition_id = resource.humanitec_resource_definition.example-s3.id
  class                  = "two"
  app_id                 = "example-propagate-class"
}

Top