Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using a named resource in another resource provisioner #1119

Open
jasondbaker opened this issue Feb 27, 2025 · 1 comment
Open

Using a named resource in another resource provisioner #1119

jasondbaker opened this issue Feb 27, 2025 · 1 comment
Labels
bug Something isn't working

Comments

@jasondbaker
Copy link

Describe the bug

I don't seem able to use a named resource in another resource provisioner. I don't know if this is by design or my implementation error. How can we reference resources created by one resource provider in another resource provider?

Expected Behavior

I would expect to be able to import a resource, like a KMS key, and be able to use it in another resource provisioner to create an encrypted resource.

Current Behavior

The CDK synth process generates an error:

  Error: Resolution error: Trying to resolve() a Construct at ..........

Reproduction Steps

I created a KMS key resource using a resource provider and LookupKmsKeyProvider method. I then tried to reference this resource as a named resource in a custom resource provider which creates a secret in secrets manager. My goal was to use the KMS key to encrypt the secret.

   blueprints.EksBlueprint.builder()
   .resourceProvider(
    blueprints.GlobalResources.KmsKey,
    new blueprints.LookupKmsKeyProvider(config.resources.myKmsKeyAlias),
  )
  .resourceProvider(
    "my-secret",
    new CreateSecretProvider("my-secret", "this is a secret description"),
  )

And here is my custom secrets provider where I'm creating a secret and expecting to be able to use the KMS key. I'm using the blueprints.getNamedResource method to try to retrieve the key.

import * as blueprints from "@aws-quickstart/eks-blueprints";
import { Secret } from "aws-cdk-lib/aws-secretsmanager";
import { IKey } from "aws-cdk-lib/aws-kms";

export class CreateSecretProvider implements blueprints.ResourceProvider<Secret> {
  constructor(
    private readonly secretName: string,
    private readonly description?: string,
  ) {}

  provide(context: blueprints.ResourceContext): Secret {
    const kmsKey = blueprints.getNamedResource(blueprints.GlobalResources.KmsKey) as IKey;

    return new Secret(context.scope, this.secretName, {
      secretName: this.secretName,
      description: this.description,
      encryptionKey: kmsKey,
    });
  }
}

I've tried different ways to use the key. The problem I keep running into when doing a cdk synth is an error like:

Error: Resolution error: Trying to resolve() a Construct at ..........

The eks blueprint is a bit of a black box for me so I don't understand what's going on behind the scenes to generate these constructs.

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.173.4

EKS Blueprints Version

1.16.3

Node.js Version

18.x

Environment details (OS name and version, etc.)

Linux

Other information

No response

@jasondbaker jasondbaker added the bug Something isn't working label Feb 27, 2025
@shapirov103
Copy link
Collaborator

@jasondbaker in your use case please use the provided resource context as opposed to the named resource.

export class CreateSecretProvider implements blueprints.ResourceProvider<Secret> {
  constructor(
    private readonly secretName: string,
    private readonly description?: string,
  ) {}

  provide(context: blueprints.ResourceContext): Secret {
    const kmsKey = context.get(blueprints.GlobalResources.KmsKey) as IKey; // this is the change

    return new Secret(context.scope, this.secretName, {
      secretName: this.secretName,
      description: this.description,
      encryptionKey: kmsKey,
    });
  }
}

The getNamedResource approach is used to pass resources to the clusterProvider, addons and teams. However, now that I observe this usage, I think it reasonable to adjust the framework to handle this case. getNamedResource and getResource generate a dynamic proxy that is resolved at runtime for blueprint creation, however that resolution happens after all resources are instantiated, hence your exception.

Also you may want to avoid using blueprints.GlobalResources.KmsKey for your KMS key, unless you also want to use the same key for secrets encryption in the cluster.
You can pass any string like my-kms-key and then use resourceContext.get('my-kms-key'). You may also want to pass the resource name in the constructor to the CreateSecretProvider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants