cfhighlander 0.4.0.alpha.1531985380 → 0.4.0.alpha.1532390766
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
[](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
|