Adinath Dhamdhere
Adinath Dhamdhere

Reputation: 31

How do I convert the Output into str, to used as inputs in Pulumi resources of the second project?

I'm trying to use the outputs of one project via stack reference as input of a second project, but it seems I'm missing the last piece as I'm getting an error as shown below that Output can't be converted into str. For the exact error see below.

I've followed the documentation Stack References and Inputs and Outputs, and several answers that are basically all the same.

This is a simplified setup of two projects each with the stack dev, backend is a Cloud Storage bucket. In the first project, VpcComponent class creates a VPC network on Google Cloud Platform (classic provider). I want to get the vpc and a simple string value my_string as input for other Pulumi resources in the second project. For example, use the vpc.name as input in a subnet created in the second project, or my_string as a the parent folder ID of a GCP project.

Versions:
pulumi CLI version   v3.62.0
Python               v3.9.2
pulumi               v3.64.0
pulumi-gcp           v6.54.0

First Project

__main__.py

import pulumi
from pulumi import ComponentResource, Output
from pulumi_gcp import compute

class VpcComponent(ComponentResource):
    def __init__(self, name, args=None, opts=None):
        super().__init__("my:vpc:VpcComponent", name, None, opts)
        
        self.vpc_network = compute.Network(f"{name}-vpc-network")
        self.subnet = compute.Subnetwork(
            f"{name}-subnet",
            ip_cidr_range="10.0.0.0/24",
            region="us-central1",
            network=self.vpc_network.id,
        )

        # Pass the output of network and subnet names
        self.vpc = self.vpc_network
        
        # self.register_outputs({"vpc": self.vpc})

# Create the VPC network and subnet using VpcComponent class

vpc_component = VpcComponent("my-vpc-component")

# Register VPC and String output
pulumi.export("vpc_out", vpc_component.vpc)
pulumi.export("string_out", "hello_world")

Output after pulumi up

Outputs: 
string_out: "hello_world"
vpc_out   : {
    auto_create_subnetworks                  : true
    delete_default_routes_on_create          : false
    description                              : ""
    enable_ula_internal_ipv6                 : false
    gateway_ipv4                             : ""
    id                                       : "projects/my-gcp-project/global/networks/my-vpc-component-vpc-network-cfaeac6"
    internal_ipv6_range                      : ""
    mtu                                      : 0
    name                                     : "my-vpc-component-vpc-network-cfaeac6"
    network_firewall_policy_enforcement_order: "AFTER_CLASSIC_FIREWALL"
    project                                  : "my-gcp-project"
    routing_mode                             : "REGIONAL"
    self_link                                : "https://www.googleapis.com/compute/v1/projects/my-gcp-project/global/networks/my-vpc-component-vpc-network-cfaeac6"
    urn                                      : "urn:pulumi:dev::vpc::gcp:compute/network:Network::my-vpc-component-vpc-network"
    }

Second Project

Now using Stack Reference I want to use vpc_out and string_out in this second pulumi project.

__main__.py

import pulumi
from pulumi import StackReference
from pulumi_gcp import compute


# Note:- 
# vpc is pulumi project name where we stored outputs and try to access those outputs in product project
# dev is stack name

stack_ref = pulumi.StackReference("organization/vpc/dev")

vpc_in=stack_ref.get_output("vpc_out")
string_in=stack_ref.get_output("string_out")

pulumi.export("Showing VPC output", vpc_in)
pulumi.export("Showing String Output", string_in)

print("Printing VPC name ", vpc_in.id.apply(lambda id: id))
print("Printing VPC name ", vpc_in.name.apply(lambda name: name))
print("Printing string_in", string_in.apply(lambda  string: string))

If we use pulumi up command on above code then it is able to print output with pulumi.export() but I can't just print().

print("Printing VPC name ", vpc_in.name.apply(lambda name: name))

and

print("Printing string_in", string_in.apply(lambda  string: string))

will both give an error like this:

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://pulumi.io/help/outputs for more details.
    This function may throw in a future version of Pulumi.
    Printing string_in Calling __str__ on an Output[T] is not supported.

More importantly, but probably for the same reason, neither can I use vpc_in.name or string_in as values in Pulumi resources of the second project where it expects type str and doesn't accept a value of type Output.

How do I convert the Output into str, so they can be used as inputs in Pulumi resources of the second project?

Upvotes: 3

Views: 3654

Answers (2)

Abbas
Abbas

Reputation: 4069

If anyone is still searching for how to convert an Output[str] into a string value here is how you can do it:

#Declare a global variable
vpn_name_str=None
def get_str_value(x):
    global value_str
    vpn_name_str=x
    return x
vpn_in.name.apply(lambda x:get_str_value(x))
pulumi.log.info(f"VPN IN name : {vpn_name_str}")

Upvotes: 0

jaxxstorm
jaxxstorm

Reputation: 13301

You cannot convert a Pulumi Output[str] to a plain string.

If you need the plain value of an Output (ie, the string itself) you'll need to print the value inside an apply.

In this code:

print("Printing VPC name ", vpc_in.id.apply(lambda id: id))
print("Printing VPC name ", vpc_in.name.apply(lambda name: name))
print("Printing string_in", string_in.apply(lambda  string: string))

You are running the print outside the apply function, which means the output hasn't yet resolved.

If you do the following:

vpc_in.id.apply(lambda id: print(f"Printing VPC id {id}")
vpc_in.name.apply(lambda name: print(f"Printing VPC name {name}")

The print will work successfully, because the value is known inside the apply.

I've written a lengthy blogpost about this here

More importantly, but probably for the same reason, neither can I use vpc_in.name or string_in as values in Pulumi resources of the second project where it expects type str and doesn't accept a value of type Output.

Again, the solutions here is to use an apply, so for example if you're creating any policies, simply use an apply. Feel free to post another question with a specific ask if needed

Upvotes: 1

Related Questions