Skip to content

Commit

Permalink
feat(core): automatic cross stack, cross region references (under fea…
Browse files Browse the repository at this point in the history
…ture flag) (#22008)

This PR adds the ability to automatically create references in cross-region stacks. You can now do something like

```ts
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 two new constructs `ExportsWriter` & `ExportReader`. These constructs create Lambda backed custom resources.

`ExportWriter` responsibilities
- Create/Update SSM parameters in the target region for each export
  - 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.

`ExportReader` responsibilities
- Tag/Untag parameter indicating whether the parameter has been "imported"
- Delete all parameters if the stack is deleted.

I am currently using `/cdk/exports/${consumingStackName}/` as the SSM path prefix to create all the exports.

Given the above example, this would create an output in `stack1`

```json
{
  "ExportsWriteruseast2828FA26B": {                                                                                                                                                                                    
   "Type": "Custom::CrossRegionExportWriter",                                                                                                                                                                          
   "Properties": {                                                                                                                                                                                                     
    "ServiceToken": {                                                                                                                                                                                                  
     "Fn::GetAtt": [                                                                                                                                                                                                   
      "CustomCrossRegionExportWriterCustomResourceProviderHandlerD8786E8A",                                                                                                                                            
      "Arn"                                                                                                                                                                                                            
     ]                                                                                                                                                                                                                 
    },                                                                                                                                                                                                                 
    "Region": "us-east-2",                                                                                                                                                                                             
    "Exports": {                                                                                                                                                                                                       
     "/cdk/exports/East2Stack/East1Stackuseast1CertRefCert5C9FAEC135985652": {                                                                                                                                                                            
      "Ref": "Cert5C9FAEC1"                                                                                                                                                                                            
     }                                                                                                                                                                                                                 
    }                                                                                                                                                                                                                  
   }, 
}
```

And then an "import" in `stack2` which is a dynamic ssm reference.

```json
{
 "Resources": {
  "Distro87EBE6BA": {
   "Type": "AWS::CloudFront::Distribution",
   "Properties": {
    "DistributionConfig": {
     "ViewerCertificate": {
      "AcmCertificateArn": "{{resolve:ssm:/cdk/exports/East2Stack/East1Stackuseast1CertRefCert5C9FAEC135985652}}"
    }
   }
  }
 }
}
```

Currently this will create a single ExportsWriter per region, but we could potentially update this to just use a single ExportsWriter which can write exports to a list of regions.

Future extensions:
- Could be updated to do cross account references as well
- Could be used to implement general weak references


----

### All Submissions:

* [ ] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md)

### Adding new Unconventional Dependencies:

* [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md/#adding-new-unconventional-dependencies)

### New Features

* [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/main/INTEGRATION_TESTS.md)?
	* [ ] 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*
  • Loading branch information
corymhall committed Oct 31, 2022
1 parent 98eb981 commit f1b5497
Show file tree
Hide file tree
Showing 67 changed files with 8,724 additions and 23 deletions.
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-cloudformation/package.json
Expand Up @@ -85,6 +85,7 @@
"@aws-cdk/aws-ssm": "0.0.0",
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/integ-runner": "0.0.0",
"@aws-cdk/integ-tests": "0.0.0",
"@aws-cdk/cfn2ts": "0.0.0",
"@aws-cdk/pkglint": "0.0.0",
"@types/aws-lambda": "^8.10.108",
Expand Down

0 comments on commit f1b5497

Please sign in to comment.