Hi guys, Sorry if my question is dumb but I'm new ...
# getting-started
f
Hi guys, Sorry if my question is dumb but I'm new to Pulumi šŸ˜‰ I'm creating a k8s service like:
Copy code
supertokens_service = k8s.core.v1.Service("supertokens-service",
    metadata={"namespace": namespace.metadata["name"]},
    spec=k8s.core.v1.ServiceSpecArgs(
        selector={"app": "supertokens"},
        ports=[k8s.core.v1.ServicePortArgs(port=3567, target_port=3567)]
    ),
    opts=pulumi.ResourceOptions(provider=k8s_provider)
)
The deployed service has name
supertokens-d8a03ac6
. Two questions: • Can I access the service name using
supertokens_service
variable somehow so I can configure my app container to query this service • Can I set a fixed value for the service to
supertokens
without the suffix so that it remains stable when I do updates, or is it Pulumi behavior to add the suffix and can't be changed ?
m
Yes to both:
Copy code
supertokens_service = k8s.core.v1.Service("supertokens-service",
    metadata={"namespace": namespace.metadata.name,
              # set a fixed name instead of auto-naming
              "name": "supertokens"},
    spec=k8s.core.v1.ServiceSpecArgs(
        selector={"app": "supertokens"},
        ports=[k8s.core.v1.ServicePortArgs(port=3567, target_port=3567)]
    ),
    opts=pulumi.ResourceOptions(provider=k8s_provider)
)

# reference the service's name in another resource
other_resource = Resource("other-resource",          service_name=supertokens_service.metadata.name)

# export the service's name as a stack output for downstream use
pulumi.export("supertokens-service-name", supertokens_service.metadata.name)
f
Ty ty šŸ˜‰ So I tried setting a variable like:
Copy code
supertokens_service_name = supertokens_service.metadata['name']
For my other resource, it's:
Copy code
auth_api_deployment = k8s.apps.v1.Deployment("auth-api",
    metadata={"namespace": namespace.metadata["name"]},
    spec=k8s.apps.v1.DeploymentSpecArgs(
        selector=k8s.meta.v1.LabelSelectorArgs(
            match_labels={"app": "auth-api"}
        ),
        replicas=1,
        template=k8s.core.v1.PodTemplateSpecArgs(
            metadata={"labels": {"app": "auth-api"}},
            spec=k8s.core.v1.PodSpecArgs(
                containers=[k8s.core.v1.ContainerArgs(
                    name="auth-api",
                    image=auth_api_image,
                    env=[
                        k8s.core.v1.EnvVarArgs(
                            name="SUPERTOKENS_URL",
                            value=f"http://{supertokens_service_name}:3567"
                        ),
                        k8s.core.v1.EnvVarArgs(
                            name="SUPERTOKENS_API_KEY",
                            value=supertokens_api_key
                        )
                    ]
                )]
            )
        )
    ),
    opts=pulumi.ResourceOptions(provider=k8s_provider)
)
However it seems I can not use
supertokens_service_name
like this, as a value i'm getting:
Copy code
<http://Calling> __str__ on an Output[T] is not supported.

            To get the value of an Output[T] as an Output[str] consider:
            1. o.apply(lambda v: f"prefix{v}suffix")

            See <https://www.pulumi.com/docs/concepts/inputs-outputs> for more details.
            This function may throw in a future version of Pulumi.:3567
        - name: SUPERTOKENS_API_KEY
m
Welcome to Pulumi Outputs šŸ˜‰
This error message is a bit cryptic, let me give you my TL;DR
f
Haha, should I do:
Copy code
supertokens_service_name = supertokens_service.metadata['name'].apply(lambda name: str(name))
?
m
Yes, this is one option. You need to keep in mind that the value of the output is not known at the point in time the Python code is evaluated. So you need to keep it as a Python object at all times, you cannot convert it to a string at runtime.
There are multiple options, they are all listed here: https://www.pulumi.com/docs/concepts/inputs-outputs/apply/#outputs-and-strings
In your scenario, my personal preference would be to use
pulumi.Output.concat("https//", supertokens_service.medatadata.name, ":3567")
I find this to be the most readable and if you have nested definitions (which is often the case for Kubernetes resources) and use a formatter, it will be neatly organized, with the variable on its own line
f
Ah I think I get it, so this should work ?
Copy code
env=[
                        k8s.core.v1.EnvVarArgs(
                            name="SUPERTOKENS_URL",
                            value=pulumi.Output.format("http://{0}:3567", supertokens_service_name)
                        ),
āœ… 1
sry, updated šŸ˜‰
m
Yes, that should work
f
perfect !
Love Pulumi so far, once I get around these hurdles I will drop Terraform completely
ā¤ļø 1
m
As a small service I'll also tell you that
pulumi.Output.json_dumps
is a thing. Not relevant here, but something that I would have liked to discover earlier. It often saves you from insane
.apply()
constructs.
f
Nice ! That's what I hated about Terraform tbh, insane one-liners to extract something from a data struct
šŸ’Æ 1
m
> Love Pulumi so far, once I get around these hurdles I will drop Terraform completely I only started using Pulumi last year, and I love it as well, hands down the best IaC framework I've used so far. I found that once I understood how outputs work (generally and in Python) it was very easy and convenient to use
Also check out the new, slimmed down syntax for arguments: https://www.pulumi.com/blog/pulumi-loves-python/#pythonic-input-types
f
That's great ! Pulumi GPT seems to not be aware of it =D
m
No, and be careful with this tool, it will happily invent APIs that look absolutely plausible and seem to be just made for your particular purpose, but in reality don't exist šŸ˜„