Rather than try to use the env parameter supplied by amplify directly in the cdk stack. I ended up creating a backend stack per environment like this
new CdkBackendStack(app, "prod-stack", {
stackName: "prod-stack",
deploymentEnvironment: "prod",
});
new CdkBackendStack(app, "dev-stack", {
stackName: "dev-stack",
deploymentEnvironment: "dev",
});
I can then use this deploymentEnvironment prop to conditionally create the stack and each stack can produce the needed output like this:
new cdk.CfnOutput(this, "ClusterSecretArn", {
value: serverlessCluster.secret?.secretArn || "",
});
Now I can synthesize both stacks and output to a custom amplify stack like this
cdk synth dev-stack > ../amplify/backend/cdk/dev/dev-cloudformation-template.yml
cdk synth prod-stack > ../amplify/backend/cdk/prod/prod-cloudformation-template.yml
Following amplify docs to add a custom stack, both the dev and prod stack are added to backend-config.json:
"cdk": {
"dev": {
"providerPlugin": "awscloudformation"
},
"prod": {
"providerPlugin": "awscloudformation"
}
},
And then I can use the output in other amplify stacks by modifying backend-config.json like this:
"dependsOn": [
{
"category": "cdk",
"resourceName": "dev",
"attributes": [
"DatabaseName",
"SchemaName",
"ClusterArn",
"ClusterSecretArn"
]
},
{
"category": "cdk",
"resourceName": "prod",
"attributes": [
"DatabaseName",
"SchemaName",
"ClusterArn",
"ClusterSecretArn"
]
}
],
I can define the new parameters in the stack like
"DevDatabaseName": {
"Fn::GetAtt": [
"cdkdev",
"Outputs.DatabaseName"
]
},
"DevSchemaName": {
"Fn::GetAtt": [
"cdkdev",
"Outputs.SchemaName"
]
},
"DevClusterArn": {
"Fn::GetAtt": [
"cdkdev",
"Outputs.ClusterArn"
]
},
"DevClusterSecretArn": {
"Fn::GetAtt": [
"cdkdev",
"Outputs.ClusterSecretArn"
]
},
"ProdDatabaseName": {
"Fn::GetAtt": [
"cdkprod",
"Outputs.DatabaseName"
]
}
...
And then in the cloudformation template I have a condition defined:
"Conditions": {
"IsDevEnvironment": {
"Fn::Equals": [
{
"Ref": "env"
},
"dev"
]
}
}
and finally, where I need these parameters I have:
"DbClusterIdentifier": {
"Fn::If": [
"IsDevEnvironment",
{
"Ref": "DevClusterArn"
},
{
"Ref": "ProdClusterArn"
}
]
},
I was hoping for a more elegant solution but this was the best I could manage.