(aws-cdk): Allow merging of the outputs file with existing files.
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
Allow merging of the outputs file with existing files.
### Use Case
We have multiple apps with multiple stacks. We have a build a little CLI application to allow us pick and choose which apps and which stacks to deploy.
We have a bunch of backend stacks in one app which deploy API GW, R53, Cognito etc and then another app which builds and deploys a front end for cloudfront for example. Hence, we need to use outputs to get the domain name, the userpoolid etc. etc.
However, the current behaviour means that if we have for example 10 stacks in the backend, each outputting these necessary variables to the outputs file, if we then choose to deploy only 1 of the 10 stacks, the rest of the outputs file gets wiped out, which is not ideal
### Proposed Solution
* Check for an existing outputs file
* Read the existing outputs file
* Do a single-level merge the new outputs with the existing outputs file
e.g. given something like this
```json
{
"APIGateway": {
"fullPath": "mock.io/api-v1",
"basePath": "api-v1"
},
"Auth": {
"coreAppClientId": "mockAppClientId",
"graphAppClientId": "mockGraphAppClientId",
"userPoolEndpoint": "https://mockendpoint",
"userPoolId": "eu-west-2_78o6yMOCK",
"userPoolRegion": "mockUserPoolRegion"
}
}
```
and I redeploy just my Auth stack with one delete app client and one new app client I'd get
```json
{
"APIGateway": {
"fullPath": "mock.io/api-v1",
"basePath": "api-v1"
},
"Auth": {
"coreAppClientId": "mockAppClientId",
"coreAppClientId2": "mockAppClientId2",
"userPoolEndpoint": "https://mockendpoint",
"userPoolId": "eu-west-2_78o6yMOCK",
"userPoolRegion": "mockUserPoolRegion"
}
}
```
Seems like this could be implemented here https://github.com/aws/aws-cdk/blob/74776f393462f7e7d23cb1953ef786a823adc896/packages/aws-cdk/lib/cdk-toolkit.ts#L235 with something like...
```ts
if (outputsFile) {
fs.ensureFileSync(outputsFile);
const existingStackOutputs = require(outputsFile)
await fs.writeJson(outputsFile, {...stackOutputs, ...existingStackOutputs}, {
spaces: 2,
encoding: 'utf8',
});
}
```
Above code is untested but seems like it should be simple enough. This could even be behind a cli flag to avoid any unexpected breaking changes.
* [x] :wave: I may be able to implement this feature request
* [ ] :warning: This feature might incur a breaking change
---
This is a :rocket: Feature Request
Contributor guide
Research direction
Read packages/aws-cdk/lib/cdk-toolkit.ts around line 235, where the outputs file is handled, and trace how current stack outputs are written. Done means an existing outputs file preserves outputs from other stacks while updating the redeployed stack's values, with the merge behavior and any CLI-flag choice covered by tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- cli, cloud
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100