Hello all. I am writing a script that will create ...
# typescript
s
Hello all. I am writing a script that will create a GCP Cloud Storage bucket for each tenant fetched as an output from another stack. The script looks like this:
Copy code
import * as pulumi from "@pulumi/pulumi";
import { Output } from "@pulumi/pulumi";
import * as gcp from "@pulumi/gcp";

export = async () => {
	const environment = pulumi.getStack();
	const clusterConfig = new pulumi.StackReference(`xyz/cluster-config/${environment}`);
	const tenantIds = await clusterConfig.requireOutput("tenantIds").apply(value => value as string[]);
	const config = new pulumi.Config();
	const project = config.require('project');
	const location = config.require('location');
	const storageClass = config.require('storageClass');

	const bucketUrls = new Array();;

	for (let tenantId of tenantIds) {
		const tenantName = tenantId.split('-')[0];
		const bucketName = `xyz-${environment}-${tenantId}`;
		const bucket = new gcp.storage.Bucket(bucketName, {
			name: bucketName,
			project,
			location,
			storageClass,
			labels: {
				'tenant': tenantName,
				'env': environment,
			},
		});
		bucketUrls.push(bucket.url);
	}

	return {
		bucketUrls
	};
};
However, when I run
pulumi up
I get this error:
index.ts(16,23): error TS2488: Type 'Output<string[]>' must have a '[Symbol.iterator]()' method that returns an iterator
because of this line:
Copy code
const tenantIds = await clusterConfig.requireOutput("tenantIds").apply(value => value as string[]);
What’s the proper way to convert
Ouptput<any>
to
string[]
and iterate the list of strings?
Sidnenote: I am converting the existing code from Pulumi
^1.0.0
to Pulumi
^3.0.0
and have to replace
requireOutputSync
(deprecated) with
requireOutput
but can’t quite figure out how to make the code async.
r
Try `pulumi.interpolate`My string with {output}``
s
I am probably missing something here, but I fail to see how
interpolate
can help me here.
r
Sorry, I dashed that message off a bit quickly, and it's not right at all! It's been a while since I've used the Nodejs SDK, but I (now) think the issue lies in what you're casting. Try casting the
Output<any>
to
Output<string[]>
first, like so:
Copy code
const tenantIds = await clusterConfig.requireOutput("tenantIds") as Output<string[]>

tenantIds.apply(ids => {
  // ...
  for (let tenantId of ids) {
    // ...
  }
}
s
Okay, thank you!
l
Note that if you do that with this code, you'll be creating buckets inside an apply, which is almost certainly not what you want.
Why do you need to get an array of tenantIds asynchronously? Can you get them any other way? Either asynchronously individually, or synchronously as an array?
Individually, Pulumi can unroll them for you when creating the buckets, so you don't need to worry about being inside an apply.
And if you pass in an array using config instead of stack references, then the values are available immediately, so you and iterate on them without needing an apply.
s
Thank you @little-cartoon-10569. I ended up using
requireOutputValue
.