Skip to content

Commit

Permalink
refactor(cloudformation): extract "custom-resources" module (#3027)
Browse files Browse the repository at this point in the history
Extract the AwsCustomResource construct to a separate module called @aws-cdk/custom-resources, dedicated to special custom resources such as this one.

Also, stop bundling the entire AWS SDK and instead extract `apis/metadata.json` during build time which fixes #2951.

BREAKING CHANGE: The `AwsCustomResource` class was moved to a new module called @aws-cdk/custom-resource
  • Loading branch information
Elad Ben-Israel committed Jun 24, 2019
1 parent 43f9fef commit 767687d
Show file tree
Hide file tree
Showing 22 changed files with 1,594 additions and 491 deletions.
85 changes: 0 additions & 85 deletions packages/@aws-cdk/aws-cloudformation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,88 +82,3 @@ See the following section of the docs on details to write Custom Resources:
* [Introduction](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html)
* [Reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref.html)
* [Code Reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html)

#### AWS Custom Resource
Sometimes a single API call can fill the gap in the CloudFormation coverage. In
this case you can use the `AwsCustomResource` construct. This construct creates
a custom resource that can be customized to make specific API calls for the
`CREATE`, `UPDATE` and `DELETE` events. Additionally, data returned by the API
call can be extracted and used in other constructs/resources (creating a real
CloudFormation dependency using `Fn::GetAtt` under the hood).

The physical id of the custom resource can be specified or derived from the data
returned by the API call.

The `AwsCustomResource` uses the AWS SDK for JavaScript. Services, actions and
parameters can be found in the [API documentation](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/index.html).

Path to data must be specified using a dot notation, e.g. to get the string value
of the `Title` attribute for the first item returned by `dynamodb.query` it should
be `Items.0.Title.S`.

##### Examples
Verify a domain with SES:

```ts
const verifyDomainIdentity = new AwsCustomResource(this, 'VerifyDomainIdentity', {
onCreate: {
service: 'SES',
action: 'verifyDomainIdentity',
parameters: {
Domain: 'example.com'
},
physicalResourceIdPath: 'VerificationToken' // Use the token returned by the call as physical id
}
});

new route53.TxtRecord(zone, 'SESVerificationRecord', {
recordName: `_amazonses.example.com`,
recordValue: verifyDomainIdentity.getData('VerificationToken')
});
```

Get the latest version of a secure SSM parameter:

```ts
const getParameter = new AwsCustomResource(this, 'GetParameter', {
onUpdate: { // will also be called for a CREATE event
service: 'SSM',
action: 'getParameter',
parameters: {
Name: 'my-parameter',
WithDecryption: true
},
physicalResourceId: Date.now().toString() // Update physical id to always fetch the latest version
}
});

// Use the value in another construct with
getParameter.getData('Parameter.Value')
```

IAM policy statements required to make the API calls are derived from the calls
and allow by default the actions to be made on all resources (`*`). You can
restrict the permissions by specifying your own list of statements with the
`policyStatements` prop.

Chained API calls can be achieved by creating dependencies:
```ts
const awsCustom1 = new AwsCustomResource(this, 'API1', {
onCreate: {
service: '...',
action: '...',
physicalResourceId: '...'
}
});

const awsCustom2 = new AwsCustomResource(this, 'API2', {
onCreate: {
service: '...',
action: '...'
parameters: {
text: awsCustom1.getData('Items.0.text')
},
physicalResourceId: '...'
}
})
```
1 change: 0 additions & 1 deletion packages/@aws-cdk/aws-cloudformation/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export * from './cloud-formation-capabilities';
export * from './custom-resource';
export * from './aws-custom-resource';

// AWS::CloudFormation CloudFormation Resources:
export * from './cloudformation.generated';
Loading

0 comments on commit 767687d

Please sign in to comment.