When defining a Resource separately from a RestApi I am unable to provide the RestApi as the parent for the Resource despite documentation suggesting otherwise:
This appears that it may have a flow-on effect when attempting to add a CognitoUserPoolsAuthorizer to the created resource, as it needs to be "attached to a RestApi".
Expected Behavior
To be able to provide a RestApi as the parent of a Resource and subsequently be able to attach a CognitoUserPoolsAuthorizer to the resource.
Current Behavior
When providing the RestApi as the parent the project cannot compile/synth.
When providing the RestApi's root resource as the parent, or creating a wrapper for RestApi that implements Amazon.CDK.AWS.APIGateway.IResource the project can compile, but fails synth with the following error:
Unhandled exception. System.Exception: Error: Resolution error: Resolution error: Resolution error: Authorizer ([REDACTED]-InfrastructureStage-dev/InfrastructureStack/Api/ApiAuthorizer) must be attached to a RestApi.
Object creation stack:
at Function.string (C:\[REDACTED]\AppData\Local\Temp\jsii-kernel-hxXIJv\node_modules\aws-cdk-lib\core\lib\lazy.js:1:766)
at CognitoUserPoolsAuthorizer.lazyRestApiId (C:\[REDACTED]\AppData\Local\Temp\jsii-kernel-hxXIJv\node_modules\aws-cdk-lib\aws-apigateway\lib\authorizers\cognito.js:1:1986)
at new CognitoUserPoolsAuthorizer (C:\[REDACTED]\AppData\Local\Temp\jsii-kernel-hxXIJv\node_modules\aws-cdk-lib\aws-apigateway\lib\authorizers\cognito.js:1:793)
at Kernel._create (C:\[REDACTED]\AppData\Local\Temp\tvnb0n21.o2d\lib\program.js:9959:29)
at Kernel.create (C:\[REDACTED]\AppData\Local\Temp\tvnb0n21.o2d\lib\program.js:9688:29)
at KernelHost.processRequest (C:\[REDACTED]\AppData\Local\Temp\tvnb0n21.o2d\lib\program.js:11539:36)
at KernelHost.run (C:\[REDACTED]\AppData\Local\Temp\tvnb0n21.o2d\lib\program.js:11499:22)
at Immediate._onImmediate (C:\[REDACTED]\AppData\Local\Temp\tvnb0n21.o2d\lib\program.js:11500:46)
at processImmediate (node:internal/timers:464:21)..
at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
at Amazon.JSII.Runtime.Services.Client.Invoke(InvokeRequest request)
at Amazon.JSII.Runtime.Services.Client.Invoke(ObjectReference objectReference, String method, Object[] arguments)
at Amazon.JSII.Runtime.Deputy.DeputyBase.<>c__DisplayClass17_0`1.<InvokeInstanceMethod>b__1(IClient client, Object[] args)
at Amazon.JSII.Runtime.Deputy.DeputyBase.<InvokeMethodCore>g__GetResult|18_0[T](<>c__DisplayClass18_0`1&)
at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeMethodCore[T](JsiiMethodAttribute methodAttribute, Object[] arguments, Func`3 beginFunc, Func`3 invokeFunc)
at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeInstanceMethod[T](Type[] parameterTypes, Object[] arguments, String methodName)
at Amazon.CDK.Pipelines.PipelineBase.AddStage(Stage stage, IAddStageOpts options)
at [REDACTED].StandardPipeline.TryCreateStageForEnvironment(DeploymentEnvironment deploymentEnvironment, ShellStep synthStep, EnvironmentGenerator environmentGenerator, IReadOnlyDictionary`2 deploymentEnvironments, EnvironmentManualApprovalOutput& environmentManualApprovalOutput)
at [REDACTED].StandardPipeline..ctor(Construct scope, String id, StandardPipelineProps props)
at Infrastructure.Program.Main(String[] args) in C:\[REDACTED]\src\Infrastructure\Program.cs:line 26
Reproduction Steps
Here's the constructor of a Stage that is used to deploy the offending resources:
public InfrastructureStage(Construct scope, string id, InfrastructureStageProps props) : base(scope,
id, props)
{
var stack = new Stack(this, "InfrastructureStack", new StackProps());
var api = new RestApi(stack, "Api", new RestApiProps());
api.Root
.AddResource("proxy")
.AddProxy(new ProxyResourceOptions
{
AnyMethod = true,
DefaultIntegration = new HttpIntegration([REDACTED]),
DefaultMethodOptions = new MethodOptions
{
ApiKeyRequired = true
}
});
/* Ommited for brevity */
var apiResource = new Resource(stack, "ApiResource", new ResourceProps
{
Parent = api, // Doesn't accept api as a valid input because it doesn't implement Amazon.CDK.AWS.APIGateway.IResource
PathPart = "graphql",
DefaultIntegration = new LambdaIntegration(new BaseDotNetFunction(stack, "ApiFunction",
new BaseDotNetFunctionProps
{
Environment = props.Environment,
FunctionName = "ApiFunction",
CodePath = "./src/API/",
Handler = "API",
FunctionEnvironmentVariables = new FunctionEnvironmentVariables()
}).Function),
DefaultMethodOptions = new MethodOptions
{
AuthorizationType = AuthorizationType.COGNITO,
Authorizer = new CognitoUserPoolsAuthorizer(api, "ApiAuthorizer", // Providing api or stack here as scope doesn't make a difference
new CognitoUserPoolsAuthorizerProps
{
CognitoUserPools = new IUserPool[] {auth.UserPool.UserPool}
})
}
});
apiResource.Node.AddDependency(distribution, api, auth);
}
As you can see this sample does use some custom constructs, especially relating to the BaseDotNetFunction and auth (which is used in the CognitoUserPoolsAuthorizerProps to provide a user pool).
Possible Solution
Having Amazon.CDK.AWS.APIGateway.IResourceProps.Parent accept both Amazon.CDK.AWS.APIGateway.IResource and Amazon.CDK.AWS.APIGateway.RestApi or have Amazon.CDK.AWS.APIGateway.RestApi implement Amazon.CDK.AWS.APIGateway.IResource. Additionally, have CognitoUserPoolsAuthorizer properly recognise when it is attached to a RestApi.
Additional Information/Context
Of note, I am having to create the apiResource like this to resolve a cyclic dependency between a CloudFront Distribution, a Cognito UserPool, and the apiResource.
Describe the bug
When defining a
Resource
separately from aRestApi
I am unable to provide theRestApi
as the parent for theResource
despite documentation suggesting otherwise:This appears that it may have a flow-on effect when attempting to add a
CognitoUserPoolsAuthorizer
to the created resource, as it needs to be "attached to aRestApi
".Expected Behavior
To be able to provide a
RestApi
as the parent of aResource
and subsequently be able to attach aCognitoUserPoolsAuthorizer
to the resource.Current Behavior
When providing the
RestApi
as the parent the project cannot compile/synth.When providing the
RestApi
's root resource as the parent, or creating a wrapper forRestApi
that implementsAmazon.CDK.AWS.APIGateway.IResource
the project can compile, but fails synth with the following error:Reproduction Steps
Here's the constructor of a
Stage
that is used to deploy the offending resources:As you can see this sample does use some custom constructs, especially relating to the
BaseDotNetFunction
andauth
(which is used in theCognitoUserPoolsAuthorizerProps
to provide a user pool).Possible Solution
Having
Amazon.CDK.AWS.APIGateway.IResourceProps.Parent
accept bothAmazon.CDK.AWS.APIGateway.IResource
andAmazon.CDK.AWS.APIGateway.RestApi
or haveAmazon.CDK.AWS.APIGateway.RestApi
implementAmazon.CDK.AWS.APIGateway.IResource
. Additionally, haveCognitoUserPoolsAuthorizer
properly recognise when it is attached to aRestApi
.Additional Information/Context
Of note, I am having to create the
apiResource
like this to resolve a cyclic dependency between a CloudFrontDistribution
, a CognitoUserPool
, and theapiResource
.CDK CLI Version
2.69.0 (build 60a5b2a)
Framework Version
.NET 7
Node.js Version
18.15.0
OS
Windows 11 Home (10.0.22621)
Language
.NET
Language Version
C# 11
Other information
No response