Container Runner
What is the Container Runner Driver?
The Container Runner Driver provides an easy, standardized and re-usable way to run a container image of your choice in your cluster. A common use case is executing your favorite IaC framework by providing an image containing the required tooling.
This Driver is a virtual driver that wraps the Container Driver. Any Resources provisioned with it will therefore display the Container Driver as the Driver type being used.
This Driver supports only AKS, EKS, and GKE clusters as a target cluster for the execution of the Kubernetes Job created by the Container Driver.
This Driver is supported in Direct mode starting from Humanitec Operator version 0.3.11 for Helm Chart and 0.16.10 for App.
The minimum Kubernetes version is 1.29.
Why use the Container Runner Driver?
Using the Container Runner Driver should ensure:
- Reusability: You may want to use a dedicated Kubernetes cluster to execute your container, e.g. to run your favorite IaC framework. By separating out the runner configuration, it can be injected into any number Resource Definitions that should use that specific cluster to provision Resources via the Container Driver.
 - Separation of concerns: As the configuration details are all in the 
configResource Definition as shown in the example below, the Container Runner Resource Definition is completely oriented to provide the container specification and the Resource configuration. 
How it works
The Container Runner Driver wraps the Container Driver and injects the cluster configuration referencing a config Resource Definition. It applies the config pattern:
- A 
configResource Definition provides the runner configuration. It needs to:- Match class 
defaultand resource idcontainer-runner(and a specific environment type) - Provide the cluster configuration in an output named 
clusterthat should contain the properties documented in the cluster object section of the Container Driver. - Have a non-sensitive output named 
skip_permission_checks: if this is set tofalse, the Container Driver creates a sidecar container to run some pre-checks before executing the application container, otherwise the pre-checks are skipped. - Have a secret template output named 
agent_urlthat should be a reference to an Agent Resource, if the cluster is accessible only via Humanitec Agent, or an empty string. 
 - Match class 
 - Any Resource Definition built on the Container Runner Driver would only care about the Container specific inputs (e.g. job, scripts, files, source…) and it automatically depends on the 
configresource. 
Matching different cluster configuration
By attaching the proper Matching Criteria to the config Resource Definition, a different Container Runner configuration can be matched e.g. per Environment Type, so that the Kubernetes Job Container is executed in the proper cluster.
Kubernetes cluster setup
Using the Container Runner Driver requires some additional setup on the target Kubernetes cluster. Refer to the instructions for the cluster type you are using:
Container Runner Driver reference
This Driver has the same inputs as the Container Driver, with the exception that:
- The 
clusterobject for configuring the cluster where the Container Runner will run is disallowed. This data is provided by theconfigresource instead 
Examples
In addition to the Container Driver examples page, we provide here an example that consists of:
- A 
configResource Definition. It matches ares_idofcontainer-runnerand produces aclusterobject as its output. - An 
s3Resource Definition using thecontainer-runnerDriver that performs provisioning of an S3 bucket via the execution of OpenTofu code stored in a private GitHub repository. The OpenTofu code will be executed in the cluster specified by theconfigResource Definition. Note that no reference to theconfigResource is required. 
Set the following environment variables for the CLI and API commands:
| Variable | Example | Description | 
|---|---|---|
HUMANITEC_TOKEN | 
          my-token | 
          The authentication token for accessing the Humanitec API | 
HUMANITEC_ORG | 
          my-org-id | 
          The unique identifier for the Humanitec Organization | 
Use the command below for the interface of your choice.
Config Resource Definition
- Create a file defining the 
configResource Definition you want to create to define the cluster where the Container Runner should run: 
cat << "EOF" > config-container-runner.yaml
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: config-container-runner
entity:
  name: Config For Container Driver Runner
  type: config
  driver_type: humanitec/template
  driver_inputs:
    values:
      templates:
        outputs:
          cluster:
            account: myOrg/myAccount
            cluster:
              cluster_type: gke
              loadbalancer: 10.10.10.10
              name: my-cluster
              project_id: my-gcp-project
              zone: cluster-zone
              # Set this property for a private GKE cluster
              # internal_ip: true
          skip_permission_checks: false
        secrets: |
          agent_url: {{ .driver.secrets.agent_url }}
    secrets:
      agent_url: ${resources.agent.outputs.url}
  criteria:
  - env_type: development
    res_id: container-runner
