p

    polite-napkin-90098

    7 months ago
    I'm struggling to get the kubeconfig from, my EKS cluster built in another stack to work as an input to my k8s.NewProvider function. My code looks like:
    package main
      
    import (
            k8s "<http://github.com/pulumi/pulumi-kubernetes/sdk/v3/go/kubernetes|github.com/pulumi/pulumi-kubernetes/sdk/v3/go/kubernetes>"
            helm "<http://github.com/pulumi/pulumi-kubernetes/sdk/v3/go/kubernetes/helm/v3|github.com/pulumi/pulumi-kubernetes/sdk/v3/go/kubernetes/helm/v3>"
            "<http://github.com/pulumi/pulumi/sdk/v3/go/pulumi|github.com/pulumi/pulumi/sdk/v3/go/pulumi>"
    )
    
    func main() {
            pulumi.Run(func(ctx *pulumi.Context) error {
                    // get the kubeconfig from the EKS stack
                    stackEKS, err := pulumi.NewStackReference(ctx, "EKS-test", nil)
                    if err != nil {
                            return err
                    }
                    kubeConfig := stackEKS.GetOutput(pulumi.String("kubeconfig"))
                    if err != nil {
                            return err
                    }
                    // create a provider with that config
                    eksProvider, err := k8s.NewProvider(ctx, "eksprov", &k8s.ProviderArgs{
                            Kubeconfig: kubeConfig,
                    })
                    if err != nil {
                            return err
                    }
                    // deploy redis from the helm chart
                    _, err = helm.NewChart(ctx, "redis", helm.ChartArgs{
                            Repo: pulumi.String("bitnami"),
                            Chart: pulumi.String("redis"),
                            Values: pulumi.Map{
                                    "auth.password": pulumi.String("MyTopSecretPassword"),
                            },
                    },
                    pulumi.ProviderMap(map[string]pulumi.ProviderResource{
                            "kubernetes": eksProvider,
                    }),)
                    if err != nil {
                            return err
                    }
                    ctx.Export("output", kubeConfig)
                    return nil
            })
    }
    If I comment out the from eksProvider down to the ctx.Export, I get what looks like a valid kubeconfig exported. But as is this results in a typing error:
    ./main.go:22:4: cannot use kubeConfig (type pulumi.AnyOutput) as type pulumi.StringPtrInput in field value:        pulumi.AnyOutput does not implement pulumi.StringPtrInput (missing ToStringPtrOutput method)
    Can anyone help me understand what I need to do here?
    b

    bored-table-20691

    7 months ago
    An example:
    kubeconfig := infraStack.GetStringOutput(pulumi.String("kubeconfig"))
    	k8sProvider, err := kubernetes.NewProvider(ctx, "k8s-ssa-provider", &kubernetes.ProviderArgs{
    		Kubeconfig: kubeconfig,
    	})
    	if err != nil {
    		return nil, err
    	}
    I think you want
    GetStringOutput
    p

    polite-napkin-90098

    7 months ago
    ah.
    I'll give that a try, thanks
    p

    prehistoric-activity-61023

    7 months ago
    I haven’t used pulumi in golang but that sounds like it
    it’s possible you can try to cast the
    AnyOutput
    class to appropriate string class
    golang is statically typed lang so it’s not gonna be happy with ANYthing 😉
    p

    polite-napkin-90098

    7 months ago
    GetStringOutput worked like a charm, Thanks @bored-table-20691
    Hmmm actually I might have to go back on that, I got a different error and thought it was going to be from the next part fo the program (the helm bit) but apparently not.
    Diagnostics:
      pulumi:pulumi:Stack (redis-redis-test):
        error: an unhandled error occurred: program exited with non-zero exit code: 1
     
        panic: interface conversion: interface {} is map[string]interface {}, not string
        goroutine 34 [running]:
        <http://github.com/pulumi/pulumi/sdk/v3/go/pulumi.(*StackReference).GetStringOutput.func1({0xb43280|github.com/pulumi/pulumi/sdk/v3/go/pulumi.(*StackReference).GetStringOutput.func1({0xb43280>, 0xc00041f4a0})
            /home/ubuntu/go/pkg/mod/github.com/pulumi/pulumi/sdk/v3@v3.19.0/go/pulumi/stack_reference.go:32 +0x5d
        reflect.Value.call({0xb16060, 0xc7bf88, 0x2}, {0xc3f6cd, 0x4}, {0xc00041f6f8, 0x1, 0x7f41e1c260f8})
            /usr/local/go/src/reflect/value.go:543 +0x814
        reflect.Value.Call({0xb16060, 0xc7bf88, 0x4617b9}, {0xc00041f6f8, 0x1, 0x1})
            /usr/local/go/src/reflect/value.go:339 +0xc5
        <http://github.com/pulumi/pulumi/sdk/v3/go/pulumi.makeContextful.func1(|github.com/pulumi/pulumi/sdk/v3/go/pulumi.makeContextful.func1(>{0xc00041f6e0, 0x4, 0x4})
            /home/ubuntu/go/pkg/mod/github.com/pulumi/pulumi/sdk/v3@v3.19.0/go/pulumi/types.go:362 +0x56
        reflect.Value.call({0xc00008aba0, 0xc000093200, 0x13}, {0xc3f6cd, 0x4}, {0xc00006afa0, 0x2, 0x2})
            /usr/local/go/src/reflect/value.go:543 +0x814
        reflect.Value.Call({0xc00008aba0, 0xc000093200, 0xc00012e020}, {0xc000059fa0, 0x2, 0x2})
            /usr/local/go/src/reflect/value.go:339 +0xc5
        <http://github.com/pulumi/pulumi/sdk/v3/go/pulumi.(*OutputState).ApplyTWithContext.func1()|github.com/pulumi/pulumi/sdk/v3/go/pulumi.(*OutputState).ApplyTWithContext.func1()>
            /home/ubuntu/go/pkg/mod/github.com/pulumi/pulumi/sdk/v3@v3.19.0/go/pulumi/types.go:470 +0x2e5
        created by <http://github.com/pulumi/pulumi/sdk/v3/go/pulumi.(*OutputState).ApplyTWithContext|github.com/pulumi/pulumi/sdk/v3/go/pulumi.(*OutputState).ApplyTWithContext>
            /home/ubuntu/go/pkg/mod/github.com/pulumi/pulumi/sdk/v3@v3.19.0/go/pulumi/types.go:458 +0x231
        exit status 2
    Which seems to me like the output (which is a json blob) is not being a string and thus GetStringOutput errors like above. 🤔
    b

    bored-table-20691

    7 months ago
    What does your export look like?
    From the other stack
    p

    polite-napkin-90098

    7 months ago
    ubuntu@ip-172-31-44-42:~/docker/EKS/pulumi$ pulumi stack output kubeconfig
    {"apiVersion":"v1","clusters":[{"cluster":{"certificate-authority-data":"<obfuscate>","server":"<https://A><here too><http://A4DD972F18.yl4.us-east-2.eks.amazonaws.com|A4DD972F18.yl4.us-east-2.eks.amazonaws.com>"},"name":"kubernetes"}],"contexts":[{"context":{"cluster":"kubernetes","user":"aws"},"name":"aws"}],"current-context":"aws","kind":"Config","users":[{"name":"aws","user":{"exec":{"apiVersion":"<http://client.authentication.k8s.io/v1alpha1|client.authentication.k8s.io/v1alpha1>","args":["eks","get-token","--cluster-name","Test-eksCluster-0c7f8e2"],"command":"aws"}}}]}
    i.e. like a json blob of kubeconfig
    b

    bored-table-20691

    7 months ago
    No sorry. The code that exports it.
    p

    polite-napkin-90098

    7 months ago
    ctx.Export("kubeconfig", cluster.Kubeconfig)
    cluster, err := eks.NewCluster(ctx, "Test", &eks.ClusterArgs{
    			VpcId: pulumi.String(vpcid),
    			PrivateSubnetIds: pulumi.StringArray{
    				pulumi.String(private[0]),
    				pulumi.String(private[1]),
    				pulumi.String(private[2]),
    			},
    			PublicSubnetIds: pulumi.StringArray{
    				pulumi.String(public[0]),
    				pulumi.String(public[1]),
    				pulumi.String(public[2]),
    			},
    			ClusterSecurityGroup: sg,
    			EndpointPrivateAccess: pulumi.Bool(true),
    			EndpointPublicAccess: pulumi.Bool(false),
    			NodeAssociatePublicIpAddress: pulumi.Bool(false),
                    })
    b

    bored-table-20691

    7 months ago
    You need to convert it to json prior to exporting. It's an abstract object right now.
    kubeconfig := cluster.Kubeconfig.ApplyT(func(kc interface{}) string {
    		str, err := json.Marshal(kc)
    		if err != nil {
    			panic(err) // TODO
    		}
    
    		return string(str)
    	}).(pulumi.StringOutput)
    I'd do it prior to exporting
    p

    polite-napkin-90098

    7 months ago
    Ok I'll give that a try.
    So the exported value now has a bunch of /s in it escaping some bits, but I still get the
    Diagnostics:
      pulumi:pulumi:Stack (redis-redis-test):
        # redis
        ./main.go:22:4: cannot use kubeConfig (type pulumi.AnyOutput) as type pulumi.StringPtrInput in field value:
            pulumi.AnyOutput does not implement pulumi.StringPtrInput (missing ToStringPtrOutput method)
    when I try to use the imported value
    no wait
    it works when I then use GetStringOutput
    thanks
    seems a little convoluted but it works so I'm happy
    b

    bored-table-20691

    7 months ago
    The core issue is that the original value is an object and not a string, but the provider expects a string. It's confusing because the export looks like a string even though it's just doing the stringification for the console for you. You could convert it after importing or before exporting.
    p

    polite-napkin-90098

    7 months ago
    Thanks Itay, good explanation, I might switch the stringification to the import side at some point, but I expect it will stay as is for the time being.