Secrets! Hey all, i'm struggling to understand whe...
# ask-community
a
Secrets! Hey all, i'm struggling to understand where i'm going wrong. I have a prefect server setup and I have secrets in my local config.toml which contain things like username / pws and some keys. I want to access these during flow execution by doing something like: my_secret = PrefectSecret('my_secret_name') I keep getting error messages: • When I try to debug on local using a localexecutor() it says secrets should only be retrieved during a flow run, not while building a flow. I've currently got my secret retrieval in my flow definition, is this wrong?
k
Hey @Adam Everington, do you get an error?
Ah can you show me how you use it in the flow/
a
Hey Kevin! Yeah sorry I sent my message to early!!
In my flow I just have something like:
Copy code
with Flow('myflow',executor=LocalExecutor()) as flow:
  my_secret = PrefectSecret('my_secret_name')
  function_that_uses_secret(my_secret)
I also get the same issue when deployed to server running on a local agent... which I assume uses the same config.toml as locally executing?
As a follow up question, when I deploy to my prod server on AKS, do I store those details in the config.toml on the server? (Agent runs on the same machine)
k
Why does
flow
have a small letter f in your
Flow
block?
a
No sorry, me being lazy in my example!
k
Cuz it seems to be working (I set the env variable so it gets loaded in context)
Copy code
import os
os.environ['PREFECT__CONTEXT__SECRETS__MYSECRET']="MY SECRET VALUE"
from prefect import task, Flow
from prefect.tasks.secrets import PrefectSecret

@task
def my_task(credentials):
    pass

with Flow("example") as flow:
    my_secret = PrefectSecret("MYSECRET")
    res = my_task(credentials=my_secret)

