pulumi-eks
pulumi-eks copied to clipboard
Calling [toString] on an [Output<T>] is not supported
What happened?
When i use pulumi eks i get below error:
Error: Invalid EC2 instance type: Calling [toString] on an [Output<T>] is not supported.
To get the value of an Output<T> as an Output<string> consider either:
1: o.apply(v => `prefix${v}suffix`)
2: pulumi.interpolate `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/pulumi.: Error: Invalid EC2 instance type: Calling [toString] on an [Output<T>] is not supported.
To get the value of an Output<T> as an Output<string> consider either:
1: o.apply(v => `prefix${v}suffix`)
2: pulumi.interpolate `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/pulumi.
at isGravitonInstance (/snapshot/eks/bin/nodegroup.js:979:15)
at getAMIType (/snapshot/eks/bin/nodegroup.js:998:25)
at getRecommendedAMI (/snapshot/eks/bin/nodegroup.js:950:21)
at createNodeGroupInternal (/snapshot/eks/bin/nodegroup.js:297:33)
at createNodeGroup (/snapshot/eks/bin/nodegroup.js:155:12)
at createCluster (/snapshot/eks/bin/cluster.js:842:60)
at new ClusterInternal (/snapshot/eks/bin/cluster.js:906:25)
at Object.construct (/snapshot/eks/bin/cmd/provider/cluster.js:21:29)
at Provider.construct (/snapshot/eks/bin/cmd/provider/index.js:131:24)
at Server.<anonymous> (/snapshot/eks/node_modules/@pulumi/pulumi/provider/server.js:315:52)
I think the problem is there: https://github.com/pulumi/pulumi-eks/blob/b6200bbf073449479c2a47b52e96f1e79d89e1f4/nodejs/eks/nodegroup.ts#L1860
You get Input<string> | undefined and then you eliminate undefined but on Input<string> call .toString()
Example
I use Scala language, Besom (Scala SDK for Pulumi) and scala-cli. If you want to run the example below, you'll need to install the scala lang plugin. I use IntelijIDEA. (https://www.jetbrains.com/help/idea/get-started-with-scala.html).
project.scala
//> using scala 3.3.1
//> using dep org.virtuslab::besom-core:0.3.1
//> using dep org.virtuslab::besom-eks:2.3.0-core.0.3
Pulumi.yaml
name: test
runtime: scala
description: Test
Main.scala
import besom.*
import besom.api.eks
@main def main = Pulumi.run {
val cluster = eks.Cluster(
"eks-cluster",
eks.ClusterArgs(
instanceType = "t2.medium"
)
)
Stack.exports(kubeconfig = cluster.kubeconfig)
}
Output of pulumi about
CLI
Version 3.116.1
Go Version go1.22.3
Go Compiler gc
Plugins KIND NAME VERSION resource aws 6.5.0 resource eks 2.3.0 resource kubernetes 4.4.0
Host
OS darwin
Version 14.4.1
Arch arm64
Additional context
No response
Contributing
Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).
@polkx Would you be able to provide a code sample for us to reproduce this issue? Thanks!
Example added. But I think in this situation the example is not so important.
Unfortunately I'm unable to reproduce this issue in any of our supported languages. I've ported the provided example you have to Java, and am able to create the cluster without issues using pulumi-eks v2.5.0. Our existing tests covers this scenario for all the other supported languages.
Example Pulumi Java code:
package myproject;
import com.pulumi.Pulumi;
import com.pulumi.eks.Cluster;
import com.pulumi.eks.ClusterArgs;
import java.util.Map;
public class App {
public static void main(String[] args) {
Pulumi.run(ctx -> {
var cluster = new Cluster("my-cluster", ClusterArgs.builder()
.instanceType("t2.medium")
.build());
ctx.export("kcfg", cluster.kubeconfig());
});
}
}
Since the issue appears to be from your usage of besom and Scala, it's quite likely that something is wrong with besom's type handling since we are expecting a Pulumi string input for the instanceType variable, but your program is generating a Pulumi output variable. Unfortunately we do not have capacity to investigate further since this example works in all our supported languages. I would recommend filing a issue within besom for further investigation.
Hi @rquitales, I'm the maintainer of pulumi-scala. This thing is a new problem on our side that surfaced once we implemented keep outputs feature in our sdk. I would like to ask you why do you think this code on TSs'/JS's side is correct to better understand why there's a problem on our side (because apparently all other langs implement keep outputs differently).
My understanding is that instanceType property's type is Input<string> | undefined (https://github.com/pulumi/pulumi-eks/blob/b6200bbf073449479c2a47b52e96f1e79d89e1f4/nodejs/eks/nodegroup.ts#L1860) where Input used here is the pulumi.Input<T> as defined here: https://github.com/pulumi/pulumi/blob/ee831fc5b6445bd6a1cd49292792ed147eac3d5d/sdk/nodejs/output.ts#L769
so: export type Input<T> = T | Promise<T> | OutputInstance<T>;
This type explicitly says that if something is Input<T> it can be an OutputInstance<T> and that's exactly what happens. Moreover, if I get this right - our SDK sends a request to Pulumi engine in CLI which then does some structural checking and if the message looks correct it passes this message to provider plugin, pulumi-eks in this case, where the request is deserialized. This in turn means that JS deserializer does understand that this field might be an Output and deserializes it without a crash as an Output. This logic also matches the type - the property is typed with Input<string>, not with string.
My best guess is that there's something hidden in the contract of keep outputs feature that we have missed in the implementation but the typescript types on pulumi-eks side do not lie - calling .toString() on Input<string> may lead to this stack trace:
Error: Invalid EC2 instance type: Calling [toString] on an [Output<T>] is not supported.
To get the value of an Output<T> as an Output<string> consider either:
1: o.apply(v => `prefix${v}suffix`)
2: pulumi.interpolate `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/pulumi.: Error: Invalid EC2 instance type: Calling [toString] on an [Output<T>] is not supported.
To get the value of an Output<T> as an Output<string> consider either:
1: o.apply(v => `prefix${v}suffix`)
2: pulumi.interpolate `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/pulumi.
at isGravitonInstance (/snapshot/eks/bin/nodegroup.js:979:15)
at getAMIType (/snapshot/eks/bin/nodegroup.js:998:25)
at getRecommendedAMI (/snapshot/eks/bin/nodegroup.js:950:21)
at createNodeGroupInternal (/snapshot/eks/bin/nodegroup.js:297:33)
at createNodeGroup (/snapshot/eks/bin/nodegroup.js:155:12)
at createCluster (/snapshot/eks/bin/cluster.js:842:60)
at new ClusterInternal (/snapshot/eks/bin/cluster.js:906:25)
at Object.construct (/snapshot/eks/bin/cmd/provider/cluster.js:21:29)
at Provider.construct (/snapshot/eks/bin/cmd/provider/index.js:131:24)
at Server.<anonymous> (/snapshot/eks/node_modules/@pulumi/pulumi/provider/server.js:315:52)
Let me reiterate - I strongly believe the problem is on your side because this pulumi-typescript program fails with exactly same exception:
import * as pulumi from "@pulumi/pulumi";
import * as eks from "@pulumi/eks";
const projectName = "myproject";
const myCluster = new eks.Cluster("my-cluster", {
instanceType: pulumi.output(Promise.resolve("t2.medium")),
});
export const kubeconfig = myCluster.kubeconfig;
λ pulumi up
Enter your passphrase to unlock config/secrets
(set PULUMI_CONFIG_PASSPHRASE or PULUMI_CONFIG_PASSPHRASE_FILE to remember):
Enter your passphrase to unlock config/secrets
Previewing update (dev):
Type Name Plan Info
+ pulumi:pulumi:Stack pulumi-eks-issue-1160-dev create 1 error; 2 messages
+ └─ eks:index:Cluster my-cluster create
+ ├─ eks:index:ServiceRole my-cluster-eksRole create
+ │ ├─ aws:iam:Role my-cluster-eksRole-role create
+ │ └─ aws:iam:RolePolicyAttachment my-cluster-eksRole-4b490823 create
+ ├─ eks:index:ServiceRole my-cluster-instanceRole create
+ │ ├─ aws:iam:Role my-cluster-instanceRole-role create
+ │ ├─ aws:iam:RolePolicyAttachment my-cluster-instanceRole-e1b295bd create
+ │ ├─ aws:iam:RolePolicyAttachment my-cluster-instanceRole-03516f97 create
+ │ └─ aws:iam:RolePolicyAttachment my-cluster-instanceRole-3eb088f2 create
+ ├─ eks:index:RandomSuffix my-cluster-cfnStackName create
+ ├─ aws:iam:InstanceProfile my-cluster-instanceProfile create
+ ├─ aws:ec2:SecurityGroup my-cluster-eksClusterSecurityGroup create
+ ├─ aws:ec2:SecurityGroupRule my-cluster-eksClusterInternetEgressRule create
+ ├─ aws:eks:Cluster my-cluster-eksCluster create
+ ├─ aws:ec2:SecurityGroup my-cluster-nodeSecurityGroup create
+ ├─ eks:index:VpcCni my-cluster-vpc-cni create
+ ├─ pulumi:providers:kubernetes my-cluster-eks-k8s create
+ ├─ aws:ec2:SecurityGroupRule my-cluster-eksNodeIngressRule create
+ ├─ kubernetes:core/v1:ConfigMap my-cluster-nodeAccess create
+ ├─ aws:ec2:SecurityGroupRule my-cluster-eksNodeClusterIngressRule create
+ ├─ aws:ec2:SecurityGroupRule my-cluster-eksClusterIngressRule create
+ ├─ aws:ec2:SecurityGroupRule my-cluster-eksNodeInternetEgressRule create
+ └─ aws:ec2:SecurityGroupRule my-cluster-eksExtApiServerClusterIngressRule create
Diagnostics:
pulumi:pulumi:Stack (pulumi-eks-issue-1160-dev):
(node:49921) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.
(Use `node --trace-deprecation ...` to show where the warning was created)
error: Running program '/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/index.ts' failed with an unhandled exception:
Error: Invalid EC2 instance type: Calling [toString] on an [Output<T>] is not supported.
To get the value of an Output<T> as an Output<string> consider either:
1: o.apply(v => `prefix${v}suffix`)
2: pulumi.interpolate `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/pulumi.
at isGravitonInstance (/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/node_modules/@pulumi/nodegroup.ts:1857:15)
at getAMIType (/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/node_modules/@pulumi/nodegroup.ts:1884:25)
at getRecommendedAMI (/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/node_modules/@pulumi/nodegroup.ts:1825:21)
at createNodeGroupInternal (/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/node_modules/@pulumi/nodegroup.ts:748:55)
at createNodeGroup (/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/node_modules/@pulumi/nodegroup.ts:561:12)
at createCluster (/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/node_modules/@pulumi/cluster.ts:1815:43)
at new Cluster (/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/node_modules/@pulumi/cluster.ts:1673:25)
at Object.<anonymous> (/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/index.ts:7:19)
at Module._compile (node:internal/modules/cjs/loader:1480:14)
at Module.m._compile (/Users/lbialy/Projects/foss/pulumi/pulumi-eks-issue-1160/node_modules/@pulumi/pulumi/vendor/[email protected]/index.js:3009:23)
I agree with @lbialy's assessment this is an eks problem. Being an MLC rather than an standard resource provider it needs to correctly deal with output values, it can't just assume the engine sends Input<string> as a plain string.
Scala SDK is sending OutputValue for every field of every arg class because
it was easier for us to implement inputs and generic derivation for serde
this way. This will change as we will have to implement "plain": true
fields and serialize them correctly without wrapping them in Outputs. The
field in question is not a plain field however, typescript sdk allows
passing pulumi.output(Promise.resolve("")) there so it's only a matter of
time somebody else using any other sdk will push this value as Output
derived from a field of, let's say, StackReference.
The fact that this started crashing on our side after 0.3.0 is related to the fact that we now use outputValues feature. Before that, everything was resolved to plain values before sending a request. Now the fact that we send an Output for every field that is an Input (so every field in any args class) is just more apparent.
On Mon 27. May 2024 at 14:25, Matthew (Matt) Jeffryes < @.***> wrote:
I think it's possible that the scala SDK is sending an Input<String> that's implemented by an OutputInstance
, but the the java example (and the equivalent example in our other SDKs) would be sending an Input<String> implemented by a plain String. (Since the example given is just using a static string for InstanceType.) I wonder if the error would reproduce in other SDKs if we used an output from another resource to populate Instance type
— Reply to this email directly, view it on GitHub https://github.com/pulumi/pulumi-eks/issues/1160#issuecomment-2133374281, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACBVNUWR4ZNG3ONXVAI7A73ZEMQ2XAVCNFSM6AAAAABIDTOACKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCMZTGM3TIMRYGE . You are receiving this because you were mentioned.Message ID: @.***>