berenddeboer / cdk-rds-sql

A CDK construct that allows creating roles and databases an on Aurora Serverless Postgresql cluster.
Apache License 2.0
23 stars 11 forks source link

Circular dependency in Nested-Stacks scenario #33

Open stephanpelikan opened 2 months ago

stephanpelikan commented 2 months ago

I want to use RDS like this:

I create a provider in Rds-Stack and pass it as a property to Application1-Stack. Within Application1-Stack I want to create the role and databases needed by the application to ensure all resources for one specific application are located in one particular stack. Addtionally, some of them need more than one database per application.

One running this scenario, I get a circular dependency one building the role. cdk diff shows the reason:

Parameters
[+] Parameter RdsStack/reference-to-IPSInfraStackCamundaStackNestedStackCamundaStackNestedStackResource194F2C09Outputs.IPSInfraStackCamundaStackIdentityPostgresqlRoleSecret39E668AFRef referencetoIPSInfraStackCamundaStackNestedStackCamundaStackNestedStackResource194F2C09OutputsIPSInfraStackCamundaStackIdentityPostgresqlRoleSecret39E668AFRef: {"Type":"String"}

Resources
[~] AWS::IAM::Policy RdsStack/RdsSql28b9e791af604a33bca8ffb6f30ef8c5/ServiceRole/DefaultPolicy RdsSql28b9e791af604a33bca8ffb6f30ef8c5ServiceRoleDefaultPolicy40EB37D2 
 └─ [~] PolicyDocument
     └─ [~] .Statement:
         └─ @@ -5,8 +5,13 @@
            [ ]       "secretsmanager:GetSecretValue"
            [ ]     ],
            [ ]     "Effect": "Allow",
            [-]     "Resource": {
            [-]       "Ref": "PostgresqlClusterSecretAttachment5C5F253E"
            [-]     }
            [+]     "Resource": [
            [+]       {
            [+]         "Ref": "PostgresqlClusterSecretAttachment5C5F253E"
            [+]       },
            [+]       {
            [+]         "Ref": "referencetoIPSInfraStackCamundaStackNestedStackCamundaStackNestedStackResource194F2C09OutputsIPSInfraStackCamundaStackIdentityPostgresqlRoleSecret39E668AFRef"
            [+]       }
            [+]     ]
            [ ]   }
            [ ] ]

The ServiceRole/DefaultPolicy is extended (which is located in RdsStack) is extended by a reference to my application's stack.

How can I achieve to build databases as part of the application-stacks but keep the common RDS stuff in the RdsStack?

berenddeboer commented 2 months ago

Seems like an interesting scenario that should work. I think the problem here is that the provider is created in each application stack. What if you create the provider in the rds stack, then reuse it in the applicatsion stack?

The issue is this code I'm guessing:

this.secret.grantRead(this.handler)

Another solution might be a secret per application stack, and pass that secret.

stephanpelikan commented 2 months ago

Creating the provider in the RdsStack was my first attempt which doesn't work.

I think the only way make this work is to not use the secret in a direct way (by the provider) but pass the ARN or some other identifier to the provider and let it lookup the secret for each stack. On doing so it is important to add proper dependencies so removing the entire stacks destructs everything in the right order.