<@ULVA73B9P> I have a prefect 3 flow which is usin...
# ask-marvin
h
@Marvin I have a prefect 3 flow which is using a work pool that I have already customized the BaseJobTemplate to accept
env
as an Object but when I add that in to my prefect.yaml as part of the
job_variables
in this way
Copy code
job_variables:
        image: "{{ build-image.image }}"
        namespace: dev
        env:
          - name: PREFECT__LOGGING__LEVEL
            valueFrom:
              secretKeyRef:
                name: lab-prefect-3-external-secret
                key: PREFECT__LOGGING__LEVEL
I am getting an error
Copy code
'detail': "Error creating deployment: Validation failed for field 'env'. Failure reason: [{'name': 'PREFECT__LOGGING__LEVEL', 'valueFrom': {'secretKeyRef': {'name': 'lab-prefect-3-external-secret', 'key': 'PREFECT__LOGGING__LEVEL'}}}] is not valid under any of the given schemas"
any idea what I am doing wrong here
m
It looks like the issue is related to the way you're defining the
env
variable within your
prefect.yaml
file. According to the documentation, the configuration within a
prefect.yaml
file needs to adhere to specific templating options when defining environment-related variables. Here are some key points and resources that might help you resolve the issue: 1. Job Configuration and Variables: The job configuration in Prefect uses a JSON schema that defines which fields can be customized. It's important to ensure that the
env
variable is supported and formatted correctly in your BaseJobTemplate. Check to see if your modification aligns with these schemas. 2. Templating and Secret Management: In Prefect 3.x, templating options such as blocks for secrets are recommended for dynamic and secure configurations. The
secretKeyRef
you're using needs to be supported by the configuration options defined in the job template. You might need to ensure that the secret handling aligns with Prefect's secret management practices. For additional guidance, you might find these documents useful: - Infrastructure Concepts in Work Pools: This document discusses how base job templates work and how to customize them for work pools. - Prefect YAML Documentation: This guide covers the templating and syntax options you can use in your
prefect.yaml
files. If your setup appears to follow the recommended practices and you're still facing issues, it may be worthwhile to revisit your job template's schema validation. Or, as a last resort, file a bug report with Prefect if the schema seems correct but isn't working as expected. Ah, YAML... always ready to remind us how much we adore precise indentation and schema validation. Happy debugging!
h
@Nate any idea about how to solve this problem ? I am happy to share my Base Job Template JSON if that helps
I have created a kubernetes secrets that is getting deployed in the same namespace where the flow is being deployed so that the secretKeyRef tag is referencing it and I named it
lab-prefect-3-external-secret
shouldn't that be enough to be able to reference it as and environment variable ?
@Marvin this is my Base Job Template configuration would this accommodate the
env
reference that I have in my prefect.yaml ?
Copy code
baseJobTemplate.json: |
    {
      "variables": {
        "type": "object",
        "properties": {
          "env": {
            "type": "object",
            "title": "Environment Variables",
            "description": "Environment variables to set when starting a flow run.",
            "additionalProperties": {
              "type": "string"
            }
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Name given to infrastructure created by a worker."
          },
          "image": {
            "type": "string",
            "title": "Image",
            "example": "<<http://docker.io/prefecthq/prefect:2-latest%7Cdocker.io/prefecthq/prefect:2-latest>>",
            "description": "The image reference of a container image to use for created jobs. If not set, the latest Prefect image will be used."
          },
          "labels": {
            "type": "object",
            "title": "Labels",
            "description": "Labels applied to infrastructure created by a worker.",
            "additionalProperties": {
              "type": "string"
            }
          },
          "command": {
            "type": "string",
            "title": "Command",
            "description": "The command to use when starting a flow run. In most cases, this should be left blank and the command will be automatically generated by the worker."
          },
          "cpu_limit": {
            "type": "string",
            "title": "CPU limit",
            "description": "CPU limit for pod"
          },
          "mem_limit": {
            "type": "string",
            "title": "Memory limit",
            "description": "Memory limit for pod"
          },
          "namespace": {
            "type": "string",
            "title": "Namespace",
            "default": "default",
            "description": "The Kubernetes namespace to create jobs within."
          },
          "cpu_request": {
            "type": "string",
            "title": "CPU request",
            "default": "500m",
            "description": "CPU request for pod"
          },
          "mem_request": {
            "type": "string",
            "title": "Memory request",
            "default": "128Mi",
            "description": "Memory request for pod"
          },
          "stream_output": {
            "type": "boolean",
            "title": "Stream Output",
            "default": true,
            "description": "If set, output will be streamed from the job to local standard output."
          },
          "cluster_config": {
            "allOf": [
              {
                "$ref": "#/definitions/KubernetesClusterConfig"
              }
            ],
            "title": "Cluster Config",
            "description": "The Kubernetes cluster config to use for job creation."
          },
          "finished_job_ttl": {
            "type": "integer",
            "title": "Finished Job TTL",
            "description": "The number of seconds to retain jobs after completion. If set, finished jobs will be cleaned up by Kubernetes after the given delay. If not set, jobs will be retained indefinitely."
          },
          "image_pull_policy": {
            "enum": [
              "IfNotPresent",
              "Always",
              "Never"
            ],
            "type": "string",
            "title": "Image Pull Policy",
            "default": "IfNotPresent",
            "description": "The Kubernetes image pull policy to use for job containers."
          },
          "service_account_name": {
            "type": "string",
            "title": "Service Account Name",
            "description": "The Kubernetes service account to use for job creation."
          },
          "job_watch_timeout_seconds": {
            "type": "integer",
            "title": "Job Watch Timeout Seconds",
            "description": "Number of seconds to wait for each event emitted by a job before timing out. If not set, the worker will wait for each event indefinitely."
          },
          "pod_watch_timeout_seconds": {
            "type": "integer",
            "title": "Pod Watch Timeout Seconds",
            "default": 60,
            "description": "Number of seconds to watch for pod creation before timing out."
          }
        },
        "definitions": {
          "KubernetesClusterConfig": {
            "type": "object",
            "title": "KubernetesClusterConfig",
            "required": [
              "config",
              "context_name"
            ],
            "properties": {
              "config": {
                "type": "object",
                "title": "Config",
                "description": "The entire contents of a kubectl config file."
              },
              "context_name": {
                "type": "string",
                "title": "Context Name",
                "description": "The name of the kubectl context to use."
              }
            },
            "description": "Stores configuration for interaction with Kubernetes clusters.\n\nSee `from_file` for creation.",
            "secret_fields": [],
            "block_type_slug": "kubernetes-cluster-config",
            "block_schema_references": {}
          }
        },
        "description": "Default variables for the Kubernetes worker.\n\nThe schema for this class is used to populate the `variables` section of the default\nbase job template."
      },
      "job_configuration": {
        "env": "{{ env }}",
        "name": "{{ name }}",
        "labels": "{{ labels }}",
        "command": "{{ command }}",
        "namespace": "{{ namespace }}",
        "job_manifest": {
          "kind": "Job",
          "spec": {
            "template": {
              "spec": {
                "containers": [
                  {
                    "env": "{{ env }}",
                    "args": "{{ command }}",
                    "name": "prefect-job",
                    "image": "{{ image }}",
                    "resources": {
                      "limits": {
                        "cpu": "{{ cpu_limit }}",
                        "memory": "{{ mem_limit }}"
                      },
                      "requests": {
                        "cpu": "{{ cpu_request }}",
                        "memory": "{{ mem_request }}"
                      }
                    },
                    "imagePullPolicy": "{{ image_pull_policy }}"
                  }
                ],
                "completions": 1,
                "parallelism": 1,
                "restartPolicy": "Never",
                "serviceAccountName": "{{ service_account_name }}"
              }
            },
            "backoffLimit": 0,
            "ttlSecondsAfterFinished": "{{ finished_job_ttl }}"
          },
          "metadata": {
            "labels": "{{ labels }}",
            "namespace": "{{ namespace }}",
            "generateName": "{{ name }}-"
          },
          "apiVersion": "batch/v1"
        },
        "stream_output": "{{ stream_output }}",
        "cluster_config": "{{ cluster_config }}",
        "job_watch_timeout_seconds": "{{ job_watch_timeout_seconds }}",
        "pod_watch_timeout_seconds": "{{ pod_watch_timeout_seconds }}"
      }
    }
