pulumi / pulumi-cdk

Pulumi/CDK Interop Library
Apache License 2.0
62 stars 5 forks source link

Support `NestedStack`s (cannot create `eks.Cluster`) #80

Open rparsonsbb opened 1 year ago

rparsonsbb commented 1 year ago

What happened?

Attempted to create EKS cluster using the ecs cluster as an example

import * as eks from 'aws-cdk-lib/aws-eks';
import * as pulumi from '@pulumi/pulumi';
import * as pulumicdk from '@pulumi/cdk';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as pulumiaws from "@pulumi/aws-native";
import { KubernetesVersion } from "aws-cdk-lib/aws-eks";

class ECSClusterStack extends pulumicdk.Stack {
    clusterArn: pulumi.Output<string>;

    constructor(id: string, options?: pulumicdk.StackOptions) {
        super(id, options);

        const vpc = ec2.Vpc.fromLookup(this, 'MyVpc', {
            isDefault: true,
        })
        const cluster = new eks.Cluster(this, 'fargate-service-autoscaling', {version: KubernetesVersion.V1_27, vpc });

        this.clusterArn = this.asOutput(cluster.clusterArn);

        this.synth();
    }
}

export const clusterArn = pulumiaws.getAccountId().then(account => {
    const stack = new ECSClusterStack('teststack', {
        props: {
            env: {
                region: pulumiaws.config.region,
                account: account.accountId,
            }
        }
    });
    return stack.clusterArn;
});

Instead of resources being created, it failed with

Diagnostics:
  pulumi:pulumi:Stack (teststack):
    error: Running program 'kubernetes\src\index.ts' failed with an unhandled exception:
    Error: Unable to find artifact with id "teststackawscdkawseksClusterResourceProviderFE26FAD9"
        at CloudAssembly.getStackArtifact (kubernetes\node_modules\aws-cdk-lib\cx-api\lib\cloud-assembly.js:1:1946)
        at AppConverter.convert (kubernetes\node_modules\@pulumi\src\stack.ts:247:48)
        at new StackComponent (kubernetes\node_modules\@pulumi\src\stack.ts:107:24)
        at ECSClusterStack.synth (kubernetes\node_modules\@pulumi\src\stack.ts:195:31)
        at new ECSClusterStack (kubernetes\src\index.ts:21:14)
        at kubernetes\src\index.ts:26:19
        at processTicksAndRejections (node:internal/process/task_queues:95:5)

Expected Behavior

Resources are created correctly

Steps to reproduce

  1. modify ecs cluster example for an eks cluster instead
  2. run pulumi preview or pulumi up

Output of pulumi about

$ pulumi about                
CLI          
Version      3.76.1
Go Version   go1.20.6
Go Compiler  gc

Plugins
NAME        VERSION
aws         5.42.0
aws         4.38.1
aws-native  0.18.0
aws-native  0.16.1
docker      3.6.1
nodejs      v18.16.0

Host
OS       Microsoft Windows 11 Pro
Version  10.0.22621 Build 22621
Arch     x86_64

This project is written in nodejs: executable='C:\Program Files\nodejs\node.exe' version='v18.16.0'

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).

danielrbradley commented 1 year ago

I can confirm that example is not working as-is. I see the same error as reported.

I have a hunch that this could be related to which specific versions of packages are resolved. Unfortunately we don't have a lock file in that example so can't reproduce the environment which was used when it was working.

From a quick test all versions back unto v2.56.0 fails with the same error. For versions v2.55.0 and below I get the error:

TypeError: source.addDependency is not a function
        at prepareApp (node_modules/@pulumi/cdk/node_modules/aws-cdk-lib/core/lib/private/prepare-app.js:1:536)
        at synthesize (node_modules/@pulumi/cdk/node_modules/aws-cdk-lib/core/lib/private/synthesis.js:1:922)
        at App.synth (node_modules/@pulumi/cdk/node_modules/aws-cdk-lib/core/lib/stage.js:1:2052)
rparsonsbb commented 1 year ago

gist of my package-lock.json in case it helps.

lukehoban commented 1 year ago

The issue here is that we don't support NestedStack resources yet in the pulumi-cdk bridge. The eks.Cluster construct uses a NestedStack internally, which is what triggers this.

A simpler example that also doesn't work is this:

import * as core from 'aws-cdk-lib/core';
import * as pulumi from '@pulumi/pulumi'; 
import * as pulumicdk from '@pulumi/cdk';
import { Construct } from "constructs";
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as pulumiaws from "@pulumi/aws-native";

class Nesty extends core.NestedStack {
    constructor(scope: Construct, id: string, props?: core.NestedStackProps) {
        super(scope, id, props);
        const bucket = new s3.Bucket(this, "bucket", {});
    }
}

class RootStack extends pulumicdk.Stack {
    nestedStackId: pulumi.Output<string>;
    constructor(id: string, options?: pulumicdk.StackOptions) {
        super(id, options);
        const x = new Nesty(this, "nesty", {});
        this.nestedStackId = this.asOutput(x.stackId);
        this.synth();
    }
}

export const nestedStackId = pulumiaws.getAccountId().then(account => {
    const stack = new RootStack('teststack', {
        props: {
            env: {
                region: pulumiaws.config.region,
                account: account.accountId,
            }
        }
    });
    return stack.nestedStackId;
});

I tested out a very simple change which just treats the nested stacks as independent aws.cloudformation.Stack resources, and this technically works, but isn't really what we want here - as we are trying to avoid the need to use CloudFormation for the deployment entirely. So we'll need to do a slightly more involved implementation to ensure we are deploying the nested stacks via Pulumi as well, and rewriting cross stack references to look up the corresponding Pulumi outputs.

I'll re-title this issue to use to track adding support for NestedStacks.