Terraform Runner
What is the Terraform Runner Driver?
The Terraform Runner Driver is a virtual driver that wraps the Terraform Driver to provide an easy, standardized and re-usable way to run the Terraform Runner in a target cluster .
The Terraform Runner Driver supports only AKS, EKS, and GKE clusters as a target cluster for the execution of the Terraform Runner. It means that it can be used in combination with a cluster_type
of aks
, eks
, or gke
.
To make the Terraform Runner run on a generic cluster, please keep on using the
Terraform Driver
and specify a runner
object with a cluster_type
of k8s
.
Why use the Terraform Runner Driver?
Using the Terraform Runner Driver should ensure:
- Reusability: You may want to use a dedicated Terraform Runner cluster to provision infrastructure via Terraform. By separating out the runner configuration, it can be injected into any number Resource Definitions that should use that specific cluster to run the Terraform Runner.
- Separation of concerns: As the configuration details are all in the
config
Resource Definition as shown in the example below, the Terraform Resource Definition is completely oriented to provide the Terraform specification.
How it works
The Terraform Runner Driver wraps the
Terraform Driver
and injects the Terraform Runner configuration referencing a config
Resource Definition. It applies the
config pattern
:
- The Terraform Runner Driver injects the
runner_mode
custom-kubernetes
. - A
config
Resource Definition should provide the runner configuration. It should:- Match class
default
and resource idtf-runner
(and a specific environment type) - Provide the cluster configuration in an output named
runner
that should contain the properties documented in the runner object section of the Terraform Driver. Theaccount
to create and handle the Kubernetes resources needed by the Terraform Runner in the cluster needs to be specified. - Have a secret template output named
agent_url
that 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 Terraform Runner Driver would only care about the Terraform specific inputs (e.g. scripts, files, source…) and it automatically depends on the
config
resource.
Matching different cluster configuration
By attaching the proper
Matching Criteria
to the config
Resource Definition, a different Terraform Runner configuration can be matched per Environment Type, so that the Terraform Runner is executed in the proper cluster.
Using Terraform Backends
By default, this Driver injects the configuration of a Kubernetes Terraform Backend that:
- Creates Kubernetes secrets in the Runner namespace.
- Uses the Resource’s Globally Unique Id as
secret_suffix
via the
context.res.guresid
placeholder, to prevent any overlapping among resources.
The Kubernetes service account used by the Runner in the target namespace
must be created and configured to have the permissions needed by the Runner to complete its execution.
Kubernetes Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: humanitec-tf-runner
namespace: humanitec-terraform
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: humanitec-terraform
name: humanitec-tf-runner
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "get", "delete", "list", "update", "deletecollection"]
# Only needed if the chosen Terraform Backend is kubernetes
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["create", "get", "list", "update", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: humanitec-tf-runner
namespace: humanitec-terraform
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: humanitec-tf-runner
subjects:
- kind: ServiceAccount
name: humanitec-tf-runner
namespace: humanitec-terraform
If you want to specify a different backend:
- Set the boolean input value
use_default_backend
tofalse
- Configure a different backend in your Terraform code.
See our backends example for ways to handle backends.
Terraform Runner Driver reference
This Driver has the same inputs as the Terraform Driver , with the exception that:
- No inputs for configuring the Terraform Runner are allowed or should be specified here.
- A non-secret input value
use_default_backend
needs to be supplied and set tofalse
in case of a backend that is not the default one should be used to store the Resource state.
Examples
In addition to the Terraform Driver examples page, we provide here an example that consists of:
- A
config
Resource Definition. It matches ares_id
oftf_runner
and produces arunner
objects as its output. - A
Terraform Runner
Resource Definition that performs provisioning of an S3 bucket via the execution of Terraform code stored in a private Github repository. The Terraform code will be executed in the cluster specified by theconfig
Resource Definition. Note that no reference to theconfig
Resource 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
config
Resource Definition you want to create to define the cluster where the Terraform Runner should run:
cat << "EOF" > config-tf-runner.yaml
apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
id: config-tf-runner
entity:
name: Config For TF Runner
type: config
driver_type: humanitec/template
driver_inputs:
values:
templates:
outputs:
runner:
account: myOrg/myAccount
cluster:
loadbalancer: 10.10.10.10
name: my-cluster
project_id: my-gcp-project
zone: cluster-zone
cluster_type: gke
namespace: humanitec-terraform
service_account: humanitec-tf-runner
secrets: |
agent_url: {{ .driver.secrets.agent_url }}
secrets:
agent_url: ${resources.agent.outputs.url}
criteria:
- env_type: development
res_id: tf-runner
EOF
- Use the
humctl create
command to create the Resource Definition in the Organization defined by your configured context:
humctl create -f config-tf-runner.yaml
rm config-tf-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-tf-runner",
"name": "Config For TF Runner",
"type": "config",
"criteria": [
{
"env_type": "development",
"res_id": "tf-runner"
}
],
"driver_type": "humanitec/template",
"driver_inputs": {
"values": {
"templates": {
"outputs": "runner:\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 namespace: humanitec-terraform\n service_account: humanitec-tf-runner\n",
"secrets": {
"agent_url": "{{ .driver.secrets.agent_url }}"
}
}
},
"secrets": {
"agent_url": "${resources.agent.outputs.url}"
}
}
}'
Terraform Runner Resource Definition
- Create a file defining the
terraform-runner
Resource Definition you want to create to define the Terraform code to execute:
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/terraform-runner
driver_inputs:
values:
source:
path: s3/terraform
rev: refs/heads/main
url: https://my-domain.com/my-org/my-repo.git
username: my-git-handler
variables:
bucket_name: my-bucket
secret_refs:
source:
password:
store: my-store
ref: path/to/git/password
....
criteria:
- env_type: development
EOF
- Use the
humctl create
command 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/terraform-runner",
"driver_inputs": {
"values": {
"source": {
"path": "s3/terraform",
"rev": "refs/heads/main",
"url": "https://my-domain.com/my-org/my-repo.git",
"username": "my-git-handler"
"variables":
"bucket_name": "my-bucket",
}
},
"secret_refs": {
"source":{
"password": {
"store": "my-store",
"ref": "path/to/git/password"
},
...
}
}
}
}'