m
Your message was too long by 1185 tokens - please shorten it and try again. For reference, here's your message at the allowed limit:
this is my Base Job Template configuration would this accommodate the
env
reference that I have in my prefect.yaml ?
``` baseJobTemplate.json: | { "variables": { "type": "object", "properties": { "env": { "type": "object", "title": "Environment Variables", "description": "Environment variables to set when starting a flow run.", "additionalProperties": { "type": "string" } }, "name": { "type": "string", "title": "Name", "description": "Name given to infrastructure created by a worker." }, "image": { "type": "string", "title": "Image", "example": "<http://docker.io/prefecthq/prefect:2-latest%7Cdocker.io/prefecthq/prefect:2-latest>", "description": "The image reference of a container image to use for created jobs. If not set, the latest Prefect image will be used." }, "labels": { "type": "object", "title": "Labels", "description": "Labels applied to infrastructure created by a worker.", "additionalProperties": { "type": "string" } }, "command": { "type": "string", "title": "Command",
h
@Marvin This is how my worker configmap is configured to allow env as an object type would this be sufficient or should I teak this configMap ? and If so how ?
m
It seems like you're trying to configure the worker's environment variables using a ConfigMap in a Kubernetes setup or something similar. However, from the searched documentation excerpts, there isn't a specific example directly detailing how to configure a worker ConfigMap for environment variables as objects within Prefect 3.x. Generally, if your worker's config is set to allow
env
as an object type, you need to ensure that the schema in the ConfigMap aligns with the job template's expected input. You should check the following: 1. ConfigMap Schema: Make sure that the schema defined in your ConfigMap for the
env
variable is correct. If you're using Kubernetes,
env
variables are often defined as a list of
name
and
value
pairs, so double-check if using
valueFrom
is fully supported in your setup. 2. Job Template Schema: As you've customized the BaseJobTemplate, verify that your configuration change actually supports and expects
env
as an object type. If you customized it, make sure that its object structure allows for
name
and
valueFrom
keys if that's what you need. For more detailed customization, you can refer to this guide on base job templates and customization: - Customizing Work Pools Moreover, ensure that your Prefect worker is correctly reading configurations from your ConfigMap. If issues persist, consider simplifying the variable, testing without the
valueFrom
construct to isolate the problem. Ah, ConfigMaps: the unsung heroes that turn our variables into environment magic—except when they decide to be mysterious and cryptic. 😄 Happy configuring!
n
please try to avoid tagging me directly if we're not in an active conversation, i can step in and help as time allows, thanks the
key
field should not point to the name of a PREFECT_SETTING, rather the key you set when making the k8s secret, like this
Copy code
kubectl create secret generic your-key \
--namespace=prefect --from-literal=key=pnu-xyz
h
Got it will keep that in mind. The key
PREFECT__LOGGING__LEVEL
is just one of the keys inside of the secret
lab-prefect-3-external-secret
that I trying to get it's value using the
valueFrom
tag similar to how you would invoke a secret env variable from a secret key in Kubernetes
n
Copy code
'detail': "Error creating deployment: Validation failed for field 'env'. Failure reason: [{'name': 'PREFECT__LOGGING__LEVEL', 'valueFrom': {'secretKeyRef': {'name': 'lab-prefect-3-external-secret', 'key': 'PREFECT__LOGGING__LEVEL'}}}] is not valid under any of the given schemas"
hmm okay. this does seem like a kubernetes error though right?
h
It seems to be some schema validation that is not allowing the structure
Copy code
env:
          - name: PREFECT__LOGGING__LEVEL
            valueFrom:
              secretKeyRef:
                name: lab-prefect-3-external-secret
                key: PREFECT__LOGGING__LEVEL
This how I have the env object setup in the Base Job template
Copy code
"properties": {
          "env": {
            "type": "object",
            "title": "Environment Variables",
            "description": "Environment variables to set when starting a flow run.",
            "additionalProperties": {
              "type": "string"
            }
          },
Should I be nesting the valueFrom key within this structure to pass the schema validation ?
n
aha yeah you'd have to change that
Copy code
"type": "string"
to a
Copy code
"type": "object"
at least