flow.run()
a
ok... so i'm gonna ask a total NOOB question here.... i've defined those values in my toml, so do I have to define them as above in my script? Isn't the point of the secrets to not have them in your script? Do you have to do it as above to get them stored?
k
no no. i’m just doing this to make a demo script but the point is that they get loaded into the prefect context. Env variables and the config.toml will both be loaded in
a
so my toml looks like:
Copy code
[context.secrets]
DEVOPS_URL = ""
AZURE_SQL_NAME = ""
etc etc
that's stored in my ~/.prefect folder
on the server I get this: Unexpected error while running flow: KeyError('Task slug AZURE_SQL_PW-1 is not found in the current Flow. This is usually caused by a mismatch between the flow version stored in the Prefect backend and the flow that was loaded from storage.\n- Did you change the flow without re-registering it?\n- Did you register the flow without updating it in your storage location (if applicable)?') Traceback (most recent call last): File "e:\adam.everington\desktop\sandbox\python\prefect\.venv\lib\site-packages\prefect\engine\cloud\flow_runner.py", line 398, in initialize_run task = tasks[task_run.task_slug] KeyError: 'AZURE_SQL_PW-1' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "e:\adam.everington\desktop\sandbox\python\prefect\.venv\lib\site-packages\prefect\engine\flow_runner.py", line 264, in run state, task_states, run_context, task_contexts = self.initialize_run( File "e:\adam.everington\desktop\sandbox\python\prefect\.venv\lib\site-packages\prefect\engine\cloud\flow_runner.py", line 400, in initialize_run raise KeyError( KeyError: 'Task slug AZURE_SQL_PW-1 is not found in the current Flow. This is usually caused by a mismatch between the flow version stored in the Prefect backend and the flow that was loaded from storage.\n- Did you change the flow without re-registering it?\n- Did you register the flow without updating it in your storage location (if applicable)?'
....it's git storage and the server version is definitely up to date as is the git version
slightly different error locally: 021-11-05 134111+0000] ERROR - prefect.TaskRunner | Task 'AZURE_SQL_USER': Exception encountered during task execution! Traceback (most recent call last): File "e:\adam.everington\Desktop\Sandbox\Python\Prefect\.venv\lib\site-packages\prefect\engine\task_runner.py", line 859, in get_task_run_state value = prefect.utilities.executors.run_task_with_timeout( File "e:\adam.everington\Desktop\Sandbox\Python\Prefect\.venv\lib\site-packages\prefect\utilities\executors.py", line 445, in run_task_with_timeout return task.run(*args, **kwargs) # type: ignore File "e:\adam.everington\Desktop\Sandbox\Python\Prefect\.venv\lib\site-packages\prefect\tasks\secrets\base.py", line 66, in run return _Secret(name).get() File "e:\adam.everington\Desktop\Sandbox\Python\Prefect\.venv\lib\site-packages\prefect\client\secrets.py", line 131, in get raise ValueError( ValueError: Secrets should only be retrieved during a Flow run, not while building a Flow.
k
I tried with the
config.toml
Copy code
[context.secrets]
TEST = "test"
and it’s working on the flow side:
Copy code
with Flow("example") as flow:
    my_secret = PrefectSecret("TEST")
    res = my_task(credentials=my_secret)
It seems like you are using
PrefectSecret
outside the Flow block?
upvote 1
a
can you show your entire flow definition? It can be that you defined some other secret at the top of your flow file (i.e. not within flow constructor)?
a
Copy code
with Flow("Load-BCC-Data-To-Azure-Capture",executor=LocalExecutor()) as flow:
    #Storage
    flow.storage = Local(path=r'E:\adam.everington\Desktop\Sandbox\Python\Prefect\BCC\BCC-Load.py')

    #flow.storage = Git(
    #    flow_path = "./BCC/BCC.py",
    #    repo="prefect",
    #    branch_name="main",
    #    git_clone_url_secret_name="DEVOPS_URL"
    #)

    #Schedule
    #flow.schedule = Schedule(
    #    clocks=[IntervalClock(timedelta(hours=24))],
    #    filters=[at_time(datetime.time(20))]
    #)
    #Secrets
    user = PrefectSecret('AZURE_SQL_USER')
    pw = PrefectSecret('AZURE_SQL_PW')
    rsa = PrefectSecret('SFTP_RSA_KEY')
That's the start of it
there are no other secrets defined
k
I can replicate your error if I do:
Copy code
with Flow("example") as flow:
    my_secret = PrefectSecret("TEST").run()
    res = my_task(credentials=my_secret)
Are you calling the
.run()
by chance?
a
Can you share your entire flow Python file? you only shared the with Flow()… definition
a
Sure, let me just get rid of some sensitive info
🙌 1
Also as always you've both been brilliant, thanks for your help
k
Oh I think unindenting
flow.run()
will fix this
👍 1
a
omg
a
and btw Adam, you don’t need to explicitly pass LocalExecutor() since this is the default. Also, you can pass the storage info directly to the flow constructor:
Copy code
with Flow("Load-BCC-Data-To-Azure-Capture", storage = Local(path=r'E:\adam.everington\Desktop\Sandbox\Python\Prefect\BCC\BCC.py')) as flow:
🙌 1
a
thanks for the tips, really appreciate all help 🙂
@Kevin Kho i can't unindent when i'm calling using the reference can I?
Also still have my issue when the flow has been deployed
k
You can (and should i think)
Copy code
with Flow("example") as flow:
    my_secret = PrefectSecret("TEST")
    res = my_task(credentials=my_secret)
flow.run()
1
a
I love you, that worked perfectly
marvin 1
... so stupid
how about my deployed version?
script is identical bar using git storage and a LocalDaskExecutor()
a
@Adam Everington regarding deploying to Kubernetes and creating a Kubernetes Secret - in this repo I have a couple of examples sowing how you could set this up. The README shows how to create Secret for different registries (I understand you need Azure, right?) and the flows/ folder shows various KubernetesRun configurations https://github.com/anna-geller/packaging-prefect-flows
a
amazing, thank you so much @Anna Geller! Our QA server is just a locally hosted server (bare metal install) the error messages I posted above are from that, not K8s however that post will be EXTREMELY useful when I move to prod so thank you
so yeah, just tried again on the locally installed server and no dice, it still thinks theres a difference between the meta on the server and the flow source it pulls from Git
Just re-pushed to both to ensure they were the same
k
Not sure it will work but can you trying putting all of the settings outside your Flow block like:
Copy code
with Flow(...) as flow:
   ...

flow.storage = ...
flow.run_config = ...
They might be messing with the Flow structure that Prefect checks
a
thing is it works just fine until I put the secrets in?
k
I think the error might not be accurate because those flow settings are tasks so it’s just raising the first task. Not sure, but I think this is worth a try. And then of course, make sure that the Github storage is using the right branch
a
It's just standard Git storage from Azure Devops, not that that should make a difference
k
Oh ok. It looks like it’s pulling fine. I think if you remove the secrets, the error message will just show the next task. Did it work without the secrets?
a
i'll try now...
ok, so i've hard coded the values in and it works (it fails down the line but that's down to a data error)
if you setup your flow so that: • You have devops storage for the flow • Execute on a localdaskexecutor on a network server • Have secrets in the local config.toml • Secrets being pulled as part of the flow def
That's where i'm at
k
I can try to replicate this. Could you give me your Storage and RunConfig? Just remove the sensitive info
a
Copy code
storage=Git(
            flow_path = "./BCC/BCC.py",
            repo="prefect",
            branch_name="main",
            git_clone_url_secret_name="DEVOPS_URL"
        )
nothing special in the run config, just on a localdaskexecutor
k
Ah ok I’m more wondering if that’s a Local Agent or Kubernetes Agent?
a
ah sorry dude, just on a localagent!
k
Ok will try this
🙌 1
Is your DEVOPS_URL in the config.toml also? Or is it a secret on Cloud? I think you are on Server right?
a
yeah, that's in the same config.toml 🙂
k
for posterity, all working magically ^
🙌 2