cfhighlander 0.4.0.alpha.1531985380 → 0.4.0.alpha.1532390766
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +200 -64
- data/bin/cfhighlander.rb +13 -2
- data/hl_ext/aws_helper.rb +22 -0
- data/lib/cfhighlander.factory.rb +1 -1
- data/lib/cfhighlander.publisher.rb +16 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b79b37a85853f86decedf859eee734343a1884c8eff8b303e3e016ced73d94e2
|
4
|
+
data.tar.gz: 0c92b574bec294dc01c1f6d312c62f98e97190be08f6b2fd5b1e0a4752327bcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a5f3b74ca37e2280a3e5998d37364e6a6eed253a92d6caf16cf6a0d14c0240790ac2314fc529d72487347869fe0cd4cda79ee5f600be57359fa76a25948b8f5
|
7
|
+
data.tar.gz: a6a4c51d8c1b2b11ed469fb92a72d690aee916b1b4ffae931808c391573658f0f6cefb63380e03737450135eb3b3864f9a05bfc76d192d7663dcd45dfbcb2780
|
data/README.md
CHANGED
@@ -1,17 +1,133 @@
|
|
1
1
|
[![Build Status](https://travis-ci.org/theonestack/cfhighlander.svg?branch=develop)](https://travis-ci.org/theonestack/cfhighlander)
|
2
2
|
|
3
|
-
#
|
4
|
-
|
5
|
-
Cfhighlander is
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
3
|
+
# Intro
|
4
|
+
|
5
|
+
Cfhighlander is a feature rich tool and DSL for infrastructure
|
6
|
+
coders working with CloudFormation templates.
|
7
|
+
|
8
|
+
It was designed to
|
9
|
+
|
10
|
+
- Abstract AWS resources or sets of resources as
|
11
|
+
**components** by describing them using Cfhighlander
|
12
|
+
DSL and [cfndsl](https://github.com/cfndsl/cfndsl).
|
13
|
+
|
14
|
+
- Produce, validate and publish CloudFormation templates
|
15
|
+
from those components
|
16
|
+
|
17
|
+
- Enable infrastructure coders to use concepts of **inheritance**
|
18
|
+
and **composition** when designing components. In other words
|
19
|
+
allowing components to be *extended*, and allowing components
|
20
|
+
to be built from other components.
|
21
|
+
|
22
|
+
- Allow for easy **discovery** and consumption of components from
|
23
|
+
different sources (git repository, file system, S3 buckets)
|
24
|
+
|
25
|
+
- Allow component developers and consumers to take
|
26
|
+
more **descriptive** approach using DSL, compared to
|
27
|
+
instructional approach.
|
28
|
+
|
29
|
+
# Installation
|
30
|
+
|
31
|
+
```
|
32
|
+
gem install cfhighlander
|
33
|
+
```
|
34
|
+
|
35
|
+
# Example
|
36
|
+
|
37
|
+
Passing output value from one substack to another substack within root stack
|
38
|
+
has to be done manually - either if you build JSON/YAML templates by hand,
|
39
|
+
or if using `Cfndsl`. With cfhighlander, this code is automatically generated for you
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
|
43
|
+
CfhighlanderTemplate do
|
44
|
+
|
45
|
+
# explicit configuration for vpc component
|
46
|
+
vpc_config = { 'maximum_availability_zones' => 2 }
|
47
|
+
|
48
|
+
# declare vpc component, and pass some parameters
|
49
|
+
# to it
|
50
|
+
Component name: 'vpc',
|
51
|
+
template: 'vpc@master.snapshot',
|
52
|
+
config: vpc_config do
|
53
|
+
parameter name: 'Az0', value: FnSelect(0,FnGetAZs())
|
54
|
+
parameter name: 'Az1', value: FnSelect(1,FnGetAZs())
|
55
|
+
parameter name: 'DnsDomain', value: 'example.com'
|
56
|
+
parameter name: 'StackMask', value: '16'
|
57
|
+
end
|
58
|
+
|
59
|
+
# Compiled cloudformation template will
|
60
|
+
# pass Compute subnets from VPC into ECS Cluster
|
61
|
+
Component name: 'ecs', template:'ecs@master.snapshot' do
|
62
|
+
parameter name: 'DnsDomain', value: 'example.com'
|
63
|
+
end
|
64
|
+
|
65
|
+
# feed mapping maparameters to components
|
66
|
+
addMapping('EnvironmentType',{
|
67
|
+
'development' => {
|
68
|
+
'MaxNatGateways'=>'1',
|
69
|
+
'EcsAsgMin' => 1,
|
70
|
+
'EcsAsgMax' => 1,
|
71
|
+
'KeyName' => 'default',
|
72
|
+
'InstanceType' => 't2.large',
|
73
|
+
'SingleNatGateway' => true
|
74
|
+
}
|
75
|
+
})
|
76
|
+
end
|
77
|
+
|
78
|
+
```
|
79
|
+
|
80
|
+
... compile the template with ...
|
81
|
+
|
82
|
+
```shell
|
83
|
+
cfcompile application.cfhighlander.rb
|
84
|
+
```
|
85
|
+
|
86
|
+
... and check how the subnets are being passed around ..
|
87
|
+
|
88
|
+
```shell
|
89
|
+
$ cat out/yaml/app.compiled.yaml | grep -A3 SubnetCompute0
|
90
|
+
SubnetCompute0:
|
91
|
+
Fn::GetAtt:
|
92
|
+
- vpc
|
93
|
+
- Outputs.SubnetCompute0
|
94
|
+
SubnetCompute1:
|
95
|
+
Fn::GetAtt:
|
96
|
+
- vpc
|
97
|
+
|
98
|
+
```
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
# Library
|
103
|
+
|
104
|
+
As part of [theonestack org](https://github.com/theonestack/), there is several publicly available components.
|
105
|
+
|
106
|
+
- [vpc](https://github.com/theonestack/hl-component-vpc) - Has separation of public
|
107
|
+
and private subnets, configurable number of NAT Gateways (per AZ or single for all
|
108
|
+
subnets, handles all of the complex routing stuff)
|
109
|
+
|
110
|
+
- [ecs](https://github.com/theonestack/hl-component-ecs) - ECS Cluster deployed in VPC Compute Subnets
|
111
|
+
- [bastion](https://github.com/theonestack/hl-component-bastion) - Deployed into VPC Public
|
112
|
+
Subnets, with configuration for whitelisting IP addresses to access port 22
|
113
|
+
- [ecs-service](https://github.com/theonestack/hl-component-ecs-service) - Deploy containerised apps running on ECS Clusters
|
114
|
+
- [loadbalancer](https://github.com/theonestack/hl-component-loadbalancer)
|
115
|
+
- [sns](https://github.com/theonestack/hl-component-sns) - SNS Topics, with implemented
|
116
|
+
Lambda function to post Slack messages
|
117
|
+
- [efs](https://github.com/theonestack/hl-component-efs) - Elastic File System, can be
|
118
|
+
used in conjuction with ECS Cluster
|
119
|
+
|
120
|
+
You can easily test any of these. Automatic component resolver will default
|
121
|
+
to 'https://github.com/theonestack/hl-component-$name' location if component
|
122
|
+
is not found in local sources.
|
123
|
+
|
124
|
+
```
|
125
|
+
cfcompile [componentname]
|
126
|
+
```
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
# How it works ?
|
15
131
|
|
16
132
|
Highlander DSL produces CloudFormation templates in 4 phases
|
17
133
|
|
@@ -22,18 +138,18 @@ Highlander DSL produces CloudFormation templates in 4 phases
|
|
22
138
|
- Producing resulting CloudFormation templates using configuration and templates generated in two previous phases.
|
23
139
|
|
24
140
|
Each phase (aside from parameter wiring) above is executable as stand-alone through CLI, making development of Highlander templates easier by enabling
|
25
|
-
debugging of produced configuration and cfndsl templates.
|
141
|
+
debugging of produced configuration and cfndsl templates.
|
26
142
|
|
27
143
|
|
28
144
|
## Highlander components
|
29
145
|
|
30
|
-
Highlander component is located on local file system or S3 location with following
|
146
|
+
Highlander component is located on local file system or S3 location with following
|
31
147
|
files defining them
|
32
148
|
|
33
149
|
- Highlander DSL file (`$componentname.highlander.rb`)
|
34
150
|
- *(Optional)* Configuration files (`*.config.yaml`)
|
35
151
|
- *(Optional)* CfnDSL file (`componentname.cfnds.rb`)
|
36
|
-
- *(Optional)* Mappings YAML files `*.mappings.yaml` -
|
152
|
+
- *(Optional)* Mappings YAML files `*.mappings.yaml` -
|
37
153
|
this file defines map used within component itself
|
38
154
|
- *(Optional)* Mappings extension file `componentname.mappings.rb` - see more under Mappings section
|
39
155
|
- *(Optional)* Ruby extensions consumed by cfndsl templates - placed in `ext/cfndsl/*.rb` - see more under
|
@@ -75,7 +191,7 @@ cfhighlander commands:
|
|
75
191
|
### Working directory
|
76
192
|
|
77
193
|
All templates and configuration generated are placed in `$WORKDIR/out` directory. Optionally, you can alter working directory
|
78
|
-
via `CFHIGHLANDER_WORKDIR` environment variable.
|
194
|
+
via `CFHIGHLANDER_WORKDIR` environment variable.
|
79
195
|
|
80
196
|
### Commands
|
81
197
|
|
@@ -112,7 +228,7 @@ pip install requests -t lib
|
|
112
228
|
Proceed (y/n)?
|
113
229
|
```
|
114
230
|
|
115
|
-
In order to avoid user prompt pass `-q` or `--quiet` switch to CLI for commands that require Lambda packaging
|
231
|
+
In order to avoid user prompt pass `-q` or `--quiet` switch to CLI for commands that require Lambda packaging
|
116
232
|
(`dslcompile`, `cfcompile`, `cfpublish`)
|
117
233
|
|
118
234
|
|
@@ -131,6 +247,26 @@ via CLI (`--dstbucket`, `--dstprefix`, `-v`). Default distribution bucket and pr
|
|
131
247
|
`DistributionBucket`, `DistributionBucket`, `DistributionPrefix` or `ComponentDistribution` statements. Check DSL specification
|
132
248
|
for more details on this statements. Version defaults to `latest` if not explicitly given using `-v` switch
|
133
249
|
|
250
|
+
If no distribution options is given using mentioned CLI options or DSL statements,
|
251
|
+
bucket will be automatically created for you. Bucket name defaults to
|
252
|
+
`$ACCOUNT.$REGION.cfhighlander.templates`, with `/published-templates`
|
253
|
+
prefix.
|
254
|
+
|
255
|
+
*cfpublish* command will give you quick launch CloudFirmation stack URL to assist
|
256
|
+
you in creating your stack:
|
257
|
+
|
258
|
+
```bash
|
259
|
+
$ cfpublish vpc@1.2.0
|
260
|
+
...
|
261
|
+
...
|
262
|
+
...
|
263
|
+
|
264
|
+
Use following url to launch CloudFormation stack
|
265
|
+
|
266
|
+
https://console.aws.amazon.com/cloudformation/home#/stacks/create/review?filter=active&templateURL=https://123456789012.ap-southeast-2.cfhighlander.templates.s3.amazonaws.com/published-templates/vpc/1.2.0/vpc.compiled.yaml&stackName=vpc
|
267
|
+
|
268
|
+
```
|
269
|
+
|
134
270
|
|
135
271
|
#### configcompile
|
136
272
|
|
@@ -152,7 +288,7 @@ compiled cloudformation templates). Same CLI / DSL options apply as for *cfpubli
|
|
152
288
|
There are 4 levels of component configuration
|
153
289
|
|
154
290
|
- Component local config file `component.config.yaml` (lowest priority)
|
155
|
-
- Outer component configuration file, under `components` key, like
|
291
|
+
- Outer component configuration file, under `components` key, like
|
156
292
|
|
157
293
|
|
158
294
|
```yaml
|
@@ -203,7 +339,7 @@ Configuration done this way will override any outer component config coming from
|
|
203
339
|
key, it may alter configuration of other components. Globally exported configuration is defined under `global`, while
|
204
340
|
component-oriented configuration is exported under `component` key. E.g. following configuration will export global
|
205
341
|
configuration defining name of ecs cluster, and targeted to vpc component configuration, defining subnets
|
206
|
-
|
342
|
+
|
207
343
|
```yaml
|
208
344
|
ecs_cluster_name: ApplicationCluster
|
209
345
|
|
@@ -212,11 +348,11 @@ subnets:
|
|
212
348
|
name: ECSCluster
|
213
349
|
type: private
|
214
350
|
allocation: 20
|
215
|
-
|
351
|
+
|
216
352
|
config_export:
|
217
353
|
global:
|
218
354
|
- ecs_cluster_name
|
219
|
-
|
355
|
+
|
220
356
|
component:
|
221
357
|
vpc:
|
222
358
|
- subnets
|
@@ -238,7 +374,7 @@ Component name: 'ecs_cluster', template: 'ecs_cluster@latest', export_config: {'
|
|
238
374
|
[CloudFormation Mappings](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html)
|
239
375
|
section matches a key to a corresponding set of named values. Highlander allows you to define this mappings in two ways
|
240
376
|
|
241
|
-
1. By using static maps defined through YAML files. Place `*.mappings.yaml` file alongside with highlander
|
377
|
+
1. By using static maps defined through YAML files. Place `*.mappings.yaml` file alongside with highlander
|
242
378
|
template to define mappings this way. Mappings defined in a static way are automatically rendered withing CloudFormation
|
243
379
|
template E.g.
|
244
380
|
|
@@ -255,7 +391,7 @@ EnvironmentType:
|
|
255
391
|
2. By defining mappings dynamically through Ruby code. Alongside with mappings, you can define default map name, and default
|
256
392
|
map key to be used when looking up value within this map. This mappings are usually rendered in outer component when inner
|
257
393
|
components pulls mapping value as parameter via `MappingParam` statement. Optionally, this mappings can be rendered within
|
258
|
-
component that defines them using `DynamicMappings` DSL statement.
|
394
|
+
component that defines them using `DynamicMappings` DSL statement.
|
259
395
|
|
260
396
|
## Extensions
|
261
397
|
|
@@ -263,7 +399,7 @@ component that defines them using `DynamicMappings` DSL statement.
|
|
263
399
|
|
264
400
|
In order to make template more DRY, template developer may reuse ruby functions. It is possible to place
|
265
401
|
such functions in separate files. Any ruby files placed within `ext/cfndsl` directory will get automatically
|
266
|
-
included via Ruby `require` function in compiled Cfndsl template.
|
402
|
+
included via Ruby `require` function in compiled Cfndsl template.
|
267
403
|
|
268
404
|
## Component DSL
|
269
405
|
|
@@ -273,13 +409,13 @@ Inner components or subcomponents are defined via `Component` DSL statement
|
|
273
409
|
|
274
410
|
```ruby
|
275
411
|
CfhighlanderTemplate do
|
276
|
-
|
412
|
+
|
277
413
|
# Example1 : Include component by template name only
|
278
|
-
Component 'vpc'
|
279
|
-
|
414
|
+
Component 'vpc'
|
415
|
+
|
280
416
|
# Example2 : Include component by template name, version and give it a name
|
281
417
|
Component template: 'ecs@master.snapshot'
|
282
|
-
|
418
|
+
|
283
419
|
end
|
284
420
|
|
285
421
|
```
|
@@ -293,16 +429,16 @@ value for feature toggle can be supplied using `enabled:` named parameter
|
|
293
429
|
|
294
430
|
# Include vpc and 2 ecs clusters with feature flags
|
295
431
|
CfhighlanderTemplate do
|
296
|
-
|
432
|
+
|
297
433
|
# vpc component
|
298
|
-
Component 'vpc'
|
299
|
-
|
434
|
+
Component 'vpc'
|
435
|
+
|
300
436
|
# Ecs Cluster 1 has feature toggle, enabled by default
|
301
437
|
Component name: 'ecs1', template: 'ecs', conditional: true
|
302
|
-
|
438
|
+
|
303
439
|
# Ecs Cluster 2 has feature toggle, and is explicitly disabled by default
|
304
440
|
Component name: 'ec2', template: 'ecs', conditional: true, enabled: false
|
305
|
-
|
441
|
+
|
306
442
|
end
|
307
443
|
|
308
444
|
```
|
@@ -311,8 +447,8 @@ end
|
|
311
447
|
|
312
448
|
### Parameters
|
313
449
|
|
314
|
-
Parameters block is used to define CloudFormation template parameters, and metadata on how they
|
315
|
-
are wired with outer or sibling components.
|
450
|
+
Parameters block is used to define CloudFormation template parameters, and metadata on how they
|
451
|
+
are wired with outer or sibling components.
|
316
452
|
|
317
453
|
```ruby
|
318
454
|
CfhighlanderTemplate do
|
@@ -329,18 +465,18 @@ Parameter block supports following parameters
|
|
329
465
|
#### ComponentParam
|
330
466
|
|
331
467
|
`ComponentParam` - Component parameter exposes parameter to be wired from outer component. Cfhighlander's
|
332
|
-
autowiring mechanism will try and find any stack outputs from other components defined by outer components with name
|
468
|
+
autowiring mechanism will try and find any stack outputs from other components defined by outer components with name
|
333
469
|
matching. If there is no explicit value provided, or autowired from outputs, parameter will be propagated to outer component.
|
334
470
|
|
335
|
-
Propagated parameter will be prefixed with component name **if it is not defined as global parameter**. Otherwise,
|
336
|
-
parameter name is kept in full.
|
471
|
+
Propagated parameter will be prefixed with component name **if it is not defined as global parameter**. Otherwise,
|
472
|
+
parameter name is kept in full.
|
337
473
|
|
338
|
-
Example below demonstrates 3 different ways of providing parameter values from outer to inner component.
|
474
|
+
Example below demonstrates 3 different ways of providing parameter values from outer to inner component.
|
339
475
|
|
340
476
|
- Provide value explicitly
|
341
477
|
- Provide value explicitly as output of another component
|
342
478
|
- Autowire value from output of another component with the same name
|
343
|
-
- Propagate parameter to outer component
|
479
|
+
- Propagate parameter to outer component
|
344
480
|
|
345
481
|
```ruby
|
346
482
|
|
@@ -368,7 +504,7 @@ CfhighlanderTemplate do
|
|
368
504
|
end
|
369
505
|
|
370
506
|
|
371
|
-
# -- contents of cfndsl
|
507
|
+
# -- contents of cfndsl
|
372
508
|
CloudFormation do
|
373
509
|
|
374
510
|
Condition 'AlwaysFalse', FnEquals('true','false')
|
@@ -407,7 +543,7 @@ CloudFormation do
|
|
407
543
|
Default ''
|
408
544
|
NoEcho false
|
409
545
|
end
|
410
|
-
|
546
|
+
|
411
547
|
Parameter('BucketName5') do
|
412
548
|
Type 'String'
|
413
549
|
Default ''
|
@@ -417,24 +553,24 @@ CloudFormation do
|
|
417
553
|
CloudFormation_Stack('s3') do
|
418
554
|
TemplateURL './s3.compiled.yaml'
|
419
555
|
Parameters ({
|
420
|
-
|
556
|
+
|
421
557
|
# Paramater that was auto-wired
|
422
558
|
'BucketName' => {"Fn::GetAtt":["nameproducer","Outputs.BucketName"]},
|
423
|
-
|
559
|
+
|
424
560
|
# Parameter that was explicitly wired as output param from another component
|
425
561
|
'BucketName2' => {"Fn::GetAtt":["nameproducer","Outputs.BucketName"]},
|
426
|
-
|
562
|
+
|
427
563
|
# Paramater that was explicitly provided
|
428
564
|
'BucketName3' => 'mybucket.example.cfhighlander.org',
|
429
|
-
|
565
|
+
|
430
566
|
# Reference to parameter that was propagated. isGlobal: false when defining
|
431
|
-
# parameter, so parameter name is prefixed with component name
|
567
|
+
# parameter, so parameter name is prefixed with component name
|
432
568
|
'BucketName4' => {"Ref":"s3BucketName4"},
|
433
|
-
|
569
|
+
|
434
570
|
# Reference to parameter that was propagated. isGlobal: true when defining
|
435
571
|
# parameter, so parameter name is not prefixed, but rather propagated as-is
|
436
572
|
'BucketName5' => {"Ref":"BucketName5"},
|
437
|
-
|
573
|
+
|
438
574
|
})
|
439
575
|
end
|
440
576
|
end
|
@@ -447,9 +583,9 @@ end
|
|
447
583
|
`MappingParam` - Mapping parameters value is passed as CloudFormation mapping lookup from outer component.
|
448
584
|
This DSL statements takes a full body, as Mapping name, Map key, and value key need to be specified. `key`,
|
449
585
|
`attribute` and `map` methods are used to specify these properties. Mapping parameters involve ruby code execution
|
450
|
-
|
451
|
-
|
452
|
-
|
586
|
+
|
587
|
+
|
588
|
+
|
453
589
|
```ruby
|
454
590
|
# Inner component
|
455
591
|
CfhighlanderTemplate do
|
@@ -457,7 +593,7 @@ CfhighlanderTemplate do
|
|
457
593
|
Parameters do
|
458
594
|
MappingParam 'BucketName' do
|
459
595
|
map 'AccountId'
|
460
|
-
attribute 'DnsDomain'
|
596
|
+
attribute 'DnsDomain'
|
461
597
|
end
|
462
598
|
end
|
463
599
|
end
|
@@ -466,7 +602,7 @@ end
|
|
466
602
|
|
467
603
|
### DependsOn
|
468
604
|
|
469
|
-
`DependsOn` - this will include any globally exported libraries from given
|
605
|
+
`DependsOn` - this will include any globally exported libraries from given
|
470
606
|
template. E.g.
|
471
607
|
|
472
608
|
```ruby
|
@@ -475,8 +611,8 @@ CfhighlanderTemplate do
|
|
475
611
|
DependsOn 'vpc@1.0.3'
|
476
612
|
end
|
477
613
|
```
|
478
|
-
|
479
|
-
Will include any cfndsl libraries present and exported in vpc template
|
614
|
+
|
615
|
+
Will include any cfndsl libraries present and exported in vpc template
|
480
616
|
so extension methods can be consumed within cfndsl template.
|
481
617
|
|
482
618
|
### LambdaFunctions
|
@@ -507,19 +643,19 @@ CfhighlanderTemplate do
|
|
507
643
|
|
508
644
|
# pulls directly from master branch of https://github.com/theonestack/hl-component-vpc
|
509
645
|
Component name: 'vpc0', template: 'vpc'
|
510
|
-
|
646
|
+
|
511
647
|
# specify branch github.com: or github: work. You specify branch with hash
|
512
648
|
Component name: 'vpc1', template: 'github:theonestack/hl-component-vpc#master'
|
513
|
-
|
649
|
+
|
514
650
|
# you can use git over ssh
|
515
651
|
# Component name: 'vpc2', template: 'git:git@github.com:theonestack/hl-component-vpc.git'
|
516
|
-
|
652
|
+
|
517
653
|
# use git over https
|
518
654
|
Component name: 'vpc3', template: 'git:https://github.com/theonestack/hl-component-sns.git'
|
519
|
-
|
655
|
+
|
520
656
|
# specify .snapshot to always clone fresh copy
|
521
657
|
Component name: 'vpc4', template: 'git:https://github.com/theonestack/hl-component-sns.git#master.snapshot'
|
522
|
-
|
658
|
+
|
523
659
|
# by default, if not found locally, highlander will search for https://github.com/theonestack/component-$componentname
|
524
660
|
# in v${version} branch (or tag for that matter)
|
525
661
|
Component name: 'vpc5', template: 'vpc@1.0.4'
|
@@ -538,6 +674,6 @@ $ cfhighlander cfcompile [component] [-v distributedversion]
|
|
538
674
|
|
539
675
|
## Global Extensions
|
540
676
|
|
541
|
-
Any extensions placed within `cfndsl_ext` folder will be
|
542
|
-
available in cfndsl templates of all components. Any extensions placed within `hl_ext` folder are
|
543
|
-
available in cfhighlander templates of all components.
|
677
|
+
Any extensions placed within `cfndsl_ext` folder will be
|
678
|
+
available in cfndsl templates of all components. Any extensions placed within `hl_ext` folder are
|
679
|
+
available in cfhighlander templates of all components.
|
data/bin/cfhighlander.rb
CHANGED
@@ -13,6 +13,7 @@ require_relative '../lib/cfhighlander.compiler'
|
|
13
13
|
require_relative '../lib/cfhighlander.factory'
|
14
14
|
require_relative '../lib/cfhighlander.publisher'
|
15
15
|
require_relative '../lib/cfhighlander.validator'
|
16
|
+
require_relative '../hl_ext/aws_helper'
|
16
17
|
|
17
18
|
class HighlanderCli < Thor
|
18
19
|
|
@@ -69,7 +70,7 @@ class HighlanderCli < Thor
|
|
69
70
|
method_option :quiet, :type => :boolean, :default => false, :aliases => '-q',
|
70
71
|
:desc => 'Silently agree on user prompts (e.g. Package lambda command)'
|
71
72
|
|
72
|
-
def cfcompile(component_name = nil)
|
73
|
+
def cfcompile(component_name = nil, autogenerate_dist = false)
|
73
74
|
|
74
75
|
if component_name.nil?
|
75
76
|
candidates = Dir["*.cfhighlander.rb"]
|
@@ -83,6 +84,13 @@ class HighlanderCli < Thor
|
|
83
84
|
|
84
85
|
component = build_component(options, component_name)
|
85
86
|
|
87
|
+
if component.distribution_bucket.nil? or component.distribution_prefix.nil?
|
88
|
+
component.distribution_bucket="#{aws_account_id()}.#{aws_current_region()}.cfhighlander.templates" if component.distribution_bucket.nil?
|
89
|
+
component.distribution_prefix="published-templates/#{component.name}" if component.distribution_prefix.nil?
|
90
|
+
puts "INFO: Reloading component, as auto-generated distribution settings are being applied..."
|
91
|
+
component.load
|
92
|
+
end if autogenerate_dist
|
93
|
+
|
86
94
|
# compile cloud formation
|
87
95
|
component_compiler = Cfhighlander::Compiler::ComponentCompiler.new(component)
|
88
96
|
component_compiler.silent_mode = options[:quiet]
|
@@ -111,9 +119,12 @@ class HighlanderCli < Thor
|
|
111
119
|
:desc => 'Silently agree on user prompts (e.g. Package lambda command)'
|
112
120
|
|
113
121
|
def cfpublish(component_name)
|
114
|
-
compiler = cfcompile(component_name)
|
122
|
+
compiler = cfcompile(component_name, true)
|
115
123
|
publisher = Cfhighlander::Publisher::ComponentPublisher.new(compiler.component, false)
|
116
124
|
publisher.publishFiles(compiler.cfn_template_paths + compiler.lambda_src_paths)
|
125
|
+
|
126
|
+
puts "\n\nUse following url to launch CloudFormation stack\n\n#{publisher.getLaunchStackUrl}\n\n"
|
127
|
+
|
117
128
|
end
|
118
129
|
|
119
130
|
|
data/hl_ext/aws_helper.rb
CHANGED
@@ -1,13 +1,35 @@
|
|
1
1
|
require 'aws-sdk-s3'
|
2
|
+
require 'aws-sdk-ec2'
|
2
3
|
|
3
4
|
def aws_credentials
|
4
5
|
# TODO implement credentials e.g. for environment create/update/delete
|
5
6
|
end
|
6
7
|
|
8
|
+
def aws_account_id()
|
9
|
+
sts = Aws::STS::Client.new
|
10
|
+
account = sts.get_caller_identity().account
|
11
|
+
return account
|
12
|
+
end
|
13
|
+
|
14
|
+
def aws_current_region()
|
15
|
+
region = Aws::EC2::Client.new.describe_availability_zones().availability_zones[0].region_name
|
16
|
+
return region
|
17
|
+
end
|
18
|
+
|
7
19
|
def s3_bucket_region(bucket)
|
8
20
|
s3 = Aws::S3::Client.new
|
9
21
|
location = s3.get_bucket_location({ bucket: bucket }).location_constraint
|
10
22
|
location = 'us-east-1' if location == ''
|
11
23
|
location = 'eu-west-1' if location == 'EU'
|
12
24
|
location
|
25
|
+
end
|
26
|
+
|
27
|
+
def s3_create_bucket_if_not_exists(bucket)
|
28
|
+
s3 = Aws::S3::Client.new
|
29
|
+
begin
|
30
|
+
s3.head_bucket(bucket: bucket)
|
31
|
+
rescue
|
32
|
+
puts(" INFO: Creating bucket #{bucket} ")
|
33
|
+
s3.create_bucket(bucket: bucket)
|
34
|
+
end
|
13
35
|
end
|
data/lib/cfhighlander.factory.rb
CHANGED
@@ -27,7 +27,7 @@ module Cfhighlander
|
|
27
27
|
raise StandardError, "highlander template #{template_name}@#{template_version} not located" +
|
28
28
|
" in sources #{@component_sources}" if template_meta.nil?
|
29
29
|
|
30
|
-
component_name = template_name if component_name.nil?
|
30
|
+
component_name = template_meta.template_name if component_name.nil?
|
31
31
|
return buildComponentFromLocation(template_meta, component_name)
|
32
32
|
|
33
33
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative './cfhighlander.compiler'
|
2
2
|
require 'aws-sdk-s3'
|
3
|
-
|
3
|
+
require 'uri'
|
4
4
|
module Cfhighlander
|
5
5
|
|
6
6
|
module Publisher
|
@@ -16,6 +16,9 @@ module Cfhighlander
|
|
16
16
|
bucket = @component.highlander_dsl.distribution_bucket
|
17
17
|
prefix = @component.highlander_dsl.distribution_prefix
|
18
18
|
version = @component.highlander_dsl.version
|
19
|
+
|
20
|
+
s3_create_bucket_if_not_exists(bucket)
|
21
|
+
|
19
22
|
s3 = Aws::S3::Client.new({ region: s3_bucket_region(bucket) })
|
20
23
|
|
21
24
|
existing_objects = s3.list_objects_v2({bucket: bucket, prefix: "#{prefix}/#{@component.name}/#{version}"})
|
@@ -37,11 +40,22 @@ module Cfhighlander
|
|
37
40
|
|
38
41
|
end
|
39
42
|
|
40
|
-
def
|
43
|
+
def getLaunchStackUrl
|
44
|
+
template_url = "https://#{@component.highlander_dsl.distribution_bucket}.s3.amazonaws.com/"
|
45
|
+
template_url += @component.highlander_dsl.distribution_prefix + "/"
|
46
|
+
template_url += @component.highlander_dsl.version
|
47
|
+
region = s3_bucket_region(@component.highlander_dsl.distribution_bucket)
|
48
|
+
template_url += "/#{@component.name}.compiled.yaml"
|
49
|
+
return "https://console.aws.amazon.com/cloudformation/home?region=#{region}#/stacks/create/review?filter=active&templateURL=" +
|
50
|
+
"#{URI::encode(template_url)}&stackName=#{@component.name}"
|
51
|
+
end
|
41
52
|
|
53
|
+
def publishFiles(file_list)
|
42
54
|
bucket = @component.highlander_dsl.distribution_bucket
|
43
55
|
prefix = @component.highlander_dsl.distribution_prefix
|
44
56
|
version = @component.highlander_dsl.version
|
57
|
+
|
58
|
+
s3_create_bucket_if_not_exists(bucket)
|
45
59
|
s3 = Aws::S3::Client.new({ region: s3_bucket_region(bucket) })
|
46
60
|
|
47
61
|
s3.list_objects_v2(bucket: bucket, prefix: "#{prefix}/#{version}").contents.each do |s3obj|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cfhighlander
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.0.alpha.
|
4
|
+
version: 0.4.0.alpha.1532390766
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikola Tosic
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-07-
|
12
|
+
date: 2018-07-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: highline
|