EOF
- Use the 
humctl createcommand to create the Resource Definition in the Organization defined by your configured context: 
humctl create -f config-container-runner.yaml
rm config-container-runner.yaml
curl https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/defs \
  -X POST \
  -H "Authorization: Bearer ${HUMANITEC_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '
{
  "id": "config-container-runner",
  "name": "Config For Container Driver Runner",
  "type": "config",
  "criteria": [
    {
      "env_type": "development",
      "res_id": "container-runner"
    }
  ],
  "driver_type": "humanitec/template",
  "driver_inputs": {
    "values": {
      "templates": {
        "outputs": "skip_permission_checks: false\ncluster:\n  account: myOrg/myAccount\n  cluster:\n    loadbalancer: 10.10.10.10\n    name: my-cluster\n    project_id: my-gcp-project\n    zone: cluster-zone\n    cluster_type: gke\n",
        "secrets": {
          "agent_url": "{{ .driver.secrets.agent_url }}"
        }
      }
    },
    "secrets": {
      "agent_url": "${resources.agent.outputs.url}"
    }
  }
}'
Container Runner Resource Definition
- Create a file defining the 
container-runnerResource Definition you want to create to define the OpenTofu code to execute in the Kubernetes Job created by the Container Driver: 
cat << "EOF" > s3-tf.yaml
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: my-s3-bucket
entity:
  name: S3 Bucket
  type: s3
  driver_type: humanitec/container-runner
  driver_inputs:
    values:
      job:
        image: ghcr.io/my-org/my-image:1.1.0
        command: ["/opt/container"]
        shared_directory: /home/runneruser/workspace
        service_account: humanitec-runner
        namespace: humanitec-runner
        pod_template: |
          spec:
            imagePullSecrets:
              - name: ghcr-private-registry
      source:
        ref: refs/heads/main
        url: https://my-domain.com/my-org/my-repo.git
        username: my-git-handler
      files:
        /home/runneruser/workspace/s3/terraform.tfvars.json:  | 
          {"bucket": "${context.app.id}-${context.env.id}"}
    secret_refs:
      source:
        password:
          store: my-store
          ref: path/to/git/password
      ....
  criteria:
  - env_type: development
EOF
- Use the 
humctl createcommand to create the Resource Definition in the Organization defined by your configured context: 
humctl create -f s3-tf.yaml
rm s3-tf.yaml
curl https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/defs \
  -X POST \
  -H "Authorization: Bearer ${HUMANITEC_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '
{
  "id": "my-s3-bucket",
  "name": "S3 Bucket",
  "type": "s3",
  "criteria": [
    {
      "env_type": "development"
    }
  ],
  "driver_type": "humanitec/container-runner",
  "driver_inputs": {
    "values": {
      "source": {
        "ref": "refs/heads/main",
        "url": "https://my-domain.com/my-org/my-repo.git",
        "username": "my-git-handler"
      },
      "files": {
        "/home/runneruser/workspace/s3/terraform.tfvars.json": "{\"bucket\": \"${context.app.id}-${context.env.id}\"}\n"
      },
      "job": {
        "command": [
          "/opt/container"
        ],
        "image": "ghcr.io/my-org/my-image:1.1.0",
        "namespace": "humanitec-runner",
        "pod_template": "spec:\n  imagePullSecrets:\n    - name: ghcr-private-registry\n",
        "service_account": "humanitec-runner",
        "shared_directory": "/home/runneruser/workspace"
      }
    },
    "secret_refs": {
      "source":{
        "password": {
          "store": "my-store",
          "ref": "path/to/git/password"
        },
        ...
      }
    }
  }
}'