aws-cdk icon indicating copy to clipboard operation
aws-cdk copied to clipboard

feat(core): automatic cross stack, cross region references (under feature flag)

Open corymhall opened this issue 2 years ago • 2 comments

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:

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)?

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

corymhall avatar Sep 12 '22 19:09 corymhall

gitpod-io[bot] avatar Sep 12 '22 19:09 gitpod-io[bot]

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...

corymhall avatar Sep 23 '22 20:09 corymhall

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).

mergify[bot] avatar Oct 31 '22 14:10 mergify[bot]

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).

mergify[bot] avatar Oct 31 '22 15:10 mergify[bot]

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

aws-cdk-automation avatar Oct 31 '22 17:10 aws-cdk-automation

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).

mergify[bot] avatar Oct 31 '22 17:10 mergify[bot]

Where does it say what the feature flag is named?

niebloomj avatar Nov 01 '22 17:11 niebloomj

This sounds great. Could something like this also help us with cross-stage dependencies?

kiernan avatar Nov 11 '22 01:11 kiernan

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.

rittneje avatar Jan 19 '23 16:01 rittneje

I take it this does not apply if the two cross-region stacks are deployed through separate CDK apps ?

DimitriosKay avatar Dec 13 '23 18:12 DimitriosKay