rough-hydrogen-27449
11/16/2021, 4:15 PMCluster
resource representing a Kafka cluster in Confluent Cloud:
class Cluster extends pulumi.dynamic.Resource {
public readonly endpoint!: pulumi.Output<string>;
constructor(
name: string,
props: IClusterInputs,
opts?: pulumi.CustomResourceOptions,
) {
super(new ClusterProvider(), name, props, opts);
}
}
and I've written a dynamic provider for this resource:
class ClusterProvider implements pulumi.dynamic.ResourceProvider {
async create(
inputs: IClusterProviderInputs
): Promise<pulumi.dynamic.CreateResult> {
const cmd = `kafka cluster create ${inputs.clusterName}`
+ ` --cloud aws`
+ ` --region ${inputs.region}`
+ ` --availability ${inputs.availability}`
+ ` --type ${inputs.clusterType}`
+ ` --environment ${inputs.environmentId}`;
const result: IClusterCreateResult = await runConfluentCliCommand(cmd, true);
return {
id: result.id,
outs: { // implements IClusterCreateOutputs
endpoint: result.endpoint,
environmentId: inputs.environmentId,
},
};
}
async update(
_id: string,
olds: IClusterProviderInputs,
_news: IClusterProviderInputs
): Promise<pulumi.dynamic.UpdateResult> {
return {outs: olds}; // FIXME: implement a real update method
}
async delete(
id: string,
props: IClusterCreateOutputs
): Promise<void> {
const cmd = `kafka cluster delete ${id} --environment ${props.environmentId}`;
return await runConfluentCliCommand(cmd, false);
}
}
Then I construct a Cluster
instance and export
an object as a stack output:
const cluster = new Cluster("MyCluster", { ... });
export let stackOutputs = {
cluster_id: cluster.id,
cluster_endpoint: cluster.endpoint,
};
When I spin up this stack and look at the stack outputs, the cluster_id
is present but the cluster_endpoint
is absent. I was able to determine that the cluster.endpoint
value was undefined
.
To "fix" this, I did the following:
export let stackOutputs = {
cluster_id: cluster.id,
cluster_endpoint: pulumi.output(cluster.endpoint),
};
cluster_endpoint
shows up in my stack outputs!pulumi.output(..)
cause it to be reified to a non undefined
value? What is actually going on here?
A corollary question:
Why did I not have to also do this for the id
?
EDIT: I was a little confused, actually. My pulumi.output(..)
edit did not, in fact, cause anything to show up in the stack output. The correct fix was to "initialize" the endpoint
with an undefined
in the call to super(..)
in the Cluster
constructor (see thread).microscopic-florist-22719
11/16/2021, 5:09 PMendpoint
bit isn’t particularly satisfying.pulumi.Resource
superclass needs to see all potential properties in the props
bag, not just input properties. If the names of the output properties are not present in that bag, the Resource
machinery can’t determine which output properties to expect.class Cluster extends pulumi.dynamic.Resource {
public readonly endpoint!: pulumi.Output<string>;
constructor(
name: string,
props: IClusterInputs,
opts?: pulumi.CustomResourceOptions,
) {
super(new ClusterProvider(), name, { endpoint: undefined, ...props }, opts);
}
}
pulumi.output(cluster.endpoint)
changed things is that it turned an undefined
value into a resolved (but defined!) pulumi.Output
value whose inner value is undefined
.id
is always defined by the SDK.rough-hydrogen-27449
11/16/2021, 5:17 PMendpoint
like that in the dynamic resource constructor?microscopic-florist-22719
11/16/2021, 6:09 PMthis
(e.g. properties that are present on every object shouldn’t be considered output properties), but my JS/TS expertise may be failing me here (cc @microscopic-pilot-97530).rough-hydrogen-27449
11/16/2021, 9:50 PM