Custom Resource Types
- Overview
- Define a Custom Resource Type
- Override an existing Resource Type
- Define inputs and outputs
- Register a Custom Resource Type
- Use a Custom Resource Type in Resource Definitions
- Introducing an override Custom Resource Type
- Use a Custom Resource Type in Score
- View a Custom Resource Type
- Update a Custom Resource Type
- Delete a Custom Resource Type
- Examples
On this page
- Overview
- Define a Custom Resource Type
- Override an existing Resource Type
- Define inputs and outputs
- Register a Custom Resource Type
- Use a Custom Resource Type in Resource Definitions
- Introducing an override Custom Resource Type
- Use a Custom Resource Type in Score
- View a Custom Resource Type
- Update a Custom Resource Type
- Delete a Custom Resource Type
- Examples
Overview
The Platform Orchestrator provides a catalog of built-in Resource Types as a basis for creating Resource Definitions.
You may extend that catalog for your Humanitec Organization and create a Custom Resource Type to:
- Provide a new Resource Type if the type you need is not available in the list of built-in Resource Types
- Override a built-in Resource Type such as
s3
to expand or modify its inputs or outputs
Managing Custom Resource Types requires the Administrator role in the Organization.
Define a Custom Resource Type
A Resource Type is made up of metadata as well as an inputs and outputs schema. A definition for a new type with no inputs and two outputs may look like this:
type: my-org/my-custom-type
use: direct
name: Demo Type
category: "Demo category"
inputs_schema:
additionalProperties: false
type: object
outputs_schema:
properties:
values:
properties:
host:
description: The IP address or hostname
title: Host
type: string
port:
description: The port on the host
maximum: 65535
minimum: 0
title: Port
type: integer
required:
- host
- port
type: object
type: object
Refer to the API documentation for details on each property. More examples are shown at the bottom of this page.
implicit
is not supported.To see existing Resource Type definitions, you can inspect the definitions of all built-in Resource Types, and Custom Types that may already have been added, using this CLI command:
humctl get resource-type -o yaml
When working with a Custom Resource Type, always use its fully qualified name including the prefixed Organization ID, e.g. my-org/my-custom-type
.
The only exception is Score where only the type name (my-custom-type
) is used.
Override an existing Resource Type
A Custom Resource Type may override one of the existing, built-in Resource Types, e.g. s3
. To do so, create a definition with a type
of my-org/<existing-type>
like so:
type: my-org/s3
...
The override needs to completely define the new type. There is no merging or inheritance of the override and the built-in type definition. An override may therefore alter the structure of a built-in type in any way. In particular, it may define its own inputs and outputs. To keep existing inputs or outputs of the built-in type, the override needs to define them anew.
To obtain the definition of any built-in type to use as a starting point for an override, e.g. s3
, use this command:
humctl get resource-type -o yaml \
| yq -r '.[] | select (.metadata.type == "s3")'
Define inputs and outputs
The inputs_schema
and outputs_schema
properties define the Resource Inputs (those supplied as resource params
in Score for direct Resource Types) and the Outputs of the Resource Type.
Both properties are based on JSON Schema , so you can use all of the JSON Schema vocabulary to construct your Resource Type, like required properties, allowable values etc. Some examples are shown further down in this section.
The Resource Inputs in inputs_schema
are always non-secret values defined like this:
type: my-org/my-custom-type
use: direct
...
# A plain string property
inputs_schema:
properties:
myProperty:
description: A demo string property
title: My property
type: string
The Resource Input declared this way can then be supplied a value via Score:
apiVersion: score.dev/v1b1
...
resources:
demo:
type: my-custom-type
params:
# Supplying a value for the Resource Input "myProperty"
myProperty: some-value
The Resource outputs in outputs_schema
distinguish between secret and non-secret outputs as secrets
and values
:
type: my-org/my-custom-type
use: direct
...
outputs_schema:
additionalProperties: false
type: object
properties:
# Secret outputs
secrets:
properties:
key:
description: A secret account key
title: Account Key
type: string
type: object
# Non-secret outputs
values:
properties:
account:
description: The account to use
title: Account
type: string
type: object
These Resource outputs can be queried in Score (for direct Resource Types):
apiVersion: score.dev/v1b1
...
containers:
demo:
variables:
KEY: ${resources.demo.key}
ACCOUNT: ${resources.demo.account}
resources:
demo:
type: my-custom-type
Some useful JSON Schema usage is shown in these examples. They apply to inputs_schema
and outputs_schema
properties alike.
Allow any additional input or output property
inputs_schema:
additionalProperties: true
type: object
outputs_schema:
additionalProperties: true
type: object
A plain string input property restricted to certain values
inputs_schema:
properties:
myEnumProperty:
description: A demo string property limited to certain values
title: My enum property
type: string
# Allow only the values defined here
enum:
- "allowed-value-1"
- "allowed-value-2"
myPatternProperty:
description: A demo string property limited in length and by RegEx
title: My pattern property
type: string
# Define length and pattern constraints
minLength: 3
maxLength: 44
pattern": "^[a-z]{3,44}$"
Required inputs or outputs
outputs_schema:
additionalProperties: false
type: object
properties:
# Secret outputs
secrets:
properties:
key:
description: A secret account key
title: Account Key
type: string
# Make "key" a required output
required:
- key
type: object
Nested/complex properties
inputs_schema:
additionalProperties: false
type: object
properties:
myParentProperty:
additionalProperties: false
description: A parent property
title: My parent property
type: object
properties:
type: object
mySubProperty:
description: A sub property
title: My sub property
type: string
Portal UI grouping
When configuring a Resource Definition via the the Humanitec Portal, a Custom Resource Type will be shown in the list of all types and grouped according to its Resource category
, e.g. category: datastore
.
Portal UI configuration
The Humanitec Portal will display a form with input fields for all the outputs defined in the outputs_schema
of the Resource Type being used, e.g. when using the Echo Driver to create a Resource Definition of that Resource Type. The Portal will use the properties of each output like this:
- The
title
anddescription
are used to label the field - A
required
output is displayed with a*
- A
secrets
output is displayed with a lock icon
You can optionally customize the UI layout using uiHints
and uiGroups
.
uiHints.order
defines the property order within the form, or within theuiGroup
it is assigned touiHints.group
assigns the property to auiGroup
uiHints.width
defines the relative width for the field within auiGroup
of typerow
. The default value is1
Define uiGroups
in the outputs_schema
using these properties:
uiGroups.<group>.order
defines the order of the group within the formuiGroups.<group>.type
defines the type of the group to be asection
(a collection ofrows
) or arow
uiGroups.<group>.title
defines the title of the a group oftype: section
uiGroups.<group>.section
assigns a group oftype: row
to asection
Example outputs schema using UI groups
This outputs schema uses UI groups to create two sections holding three output properties.
outputs_schema:
properties:
values:
properties:
name:
description: The name of the topic that the workload should use.
title: Topic Name
type: string
uiHints:
group: topic
order: 1
host:
description: The IP address or hostname the cluster is available on.
title: Host
type: string
uiHints:
group: hostport
order: 1
width: 2
port:
description: The port on the host that the cluster is available on.
maximum: 65535
minimum: 0
title: Port
type: integer
uiHints:
group: hostport
order: 2
required:
- name
- host
- port
type: object
type: object
uiGroups:
topic:
order: 1
title: Topic
type: section
cluster:
order: 2
title: Cluster
type: section
hostport:
order: 2
section: cluster
type: row
Register a Custom Resource Type
For the CLI or API commands in this and the following sections, set these environment variables to prepare the command execution:
# Set your Humanitec Organization ID
export HUMANITEC_ORG=my-org
# Set an API token (API only)
export HUMANITEC_TOKEN=token-value
Place the Custom Resource Type definition in YAML format in a file named custom-resource-type.yaml
.
Prepare the command payload in JSON format:
export PAYLOAD=$(yq custom-resource-type.yaml -o json)
humctl api post "/orgs/${HUMANITEC_ORG}/resources/types" \
-d "$PAYLOAD"
curl "https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/types" \
-X POST \
-H "Authorization: Bearer $HUMANITEC_TOKEN" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"
Use a Custom Resource Type in Resource Definitions
Once registered, you can use a Custom Resource Type in Resource Definitions like a regular built-in type.
Create Resource Definitions based on a Custom Resource Type
You base a Resource Definition on a Custom Resource Type by using its fully qualified name (e.g. my-org/my-custom-type
) as the type
:
|
|
Using Custom Resource Types in references, selectors, co-provisioning
Resource Definitions for a built-in type (e.g. s3
) and a corresponding override type (my-org/s3
) can exist in parallel and even have the same matching criteria. Authors of Resource Definitions need to be specific when requesting a type in Resource References, Resource Selectors, or co-provisioning.
A mix of Resources of a built-in type and its override type in a Resource Graph is possible.
Given a Custom Resource Type my-org/my-custom-type
and an override Custom Resource Type my-org/s3
, these Resource References and selectors are valid:
# Request a "my-org/my-custom-type" Resource of the current Resource class and ID
${resources['my-org/my-custom-type'].outputs.region}
# Request a "my-org/s3" (an override type) Resource of the current Resource class and ID
${resources['my-org/s3'].outputs.region}
# Request a "s3" (the standard built-in type) Resource of the current Resource class and ID
${resources['s3'].outputs.region}
# Request a "my-org/s3" Resource of the Resource class "sensitive"
${resources['my-org/s3.sensitive'].outputs.region}
# Select a "my-org/s3" Resource that is depended on by a workload of the current Resource class and ID
${resources['workload>my-org/s3'].outputs.region}
# Co-provision a "my-org/my-custom-type" Resource of the current Resource class and ID
provision:
my-org/my-custom-type:
is_dependent: true
Introducing an override Custom Resource Type
my-org/s3
, has some implications to be aware of if you have been previously using the corresponding built-in type (s3
).Score matching for overridden types
Whenever at least one Resource Definition exists using an override of a built-in type, resource requests from Score to that type (e.g. s3
) are always expanded to request the override (my-org/s3
).
apiVersion: score.dev/v1b1
...
resources:
# This resource request will be expanded to the override type "my-org/s3"
# if a Resource Definition of that override type exists
my-bucket:
type: s3
Be aware that in this setup:
- Only Resource Definitions based on the override type (
my-org/s3
) are considered for matching resource requests from Score for the corresponding built-in type (s3
) - Even if there is a Resource Definition for the built-in type (
s3
) having the proper matching criteria, it is not considered for matching
When introducing Resource Definitions for override types, make sure to provide Definitions for all previously used matching contexts to avoid failing Deployments.
New Active Resource
If a Deployment has previously been using a Resource Definition based on a built-in type, e.g. s3
, then with the introduction of a Resource Definition of the override type the Platform Orchestrator will create a new Active Resource of the override type my-org/s3
on the next Deployment. It will also keep the previous Active Resource of type s3
to support potential rollbacks.
Using the humctl resources active-resource-usage
CLI command to observe Active Resources will show this setup:
$ humctl resources active-resource-usage
ResType Class ResID Usage Last referencing deployment Last referencing
s3 default modules.demo.externals.my-bucket 1 deploy ago 183dd45d31191a1a 4m56.986245652s
my-org/s3 default modules.demo.externals.my-bucket current deploy 183dd49e29138a51 17.947954245s
Output of the ${context.res.type}
placeholder
The Placeholder ${context.res.type}
in a Resource Definition based on an override type will return the fully qualified custom type, e.g. my-org/s3
.
If your Resource Definition code has been using the output of this Placeholder to name or access any stateful data for an Active Resource, make sure to use the part following the /
only to continue using the same data in the follow-up Resource.
Use a Custom Resource Type in Score
Custom Resource Types are used like built-in types when requesting resources
in Score. Always use the simple name for the type
, i.e. without the Organization ID prefix, for both newly created types as well as overridden built-in types.
apiVersion: score.dev/v1b1
...
resources:
# Requesting a resource of a newly defined Custom Resource Type
demo:
type: my-custom-type
# Requesting a resource of a built-in Resource Type which may or may not be
# overriden by a Custom Resource Type
my-bucket:
type: s3
Whether or not a built-in Resource Type such as s3
is overridden in the Organization is transparent to Score users.
For the general handling of Resource Inputs and outputs of Custom Resource Types Score, see Define inputs and outputs.
Any newly added or changed Resource Inputs or outputs introduced by an override Custom Resource Type are available in Score. E.g. if the type my-org/s3
defines an additional output object-lock-enabled
, it can be queried by the requesting Workload like any other output:
apiVersion: score.dev/v1b1
...
containers:
hello:
image: .
variables:
LOCK: ${resources.my-bucket.object-lock-enabled}
resources:
my-bucket:
type: s3
Starting from humctl
version 0.39.4
, you can use these Score-related CLI commands with Custom Resource Types:
# Note: In the presence of a Resource Definition based on an override type,
# e.g. "my-org/s3" for "s3", this command will display a value of "s3"
# because that is the type to use in Score
humctl score available-resource-types
humctl score validate score.yaml
humctl score deploy -f score.yaml
View a Custom Resource Type
These commands view the Resource Type named my-custom-type
.
YAML format:
humctl get resource-type -o yaml \
| yq -r ".[] | select (.metadata.type == \"$HUMANITEC_ORG/my-custom-type\")"
JSON format:
humctl get resource-type -o json \
| jq -r ".[] | select(.metadata.type == \"$HUMANITEC_ORG/my-custom-type\")"
YAML format:
curl -s "https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/types" \
-X GET \
-H "Authorization: Bearer $HUMANITEC_TOKEN" \
| jq -r ".[] | select(.type == \"$HUMANITEC_ORG/my-custom-type\")" \
| yq -P
JSON format:
curl -s "https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/types" \
-X GET \
-H "Authorization: Bearer $HUMANITEC_TOKEN" \
| jq -r ".[] | select(.type == \"$HUMANITEC_ORG/my-custom-type\")"
Update a Custom Resource Type
You can update a Custom Resource Type at any time, including when Resource Definitions exist using that type, and when there are Active Resources of such Resource Definitions.
Custom Resource Types are not versioned. Updates are effective immediately, i.e. for all future Deployments referencing the type.
Note: you need to provide JSON format for the CLI and API calls shown below. We recommend to maintain sources in YAML for better readability and transform them on the fly as shown.
For a partial update, define the update JSON snippet like this:
# Example: change the Custom Resource Type `my-org/my-custom-type` to have a `use:` of `indirect`
export PAYLOAD='{"use": "indirect"}'
For a full update, read the entire Custom Resource Type definition from a file:
# Read the Custom Resource Type definition from a file and convert to JSON
export PAYLOAD=$(yq custom-resource-type.yaml -o json)
humctl api patch "/orgs/${HUMANITEC_ORG}/resources/types/${HUMANITEC_ORG}%2Fmy-custom-type" \
-d "$PAYLOAD"
curl -s "https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/types/${HUMANITEC_ORG}%2Fmy-custom-type" \
-X PATCH \
-H "Authorization: Bearer $HUMANITEC_TOKEN" \
-H "Content-Type: application/json" \
-d "$PAYLOAD"
Delete a Custom Resource Type
These commands delete the Custom Resource Type my-org/my-custom-type
. Deletion will be disallowed if there is a Resource Definition using that type.
humctl api delete "/orgs/${HUMANITEC_ORG}/resources/types/${HUMANITEC_ORG}%2Fmy-custom-type"
curl -s "https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/types/${HUMANITEC_ORG}%2Fmy-custom-type" \
-X DELETE \
-H "Authorization: Bearer $HUMANITEC_TOKEN" \
-H "Content-Type: application/json"
Examples
New Custom Resource Type example
This Custom Resource Type introduce the milvus
and milvus-instance
types for the Milvus database .
Custom Resource Type "milvus"
type: my-org/milvus
use: direct
category: datastore
inputs_schema:
additionalProperties: false
properties:
extensions:
additionalProperties:
additionalProperties: false
properties:
schema:
type: string
version:
type: string
type: object
type: object
type: object
name: Milvus
outputs_schema:
properties:
secrets:
properties:
password:
description: The password for the user or role.
title: Password
type: string
uiHints:
group: database
order: 3
username:
description: The user or role that the workload should use to connect to
the database.
title: User / Role
type: string
uiHints:
group: database
order: 2
required:
- username
- password
type: object
values:
properties:
host:
description: The IP address or hostname the instance is available on.
title: Host
type: string
uiHints:
group: hostport
order: 1
width: 2
name:
description: The name of the database that the workload should connect to.
title: Name
type: string
uiHints:
group: database
order: 1
port:
description: The port on the host that the instance is available on.
maximum: 65535
minimum: 0
title: Port
type: integer
uiHints:
group: hostport
order: 2
required:
- name
- host
- port
type: object
uiGroups:
database:
order: 1
title: Database
type: section
hostport:
order: 2
section: instance
type: row
instance:
order: 2
title: Instance
type: section
type: object
Custom Resource Type "milvus-instance"
category: datastore
type: my-org/milvus-instance
use: indirect
inputs_schema:
properties:
extensions:
additionalProperties:
additionalProperties: false
properties:
schema:
type: string
version:
type: string
type: object
type: object
type: object
name: Milvus Instance
outputs_schema:
properties:
secrets:
properties:
password:
description: The password for the user or role.
title: Password
type: string
uiHints:
group: database
order: 3
username:
description: The user or role that the workload should use to connect to
the database.
title: User / Role
type: string
uiHints:
group: database
order: 2
type: object
values:
properties:
host:
description: The IP address or hostname the instance is available on.
title: Host
type: string
uiHints:
group: hostport
order: 1
width: 2
name:
description: The name of the database that the workload should connect to.
title: Name
type: string
uiHints:
group: database
order: 1
port:
description: The port on the host that the instance is available on.
maximum: 65535
minimum: 0
title: Port
type: integer
uiHints:
group: hostport
order: 2
type: object
uiGroups:
database:
order: 1
title: Database
type: section
hostport:
order: 2
section: instance
type: row
instance:
order: 2
title: Instance
type: section
type: object
Override Custom Resource Type example
This Custom Resource Type overrides the built-in type s3
to provide an additional output object-lock-enabled
.
Override of the "s3" type
category: datastore
type: my-org/s3
use: direct
name: S3 Bucket Override
inputs_schema:
additionalProperties: false
type: object
outputs_schema:
properties:
values:
properties:
arn:
description: The Amazon Resource Name (ARN) of the S3 Bucket
title: ARN
type: string
uiHints:
group: bucket
order: 3
bucket:
description: The globally unique name for the bucket.
title: S3 Bucket Name
type: string
uiHints:
group: bucket
order: 1
region:
description: The AWS region the bucket is hosted in.
title: AWS Region
type: string
uiHints:
group: bucket
order: 2
# Additional output in this Custom Resource Type
object-lock-enabled:
description: Indicates whether this bucket has an Object Lock configuration enabled.
title: Object Lock enabled true/false
type: boolean
uiHints:
group: bucket
order: 4
required:
- region
- bucket
type: object
uiGroups:
bucket:
order: 1
title: S3 Bucket
type: section
type: object