1 | /**
|
2 | * # Kes: Making deployment with CloudFormation Fun
|
3 | *
|
4 | * Kes helps with managing and deploying AWS resources using CloudFormation.
|
5 | *
|
6 | * It makes it much easier to deploy lambda functions and create API gateway resources.
|
7 | *
|
8 | * ## Installation
|
9 | *
|
10 | * ```bash
|
11 | * $ npm install -g kes
|
12 | * $ kes -h
|
13 | *
|
14 | * Usage: kes TYPE COMMAND [options]
|
15 | *
|
16 | * Start a Kes project
|
17 | *
|
18 | * Options:
|
19 | *
|
20 | * -V, --version output the version number
|
21 | * -p, --profile <profile> AWS profile name to use for authentication
|
22 | * --role <role> AWS role arn to be assumed for the deployment
|
23 | * -c, --config <config> Path to config file
|
24 | * --env-file <envFile> Path to env file
|
25 | * --cf-file <cfFile> Path to CloudFormation templateUrl
|
26 | * -t, --template <template> A kes application template used as the base for the configuration
|
27 | * --kes-class <kesClass> Kes Class override
|
28 | * -k, --kes-folder <kesFolder> Path to config folder
|
29 | * -r, --region <region> AWS region
|
30 | * --stack <stack> stack name, defaults to the config value
|
31 | * --showOutputs Show the list of a CloudFormation template outputs
|
32 | * --yes Skip all confirmation prompts
|
33 | * -d, --deployment <deployment> Deployment name, default to default
|
34 | * -h, --help output usage information
|
35 | *
|
36 | * Commands:
|
37 | * cf [deploy|validate|compile] CloudFormation Operations:
|
38 | * create Creates the CF stack (deprecated, start using deploy)
|
39 | * update Updates the CF stack (deprecated, start using deploy)
|
40 | * upsert Creates the CF stack and Update if already exists (deprecated, start using deploy)
|
41 | * deploy Creates the CF stack and Update if already exists
|
42 | * delete Delete the CF stack
|
43 | * validate Validates the CF stack
|
44 | * compile Compiles the CF stack
|
45 | * lambda <lambdaName> uploads a given lambda function to Lambda service
|
46 | *
|
47 | * ```
|
48 | *
|
49 | * ## Setting Up the First Project
|
50 | *
|
51 | * Go to your project directory and run the following command.
|
52 | *
|
53 | * ```bash
|
54 | * $ npm init
|
55 | * ```
|
56 | *
|
57 | * This will create a `.kes` folder on your project folder. It will include the following files:
|
58 | *
|
59 | * | file | description
|
60 | * | ---- | -------------
|
61 | * |`.env`| This optional file can hold your project secrets and should not be committed
|
62 | * |`cloudformation.template.yml`| A base CF template written with Mustache/Handlebar templating language
|
63 | * |`config.yml`| The main required configuration file for a kes deployment
|
64 | * |`kes.js`| An optional Kes class override that can change how Kes class is used
|
65 | *
|
66 | * The `cloudformation.template.yml` and `config.yml` are required files.
|
67 | * The variables in `config.yml` are parsed and used to generate the `cloudformation.yml`. By default,
|
68 | * the `default` section of the `config.yml` is parsed and used in `cloudformation.template.yml`. If
|
69 | * another deployment is specified in the `config.yml` the values of that deployment overrides the
|
70 | * values of `default`
|
71 | * file which is sent to AWS CloudFormation to create and update the stack.
|
72 | *
|
73 | * ### CF Stack Name
|
74 | * The Cloudformation stack name is the same as `stackName` in `config.yml`.
|
75 | *
|
76 | * ### Parameters
|
77 | *
|
78 | * To pass parameters to the CloudFormation template, use the `parameters` key in config.yml. Example:
|
79 | *
|
80 | * ```yaml
|
81 | * # config.yml
|
82 | * default:
|
83 | * stackName: myStack
|
84 | * parameters:
|
85 | * - name: MyParameter
|
86 | * value: someValue
|
87 | * ```
|
88 | *
|
89 | * ```yaml
|
90 | * # cloudformation.template.yml
|
91 | * AWSTemplateFormatVersion: '2010-09-09'
|
92 | * Description: 'stack: {{stackName}} | deployed by Kes'
|
93 | * Parameters:
|
94 | * MyParameter:
|
95 | * Type: String
|
96 | * Description: 'My parameter'
|
97 | * ```
|
98 | *
|
99 | * ### CF Capabailities
|
100 | *
|
101 | * To pass capabilities such as `CAPABILITY_IAM` use `capabilities` key:
|
102 | *
|
103 | * ```yaml
|
104 | * # config.yml
|
105 | * default:
|
106 | * stackName: myStack
|
107 | * parameters:
|
108 | * - name: MyParameter
|
109 | * value: someValue
|
110 | * capabilities:
|
111 | * - CAPABILITY_IAM
|
112 | * ```
|
113 | *
|
114 | * ### CloudFormation Tagging
|
115 | *
|
116 | * To manage tags associated with your CloudFormation stack, use the `tags` key:
|
117 | *
|
118 | * ```yaml
|
119 | * # config.yml
|
120 | * default:
|
121 | * tags:
|
122 | * color: orange
|
123 | * tree: oak
|
124 | * ```
|
125 | *
|
126 | * ### Lambda Functions
|
127 | * To add lambda functions, use `lambdas` key and add them as array object.
|
128 | * The lambda function code can be either a folder or file on your computer
|
129 | * or a zip file on aws.
|
130 | *
|
131 | * **Note:** In version 2.0.0 of kes, the lambda packaging is handled natively in nodejs.
|
132 | * If you point the `source` to a directory, the directory is saved at the root of the zip
|
133 | * package. This changes how handler path should be setup.
|
134 | *
|
135 | * For example, if the `index.js` is located at `/path/to/package/index.js` and
|
136 | * `source: /path/to/package/index.js`, the handler should be `handler: index.handler`.
|
137 | *
|
138 | * **Required Fields:**
|
139 | * - name
|
140 | * - handler
|
141 | * - source/s3Source
|
142 | *
|
143 | * **Env Variables:**
|
144 | * You can add env variables to each lambda function as shown in the example below.
|
145 | *
|
146 | * **Example:**
|
147 | *
|
148 | * ```yaml
|
149 | * # config.yml
|
150 | * default:
|
151 | * stackName: myStack
|
152 | * parameters:
|
153 | * - name: MyParameter
|
154 | * value: someValue
|
155 | * capabilities:
|
156 | * - CAPABILITY_IAM
|
157 | *
|
158 | * lambdas:
|
159 | * - name: myLambda1
|
160 | * handler: index.handler
|
161 | * timeout: 200
|
162 | * source: 'node_modules/someNpmPackage'
|
163 | * - name: myLambda2
|
164 | * handler: package.handler
|
165 | * timeout:100
|
166 | * s3Source:
|
167 | * bucket: mybucket
|
168 | * key: mylambda.zip
|
169 | * envs:
|
170 | * DEBUG: true
|
171 | * ```
|
172 | *
|
173 | * **Note:**
|
174 | *
|
175 | * Adding lambda functions in the config.yml has no effect unless you add
|
176 | * the relevant CF syntax to `cloudformation.template.yml`
|
177 | *
|
178 | * ### Handlebar Helpers
|
179 | * We use [Handlebar](http://handlebarsjs.com/) for templating a CF template.
|
180 | *
|
181 | * **Each**
|
182 | *
|
183 | * ```yaml
|
184 | * # config.yml
|
185 | * default:
|
186 | * myArray:
|
187 | * - name: name1
|
188 | * - name: name2
|
189 | * ```
|
190 | *
|
191 | * ```yaml
|
192 | * # cloudformation.template.yml
|
193 | * Resources:
|
194 | *
|
195 | * {{# each myArray}}
|
196 | * {{name}}:
|
197 | * Type: SomeAWSResource
|
198 | * {{/each}}
|
199 | * ```
|
200 | *
|
201 | * **If/else**
|
202 | *
|
203 | * ```yaml
|
204 | * # config.yml
|
205 | * default:
|
206 | * myArray:
|
207 | * - name: name1
|
208 | * runtime: python2.7
|
209 | * - name: name2
|
210 | * ```
|
211 | *
|
212 | * ```yaml
|
213 | * # cloudformation.template.yml
|
214 | * Resources:
|
215 | *
|
216 | * {{# each myArray}}
|
217 | * {{name}}:
|
218 | * Type: SomeAWSResource
|
219 | * Properties:
|
220 | * Runtime: {{# if runtime}}{{runtime}}{{else}}nodejs6.10{{/if}}
|
221 | * {{/each}}
|
222 | * ```
|
223 | *
|
224 | * **Each for Objects**
|
225 | *
|
226 | * ```yaml
|
227 | * # config.yml
|
228 | * default:
|
229 | * myArray:
|
230 | * - DEBUG: true
|
231 | * ```
|
232 | *
|
233 | * ```yaml
|
234 | * # cloudformation.template.yml
|
235 | * Resources:
|
236 | *
|
237 | * {{# each myArray}}
|
238 | * Lambda:
|
239 | * Type: SomeAWSResource
|
240 | * Properties:
|
241 | * Environments:
|
242 | * - {{@key}}: {{this}}
|
243 | * {{/each}}
|
244 | * ```
|
245 | *
|
246 | * ## Deployment
|
247 | *
|
248 | * To create a CF stack or update and existing one run
|
249 | * ```bash
|
250 | * kes cf deploy
|
251 | * ```
|
252 | *
|
253 | * ### Delete an existing stack
|
254 | *
|
255 | * To delete an existing stack:
|
256 | * ```bash
|
257 | * kes cf delete
|
258 | * ```
|
259 | *
|
260 | * ### Different deployment configurations
|
261 | *
|
262 | * You can configure different values for different deployments. For example you might want to configure your test deployment
|
263 | * differently from your staging and production deployments. Here is how to achieve it:
|
264 | *
|
265 | * ```yaml
|
266 | * # config.yml
|
267 | * default:
|
268 | * stackName: myStack-test
|
269 | * myArray:
|
270 | * - DEBUG: true
|
271 | *
|
272 | * staging:
|
273 | * stackName: myStack-staging
|
274 | * myArray:
|
275 | * - DEBUG: false
|
276 | * ```
|
277 | *
|
278 | * To deploy a stack with the `staging` configuration run:
|
279 | *
|
280 | * ```bash
|
281 | * kes cf deploy --deployment staging
|
282 | * ```
|
283 | *
|
284 | *
|
285 | * ## Deployment Using IAM Role
|
286 | *
|
287 | * You can specify an IAM role for the deployment using `--role` option or by setting `AWS_DEPLOYMENT_ROLE` environment variable.
|
288 | *
|
289 | * **Note:** You still need an aws user with AssumeRole permission for this to work
|
290 | *
|
291 | * ```bash
|
292 | * kes cf deploy --profile myUser --role arn:aws:iam::00000000000:role/myDeploymentRole
|
293 | * ```
|
294 | *
|
295 | * ### Updating One Lambda Function
|
296 | * To update one lambda function outside of CF
|
297 | *
|
298 | * ```bash
|
299 | * kes lambda myLambda
|
300 | * ```
|
301 | *
|
302 | * ## Use Templates
|
303 | * Kes enables you to distribute your AWS applications built with kes using a concept called template. A template is essentially a `.kes` folder with
|
304 | * a `cloudformation.template.yml`, a `config.yml` and a `kes.js` if needed.
|
305 | *
|
306 | * The user of a template can point to your template folder with the `--template` flag and the kes command will use the template to build the cloudformation.yml.
|
307 | *
|
308 | * The user still has the option of creating her own `config.yml` and `cloudformation.template.yml`. Any variables in these files will override existing ones
|
309 | * in the template or append it if it doesn't exist.
|
310 | *
|
311 | * This setup gives users of the templates a great degree of flexibility and ownership.
|
312 | *
|
313 | * ## Nested Templates
|
314 | * Kes supports use of [Cloudformation Nested Templates](https://aws.amazon.com/blogs/devops/use-nested-stacks-to-create-reusable-templates-and-support-role-specialization/).
|
315 | * To use nested templates, create a separate `template.yml` and `config.yml` files for each nested template using the same rules explained above.
|
316 | * Then include references in your main `config.yml`.
|
317 | *
|
318 | * All nested templates will receive the parent configuration under the `parent` key.
|
319 | *
|
320 | * ### Example
|
321 | * ```yaml
|
322 | * # config.yml
|
323 | * default:
|
324 | * stackName: myStack-test
|
325 | * myArray:
|
326 | * - DEBUG: true
|
327 | * nested_templates:
|
328 | * myNestedTemplate:
|
329 | * cfFile: /path/to/myNestedTemplate.template.yml
|
330 | * configFile: /path/to/myNestedConfig.yml
|
331 | *
|
332 | * staging:
|
333 | * stackName: myStack-staging
|
334 | * myArray:
|
335 | * - DEBUG: false
|
336 | * ```
|
337 | *
|
338 | * ```yaml
|
339 | * # myNestedConfig.yml
|
340 | * default:
|
341 | * timeout: 300
|
342 | * ```
|
343 | *
|
344 | * ```yaml
|
345 | * # myNestedTemplate.template.yml
|
346 | * Resources:
|
347 | *
|
348 | * {{# each parent.myArray}}
|
349 | * Lambda:
|
350 | * Type: SomeAWSResource
|
351 | * Properties:
|
352 | * Timeout: {{../timeout}}
|
353 | * Environments:
|
354 | * - {{@key}}: {{this}}
|
355 | * {{/each}}
|
356 | * ```
|
357 | */
|