diff --git a/.changes/next-release/Feature-4f5decb4-40cb-458d-abde-407daaa98084.json b/.changes/next-release/Feature-4f5decb4-40cb-458d-abde-407daaa98084.json new file mode 100644 index 00000000..00b2f5e4 --- /dev/null +++ b/.changes/next-release/Feature-4f5decb4-40cb-458d-abde-407daaa98084.json @@ -0,0 +1,4 @@ +{ + "type": "Feature", + "description": "Added DisableRollback boolean paramater to cloudFormationExecuteChangeSet so that we can optionally disable rollback when executing a changeset through a pipeline." +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e0f0aae4..6ce2f9ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@typescript-eslint/typescript-estree": "^4.17.0", "adm-zip": "^0.5.3", - "aws-sdk": "^2.916.0", + "aws-sdk": "^2.979.0", "azure-pipelines-task-lib": "^3.3.1", "base-64": "^0.1.0", "https-proxy-agent": "^5.0.0", @@ -582,31 +582,6 @@ "node": ">=0.1.90" } }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -1526,38 +1501,6 @@ "node": ">= 6" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true, - "optional": true, - "peer": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/@types/adm-zip": { "version": "0.4.33", "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.33.tgz", @@ -2291,9 +2234,9 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "node_modules/aws-sdk": { - "version": "2.916.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.916.0.tgz", - "integrity": "sha512-/k9Jh1KGFODLOfBeoT0BDs4BmV1+Y39kDWIygQ0eWIkE98WO7aWLxOZuRku9vEx6IhpEkhzxsi/j2EXc6sgoZg==", + "version": "2.956.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.956.0.tgz", + "integrity": "sha512-vSzL66tjeRSBPnLR2Pkx4qS7SPqADT7K9QBjWdMhVd9BF5spyMvJ9hReIEShILp3hq99sHI+MvO+uTUm5s023g==", "hasInstallScript": true, "dependencies": { "buffer": "4.9.2", @@ -2970,14 +2913,6 @@ "ieee754": "^1.1.4" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3790,7 +3725,6 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, - "license": "MIT", "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -5992,7 +5926,6 @@ "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-13.0.0.tgz", "integrity": "sha512-JSHR+Dhb32FGJaiKkqsB7AR3OqWKtldLd6ZH2+FJ8D4tsweb8Id8zEVReU4+OlrRO1ZluqJLQEETm+Q6/KilBg==", "dev": true, - "license": "Apache-2.0", "dependencies": { "mkdirp": "^1.0.4", "strip-ansi": "^6.0.1", @@ -8206,6 +8139,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", "engines": { "node": ">=0.4.x" } @@ -9706,14 +9640,6 @@ "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", - "dev": true, - "optional": true, - "peer": true - }, "node_modules/v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -9752,7 +9678,6 @@ "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", "dev": true, - "license": "MIT", "engines": { "node": ">= 0.10" } @@ -9761,6 +9686,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", "dev": true, "dependencies": { "browser-process-hrtime": "^1.0.0" @@ -10503,25 +10429,6 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "optional": true, - "peer": true - }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" - } - }, "@eslint/eslintrc": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", @@ -11210,38 +11117,6 @@ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true, - "optional": true, - "peer": true - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true, - "optional": true, - "peer": true - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true, - "optional": true, - "peer": true - }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true, - "optional": true, - "peer": true - }, "@types/adm-zip": { "version": "0.4.33", "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.33.tgz", @@ -11800,9 +11675,9 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "aws-sdk": { - "version": "2.916.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.916.0.tgz", - "integrity": "sha512-/k9Jh1KGFODLOfBeoT0BDs4BmV1+Y39kDWIygQ0eWIkE98WO7aWLxOZuRku9vEx6IhpEkhzxsi/j2EXc6sgoZg==", + "version": "2.956.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.956.0.tgz", + "integrity": "sha512-vSzL66tjeRSBPnLR2Pkx4qS7SPqADT7K9QBjWdMhVd9BF5spyMvJ9hReIEShILp3hq99sHI+MvO+uTUm5s023g==", "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -12361,14 +12236,6 @@ } } }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true, - "peer": true - }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -17315,14 +17182,6 @@ "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", "dev": true }, - "v8-compile-cache-lib": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", - "dev": true, - "optional": true, - "peer": true - }, "v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", diff --git a/package.json b/package.json index 73daba95..33da28fc 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "dependencies": { "@typescript-eslint/typescript-estree": "^4.17.0", "adm-zip": "^0.5.3", - "aws-sdk": "^2.916.0", + "aws-sdk": "^2.956.0", "azure-pipelines-task-lib": "^3.3.1", "base-64": "^0.1.0", "https-proxy-agent": "^5.0.0", diff --git a/src/tasks/CloudFormationExecuteChangeSet/TaskOperations.ts b/src/tasks/CloudFormationExecuteChangeSet/TaskOperations.ts index 7065b87d..e4640cd9 100644 --- a/src/tasks/CloudFormationExecuteChangeSet/TaskOperations.ts +++ b/src/tasks/CloudFormationExecuteChangeSet/TaskOperations.ts @@ -23,7 +23,8 @@ export class TaskOperations { public async execute(): Promise { const changeSet = await this.verifyResourcesExist( this.taskParameters.changeSetName, - this.taskParameters.stackName + this.taskParameters.stackName, + this.taskParameters.disableRollback ) let waitForUpdate = false const stackId = changeSet.StackId || '' @@ -51,12 +52,13 @@ export class TaskOperations { } } else { console.log( - tl.loc('ExecutingChangeSet', this.taskParameters.changeSetName, this.taskParameters.stackName) + tl.loc('ExecutingChangeSet', this.taskParameters.changeSetName, this.taskParameters.stackName, this.taskParameters.disableRollback) ) await this.cloudFormationClient .executeChangeSet({ ChangeSetName: this.taskParameters.changeSetName, - StackName: this.taskParameters.stackName + StackName: this.taskParameters.stackName, + DisableRollback: this.taskParameters.disableRollback }) .promise() @@ -90,7 +92,8 @@ export class TaskOperations { private async verifyResourcesExist( changeSetName: string, - stackName: string + stackName: string, + disableRollback: boolean ): Promise { try { const request: CloudFormation.DescribeChangeSetInput = { @@ -99,6 +102,9 @@ export class TaskOperations { if (stackName) { request.StackName = stackName } + if (disableRollback) { + request.DisableRollback = disableRollback + } return await this.cloudFormationClient.describeChangeSet(request).promise() } catch (err) { diff --git a/src/tasks/CloudFormationExecuteChangeSet/TaskParameters.ts b/src/tasks/CloudFormationExecuteChangeSet/TaskParameters.ts index a9d80747..80718f63 100644 --- a/src/tasks/CloudFormationExecuteChangeSet/TaskParameters.ts +++ b/src/tasks/CloudFormationExecuteChangeSet/TaskParameters.ts @@ -20,6 +20,7 @@ export interface TaskParameters { outputVariable: string captureStackOutputs: string captureAsSecuredVars: boolean + disableRollback: boolean } export function buildTaskParameters(): TaskParameters { @@ -31,7 +32,8 @@ export function buildTaskParameters(): TaskParameters { deleteEmptyChangeSet: getBoolInput('deleteEmptyChangeSet', false), outputVariable: getInputOrEmpty('outputVariable'), captureStackOutputs: getInputOrEmpty('captureStackOutputs'), - captureAsSecuredVars: getBoolInput('captureAsSecuredVars', false) + captureAsSecuredVars: getBoolInput('captureAsSecuredVars', false), + disableRollback: getBoolInput('disableRollback', false) } return parameters diff --git a/tests/taskTests/cloudFormationExecuteChangeSet/cloudFormationExecuteChangeSet-test.ts b/tests/taskTests/cloudFormationExecuteChangeSet/cloudFormationExecuteChangeSet-test.ts index 2ae6e051..a959372b 100644 --- a/tests/taskTests/cloudFormationExecuteChangeSet/cloudFormationExecuteChangeSet-test.ts +++ b/tests/taskTests/cloudFormationExecuteChangeSet/cloudFormationExecuteChangeSet-test.ts @@ -19,7 +19,8 @@ const defaultTaskParameters: TaskParameters = { deleteEmptyChangeSet: false, outputVariable: '', captureStackOutputs: '', - captureAsSecuredVars: false + captureAsSecuredVars: false, + disableRollback: true } const changeSetNotFound = {