Hey all! :wave: We're running into a puzzling issue with conditional resource logic in Python for ou...
a
Hey all! 👋 We're running into a puzzling issue with conditional resource logic in Python for our GCP projects and would greatly appreciate any insights. The Goal We want to create temporary "preview" stacks for merge requests. These preview stacks should reuse existing resources (like a Cloud SQL database) from our permanent
dev
environment, not create new ones. We control this behavior with a Pulumi config flag. The Problem We use a simple
if/else
block based on an
is_preview
boolean flag to decide whether to get an existing database or create a new one. Here is a simplified version of our code: Python
Copy code
import pulumi
import pulumi_gcp as gcp

config = pulumi.Config()
is_preview = config.get_bool("is_preview") or False

# We print this value and confirm it's True in our CI logs
print(f"Executing with is_preview = {is_preview}") 

if not is_preview:
    # This block should only run for 'dev', 'staging', etc.
    print("Executing 'create' block...")
    db = gcp.sql.DatabaseInstance("my-db-instance",
        name="my-actual-db-in-gcp",
        # ... other settings
    )
else:
    # This block should run for preview stacks
    print("Executing 'get' block...")
    db = gcp.sql.get_database_instance(
        name="my-actual-db-in-gcp",
        project="my-gcp-project-name"
    )

# The 'db' variable is then used later in a Cloud Run service
# ...
The
is_preview
flag is confirmed to be
True
at runtime via the print statement. We expect the
else
block to run and for Pulumi to simply
get
the existing instance. However, the
pulumi preview
plan incorrectly shows that it will create the
gcp.sql.DatabaseInstance
, which is the logic from the
if not is_preview
block. This leads to a
409: Instance Already Exists
error during the update. What We've Ruled Out • Stuck State: The error occurs even on a brand-new stack that is created and destroyed in the same CI job, so it's not a corrupted state file. • Refactoring: We have tried refactoring this logic to use separate variable names and even encapsulated it into a
pulumi.ComponentResource
, but the exact same issue persists. • Configuration: We've confirmed via
print()
statements that the
is_preview
boolean is correctly evaluated as
True
during the program's execution. Our Question Has anyone encountered a scenario where the Pulumi engine's preview plan seems to ignore a Python
if/else
condition for resource declaration? Is there a known pattern or caveat for this type of conditional logic with the GCP provider that we might be missing? Any help or pointers would be greatly appreciated. Thank you!
e
Has anyone encountered a scenario where the Pulumi engine's preview plan seems to ignore a Python
if/else
condition for resource declaration?
There is no possible way for the engine to do this. The engine has nothing to do with how your python code is executed. If your getting a create called either there's a bug in your code causing a new resource to be registered, or there's a bug in the get logic causing get_database_instance to somehow turn into a create. Can you confirm that only your "Executing 'get' block..." print statement executes? If you remove the
db = gcp.sql.DatabaseInstance
line entirely do you still see a 'create'?
a
• Yes the print statement executes. • yes we still have the 'create' even after removing
db = gcp.sql.DatabaseInstance
. to be precise we have this in our logs-
gcp:sql:DatabaseInstance *******-db creating
e
I strongly suspect you must have another call to gcp.sql.DatabaseInstance somewhere in your code, I can't see anyway that
gcp.sql.get_database_instance
could be causing the engine to trigger a create step
a
We are confused by the same fact that we have removed all calls to
gcp.sql.DatabaseInstance
, but we have the same log with creation of db instead of the read operation
e
What command are you running to see that log line?
a
We are running the
pulumi up
command.
e
I think you'll have to raise an issue on github about this with as much information as you can. I can't see any way that get_database_instance could translate to a create.
a
I will do that. thank you