Skip to content

Commit cd7febc

Browse files
author
Matt Semar
committed
Fix issue with alias remove for large templates
1 parent 6b9d0ac commit cd7febc

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ class AwsAlias {
165165

166166
'alias:remove:remove': () => BbPromise.bind(this)
167167
.then(this.validate)
168+
.then(this.setBucketName)
168169
.then(this.aliasStackLoadCurrentCFStackAndDependencies)
169170
.spread(this.removeAlias)
170171
};

lib/removeAlias.js

+39-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const _ = require('lodash');
55
const utils = require('./utils');
66

77
const NO_UPDATE_MESSAGE = 'No updates are to be performed.';
8+
const TEMPLATE_MIN_SIZE_FOR_UPLOAD = 51200;
89

910
module.exports = {
1011

@@ -135,7 +136,7 @@ module.exports = {
135136
});
136137
},
137138

138-
aliasApplyStackChanges(currentTemplate, aliasStackTemplates, currentAliasStackTemplate) {
139+
aliasApplyStackChanges(currentTemplate, aliasStackTemplates, currentAliasStackTemplate, templateUrl) {
139140

140141
const stackName = this._provider.naming.getStackName();
141142

@@ -155,10 +156,15 @@ module.exports = {
155156
'CAPABILITY_NAMED_IAM',
156157
],
157158
Parameters: [],
158-
TemplateBody: JSON.stringify(currentTemplate),
159159
Tags: _.map(_.keys(stackTags), key => ({ Key: key, Value: stackTags[key] })),
160160
};
161161

162+
if (templateUrl) {
163+
params.TemplateURL = templateUrl;
164+
} else {
165+
params.TemplateBody = JSON.stringify(currentTemplate);
166+
}
167+
162168
this.options.verbose && this._serverless.cli.log(`Checking stack policy`);
163169

164170
// Policy must have at least one statement, otherwise no updates would be possible at all
@@ -185,8 +191,38 @@ module.exports = {
185191

186192
},
187193

194+
uploadCloudFormationTemplate(currentTemplate, aliasStackTemplates, currentAliasStackTemplate) {
195+
const templateSize = JSON.stringify(currentTemplate).length;
196+
if (templateSize < TEMPLATE_MIN_SIZE_FOR_UPLOAD) {
197+
this.serverless.cli.log(`Skipping Upload of CloudFormation alias file to S3, size is only ${templateSize}`);
198+
return BbPromise.resolve([ currentTemplate, aliasStackTemplates, currentAliasStackTemplate]);
199+
}
200+
this.serverless.cli.log('Uploading CloudFormation alias file to S3...');
201+
const body = JSON.stringify(currentTemplate);
202+
203+
const fileName = 'compiled-cloudformation-template-alias.json';
204+
205+
let params = {
206+
Bucket: this.bucketName,
207+
Key: `${this.serverless.service.package.artifactDirectoryName}/${fileName}`,
208+
Body: body,
209+
ContentType: 'application/json',
210+
};
211+
212+
return this.provider.request('S3',
213+
'putObject',
214+
params,
215+
this._options.stage,
216+
this._options.region)
217+
.then(() => {
218+
const templateUrl = `https://s3.amazonaws.com/${this.bucketName}/${this._serverless.service.package.artifactDirectoryName}/compiled-cloudformation-template-alias.json`;
219+
return BbPromise.resolve([ currentTemplate, aliasStackTemplates, currentAliasStackTemplate, templateUrl ]);
220+
});
221+
},
222+
188223
aliasRemoveAliasStack(currentTemplate, aliasStackTemplates, currentAliasStackTemplate) {
189224

225+
190226
const stackName = `${this._provider.naming.getStackName()}-${this._alias}`;
191227

192228
this.options.verbose && this._serverless.cli.log(`Removing CF stack ${stackName}`);
@@ -245,9 +281,8 @@ module.exports = {
245281
return BbPromise.resolve([ currentTemplate, aliasStackTemplates, currentAliasStackTemplate ]).bind(this)
246282
.spread(this.aliasCreateStackChanges)
247283
.spread(this.aliasRemoveAliasStack)
284+
.spread(this.uploadCloudFormationTemplate)
248285
.spread(this.aliasApplyStackChanges)
249286
.then(() => BbPromise.resolve());
250-
251287
}
252-
253288
};

test/removeAlias.test.js

+4
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,14 @@ describe('removeAlias', () => {
6767
let aliasCreateStackChangesStub;
6868
let aliasRemoveAliasStackStub;
6969
let aliasApplyStackChangesStub;
70+
let uploadCloudFormationTemplateStub;
7071
let pluginManagerSpawnStub;
7172

7273
beforeEach(() => {
7374
aliasApplyStackChangesStub = sandbox.stub(awsAlias, 'aliasApplyStackChanges');
7475
aliasCreateStackChangesStub = sandbox.stub(awsAlias, 'aliasCreateStackChanges');
7576
aliasRemoveAliasStackStub = sandbox.stub(awsAlias, 'aliasRemoveAliasStack');
77+
uploadCloudFormationTemplateStub = sandbox.stub(awsAlias, 'uploadCloudFormationTemplate');
7678
pluginManagerSpawnStub = sandbox.stub(awsAlias._serverless.pluginManager, 'spawn');
7779
});
7880

@@ -131,12 +133,14 @@ describe('removeAlias', () => {
131133
aliasApplyStackChangesStub.returns([ slsStack1, [ aliasStack2 ], aliasStack1 ]);
132134
aliasCreateStackChangesStub.returns([ slsStack1, [ aliasStack2 ], aliasStack1 ]);
133135
aliasRemoveAliasStackStub.returns([ slsStack1, [ aliasStack2 ], aliasStack1 ]);
136+
uploadCloudFormationTemplateStub.returns([ slsStack1, [ aliasStack2 ], aliasStack1, 'templateUrl' ]);
134137

135138
return expect(awsAlias.removeAlias(slsStack1, [ aliasStack2 ], aliasStack1)).to.be.fulfilled
136139
.then(() => BbPromise.all([
137140
expect(aliasCreateStackChangesStub).to.have.been.calledOnce,
138141
expect(aliasRemoveAliasStackStub).to.have.been.calledOnce,
139142
expect(aliasApplyStackChangesStub).to.have.been.calledOnce,
143+
expect(uploadCloudFormationTemplateStub).to.have.been.calledOnce,
140144
expect(pluginManagerSpawnStub).to.not.have.been.called,
141145
]));
142146
});

0 commit comments

Comments
 (0)