Namespaces

Kubernetes Namespaces are used to organize Kubernetes objects within a Kubernetes cluster.

From a networking perspective, Namespaces provide a level of separation and boundary for in-cluster RBAC.

In Humanitec, an Application is a collection of Workloads which run in the same Namespace, meaning that every Environment that’s created has its own Namespace.

To perform any deployment, Humanitec requires a Namespace name. By default, Humanitec will generate a Namespace in the form of a UUID. This ensures that the Namespace will be unique within the cluster. Often, it would be better to have a more meaningful Namespace name. This can be done by matching a resource of type k8s-namespace to a particular Environment in an Application.

Static Namespaces

In this case, we want to specify the Namespace for a particular environment exactly. This is often the case for long-lived environments such as Production or Staging.

To create a static Namespace name:

  1. Create a Resource Definition of type k8s-namespace.
  2. Use the Template Driver to define the Namespace manifest.
  3. Add Matching Criteria that exactly matches the specific Environment in an Application that the Namespace is for.

The Namespace name must be unique to the environment within the cluster.

Trying to deploy 2 different environments into the same cluster with the same Namespace name will result in conflicts.

Dynamic Namespaces

It is often the case that it would be useful to name the Namespace based on the app and environment being deployed. This is especially useful for ephemeral environments. The steps are the same as for static, except that the context placeholder is used.

To create a Namespace that has the form {environment ID}-env-{application ID}-app, the following could be used:

${context.env.id}-env-${context.app.id}-app

The matching criteria can then be very broad - even for all Namespaces. Ensure the Namespace name will resolve to a unique name.

Notes

It’s not allowed to generate multiple Kubernetes Resources while provisioning a k8s-namespace Resource. This means that you can’t output any other Kubernetes manifests than the Namespace one, in a k8s-namespace Resource Definition.

Examples

Using the Template Driver

Prepare the Resource Definition of type k8s-namespace as shown below. It uses the Template Driver to generate and deploy a Kubernetes manifest for the namespace.

Adjust the example as needed:

  • Replace the dynamic naming in the name: line with a string for static naming, or with another pattern you want to use for namespace naming.
  • The code adds a sample label pod-security.kubernetes.io to each namespace created using this Resource Definition. Remove this label, or add your own labels, as required.
  • Add matching criteria as required for your context.
    • The API documentation has details and examples on the format of matching criteria.
    • E.g. to match this Resource Definition to the Application ID example-app in the Environment type production, configure this criteria section (shown for the CLI format):
  criteria:
  - app_id: example-app
  - env_type: production

Example code:

Create this Resource Definition:

apiVersion: entity.humanitec.io/v1b1
kind: Definition
metadata:
  id: custom-namespace
entity:
  name: custom-namespace
  type: k8s-namespace
  driver_type: humanitec/template
  driver_inputs:
    values:
      templates:
        init: |
          name: ${context.env.id}-${context.app.id}
        manifests: |-
          namespace.yaml:
            location: cluster
            data:
              apiVersion: v1
              kind: Namespace
              metadata:
                labels:
                  pod-security.kubernetes.io/enforce: restricted
                name: {{ .init.name }}
        outputs: |
          namespace: {{ .init.name }}
  criteria:
    - {}

Apply the Resource Definition using the CLI :

humctl create -f custom-namespace.yaml

Use this Resource Definition for the Humanitec Terraform Provider :

resource "humanitec_resource_definition" "namespace" {
  id          = "custom-namespace"
  name        = "custom-namespace"
  type        = "k8s-namespace"
  driver_type = "humanitec/template"

  driver_inputs = {
    values_string = jsonencode({
      templates = {
        init      = "name: $${context.env.id}-$${context.app.id}"
        manifests = <<EOL
namespace.yaml:
  location: cluster
  data:
    apiVersion: v1
    kind: Namespace
    metadata:
      labels:
        pod-security.kubernetes.io/enforce: restricted
      name: {{ .init.name }}
EOL
        outputs   = "namespace: {{ .init.name }}"
      }
    })
  }
}

resource "humanitec_resource_definition_criteria" "namespace" {
  resource_definition_id  = humanitec_resource_definition.namespace.id
}

Using the Echo Driver

Prepare the Resource Definition of type k8s-namespace as shown below. It uses the Echo Driver to return the name of a namespace which is managed by an external process, i.e. not via the Platform Orchestrator.

Create this Resource Definition:

apiVersion: core.api.humanitec.io/v1
kind: Definition
metadata:
  id: default-namespace
entity:
  name: default-namespace
  type: k8s-namespace
  driver_type: humanitec/echo
  driver_inputs:
    values:
      namespace: ${context.app.id}-${context.env.id}
  criteria:
    - {}

Apply the Resource Definition using the CLI :

humctl create -f default-namespace.yaml

Use this Resource Definition for the Humanitec Terraform Provider :

resource "humanitec_resource_definition" "k8s_namespace" {
  driver_type = "humanitec/echo"
  id          = "default-namespace"
  name        = "default-namespace"
  type        = "k8s-namespace"

  driver_inputs = {
    values_string = jsonencode({
      "namespace" = "$${context.app.id}-$${context.env.id}"
    })
  }
}

resource "humanitec_resource_definition_criteria" "k8s_namespace" {
  resource_definition_id = humanitec_resource_definition.k8s_namespace.id
}
Top