aws-cdk
aws-cdk copied to clipboard
feat(core): automatic cross stack, cross region references (under feature flag)
This PR adds the ability to automatically create references in cross-region stacks. You can now do something like
const stack1 = new Stack(app, 'Stack1', { env: { region: 'us-east-1' } });
const cert = new certificatemanager.Certificate(stack1, 'Cert', {...});
const stack2 = new Stack(app, 'Stack2', { env: { region: 'us-east-2' } });
new cloudfront.Distribution(stack2, 'Distro', {
certificate: cert,
})
The above is a good example of the motivation behind this feature. A CloudFront distribution is a global resource and can be created in a CloudFormation stack in any region. Other resources, like the ACM certificate, that need to be attached to the CloudFront distribution can only be created in us-east-1. Another example is the CloudFront.EdgeFunction
where we use a support stack and a custom resource to lookup the value.
To accomplish this, I've added a new construct ExportsReader
which creates a Lambda backed custom resource. This custom resource will return all of the CloudFormation exports in a given region.
Given the above example, this would create an output in stack1
{
"Outputs": {
"ExportsOutputRefCert5C9FAEC110AE5C6A": {
"Value": {
"Ref": "Cert5C9FAEC1"
},
"Export": {
"Name": "East1:ExportsOutputRefCert5C9FAEC110AE5C6A"
}
}
}
}
And then an "import" in stack2
which references the ExportReader
{
"Resources": {
"Distro87EBE6BA": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"ViewerCertificate": {
"AcmCertificateArn": {
"Fn::GetAtt": [
"ExportsReaderuseast1D746CBDB",
"East1:ExportsOutputRefCert5C9FAEC110AE5C6A"
]
}
}
}
}
}
}
Currently this will create a single ExportsReader per region, but we could potentially update this to just use a single ExportsReader which can list exports from a list of regions.
Future extensions:
- Could be updated to do cross account references as well
- Could be used to implement weak references
All Submissions:
- [ ] Have you followed the guidelines in our Contributing guide?
Adding new Unconventional Dependencies:
- [ ] This PR adds new unconventional dependencies following the process described here
New Features
- [ ] Have you added the new feature to an integration test?
- [ ] Did you use
yarn integ
to deploy the infrastructure and generate the snapshot (i.e.yarn integ
without--dry-run
)?
- [ ] Did you use
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
The Pull Request Linter fails with the following errors:
❌ Features must contain a change to a README file.
PRs must pass status checks before we can provide a meaningful review.
I did change a README file...
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).
AWS CodeBuild CI Report
- CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
- Commit ID: 6197448d795f19a81399b2cc58b3bd80717b6a17
- Result: SUCCEEDED
- Build Logs (available for 30 days)
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).
Where does it say what the feature flag is named?
This sounds great. Could something like this also help us with cross-stage dependencies?
Will first check to make sure that the export is not "imported" by the consuming stack. If it is, then it will not update the value. This is to mimic the behavior of CloudFormation stack exports.
@corymhall Standard CloudFormation exports also cannot be deleted if they are in use. (If you try, the entire stack update/delete is immediately aborted.) However, since your approach models these exports as custom resources, that means they won't be deleted until the end of the deployment. Furthermore, CloudFormation basically ignores failures that occur during the UPDATE_COMPLETE_CLEANUP_IN_PROGRESS phase, meaning that the custom resource (and anything it manages) will just get leaked. Is this analysis correct?
On a related note, I think you may need something like Stack.export_value
in order to address the "deadly embrace" issue that used to plague regular exports.
I take it this does not apply if the two cross-region stacks are deployed through separate CDK apps ?