diff --git a/docs/guide/custom-provider-resources.md b/docs/guide/custom-provider-resources.md index 673c6694b..b03c72165 100644 --- a/docs/guide/custom-provider-resources.md +++ b/docs/guide/custom-provider-resources.md @@ -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 diff --git a/lib/plugins/aws/deploy/lib/createStack.js b/lib/plugins/aws/deploy/lib/createStack.js index 383c1fbbe..1dac2e471 100644 --- a/lib/plugins/aws/deploy/lib/createStack.js +++ b/lib/plugins/aws/deploy/lib/createStack.js @@ -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; diff --git a/lib/plugins/aws/deploy/tests/createStack.js b/lib/plugins/aws/deploy/tests/createStack.js index f751f2347..79e1d81d9 100644 --- a/lib/plugins/aws/deploy/tests/createStack.js +++ b/lib/plugins/aws/deploy/tests/createStack.js @@ -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(); }); diff --git a/lib/plugins/create/templates/aws-java-gradle/serverless.yml b/lib/plugins/create/templates/aws-java-gradle/serverless.yml index 7f4f27178..361db728f 100644 --- a/lib/plugins/create/templates/aws-java-gradle/serverless.yml +++ b/lib/plugins/create/templates/aws-java-gradle/serverless.yml @@ -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" diff --git a/lib/plugins/create/templates/aws-java-maven/serverless.yml b/lib/plugins/create/templates/aws-java-maven/serverless.yml index cb9fa71d4..9cd729f39 100644 --- a/lib/plugins/create/templates/aws-java-maven/serverless.yml +++ b/lib/plugins/create/templates/aws-java-maven/serverless.yml @@ -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" diff --git a/lib/plugins/create/templates/aws-nodejs/serverless.yml b/lib/plugins/create/templates/aws-nodejs/serverless.yml index 1968b055f..637667c9d 100644 --- a/lib/plugins/create/templates/aws-nodejs/serverless.yml +++ b/lib/plugins/create/templates/aws-nodejs/serverless.yml @@ -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" diff --git a/lib/plugins/create/templates/aws-python/serverless.yml b/lib/plugins/create/templates/aws-python/serverless.yml index cb3cd121d..7ca1a80d3 100644 --- a/lib/plugins/create/templates/aws-python/serverless.yml +++ b/lib/plugins/create/templates/aws-python/serverless.yml @@ -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"