Delegator Resource
Delegator Resource
This example demonstrates how delegator Resource Definitions can be used to expose a shared base resource with different access policies.
How the example works
This example is made up of:
- Two delegator
s3
Resource Definitions - One base
s3
Resource Definition - Two
aws-policy
Resource Definitions
and the resulting graph will look like:
flowchart LR
WL_A[Workload A] -->|score resource dependency| DELEGATOR_RES_ADMIN(type: s3, id: shared.main-s3, class: admin)
WL_B[Workload B] -->|score resource dependency| DELEGATOR_RES_READ_ONLY(type: s3, id: shared.main-s3, class: read-only)
DELEGATOR_RES_ADMIN -->|co-provision| POL_ADMIN(type: aws-policy, id: shared.main-s3, class: s3-admin)
DELEGATOR_RES_ADMIN -->|Resource Reference| BASE_RES(type: s3, id: shared.main-s3, class: concrete)
DELEGATOR_RES_READ_ONLY -->|co-provision| POL_READ_ONLY(type: aws-policy, id: shared.main-s3, class: s3-read-only)
DELEGATOR_RES_READ_ONLY -->|Resource Reference| BASE_RES
To keep the examples as simple as possible, the
humanitec/echo
driver is used throughout. Check out the
Resource Packs
if you are interested in examples with Resource Definitions that also include provisioning.
The s3
Resource Definition def-s3-concrete.yaml
defines the underlying “base” resource and is matched as class: concrete
.
In a real-world setup, this Resource Definition is the only one that would actually provision the s3 bucket using a Driver other than Echo, e.g. the
Terraform Driver
. The delegator resources will not actually provision anything. Their purpose is the co-provisioning of the appropriate aws-policy
resource based on their class
.
The aws-policy
Resource Definitions def-aws-policy-s3-admin.yaml
and def-aws-policy-s3-read-only.yaml
contain the different policies we want to make available. Those are matched as admin
and read-only
.
The s3
Resource Definitions def-s3-admin.yaml
and dev-s3-read-only.yaml
are delegator resources that have two functions:
- Co-provision the respective
aws-policy
Resource Definition. - Forward the outputs of the “base” resource using a Resource Reference .
When the workload defined in score-a.yaml
now requests an s3
resource with class: admin
, the Humanitec Platform Orchestrator creates the “delegator” s3
resource class: admin
, the “base” s3
resource class: concrete
, and co-provisions the aws-policy
resource class: s3-admin
.
Similar to the first workload, score-b.yaml
requests an s3
resource, but this time with class: read-only
and here the Humanitec Platform Orchestrator creates the “delegator” s3
resource class: read-only
, the “base” s3
resource class: concrete
, and co-provisions the aws-policy
resource class: s3-read-only
.
As both workloads used the same s3
resource id main-s3
via the id
property on the resource
objects in their Score files, they will use the same resource and thus the same underlying s3 bucket, but each workload uses a different access policy. The
Score schema reference
has details on this property.
Run the demo
Prerequisites
See the prerequisites section
in the README at the root of this section.
In addition, set these environment variables:
export HUMANITEC_APP=example-delegator
export HUMANITEC_ENV=development
export HUMANITEC_ORG=<your-org-id>
Cost
This example will result in a two Pods being deployed to a Kubernetes cluster.
Deploy the example
-
Login to the Platform Orchestrator:
humctl login
-
Create a new app:
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 A:
humctl score deploy --org "${HUMANITEC_ORG}" --app "${HUMANITEC_APP}" --env "${HUMANITEC_ENV}" --file score-a.yaml
-
Deploy the Score workload B:
humctl score deploy --org "${HUMANITEC_ORG}" --app "${HUMANITEC_APP}" --env "${HUMANITEC_ENV}" --file score-b.yaml
-
Create the Resource Graph:
humctl resources graph --org "${HUMANITEC_ORG}" --app "${HUMANITEC_APP}" --env "${HUMANITEC_ENV}" > graph.dot
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-a.yaml
(
view on GitHub
)
:
apiVersion: score.dev/v1b1
metadata:
name: example-a
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"
variables:
BUCKET_NAME: ${resources.s3.bucket}
resources:
s3:
type: s3
class: admin
id: main-s3
score-b.yaml
(
view on GitHub
)
:
apiVersion: score.dev/v1b1
metadata:
name: example-b
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"
variables:
BUCKET_NAME: ${resources.s3.bucket}
resources:
s3:
type: s3
class: read-only
id: main-s3
Resource Definitions
def-aws-policy-s3-admin.yaml
(
view on GitHub
)
:
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: aws-policy-s3-admin
entity:
criteria:
- app_id: example-delegator
class: s3-admin
driver_inputs:
values:
arn: arn:aws:iam::aws:policy/AmazonS3FullAccess
# In a real-world scenario, a different Driver would be used for this resource, e.g. Terraform
driver_type: humanitec/echo
name: aws-policy-s3-admin
type: aws-policy
def-aws-policy-s3-read-only.yaml
(
view on GitHub
)
:
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: aws-policy-s3-read-only
entity:
criteria:
- app_id: example-delegator
class: s3-read-only
driver_inputs:
values:
arn: arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# In a real-world scenario, a different Driver would be used for this resource, e.g. Terraform
driver_type: humanitec/echo
name: aws-policy-s3-read-only
type: aws-policy
def-s3-admin.yaml
(
view on GitHub
)
:
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: s3-admin
entity:
criteria:
- app_id: example-delegator
class: admin
driver_inputs:
values:
# This Resource reference to 's3.concrete' creates the dependency to the base resource
bucket: ${resources['s3.concrete'].outputs.bucket}
provision:
# Co-provision a Resource of type "aws-policy" and class "s3-admin"
aws-policy.s3-admin:
is_dependent: false
match_dependents: true
driver_type: humanitec/echo
name: s3-admin
type: s3
def-s3-concrete.yaml
(
view on GitHub
)
:
# This Resource Definition represents the concrete base resource of the Delegator pattern
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: s3-concrete
entity:
criteria:
- app_id: example-delegator
class: concrete
driver_inputs:
values:
bucket: example-bucket
# In a real-world scenario, a different Driver would be used for the base resource, e.g. Terraform
driver_type: humanitec/echo
name: s3-concrete
type: s3
def-s3-read-only.yaml
(
view on GitHub
)
:
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: s3-read-only
entity:
criteria:
- app_id: example-delegator
class: read-only
driver_inputs:
values:
# This Resource reference to 's3.concrete' creates the dependency to the base resource
bucket: ${resources['s3.concrete'].outputs.bucket}
provision:
# Co-provision a Resource of type "aws-policy" and class "s3-read-only"
aws-policy.s3-read-only:
is_dependent: false
match_dependents: true
driver_type: humanitec/echo
name: s3-read-only
type: s3
def-aws-policy-s3-admin.tf
(
view on GitHub
)
:
resource "humanitec_resource_definition" "aws-policy-s3-admin" {
driver_type = "humanitec/echo"
id = "aws-policy-s3-admin"
name = "aws-policy-s3-admin"
type = "aws-policy"
driver_inputs = {
values_string = jsonencode({
"arn" = "arn:aws:iam::aws:policy/AmazonS3FullAccess"
})
}
}
resource "humanitec_resource_definition_criteria" "aws-policy-s3-admin_criteria_0" {
resource_definition_id = resource.humanitec_resource_definition.aws-policy-s3-admin.id
app_id = "example-delegator"
class = "s3-admin"
}
def-aws-policy-s3-read-only.tf
(
view on GitHub
)
:
resource "humanitec_resource_definition" "aws-policy-s3-read-only" {
driver_type = "humanitec/echo"
id = "aws-policy-s3-read-only"
name = "aws-policy-s3-read-only"
type = "aws-policy"
driver_inputs = {
values_string = jsonencode({
"arn" = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
})
}
}
resource "humanitec_resource_definition_criteria" "aws-policy-s3-read-only_criteria_0" {
resource_definition_id = resource.humanitec_resource_definition.aws-policy-s3-read-only.id
app_id = "example-delegator"
class = "s3-read-only"
}
def-s3-admin.tf
(
view on GitHub
)
:
resource "humanitec_resource_definition" "s3-admin" {
driver_type = "humanitec/echo"
id = "s3-admin"
name = "s3-admin"
type = "s3"
driver_inputs = {
values_string = jsonencode({
"bucket" = "$${resources['s3.concrete'].outputs.bucket}"
})
}
provision = {
"aws-policy.s3-admin" = {
is_dependent = false
match_dependents = true
}
}
}
resource "humanitec_resource_definition_criteria" "s3-admin_criteria_0" {
resource_definition_id = resource.humanitec_resource_definition.s3-admin.id
app_id = "example-delegator"
class = "admin"
}
def-s3-concrete.tf
(
view on GitHub
)
:
resource "humanitec_resource_definition" "s3-concrete" {
driver_type = "humanitec/echo"
id = "s3-concrete"
name = "s3-concrete"
type = "s3"
driver_inputs = {
values_string = jsonencode({
"bucket" = "example-bucket"
})
}
}
resource "humanitec_resource_definition_criteria" "s3-concrete_criteria_0" {
resource_definition_id = resource.humanitec_resource_definition.s3-concrete.id
app_id = "example-delegator"
class = "concrete"
}
def-s3-read-only.tf
(
view on GitHub
)
:
resource "humanitec_resource_definition" "s3-read-only" {
driver_type = "humanitec/echo"
id = "s3-read-only"
name = "s3-read-only"
type = "s3"
driver_inputs = {
values_string = jsonencode({
"bucket" = "$${resources['s3.concrete'].outputs.bucket}"
})
}
provision = {
"aws-policy.s3-read-only" = {
is_dependent = false
match_dependents = true
}
}
}
resource "humanitec_resource_definition_criteria" "s3-read-only_criteria_0" {
resource_definition_id = resource.humanitec_resource_definition.s3-read-only.id
app_id = "example-delegator"
class = "read-only"
}