1 | # condensation
|
2 |
|
3 | Package, reuse and share particles for CloudFormation projects
|
4 |
|
5 | ![condensation][condensation-image]
|
6 |
|
7 | [![NPM][npm-image]][npm-url]
|
8 | [![Gitter][gitter-image]][gitter-url]
|
9 | [![Build Status][travis-image]][travis-url]
|
10 | [![Code Climate][codeclimate-image]][codeclimate-url]
|
11 | [![Coverage Status][coveralls-image]][coveralls-url]
|
12 | [![Dependency Status][daviddm-image]][daviddm-url]
|
13 |
|
14 |
|
15 | ## Summary
|
16 |
|
17 | Condensation uses [gulp](http://gulpjs.com) to generate tasks that
|
18 | compile, package and upload [AWS CloudFormation](http://aws.amazon.com/cloudformation/)
|
19 | templates and supporting assets as distributions.
|
20 |
|
21 | Any file with the extension `.hbs` will be compiled with
|
22 | [Handlebars.js](http://handlebarsjs.com/) to support
|
23 | partials, helpers and variable replacement.
|
24 |
|
25 | ## Quick Start
|
26 |
|
27 | ### With Docker
|
28 |
|
29 | The fastest way to get started with condensation: [condensation-docker][condensation-docker-url]
|
30 |
|
31 | ```
|
32 | $ alias condensation="docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN -v \"$HOME\"/.aws/credentials:/home/condensation/.aws/credentials -v \`pwd\`:/particles --rm -it sungardas/condensation"
|
33 |
|
34 |
|
35 | $ condensation create project particles-MYPROJECT
|
36 | $ cd particles-MYPROJECT
|
37 | $ condensation run build
|
38 | ```
|
39 |
|
40 | ### With a nodejs environment
|
41 |
|
42 | Use the Yeoman
|
43 | [generator](https://github.com/SungardAS/generator-condensation).
|
44 |
|
45 | ```
|
46 | $ npm install -g yo
|
47 | $ npm install -g generator-condensation
|
48 | $ yo condensation:project particles-MYPROJECT
|
49 | $ cd particles-MYPROJECT
|
50 | $ npm run build
|
51 | ```
|
52 |
|
53 | ### Example Projects
|
54 |
|
55 | * [condensation-examples](https://github.com/SungardAS/condensation-examples)
|
56 | * [particles-vpc](https://github.com/SungardAS/particles-vpc)
|
57 | * [particles-cloudsploit-scans](https://github.com/SungardAS/particles-cloudsploit-scans)
|
58 | * [particles-enhanced-snapshots](https://github.com/SungardAS/particles-enhanced-snapshots)
|
59 |
|
60 | Check out the growing list of particles on
|
61 | [npm](https://www.npmjs.com/browse/keyword/condensation-particles)!
|
62 |
|
63 |
|
64 | ## Features
|
65 |
|
66 | * Write reusable CloudFormation snippets, called `particles` that can be used
|
67 | accross condensation projets
|
68 | * Package templates and assets then upload full distributions to multiple buckets across
|
69 | regions with one command.
|
70 | * Reference another template within the distribution with
|
71 | [AWS::CloudFormation::Stack](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-stack.html)
|
72 | and the `templateS3Url` helper
|
73 | * Upload scripts, configuration files and other assets alongside
|
74 | CloudFormation templates and reference them with asset helpers.
|
75 |
|
76 | ## Why?
|
77 |
|
78 | CloudFormation templates are great for creating, updating and deleting
|
79 | AWS resources. Reusing parts of templates, referencing other
|
80 | templates with `AWS::CloudFormation::Stack` and deploying cloud-init
|
81 | scripts can be difficult to manage.
|
82 |
|
83 | * Sections such as AMI [mappings](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html)
|
84 | are often re-used by many templates. Particles provide a way to
|
85 | write the mapping once and reuse it in other templates by reference.
|
86 | * It is common to set up resources, such as a VPC, with nearly
|
87 | identical attributes and structure for different applications and
|
88 | services. Condensation allows that definition to become a independent
|
89 | stack that can be referenced by other templates that are part of the
|
90 | same distribution.
|
91 | * When bootstrapping ec2 instances it is beneficial to have versioned scripts and configuration
|
92 | files deployed in the same bucket and path as the CloudFormation template
|
93 | they are associated with.
|
94 | * When using `AWS::CloudFormation::Authentication` to download assets from
|
95 | S3 buckets all resources must be in the same region. Condensation
|
96 | makes it easy to deploy the same templates and assets to multiple
|
97 | regions and ensure the referencing URLs are always pointing to the
|
98 | right place.
|
99 |
|
100 | For example, templates in a distribution can reference one another based on the
|
101 | bucket they are deployed to.
|
102 |
|
103 | Example:
|
104 |
|
105 | "TemplateURL": "{{templateS3Url 'vpc.template' }}"
|
106 | ...
|
107 | "TemplateURL": "{{templateS3Url 'subnet.template' }}"
|
108 |
|
109 | Output:
|
110 |
|
111 | "TemplateURL": "https://s3-us-west-1.amazonaws.com/<BUCKET>/cftemplates/vpc.template"
|
112 | ...
|
113 | "TemplateURL": "https://s3-us-west-1.amazonaws.com/<BUCKET>/cftemplates/subnet.template"
|
114 |
|
115 | The Handlebars helper, `templateS3Url`, creates a URL that will always reference a template deployed within the same bucket.
|
116 |
|
117 |
|
118 |
|
119 | ## Use
|
120 |
|
121 | ### Project Structure
|
122 |
|
123 | particles-my-project
|
124 | |
|
125 | -- guplfile.js
|
126 | |
|
127 | -- README.md
|
128 | |
|
129 | -- CHANGELOG.md
|
130 | |
|
131 | --particles
|
132 | |
|
133 | -- assets
|
134 | |
|
135 | -- conditions
|
136 | |
|
137 | -- cftemplates
|
138 | |
|
139 | -- helpers
|
140 | |
|
141 | -- mappings
|
142 | |
|
143 | -- metadata
|
144 | |
|
145 | -- outputs
|
146 | |
|
147 | -- parameters
|
148 | |
|
149 | -- resources
|
150 | |
|
151 | -- sets
|
152 | |
|
153 | -- partials
|
154 |
|
155 | Condensation builds templates with Handlebars helpers that
|
156 | are able to load particles from the local project
|
157 | or from any condensation compatible module added as a npm
|
158 | dependency.
|
159 |
|
160 | All helpers follow the same pattern:
|
161 |
|
162 | {{<CONDENSATION-HELPER> [module:<MODULE>] '<PATH_TO_PARTICLE>' [OPTIONS...]}}
|
163 |
|
164 | When including the particles from another project *MODULE* is the name
|
165 | of the npm dependency.
|
166 |
|
167 | **New in 0.5.0**
|
168 |
|
169 | Use `m` instead of `module` if referencing a module that
|
170 | starts with `particles-` to minimize characters used. The `m` option
|
171 | will add `particles-` to the beginning of \<MODULE\> for you.
|
172 |
|
173 | {{<CONDENSATION-HELPER> [m:<MODULE>] '<PATH_TO_PARTICLE>' [OPTIONS...]}}
|
174 |
|
175 | Example, load a particle from `particles-core`
|
176 |
|
177 | {{parameter "m:core" "base" logicalId="Parameter1"}}
|
178 |
|
179 | #### Lazy Loading
|
180 |
|
181 | Particles will only be included in the final distribution if they are
|
182 | referenced in a `hbs` file.
|
183 |
|
184 | ### layout support
|
185 |
|
186 | **New in 0.3.0**
|
187 |
|
188 | Instead of including particles within a traditional CloudFormation
|
189 | template the introduction of a layout supports capturing helper output
|
190 | and adding it to the correct section. Helpers within a layout do not
|
191 | have to to be in any specific order.
|
192 |
|
193 | ---
|
194 | things:
|
195 | -
|
196 | name: subnet1
|
197 | cidr: "10.0.0.0/24"
|
198 | -
|
199 | name subnet2
|
200 | cidr: "10.0.1.0/24"
|
201 | ---
|
202 |
|
203 | {{#layout templateDescription="condensation rocks!"}}
|
204 | {{parameter 'my_parameter' logicalId="MyParameter"}}
|
205 | {{condition 'my_condition' logicalId="MyCondition"}}
|
206 |
|
207 | {{! helpers can occur in any order, allowing you to group related section parts together }}
|
208 |
|
209 | {{#each things}}
|
210 | {{parameter 'repeate_me' logicalId="RepeateMe" logicalIdSuffix=@index}}
|
211 | {{condition 'repeate_me' logicalId="RepeateMeCond" logicalIdSuffix=@index}}
|
212 | {{resource 'repeate_me' logicalId="RepeateMeResource" logicalIdSuffix=@index}}
|
213 | {{output 'repeate_me' logicalId="RepeateMeOutput" logicalIdSuffix=@index}}
|
214 | {{/each}}
|
215 | {{/layout}}
|
216 |
|
217 |
|
218 | #### assets
|
219 |
|
220 | Files to be uploaded to S3 that are used to supplement CloudFormation
|
221 | templates. Files can include bootsrap scripts, packaged install files
|
222 | or configuration files.
|
223 |
|
224 | Any file with a `.hbs` extension will be
|
225 | compiled with handlebars and saved to S3. The `.hbs` extension will be
|
226 | removed from the filename.
|
227 |
|
228 | Asset URLs can be built with the `assetS3Url` helper:
|
229 |
|
230 | {{assetS3Url 'my-asset' [protocol=https|s3]}}
|
231 |
|
232 | {{assetS3Url 'module:<MODULE>' 'module-asset' [protocol=https|s3]}}
|
233 |
|
234 |
|
235 | Parameters:
|
236 |
|
237 | **protocol** *optional* https|s3 - Forces the protocol of the url to https:// or s3://
|
238 |
|
239 | Example Output:
|
240 |
|
241 | "https://s3-us-west-1.amazonaws.com/BUCKET/assets/my-asset"
|
242 |
|
243 | "https://s3-us-west-1.amazonaws.com/BUCKET/node_modules/MODULE/particles/assets/module-asset"
|
244 |
|
245 | Asset paths (the full key path as it will be in the s3 bucket) can be built with the `assetPath` helper:
|
246 |
|
247 | {{assetPath 'my-asset'}}
|
248 |
|
249 | {{assetPath 'module:<MODULE>' 'module-asset' }}
|
250 |
|
251 | Example Output:
|
252 |
|
253 | "/assets/my-asset"
|
254 |
|
255 | "/node_modules/MODULE/particles/assets/module-asset"
|
256 |
|
257 | For both assetS3Url and assetPath the particle path will match the name of the asset without the `.hbs` extension, if it exists.
|
258 |
|
259 | To include assets that are not directly referenced from a template
|
260 | use the `requireAssets` helper. It will ensure a glob of assets are
|
261 | included in the distribution.
|
262 |
|
263 | {{requireAssets '/**'}}
|
264 |
|
265 | {{requireAssets 'module:<MODULE>' '/**'}}
|
266 |
|
267 | `requireAssets` will not produce output, only ensure that the glob is
|
268 | uploaded to S3.
|
269 |
|
270 | #### conditions
|
271 |
|
272 | Contents of files will be loaded as conditions that can be used in
|
273 | in a traditional template or a `layout` (**recommended**)
|
274 |
|
275 | Directory: `conditions`
|
276 | Helper: `condition`
|
277 |
|
278 | {{condition 'my-condition' logicalId="MyCond"}}
|
279 |
|
280 | {{condition 'module:<MODULE>' 'condition-name' logicalId="TheirCond"}}
|
281 |
|
282 | The particle path can match the base name of the file or the base name
|
283 | plus any extensions.
|
284 |
|
285 |
|
286 | #### cftemplates
|
287 |
|
288 | CloudFormation templates that will be uploaded to S3.
|
289 |
|
290 | Any file with a `.hbs` extension will be compiled with
|
291 | handlebars and saved to S3 without the `.hbs` extension.
|
292 |
|
293 | Template URLs can be built with the `assetS3Url` helper:
|
294 |
|
295 | {{templateS3Url 'my.template'}}
|
296 |
|
297 | {{templateS3Url 'module:<MODULE>' 'module.template'}}
|
298 |
|
299 | The particle path should match the name of the template without the `.hbs` extension, if it exists.
|
300 |
|
301 | Example Output:
|
302 |
|
303 | "https://s3-us-west-1.amazonaws.com/BUCKET/cftemplates/my.template"
|
304 |
|
305 | "https://s3-us-west-1.amazonaws.com/BUCKET/node_modules/MODULE/particles/cftemplates/module.template"
|
306 |
|
307 | #### helpers
|
308 |
|
309 | Node modules that export a function that is built as a
|
310 | Handlebars [block helper](http://handlebarsjs.com/block_helpers.html).
|
311 |
|
312 | Helpers are called with the `helper` helper:
|
313 |
|
314 | {{helper 'my-helper'}}
|
315 |
|
316 | {{helper 'module:<MODULE>' 'module-helper'}}
|
317 |
|
318 | The particle path should match the name of the helper without the `.js` extension.
|
319 |
|
320 | #### mappings
|
321 |
|
322 | Contents of files will be loaded as mappings that can be used in
|
323 | in a traditional template or a `layout` (**recommended**)
|
324 |
|
325 | Directory: `mappings`
|
326 | Helper: `mapping`
|
327 |
|
328 | {{mapping 'my-mapping' logicalId="MyMapping"}}
|
329 |
|
330 | {{mapping 'module:<MODULE>' 'mapping-name' logicalId="TheirMapping"}}
|
331 |
|
332 | The particle path can match the base name of the file or the base name
|
333 | plus any extensions.
|
334 |
|
335 | #### metadata
|
336 |
|
337 | Contents of files will be loaded as metadata that can be used in
|
338 | in a traditional template or a `layout` (**recommended**)
|
339 |
|
340 | Directory: `metadata`
|
341 | Helper: `metadata`
|
342 |
|
343 | {{metadata 'my-metadata' logicalId="MyMetadata"}}
|
344 |
|
345 | {{metadata 'module:<MODULE>' 'metadata-name' logicalId="TheirMetadata"}}
|
346 |
|
347 | The particle path can match the base name of the file or the base name
|
348 | plus any extensions.
|
349 |
|
350 | #### outputs
|
351 |
|
352 | Contents of files will be loaded as outputs that can be used in
|
353 | in a traditional template or a `layout` (**recommended**)
|
354 |
|
355 | Directory: `outputs`
|
356 | Helper: `output`
|
357 |
|
358 | {{output 'my-output' logicalId="MyOutput"}}
|
359 |
|
360 | {{output 'module:<MODULE>' 'output-name' logicalId="TheirOutput"}}
|
361 |
|
362 | The particle path can match the base name of the file or the base name
|
363 | plus any extensions.
|
364 |
|
365 | #### parameters
|
366 |
|
367 | Contents of files will be loaded as parameters that can be used in
|
368 | in a traditional template or a `layout` (**recommended**)
|
369 |
|
370 | Directory: `parameters`
|
371 | Helper: `parameter`
|
372 |
|
373 | {{parameter 'my-output' logicalId="MyParameter"}}
|
374 |
|
375 | {{parameter 'module:<MODULE>' 'parameter-name' logicalId="TheirParameter"}}
|
376 |
|
377 | The particle path can match the base name of the file or the base name
|
378 | plus any extensions.
|
379 |
|
380 | #### partials
|
381 |
|
382 | Contents of files here will be loaded as partials that can be used in
|
383 | `assets` and `cftemplates`.
|
384 |
|
385 | These files will not be packaged or uploaded to S3.
|
386 |
|
387 | Partials can be loaded with the `partial` helper:
|
388 |
|
389 | {{partial 'my-partial'}}
|
390 |
|
391 | {{partial 'module:<MODULE>' 'module-partial'}}
|
392 |
|
393 | The particle path only needs to match the base name of the partial.
|
394 |
|
395 | A path of `some_partial` would match `some_partial.json` or `some_partial.json.hbs`.
|
396 |
|
397 | If the desired partial is not being loaded ensure precedence is given to an exact match.
|
398 |
|
399 | #### resources
|
400 |
|
401 | Contents of files will be loaded as resources that can be used in
|
402 | in a traditional template or a `layout` (**recommended**)
|
403 |
|
404 | Directory: `resources`
|
405 | Helper: `resource`
|
406 |
|
407 | {{resource 'my-output' logicalId="MyResource"}}
|
408 |
|
409 | {{resource 'module:<MODULE>' 'resource-name' logicalId="TheirResource"}}
|
410 |
|
411 | The particle path can match the base name of the file or the base name
|
412 | plus any extensions.
|
413 |
|
414 | #### sets
|
415 |
|
416 | Intended for use with `layout`
|
417 |
|
418 | A grouping of section definitions that will always be generated
|
419 | together. Most commonly used to generate parameters with corresponding
|
420 | conditions.
|
421 |
|
422 | Directory: `sets`
|
423 | Helper: `set`
|
424 |
|
425 | {{set 'my-set' logicalId="MySet"}}
|
426 |
|
427 | {{set 'module:<MODULE>' 'set-name' logicalId="TheirSet"}}
|
428 |
|
429 | The particle path can match the base name of the file or the base name
|
430 | plus any extensions.
|
431 |
|
432 | ##### Scoping
|
433 |
|
434 | Sets can be repeated multiple times in a template. Sets can also be
|
435 | embedded within other sets. To help with namespacing a set can be
|
436 | scoped with a `logicalIdPrefix` and/or a 'logicalIdSuffix`. These
|
437 | values will be apporperiately added to and logicalIds within the set.
|
438 |
|
439 | To reference a logicalId within a scoped set use the `scopeId` and `ref`
|
440 | handlebars helpers provided by condensation.
|
441 |
|
442 | {{!-- sets/my_set.hbs --}}
|
443 | {{parameter "cidr" logicalId="Cidr"}}
|
444 | {{resource "subnet" logicalId="Subnet" cidr=(ref "cidr")}}
|
445 |
|
446 | ---
|
447 |
|
448 | {{!-- cftemplates/my_template.template.json.hbs --}}
|
449 |
|
450 | {{set "my_set" logicalIdSuffix="1"}}
|
451 | {{set "my_set" logicalIdSuffix="2"}}
|
452 |
|
453 | The definition above would produce two parameters, `Cidr1` and `Cidr2`, and
|
454 | two resources, `Subnet1` and `Subnet2`. Each subnet will reference
|
455 | their respective Cidr parameter.
|
456 |
|
457 | ### Tasks
|
458 |
|
459 | Get a full list of tasks by running `gulp -T`
|
460 |
|
461 | By default all tasks are prefixed with `condensation:`. This can be
|
462 | changed with the `taskPrefix` config option.
|
463 |
|
464 | #### Default
|
465 |
|
466 | The `default` task is an alias for `build`. It will prepare all files
|
467 | for deployment to s3. Templates and assets are written to the configured
|
468 | `dist` directory.
|
469 |
|
470 | > gulp condensation:default
|
471 |
|
472 |
|
473 | #### condensation:s3:list
|
474 | Will list all the configured s3 buckets and module corresponding ID.
|
475 |
|
476 | > gulp condensation:s3:list
|
477 | [10:21:47] Using gulpfile ~/condensation-example/gulpfile.js
|
478 | [10:21:47] Starting 'condensation:s3:list'...
|
479 | 0: a.bucket.in.us-east-1
|
480 | 1: a.bucket.in.us-west-2
|
481 | [10:21:47] Finished 'condensation:s3:list' after 153 μs
|
482 |
|
483 | The IDs can be used to deploy to a single bucket instead of all buckets.
|
484 |
|
485 | #### condensation:deploy
|
486 | For the `deploy` task to run AWS credentials must be set as environment
|
487 | variables: `AWS_SECRET_ACCESS_KEY` and `AWS_ACCESS_KEY_ID`
|
488 |
|
489 | > AWS_SECRET_ACCESS_KEY=XXXX AWS_ACCESS_KEY_ID=XXXX gulp deploy
|
490 |
|
491 | This will upload templates to all cofigured S3 buckets.
|
492 |
|
493 | #### condensation:deploy:ID
|
494 | Deploy templates to a specific S3 bucket.
|
495 |
|
496 | #### condensation:deploy:LABEL
|
497 | Deploy templates to all S3 buckets that contain the label, LABEL.
|
498 |
|
499 | ## Config Options
|
500 |
|
501 | var config = {
|
502 | // Array of S3 buckets to deploy to
|
503 | s3: [
|
504 | {
|
505 | // AWS specific options
|
506 | aws: {
|
507 | region: 'us-east-1',
|
508 | bucket: 'my.bucket.in.us-east-1',
|
509 | },
|
510 |
|
511 | // Run CloudFormation validation during the build task for this bucket
|
512 | validate: true,
|
513 |
|
514 | // Create this bucket if it does not already exist
|
515 | create: true
|
516 |
|
517 | // Prefix all objects (allows for multiple deployments to the same bucket
|
518 | prefix: '',
|
519 |
|
520 | labels: ['east']
|
521 | },
|
522 | ],
|
523 | // The prefix to add to all generated gulp tasks (default: 'condensation')
|
524 | // An empty string will remove the prefix
|
525 | // - condensation:deploy will become deploy
|
526 | taskPrefix: '',
|
527 |
|
528 | // Directory that contains the `particles` directory.
|
529 | // Used for test scripts, should not be changed if sharing templates
|
530 | root: './',
|
531 |
|
532 | // Where the build task will put the distribution
|
533 | dist: 'dist'
|
534 | };
|
535 |
|
536 | ## Condensation Helpers
|
537 |
|
538 | ### ref
|
539 |
|
540 | Build a reference to a logicalId. By default `ref` will return a
|
541 | logicalId in relation to it's scope adding any logicalIdPrefix and/or
|
542 | logicalIdSuffix as necessary. This can be turned off by setting `scope`
|
543 | to `false`.
|
544 |
|
545 | {{ref 'MyParameter'}}
|
546 | {{ref 'MyParameter' scope=false}}
|
547 |
|
548 | ### scopeId
|
549 |
|
550 | Return a logicalId based on it's current scope. Will add any
|
551 | logicalIdPrefix and/or logicalIdSuffix that is defined.
|
552 |
|
553 | {{scopeId 'MyParameter'}}
|
554 |
|
555 | ## Handlebars Helpers
|
556 |
|
557 | Aside from the helpers to load particles, condensation provides the
|
558 | following generic handlebars helpers.
|
559 |
|
560 | ### concat
|
561 |
|
562 | Concatenate strings
|
563 |
|
564 | {{concat 'one' 'two'}}
|
565 | {{#parameter logicalId=(concat 'myPrefix' myStrVar)}}
|
566 |
|
567 | ## Front Matter
|
568 |
|
569 | All `cftemplates` and `partials` are first processed with
|
570 | [gray-matter](https://github.com/jonschlinkert/gray-matter) to load any
|
571 | default data definitions.
|
572 |
|
573 | ## Errors
|
574 |
|
575 | Errors due to badly formed JSON or failed CF validations will stop the
|
576 | process and the offending files will be dumped to `condensation_errors`
|
577 |
|
578 | ## Experimental
|
579 |
|
580 | ### condensation.js
|
581 |
|
582 | If a project contains `condensation.js` the file will be loaded as a
|
583 | module and will attement to run the `initialize` function providing a
|
584 | callback as the only parameter.
|
585 |
|
586 | This can be used by particle project to bootstrap any necessary assets
|
587 | before any template compiling begins.
|
588 |
|
589 | Example:
|
590 | [particles-cloudsploit-scans](https://github.com/SungardAS/particles-cloudsploit-scans)
|
591 |
|
592 | ## Acknowledgements
|
593 |
|
594 | Big thank-you to [Brent Stees](https://github.com/bstees) for creating
|
595 | the condensation logo!
|
596 |
|
597 | ## Sungard Availability Services | Labs
|
598 | [![Sungard Availability Services | Labs][labs-logo]][labs-github-url]
|
599 |
|
600 | This project is maintained by the Labs team at [Sungard Availability
|
601 | Services](http://sungardas.com)
|
602 |
|
603 | GitHub: [https://sungardas.github.io](https://sungardas.github.io)
|
604 |
|
605 | Blog:
|
606 | [http://blog.sungardas.com/CTOLabs/](http://blog.sungardas.com/CTOLabs/)
|
607 |
|
608 |
|
609 | [codeclimate-image]: https://codeclimate.com/github/SungardAS/condensation/badges/gpa.svg
|
610 | [codeclimate-url]: https://codeclimate.com/github/SungardAS/condensation
|
611 | [condensation-image]: ./docs/images/condensation_logo.png?raw=true
|
612 | [coveralls-image]: https://coveralls.io/repos/SungardAS/condensation/badge.svg
|
613 | [coveralls-url]: https://coveralls.io/r/SungardAS/condensation
|
614 | [condensation-docker-url]: https://github.com/SungardAS/condensation-docker
|
615 | [daviddm-image]: https://david-dm.org/SungardAS/condensation.svg?theme=shields.io
|
616 | [daviddm-url]: https://david-dm.org/SungardAS/condensation
|
617 | [gitter-image]: https://badges.gitter.im/Join%20Chat.svg
|
618 | [gitter-url]: https://gitter.im/SungardAS/condensation?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge
|
619 | [labs-github-url]: https://sungardas.github.io
|
620 | [labs-logo]: https://raw.githubusercontent.com/SungardAS/repo-assets/master/images/logos/sungardas-labs-logo-small.png
|
621 | [npm-image]: https://badge.fury.io/js/condensation.svg
|
622 | [npm-url]: https://npmjs.org/package/condensation
|
623 | [travis-image]: https://travis-ci.org/SungardAS/condensation.svg?branch=master
|
624 | [travis-url]: https://travis-ci.org/SungardAS/condensation
|