This package implements the following pattern of stack creation and deletion in order to run either the creation of a new stack or the replacement of an existing stack:
- Request stack creation.
- Wait on the stack status to show show success.
- Update existing resources to point to the new stack.
- Delete any previous instances of the stack once the switchover is done.
This is well suited to, for example, the deployment an Auto Scaling Group for webservers that attaches to an existing Elastic Load Balancer. In this way updates can be seamless: the new servers are added, the old removed, without any interruption of traffic.
In general it is a good idea to keep long-lasting resources such as an Elastic Load Balancer or Route 53 DNS entry in their own stack, separate from those resources that will be frequently updated. References to the long-lasting resources can be passed into the deployed stack via parameters, or connections can be made via a function passed in to the stack deployment process.
Generate or load the CloudFormation template. This module can accept the template as either a JSON string, an object, or a URL to a template uploaded to S3. Use the latter method for larger templates, as it has a larger maximum size limit.
Run the following code.
cloudFormationDeploy = require('cloudformation-deploy');
// Pull in the CloudFormation template from a JSON file or object.
//var template = fs.readFileSync('example.json', { encoding: 'utf8' });
//var template = { ... };
// Or specify a URL.
var template = 'http://s3.amazonaws.com/bucket/example.json';
var config = {
// --------------------
// Required properties.
// --------------------
// The baseName and deployId are combined to form a unique name.
//
// Tags are automatically added based on these values and the version, and are
// used when deleting old stacks from earlier versions and prior deployments.
//
// The deployId property is along the lines of BUILD_NUMBER in Jenkins or
// a similar values generated by another task framework. Using a Unix
// timestamp is an acceptable fallback if nothing else is available.
baseName: 'example-stack',
deployId: '15',
version: '0.1.0',
// --------------------
// Optional properties.
// --------------------
// If defined, this property is passed to the AWS SDK client. It is not
// recommended to use this approach, see above for comments on configuring
// AWS access via the environment.
// clientOptions: {
// accessKeyId: 'akid',
// secretAccessKey: 'secret',
// region: 'us-east-1'
// },
// Needed for stacks that affect permissions, which is most application stacks
// these days.
// See: http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html
capabilities: [
cloudFormationDeploy.capabilities.CAPABILITY_IAM,
cloudFormationDeploy.capabilities.CAPABILITY_NAMED_IAM
],
// Timeout in minutes for the process of stack creation.
createStackTimeoutInMinutes: 10,
// Specify additional tags to apply to the stack.
tags: {
name: 'value'
},
// Pass in any parameters required by the template.
parameters: {
name: 'value'
},
// Seconds to wait between each check on the progress of stack creation or
// deletion.
progressCheckIntervalInSeconds: 10,
// A function invoked whenever a CloudFormation event is created during
// stack creation or deletion.
onEventFn: function (event) {
console.log(event);
},
// A function invoked after the CloudFormation stack is successfully created
// but before any prior stack is deleted. This allows for a clean switchover
// of resources to use the new stack.
//
// The provided stackDescription object is the standard output from the
// describeStacks API for the created stack.
postCreationFn: function (stackDescription, callback) {
// Take action here, such as updating a Route 53 DNS entry and waiting for
// propagation to complete.
callback();
},
// What to do with prior instances of this stack, which is defined as any
// stack deployed with the same baseName.
priorInstance: cloudFormationDeploy.priorInstance.DELETE,
// What to do with this deployed stack should it fail to complete
// successfully.
onDeployFailure: cloudFormationDeploy.onDeployFailure.DELETE
};
cloudFormationDeploy.deploy(config, template, function (error, results) {
if (error) {
console.error(error);
}
// Whether or not there is an error, the results object is returned. It will
// usually have additional useful information on why the stack deployment
// failed. On success it will include the stack description, outputs
// defined in the CloudFormation template, and events.
console.log(results);
});
The config
object passed to cloudFormationDeploy.deploy
supports the
following required and optional properties.
baseName
- string
- Combined with deployId
to generat the stack name.
version
- string
- The version of the application deployed to the stack.
deployId
- string
- A distinguishing string for this stack baseName, such as
a build number, to ensure this stack name is unique even for multiple
deployments of the same version.
createStackTimeoutInMinutes
- number
- A timeout in minutes for stack
creation or deletion. Defaults to 10
.
tags
- object
- The tags to apply to the stack in addition to those created
automatically based on the baseName
. Tag values must be strings.
parameters
- object
- Values to apply to the parameters in the
CloudFormation template. Parameter values must be strings.
progressCheckIntervalInSeconds
- number
- Number of seconds to wait between each
check on the progress of stack creation or deletion. Defaults to 10
.
onEventFn
- function
- A function invoked whenever a new event is
created during stack creation or deletion.
function (event) {
console.log(event);
}
postCreationFunction
- function
- A function invoked after a stack is
successfully created but before any prior instance of the stack with the same
baseName
is destroyed. This allows resources to be updated to use the new
stack.
function (stackDescription, callback) {
// Take action here, such as updating a Route 53 DNS entry and waiting for
// propagation to complete.
callback();
}
priorInstance
- string
- One of the allowed values describing what to do
with previously deployed stacks with the same baseName
. Defaults to
cloudFormationDeploy.priorInstance.DELETE
and the allowed values are:
cloudFormationDeploy.priorInstance.DELETE
cloudFormationDeploy.priorInstance.DO_NOTHING
onDeployFailure
- string
- One of the allowed values describing what to do with
the deployed stack on failure. Defaults to
cloudFormationDeploy.onDeployFailure.DELETE
and the allowed values are:
cloudFormationDeploy.onDeployFailure.DELETE
cloudFormationDeploy.onDeployFailure.DO_NOTHING
All failure cases will result in cloudFormationDeploy.deploy
calling back with
an error. The state of the stacks depends on where in the process that error
occurred, however.
- If the stack creation fails, then:
- The
postCreationFn
function is not invoked. - The failed stack is deleted if
priorInstance
iscloudFormationDeploy.onDeployFailure.DELETE
. - Any prior stacks are left untouched.
- If the stack creation succeeds, but subsequent calls to obtain the stack details fail, then:
- The
postCreationFn
function is not invoked. - The newly created stack is not deleted.
- Any prior stacks are left untouched.
- If the
postCreationFn
calls back with an error due to failure, then:
- The newly created stack is not deleted.
- Any prior stacks are left untouched.
- If the deletion of prior stacks fails, then:
- The newly created stack is not deleted.
- Any prior stacks are left in whatever state the deletion failure leaves them in.