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