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

[apigateway] Reference existing API Key in usagePlan.addApiKey() via ID or similar #8367

Closed
2 tasks
ghost opened this issue Jun 4, 2020 · 13 comments · Fixed by #9155
Closed
2 tasks

[apigateway] Reference existing API Key in usagePlan.addApiKey() via ID or similar #8367

ghost opened this issue Jun 4, 2020 · 13 comments · Fixed by #9155
Assignees
Labels
@aws-cdk/aws-apigateway Related to Amazon API Gateway effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. good first issue Related to contributions. See CONTRIBUTING.md in-progress This issue is being actively worked on.

Comments

@ghost
Copy link

ghost commented Jun 4, 2020

When adding API Keys to a Usage Plan, there seems to be no way to reference an already existing one via ID.

Use Case

We want to create a single API Key with a static value (e.g. deployed in separate stack) to be referenced by many different Usage Plans when deploying APIs. The benefit is that our developers only need to know a single API Key to be able to invoke all the APIs on our test environment.

Proposed Solution

The method addApiKey() should be able to reference a API Key by ID or similar, rather than only a local IApiKey object.

  • 👋 I may be able to implement this feature request
  • ⚠️ This feature might incur a breaking change

This is a 🚀 Feature Request

@ghost ghost added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels Jun 4, 2020
@SomayaB SomayaB added the @aws-cdk/aws-apigateway Related to Amazon API Gateway label Jun 5, 2020
@nija-at
Copy link
Contributor

nija-at commented Jun 10, 2020

The method addApiKey() actually refers to creating a new API key.

Instead, what we would need here is a new method - fromApiKeyId() - which would then be used as so -

const globalApiKey = ApiKey.fromApiKeyId(this, 'GlobalApiKey', '<api-key-id>');

restApi.addUsagePlan('UsagePlan', {
  // ...
  apiKey: globalApiKey,
});

@makruege - let me know if this doesn't satisfy your use case.

@nija-at nija-at added effort/small Small work item – less than a day of effort good first issue Related to contributions. See CONTRIBUTING.md and removed needs-triage This issue or PR still needs to be triaged. labels Jun 10, 2020
@ghost
Copy link
Author

ghost commented Jun 10, 2020

Hi @nija-at, the proposed solution would be perfectly fine.

@SomayaB SomayaB added the in-progress This issue is being actively worked on. label Jul 20, 2020
@mergify mergify bot closed this as completed in #9155 Aug 4, 2020
mergify bot pushed a commit that referenced this issue Aug 4, 2020
add fromApiKeyId import method to the ApiKey construct

closes #8367

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
eladb pushed a commit that referenced this issue Aug 10, 2020
add fromApiKeyId import method to the ApiKey construct

closes #8367

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
curtiseppel pushed a commit to curtiseppel/aws-cdk that referenced this issue Aug 11, 2020
add fromApiKeyId import method to the ApiKey construct

closes aws#8367

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@VictorioBerra
Copy link

Is there a simple way to create if one does not exist? How can I keep my CDK script idempotent?

@rcoundon
Copy link

Is there a simple way to create if one does not exist? How can I keep my CDK script idempotent?

Hi - I'm curious if you ever found a solution?

@VictorioBerra
Copy link

@rcoundon I did not. Here is what I ended up with. My project was a POC and this was my first dive into the CDK. https://github.com/VictorioBerra/cod-stats-tracker-bot/blob/main/lib/cod_tracker_service.ts#L42

@rcoundon
Copy link

@rcoundon I did not. Here is what I ended up with. My project was a POC and this was my first dive into the CDK. https://github.com/VictorioBerra/cod-stats-tracker-bot/blob/main/lib/cod_tracker_service.ts#L42

Thanks for getting back to me. I think that the repo must be private as I get a 404 hitting that link. Are you able to paste a snippet instead? Thanks again

@VictorioBerra
Copy link

You are right its private.

import * as core from "@aws-cdk/core";
import * as lambda from '@aws-cdk/aws-lambda-nodejs';
import * as apigateway from "@aws-cdk/aws-apigateway";
import * as s3 from "@aws-cdk/aws-s3";
import * as secretsManager from "@aws-cdk/aws-secretsmanager";

