1 | # condensation
|
2 |
|
3 | Package, reuse and share particles for CloudFormation projects
|
4 |
|
5 | [![NPM](https://nodei.co/npm/condensation.png)](https://nodei.co/npm/condensation/)
|
6 |
|
7 | [![Build Status](https://travis-ci.org/SungardAS/condensation.svg?branch=master)](https://travis-ci.org/SungardAS/condensation?branch=master)
|
8 | [![Code Climate](https://codeclimate.com/github/SungardAS/condensation/badges/gpa.svg?branch=master)](https://codeclimate.com/github/SungardAS/condensation?branch=master)
|
9 | [![Coverage Status](https://coveralls.io/repos/SungardAS/condensation/badge.svg?branch=master)](https://coveralls.io/r/SungardAS/condensation?branch=master)
|
10 | [![Dependency Status](https://david-dm.org/SungardAS/condensation.svg?branch=master)](https://david-dm.org/SungardAS/condensation?branch=master)
|
11 |
|
12 |
|
13 | ## Summary
|
14 |
|
15 | Condensation is a [gulp](http://gulpjs.com) task generator that helps
|
16 | compile, package and upload [AWS CloudFormation](http://aws.amazon.com/cloudformation/)
|
17 | templates and supporting assets.
|
18 |
|
19 | Any file with the extension `.hbs` will be compiled with
|
20 | [Handlebars.js](http://http://handlebarsjs.com/) to support
|
21 | partials, helpers and variable replacement.
|
22 |
|
23 | ## Features
|
24 |
|
25 | * Write reusable CloudFormation snippits that can be included as
|
26 | partials
|
27 | * Package and upload templates and assets to multiple buckets across
|
28 | regions with one command.
|
29 | * References other templates within a distribution with
|
30 | [AWS::CloudFormation::Stack](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html)
|
31 | and the `templateS3Url` helper
|
32 | * Upload scripts, configuration files and other assets alongside
|
33 | CloudFormation templates.
|
34 | * Use particles from other condensation compatible projects.
|
35 |
|
36 | ## Why?
|
37 |
|
38 | CloudFormation templates are great for creating, updating and deleting
|
39 | AWS resources. Reusing parts of templates, referencing other
|
40 | templates with `AWS::CloudFormation::Stack` and deploying cloud-init
|
41 | scripts can be difficult to manage.
|
42 |
|
43 | * Often sections such as AMI [mappings](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html)
|
44 | are re-used by many templates. Handlebars partials provide a way to
|
45 | write the mapping once and reuse it without copying from template to
|
46 | template.
|
47 | * It is common to set up resources, such as a VPC, with nearly
|
48 | identical attributes and structure for different applications and
|
49 | services. Condensation allows that definition to become a independent
|
50 | stack that can be referenced by other templates that are part of the
|
51 | same package.
|
52 | * To bootstrap instances it is beneficial to have scripts and configuration
|
53 | files deployed in a known location and verisoned with the template
|
54 | they are associated with.
|
55 | * When using `AWS::CloudFormation::Authentication` to download assets from
|
56 | S3 buckets all resources must be in the same region. Condensation
|
57 | makes it easy to deploy the same templates and assets to multiple
|
58 | regions and ensure the referencing URLs are correct.
|
59 |
|
60 | Stacks (templates) can be deployed to a bucket
|
61 | where each stack is able to reference one another. That pattern can
|
62 | repeated using difference confgurations for the same templates
|
63 | to support development, production and multi-region buckets.
|
64 |
|
65 | Example:
|
66 |
|
67 | "TemplateURL": "{{{templateS3Url 'vpc.template' }}}"
|
68 | ...
|
69 | "TemplateURL": "{{{templateS3Url 'subnet.template' }}}"
|
70 |
|
71 | Output:
|
72 |
|
73 | "TemplateURL": "https://s3-us-west-1.amazonaws.com/<BUCKET>/cftemplates/vpc.template"
|
74 | ...
|
75 | "TemplateURL": "https://s3-us-west-1.amazonaws.com/<BUCKET>/cftemplates/subnet.template"
|
76 |
|
77 | With the help of Handlebars the URL will always reference a template deployed within the same
|
78 | bucket.
|
79 |
|
80 |
|
81 | ## Use
|
82 |
|
83 | Quick Start Examples: [condensation-examples](https://github.com/SungardAS/condensation-examples)
|
84 |
|
85 | ### Create a project
|
86 |
|
87 | > npm init
|
88 |
|
89 | ### Recommended .gitignore
|
90 |
|
91 | condensation_errors
|
92 | config/local.js
|
93 | dist
|
94 | node_modules
|
95 |
|
96 | #### Install [gulp](http://gulpjs.com/)
|
97 |
|
98 | > npm install -g gulp
|
99 |
|
100 | #### Install condensation
|
101 |
|
102 | > npm install condensation --save
|
103 |
|
104 | #### Add condensation to gulpfile.js
|
105 |
|
106 | var gulp = require('gulp');
|
107 |
|
108 | var config = {
|
109 | s3: [
|
110 | {
|
111 | aws: {
|
112 | region: 'us-east-1',
|
113 | bucket: 'MY-FAVORITE-BUCKET',
|
114 | },
|
115 | validate: true,
|
116 | create: true
|
117 | }
|
118 | ],
|
119 | dist: 'dist'
|
120 | };
|
121 |
|
122 | // Add necessary gulp tasks to build, compile and validate
|
123 | // CloudFormation templates
|
124 | require('condensation').buildTasks(gulp,config);
|
125 |
|
126 | ### Project Structure
|
127 |
|
128 | my-project
|
129 | |
|
130 | -- guplfile.js
|
131 | |
|
132 | -- README.md
|
133 | |
|
134 | --particles
|
135 | |
|
136 | --assets
|
137 | |
|
138 | -- cftemplates
|
139 | |
|
140 | -- helpers
|
141 | |
|
142 | -- partials
|
143 |
|
144 | Condensation loads particles through core helper methods.
|
145 | The core helper methods are able to load particles from the local project
|
146 | as well as any condensation compatible project added as a npm
|
147 | dependency.
|
148 |
|
149 | All helpers follow the same pattern:
|
150 |
|
151 | {{{<CONDENSATION-HELPER> [module:<MODULE>] '<PATH_TO_PARTICLE>' [OPTIONS...]}}}
|
152 |
|
153 |
|
154 | #### Lazy Loading
|
155 |
|
156 | Particles will only be included in the final distribution if they are
|
157 | referenced from a `hbs` file.
|
158 |
|
159 |
|
160 | #### assets
|
161 |
|
162 | Files to be uploaded to S3 that are used to supplement CloudFormation
|
163 | templates. Files can include boostrap scripts, packaged install files
|
164 | or configuration files.
|
165 |
|
166 | Any file with a `.hbs` extension will be
|
167 | compiled with handlebars and saved to S3 without the `.hbs` extension.
|
168 |
|
169 | Asset URLs can be built with the `assetS3Url` helper:
|
170 |
|
171 | {{{assetS3Url 'my-asset'}}}
|
172 |
|
173 | {{{assetS3Url 'module:<MODULE>' 'module-asset'}}}
|
174 |
|
175 | The particle path should match the name of the asset without the `.hbs` extension, if it exists.
|
176 |
|
177 | Example Output:
|
178 |
|
179 | "https://s3-us-west-1.amazonaws.com/BUCKET/assets/my-asset"
|
180 |
|
181 | "https://s3-us-west-1.amazonaws.com/BUCKET/node_modules/MODULE/particles/assets/module-asset"
|
182 |
|
183 | To include assets that are not directly referenced from a template
|
184 | use the `requireAssets` helper. It will ensure a glob of assets are
|
185 | included in the distribution.
|
186 |
|
187 | {{{requireAssets '/**'}}
|
188 |
|
189 | {{{requireAssets 'module:<MODULE>' '/**'}}}
|
190 |
|
191 | #### cftemplates
|
192 |
|
193 | CloudFormation templates that will be uploaded to S3.
|
194 |
|
195 | Any file with a `.hbs` extension will be compiled with
|
196 | handlebars and saved to S3 without the `.hbs` extension.
|
197 |
|
198 | Template URLs can be built with the `assetS3Url` helper:
|
199 |
|
200 | {{{templateS3Url 'my.template'}}}
|
201 |
|
202 | {{{templateS3Url 'module:<MODULE>' 'module.template'}}}
|
203 |
|
204 | The particle path should match the name of the template without the `.hbs` extension, if it exists.
|
205 |
|
206 | Example Output:
|
207 |
|
208 | "https://s3-us-west-1.amazonaws.com/BUCKET/cftemplates/my.template"
|
209 |
|
210 | "https://s3-us-west-1.amazonaws.com/BUCKET/node_modules/MODULE/particles/cftemplates/module.template"
|
211 |
|
212 | #### partials
|
213 |
|
214 | Contents of files here will be loaded as partials that can be used in
|
215 | `assets` and `cftemplates`.
|
216 |
|
217 | These files will not be packaged or uploaded to S3.
|
218 |
|
219 | Partials can be loaded with the `partial` helper:
|
220 |
|
221 | {{{partial 'my-partial'}}}
|
222 |
|
223 | {{{partial 'module:<MODULE>' 'module-partial'}}}
|
224 |
|
225 | The particle path only needs to match the base name of the partial.
|
226 |
|
227 | A path of `some_partial` would match `some_partial.json` or `some_partial.json.hbs`.
|
228 |
|
229 | If the desired partial is not being loaded ensure precedence is given to an exact match.
|
230 |
|
231 | #### helpers
|
232 |
|
233 | Node modules that export a function that is built as a
|
234 | Handlebars [block helper](http://handlebarsjs.com/block_helpers.html).
|
235 |
|
236 | Helpers are called with the `helper` helper:
|
237 |
|
238 | {{{helper 'my-helper'}}}
|
239 |
|
240 | {{{helper 'module:<MODULE>' 'module-helper'}}}
|
241 |
|
242 | The particle path should match the name of the helper without the `.js` extension.
|
243 |
|
244 | ### Tasks
|
245 |
|
246 | Get a full list of tasks by running `gulp -T`
|
247 |
|
248 | By default all tasks are prefixed with `condensation:`. This can be
|
249 | changed with the `taskPrefix` config option.
|
250 |
|
251 | #### Default
|
252 |
|
253 | The `default` task is an alias for `build`. It will prepare all files
|
254 | for deployment to s3. Templates and assets are written to the configured
|
255 | `dist` directory.
|
256 |
|
257 | > gulp condensation:default
|
258 |
|
259 |
|
260 | #### condensation:s3:list
|
261 | Will list all the configured s3 bukets and module corresponding ID.
|
262 |
|
263 | > gulp condensation:s3:list
|
264 | [10:21:47] Using gulpfile ~/condensation-example/gulpfile.js
|
265 | [10:21:47] Starting 'condensation:s3:list'...
|
266 | 0: a.bucket.in.us-east-1
|
267 | 1: a.bucket.in.us-west-2
|
268 | [10:21:47] Finished 'condensation:s3:list' after 153 μs
|
269 |
|
270 | The IDs can be used to deploy to a single bucket instead of all buckets.
|
271 |
|
272 | #### condensation:deploy
|
273 | For the `deploy` task to run AWS credentials must be set as environment
|
274 | variables: `AWS_SECRET_ACCESS_KEY` and `AWS_ACCESS_KEY_ID`
|
275 |
|
276 | > AWS_SECRET_ACCESS_KEY=XXXX AWS_ACCESS_KEY_ID=XXXX gulp deploy
|
277 |
|
278 | This will upload templates to all cofigured S3 buckets.
|
279 |
|
280 | #### condensation:deploy:ID
|
281 | Deploy tempates to a specific S3 bucket.
|
282 |
|
283 | #### condensation:deploy:LABEL
|
284 | Deploy tempates to all S3 buckets that contain the label, LABEL.
|
285 |
|
286 | ## Config Options
|
287 |
|
288 | var config = {
|
289 | // Array of S3 buckets to deploy to
|
290 | s3: [
|
291 | {
|
292 | // AWS specific options
|
293 | aws: {
|
294 | region: 'us-east-1',
|
295 | bucket: 'my.bucket.in.us-east-1',
|
296 | },
|
297 |
|
298 | // Run CloudFormation validation during the build task for this bucket
|
299 | validate: true,
|
300 |
|
301 | // Create this bucket if it does not already exist
|
302 | create: true
|
303 |
|
304 | // Prefix all objects (allows for multiple deploymets to the same bucket
|
305 | prefix: '',
|
306 |
|
307 | labels: ['east']
|
308 | },
|
309 | ],
|
310 | // The prefix to add to all generated gulp tasks (default: 'condensation')
|
311 | // An empty string will remove the prefix
|
312 | // - condensation:deploy will become deploy
|
313 | taskPrefix: '',
|
314 |
|
315 | // Directory that contains the `particles` directory.
|
316 | // Used for test scripts, should not be changed if sharing templates
|
317 | root: './',
|
318 |
|
319 | // Where the build task will put the distribution
|
320 | dist: 'dist'
|
321 | };
|
322 |
|
323 | ## Front Matter
|
324 |
|
325 | All `cftemplates` and `partials` are first processed with
|
326 | [gray-matter](https://github.com/jonschlinkert/gray-matter) to load any
|
327 | default data definitions.
|
328 |
|
329 | ## Errors
|
330 |
|
331 | Errors due to badly formed JSON or failed CF validations will stop the
|
332 | process and the offendng files will be dumped to `condensation_error`
|
333 |
|
334 |
|