There is also a possibility to remove the auth explicitly on the method, here I also remove requirement for OPTIONS in the requestsX-API-Key
const lambdaApi = new apigateway.LambdaRestApi(...) // This API has CORS enabled in defaultCorsPreflightOptions
lambdaApi.methods
.filter((method) => method.httpMethod === "OPTIONS")
.forEach((method) => {
const methodCfn = method.node.defaultChild as apigateway.CfnMethod;
methodCfn.authorizationType = apigateway.AuthorizationType.NONE;
methodCfn.authorizerId = undefined;
methodCfn.authorizationScopes = undefined;
methodCfn.apiKeyRequired = false;
});
TL;DR Use a single stack and pass in the stg/prod as an env var to .app.py
Pass config down from > Stacks > Constructs as Python Parameters (constructor args). Avoid using CDK Parameters* for config, says AWS's CDK Application Best Practices.app.py
Practically speaking, you pass the account or alias as a environment variable, which reads to perform the metadata lookups and set the stack props. Here's a node-flavoured version of this pattern:app.py
AWS_ACCOUNT=123456789012 npx cdk deploy '*' -a 'node ./bin/app' --profile test-account"
Why not 2 stacks in app.py, one for PROD and one for STAGING?
A 2-stack approach can certainly work. The downsides are that you rarely want to deploy both environments at the same time (outside a CI/CD context). And cross-account permissions are trickier to handle safely if mixed in a single .cdk deploy
Within your code, use a dict, class or whatever to return the configuration you want based on an account or region input. Finally, pass the variables to the constructs. Here's an example of code that uses , account and region props to customise a s3 bucket:isProduction
const queriesBucket = new s3.Bucket(this, 'QueriesBucket', {
bucketName: `${props.appName.toLowerCase()}-queries-${props.env.account}-${
props.env.region
}`,
removalPolicy: props.isProduction
? cdk.RemovalPolicy.RETAIN
: cdk.RemovalPolicy.DESTROY,
versioned: props.isProduction,
lifecycleRules: [
{
id: 'metadata-rule',
prefix: 'metadata',
noncurrentVersionExpiration: props.isProduction
? cdk.Duration.days(30)
: cdk.Duration.days(14),
},
],
});
* "Parameter" has different meaning in Python and CDK. Passing variables between constructs in code using Python Parameters (=method arguments) is a best practice. In CDK-speak a Parameter has the special meaning of a variable value passed to CloudFormation at deploy time. These are not CDK best practice.