export class CodStatsTrackerService extends core.Construct {
    constructor(scope: core.Construct, id: string) {
        super(scope, id);

        const bucket = new s3.Bucket(this, "cod.redacted.com");
        bucket.grantPublicAccess();

        // https://docs.aws.amazon.com/cdk/api/latest/docs/aws-lambda-nodejs-readme.html
        const handler = new lambda.NodejsFunction(this, 'cod-stats', {
            entry: 'resources/stack.cod-stats.ts',
            externalModules: [
                'aws-sdk', // Use the 'aws-sdk' available in the Lambda runtime
            ],
            nodeModules: ['aws-lambda-router'],
            handler: 'handler',
            environment: {
                BROWSERLESS_API_KEY: `${secretsManager.Secret.fromSecretAttributes(this, "BrowserlessApiKeyImportedSecret", {
                    secretArn: "arn:aws:secretsmanager:us-east-1:redacted:secret:BrowserlessApiKey",
                }).secretValue}`
            }
        });

        bucket.grantReadWrite(handler); // was: handler.role);

        const api = new apigateway.RestApi(this, "codstats-api", {
            restApiName: "Cod Stats Service",
            description: "This service serves COD stats."
        });

        const getCodStatsIntegration = new apigateway.LambdaIntegration(handler, {
            requestTemplates: { "application/json": '{ "statusCode": "200" }' }
        });

        const getMethod = api.root.addMethod("POST", getCodStatsIntegration);

        const key = api.addApiKey('ApiKey');

        const plan = api.addUsagePlan('UsagePlan', {
            name: 'CodStatsUsagePlan',
            apiKey: key,
            throttle: {
                rateLimit: 1,
                burstLimit: 2
            }
        });

        plan.addApiStage({
            stage: api.deploymentStage,
            throttle: [
                {
                    method: getMethod,
                    throttle: {
                        rateLimit: 10,
                        burstLimit: 2
                    }
                }
            ]
        });
    }
}

@jgreen-linx
Copy link

Is there a method to get the API key if you don't know its ID but know its name or value as you cant create api keys with the same value.
I have multiple stacks that want to use the same key but didn't want to "hard code" the key into the project.
( fromApiKeyId works if you know the key ID and thats my temp solution )

@nickygb
Copy link

nickygb commented May 4, 2023

Hi! I'm trying to use an existing api key with aws-cdk-lib (aws-cdk v2). But the method addUsagePlan don't contains the property apiKey. Do you know how to use an existing apiKey with cdk v2?

@Brachacz
Copy link

Hi! I'm trying to use an existing api key with aws-cdk-lib (aws-cdk v2). But the method addUsagePlan don't contains the property apiKey. Do you know how to use an existing apiKey with cdk v2?

I have the same problem

@rcoundon
Copy link

Hi! I'm trying to use an existing api key with aws-cdk-lib (aws-cdk v2). But the method addUsagePlan don't contains the property apiKey. Do you know how to use an existing apiKey with cdk v2?

I have the same problem

It's worth mentioning this in the CDK Dev Slack https://cdk-dev.slack.com/

@Brachacz
Copy link

Brachacz commented Jun 13, 2023

@nickygb what helped me was to do something like this:

const api = new apigw.RestApi(this, `api`, {
    description: `API`,
    deployOptions: {
        stageName: config.getEnvName(),
        metricsEnabled: true,
        loggingLevel: apigw.MethodLoggingLevel.INFO,
        dataTraceEnabled: true,
    },
});

// Here I create an ApiKey construct without binding it to any other one
const apiKey = new apigw.ApiKey(this, api-key', {
    apiKeyName: 'api-key',
    enabled: true,
    value: config.apiKeyValue,
});

const usagePlan = api.addUsagePlan('UsagePlan', {
    name: 'UsagePlan',
    apiStages: [{ api, stage: api.deploymentStage }],
    throttle: { burstLimit: 500, rateLimit: 1000 },
    quota: { limit: 10000000, period: apigw.Period.MONTH },
});

// addApiKey has to happen only once, either on usagePlan or api constructs
usagePlan.addApiKey(apiKey); 

new CfnOutput(this, 'apiUrl', { value: api.url });

return api;
   

@andrew-hossack
Copy link

andrew-hossack commented Dec 27, 2023

Is there a method to get the API key if you don't know its ID but know its name or value as you cant create api keys with the same value. I have multiple stacks that want to use the same key but didn't want to "hard code" the key into the project. ( fromApiKeyId works if you know the key ID and thats my temp solution )

Did you find any solution to this? Right now we could simply run our stack deploys twice (once to generate the API key and get API key ID, and the next to associate api key ID with the resource). But that isn't very clean.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-apigateway Related to Amazon API Gateway effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. good first issue Related to contributions. See CONTRIBUTING.md in-progress This issue is being actively worked on.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants