Add full custom resource merging support

This commit is contained in:
Philipp Muens 2016-08-14 17:44:29 +02:00
parent a7235446ad
commit d4bf0342d7
7 changed files with 74 additions and 27 deletions

View File

@ -20,6 +20,10 @@ It will create an own, empty one if it doesn't exist.
You can use this place to add custom provider resources by writing the resource definition in YAML syntax inside the
`resources` object. You can also use your variables from `serverless.env.yml` in the Values
**Note:** You'll have the whole flexibility to overwrite / attach any kind of resource to your CloudFormation stack so
it's no problem to add some new `Resources`, `Outputs` or even overwrite the `Description`. Please be cautious as overwriting
existing parts of your CloudFormation stack might introduce unexpected behavior.
```yml
# serverless.yml
resources:
@ -28,6 +32,9 @@ resources:
Type: ResourceType
Properties:
Key: Value
Outputs:
CustomOutput:
Value: "My Custom Output"
```
### Example custom resources - S3 bucket

View File

@ -93,15 +93,14 @@ module.exports = {
// check if the user has added some "custom provider resources"
// and merge them into the CloudFormation template if there are any
if (this.serverless.service.resources && this.serverless.service.resources.Resources) {
_.forEach(this.serverless.service.resources.Resources, (value, key) => {
const newResourceObject = {
[key]: value,
};
_.merge(coreCloudFormationTemplate.Resources, newResourceObject);
});
}
_.forEach(this.serverless.service.resources, (resourceValue, resourceKey) => {
if (typeof resourceValue === 'string') {
coreCloudFormationTemplate[resourceKey] = resourceValue;
} else if (typeof resourceValue === 'object') {
_.merge(coreCloudFormationTemplate[resourceKey], resourceValue);
}
});
this.serverless.service.resources = coreCloudFormationTemplate;

View File

@ -166,26 +166,55 @@ describe('createStack', () => {
sinon.stub(awsDeploy.sdk, 'request').returns(BbPromise.resolve());
const customResourcesMock = {
fakeResource1: {
foo: 'bar',
Description: 'Some shiny new description',
Resources: {
FakeResource1: {
FakePropKey: 'fakePropValue',
},
FakeResource2: {
FakePropKey: 'fakePropValue',
},
},
fakeResource2: {
baz: 'qux',
Outputs: {
FakeOutput1: {
Value: 'fakeValue',
},
FakeOutput2: {
Value: 'fakeValue',
},
},
CustomDefinition: {
Foo: 'bar',
},
};
awsDeploy.serverless.service.resources.Resources = customResourcesMock;
awsDeploy.serverless.service.resources = customResourcesMock;
return awsDeploy.createStack().then(() => {
// make sure that the core CloudFormation template is used to merge stuff into it
// make sure that the core CloudFormation template is used
// and the merging won't break any stuff
expect(awsDeploy.serverless.service.resources.AWSTemplateFormatVersion)
.to.not.equal(undefined);
expect(awsDeploy.serverless.service.resources.Description)
.to.not.equal(undefined);
expect(awsDeploy.serverless.service.resources.Resources
.ServerlessDeploymentBucket.Type).to.equal('AWS::S3::Bucket');
.ServerlessDeploymentBucket).to.not.equal(undefined);
expect(awsDeploy.serverless.service.resources.Outputs
.ServerlessDeploymentBucketName).to.not.equal(undefined);
// check if the custom provider resources are used
expect(awsDeploy.serverless.service.resources.Resources.fakeResource1)
.to.deep.equal(customResourcesMock.fakeResource1);
expect(awsDeploy.serverless.service.resources.Resources.fakeResource2)
.to.deep.equal(customResourcesMock.fakeResource2);
expect(awsDeploy.serverless.service.resources.Description)
.to.equal(customResourcesMock.Description);
expect(awsDeploy.serverless.service.resources.Resources.FakeResource1)
.to.deep.equal(customResourcesMock.Resources.FakeResource1);
expect(awsDeploy.serverless.service.resources.Resources.FakeResource2)
.to.deep.equal(customResourcesMock.Resources.FakeResource2);
expect(awsDeploy.serverless.service.resources.Outputs.FakeOutput1)
.to.deep.equal(customResourcesMock.Outputs.FakeOutput1);
expect(awsDeploy.serverless.service.resources.Outputs.FakeOutput2)
.to.deep.equal(customResourcesMock.Outputs.FakeOutput2);
expect(awsDeploy.serverless.service.resources.CustomDefinition)
.to.deep.equal(customResourcesMock.Outputs.CustomDefinition);
awsDeploy.sdk.request.restore();
});

View File

@ -46,7 +46,10 @@ functions:
# you can add CloudFormation resource templates here
#resources:
# Resources:
# newResource:
# NewResource:
# Type: AWS::S3::Bucket
# Properties:
# BucketName: newBucket
# BucketName: my-new-bucket
# Outputs:
# NewOutput:
# Value: "Some output value"

View File

@ -46,7 +46,10 @@ functions:
# you can add CloudFormation resource templates here
#resources:
# Resources:
# newResource:
# NewResource:
# Type: AWS::S3::Bucket
# Properties:
# BucketName: newBucket
# BucketName: my-new-bucket
# Outputs:
# NewOutput:
# Value: "Some output value"

View File

@ -46,7 +46,10 @@ functions:
# you can add CloudFormation resource templates here
#resources:
# Resources:
# newResource:
# NewResource:
# Type: AWS::S3::Bucket
# Properties:
# BucketName: newBucket
# BucketName: my-new-bucket
# Outputs:
# NewOutput:
# Value: "Some output value"

View File

@ -46,7 +46,10 @@ functions:
# you can add CloudFormation resource templates here
#resources:
# Resources:
# newResource:
# NewResource:
# Type: AWS::S3::Bucket
# Properties:
# BucketName: newBucket
# BucketName: my-new-bucket
# Outputs:
# NewOutput:
# Value: "Some output value"