cfer 0.2.0 → 0.3.0
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 +5 -13
- data/.codeclimate.yml +25 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +1168 -0
- data/.travis.yml +14 -1
- data/Gemfile +2 -0
- data/README.md +48 -10
- data/Rakefile +6 -7
- data/cfer.gemspec +2 -1
- data/examples/chef_instance.rb +56 -0
- data/examples/common/instance_deps.rb +34 -0
- data/examples/instance.rb +3 -36
- data/examples/vpc.rb +1 -1
- data/lib/cfer.rb +42 -23
- data/lib/cfer/cfn/client.rb +124 -50
- data/lib/cfer/cli.rb +13 -4
- data/lib/cfer/core/client.rb +0 -4
- data/lib/cfer/core/fn.rb +7 -7
- data/lib/cfer/core/resource.rb +1 -1
- data/lib/cfer/core/stack.rb +24 -36
- data/lib/cfer/util/error.rb +3 -0
- data/lib/cfer/version.rb +1 -1
- data/lib/cferext/aws/auto_scaling/launch_configuration.rb +15 -0
- data/lib/cferext/aws/ec2/instance.rb +3 -0
- data/lib/cferext/provisioning.rb +12 -2
- data/lib/cferext/provisioning/cfn-bootstrap.rb +186 -0
- data/lib/cferext/provisioning/chef.rb +75 -0
- metadata +58 -36
- data/cfer-demo.gif +0 -0
data/.travis.yml
CHANGED
@@ -1,11 +1,24 @@
|
|
1
1
|
language: ruby
|
2
2
|
install: bundle install --without debug --jobs=3 --retry=3
|
3
3
|
rvm:
|
4
|
-
- 2.1
|
4
|
+
- 2.1
|
5
|
+
- 2.2
|
6
|
+
- 2.3.0
|
5
7
|
- ruby-head
|
8
|
+
matrix:
|
9
|
+
allow_failures:
|
10
|
+
- rvm: ruby-head
|
11
|
+
branches:
|
12
|
+
only:
|
13
|
+
- master
|
14
|
+
- develop
|
6
15
|
script:
|
7
16
|
- bundle exec rspec
|
8
17
|
- bundle exec yard
|
18
|
+
addons:
|
19
|
+
code_climate:
|
20
|
+
repo_token:
|
21
|
+
secure: yokaltZRMTADMBq/htRjXYxchq4e7e66Zlvv0DrLs3yppy3bpCKbXkmtZdUm4XoxOA8fcoeFB0/VVuijmkdpJd2fAj1dc8RDb5uEdwA6ifI2ni1wKZHg15YheL4VwvDK1Nhb9Gr06uXReQ1Fy6jYcXDktyirbX7/AN/csD83IEQ29U58DVCwPxtG1k3h8ji6r/BMayzAd3T/bAeNkLd6t7YIdUAQHqIQsHsER/wQEYRTBVrx+D9b5rj2UluctfJDmpM61lvQnMt6VfgewzGXZCKNdY2DAvySaNg4+9/saZt3Ygpnt7Ef7uBMqgWTayNQ0Wk2VZSUvvLDRAKg+3WLBXTUnbFKK4/GT2T/37Rw9KQGDBJATjDLvNkS1V6Ikzg/4eNtni9RsV/bIwEaYg4CjhVEccj9fa1iPl+2Nzyw7q15UUT89TYJR3L00MQ+M7j5BDgg48kmg2tXBL62kIj/mFzEGuwNLn5nuVkwlnciQ5KCNDrQmN7XL3sPSDyIQ1dAezuj/CAqrRu43KukNZPn9TK9z/NPLUfHvco2E10Mlsw4gXiSp8j1WOmgcenivAoP2x4z5isZ2FShXkxLGq/sT0R4Ko+oGTnD/ghIHuhY3dUDfBhpOkq1wrFB73GjnUh5cYetlS3MvOj0dxT0iUK4oNp1/ds2Bn8in6juiOkN/Zc=
|
9
22
|
deploy:
|
10
23
|
provider: rubygems
|
11
24
|
api_key:
|
data/Gemfile
CHANGED
@@ -8,6 +8,7 @@ group :test do
|
|
8
8
|
gem 'rspec-mocks'
|
9
9
|
gem 'guard-rspec'
|
10
10
|
gem 'coveralls', require: false
|
11
|
+
gem "codeclimate-test-reporter", require: nil
|
11
12
|
end
|
12
13
|
|
13
14
|
group :debug do
|
@@ -15,4 +16,5 @@ group :debug do
|
|
15
16
|
gem 'pry-byebug'
|
16
17
|
gem 'pry-rescue'
|
17
18
|
gem 'pry-stack_explorer'
|
19
|
+
gem 'travis'
|
18
20
|
end
|
data/README.md
CHANGED
@@ -1,13 +1,22 @@
|
|
1
1
|
# Cfer
|
2
2
|
|
3
3
|
[](https://travis-ci.org/seanedwards/cfer)
|
4
|
-
[](https://coveralls.io/r/seanedwards/cfer)
|
5
4
|
[](http://badge.fury.io/rb/cfer)
|
5
|
+
[](https://codeclimate.com/github/seanedwards/cfer)
|
6
|
+
[](https://codeclimate.com/github/seanedwards/cfer/coverage)
|
7
|
+
[](https://codeclimate.com/github/seanedwards/cfer)
|
8
|
+
|
6
9
|
|
7
10
|
Cfer is a lightweight toolkit for managing CloudFormation templates.
|
8
11
|
|
9
12
|
Read about Cfer [here](http://tilmonedwards.com/2015/07/28/cfer.html).
|
10
13
|
|
14
|
+
## Support
|
15
|
+
|
16
|
+
Cfer is pre-1.0 software, and may contain bugs or incomplete features. Please see the [license](https://github.com/seanedwards/cfer/blob/master/LICENSE.txt) for disclaimers.
|
17
|
+
|
18
|
+
If you would like support or guidance on Cfer, or CloudFormation in general, I offer DevOps consulting services. Please [Contact Bitlancer](http://www.bitlancer.com/contact-us/) and we'll be happy to discuss your needs.
|
19
|
+
|
11
20
|
## Installation
|
12
21
|
|
13
22
|
Add this line to your application's Gemfile:
|
@@ -35,12 +44,12 @@ cfer converge instance -t examples/instance.rb --profile [YOUR-PROFILE] --region
|
|
35
44
|
|
36
45
|
You should see something like this:
|
37
46
|
|
38
|
-

|
47
|
+

|
39
48
|
|
40
49
|
### Command line
|
41
50
|
|
42
51
|
Commands:
|
43
|
-
cfer converge [OPTIONS] <stack-name> #
|
52
|
+
cfer converge [OPTIONS] <stack-name> # Creates or updates a cloudformation stack according to the template
|
44
53
|
cfer generate [OPTIONS] <template.rb> # Generates a CloudFormation template by evaluating a Cfer template
|
45
54
|
cfer help [COMMAND] # Describe available commands or one specific command
|
46
55
|
cfer tail <stack-name> # Follows stack events on standard output as they occur
|
@@ -65,10 +74,12 @@ Creates or updates a CloudFormation stack according to the specified template.
|
|
65
74
|
|
66
75
|
The following options may be used with the `converge` command:
|
67
76
|
|
68
|
-
* `--follow` (`-f`): Follows stack events on standard output as the create/update process takes place.
|
77
|
+
* `--follow` (`-f`): Follows stack events on standard output as the create/update process takes place.
|
69
78
|
* `--stack-file <template.rb>`: Reads this file from the filesystem, rather than the default `<stack-name>.rb`
|
70
79
|
* `--parameters <Key1>:<Value1> <Key2>:<Value2> ...`: Specifies input parameters, which will be available to Ruby in the `parameters` hash, or to CloudFormation by using the `Fn::ref` function
|
71
80
|
* `--on-failure <DELETE|ROLLBACK|DO_NOTHING>`: Specifies the action to take when a stack creation fails. Has no effect if the stack already exists and is being updated.
|
81
|
+
* `--stack-policy <filename|URL|JSON string>` (`-s`): Stack policy to apply to the stack in order to control updates; takes a local filename containing the policy, a URL to an S3 object, or a raw JSON string.
|
82
|
+
* `--stack-policy-during-update <filename|URL|JSON string>` (`-u`): Stack policy as in `--stack-policy` option above, but applied as a temporary override to the permanent policy during stack update.
|
72
83
|
|
73
84
|
#### `tail <stack-name>`
|
74
85
|
|
@@ -76,7 +87,7 @@ Prints the latest `n` stack events, and optionally follows events while a stack
|
|
76
87
|
|
77
88
|
The following options may be used with the `tail` command:
|
78
89
|
|
79
|
-
* `--follow` (`-f`): Follows stack events on standard output as the create/update process takes place.
|
90
|
+
* `--follow` (`-f`): Follows stack events on standard output as the create/update process takes place.
|
80
91
|
* `--number` (`-n`): Print the last `n` stack events.
|
81
92
|
|
82
93
|
### Template Anatomy
|
@@ -93,8 +104,6 @@ parameter :ParameterName,
|
|
93
104
|
default: 'ParameterValue'
|
94
105
|
```
|
95
106
|
|
96
|
-
A parameter's value may have the form `@stack.output` to look up output values from other stacks in the same account and region. This works anywhere a parameter value is specified, including defaults and inputs. (See the SDK section on [Cfer Stacks](#cfer-stacks) for caveats.)
|
97
|
-
|
98
107
|
Any parameter can be referenced either in Ruby by using the `parameters` hash:
|
99
108
|
|
100
109
|
```ruby
|
@@ -139,6 +148,12 @@ Outputs may be defined using the `output` function:
|
|
139
148
|
output :OutputName, Fn::ref(:ResourceName)
|
140
149
|
```
|
141
150
|
|
151
|
+
Outputs may be retireved from other stacks anywhere in a template by using the `lookup_output` function.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
lookup_output('stack_name', 'output_name')
|
155
|
+
```
|
156
|
+
|
142
157
|
#### Including code from multiple files
|
143
158
|
|
144
159
|
Templates can get pretty large, and splitting template code into multiple
|
@@ -229,15 +244,13 @@ stack = Cfer::stack_from_block(client: <client>) do
|
|
229
244
|
end
|
230
245
|
```
|
231
246
|
|
232
|
-
Note: Specifying a client is optional, but if no client is specified, parameter mappings will not occur.
|
233
|
-
|
234
247
|
## Contributing
|
235
248
|
|
236
249
|
This project uses [git-flow](http://nvie.com/posts/a-successful-git-branching-model/). Please name branches and pull requests according to that convention.
|
237
250
|
|
238
251
|
Always use `--no-ff` when merging into `develop` or `master`.
|
239
252
|
|
240
|
-
This project also contains a [Code of Conduct](CODE_OF_CONDUCT.md), which should be followed when submitting feedback or contributions to this project.
|
253
|
+
This project also contains a [Code of Conduct](https://github.com/seanedwards/cfer/blob/master/CODE_OF_CONDUCT.md), which should be followed when submitting feedback or contributions to this project.
|
241
254
|
|
242
255
|
### New features
|
243
256
|
|
@@ -263,3 +276,28 @@ This project also contains a [Code of Conduct](CODE_OF_CONDUCT.md), which should
|
|
263
276
|
* Merge into `develop` and `master`
|
264
277
|
* Name branch `release/<major.minor>`
|
265
278
|
|
279
|
+
# Release Notes
|
280
|
+
|
281
|
+
## 0.3.0
|
282
|
+
|
283
|
+
### Enhancements:
|
284
|
+
* `parameters` hash now includes parameters that are set on the existing stack, but not passed in via CLI during a stack update.
|
285
|
+
* `parameters` hash now includes defaults for parameters that were not passed on the CLI during a stack creation.
|
286
|
+
* Adds a `lookup_output` function, for looking up outputs of stacks in the same account+region. (See #8)
|
287
|
+
* Adds provisioning for cfn-init and chef-solo, including resource signaling.
|
288
|
+
* Adds support for stack policies.
|
289
|
+
* Cfer no longer validates parameters itself. CloudFormation will throw an error if something is wrong.
|
290
|
+
* Adds release notes to the README.
|
291
|
+
|
292
|
+
### Bugfixes:
|
293
|
+
* Removes automatic parameter mapping in favor of an explicit function available to resources. (Fixes Issue #8)
|
294
|
+
* No more double-printing the stack summary when converging a stack with tailing enabled.
|
295
|
+
* Update demo to only use 2 AZs, since us-west-1 only has two.
|
296
|
+
* `AllowedValues` attribute on parameters is now an array, not a CSV string. (Thanks to @rlister)
|
297
|
+
|
298
|
+
## 0.2.0
|
299
|
+
|
300
|
+
### Enhancements:
|
301
|
+
* Adds support for including other files via `include_template` function.
|
302
|
+
* Adds basic Dockerfile
|
303
|
+
|
data/Rakefile
CHANGED
@@ -3,13 +3,11 @@ gem 'cfer'
|
|
3
3
|
require 'cfer'
|
4
4
|
require 'highline'
|
5
5
|
|
6
|
-
Cfer::LOGGER.level = Logger::DEBUG
|
7
|
-
|
8
6
|
task :default => [:spec]
|
9
7
|
|
10
8
|
task :config_aws, [:profile] do |t, args|
|
11
|
-
Aws.config.update region: ENV['AWS_REGION'] || 'us-east-1',
|
12
|
-
credentials: Aws::SharedCredentials.new(profile_name: ENV['AWS_PROFILE'] || 'default')
|
9
|
+
Aws.config.update region: ENV['AWS_REGION'] || ask('AWS Region?') { |q| q.default = 'us-east-1' },
|
10
|
+
credentials: Aws::SharedCredentials.new(profile_name: ENV['AWS_PROFILE'] || ask('AWS Profile?') { |q| q.default = 'default' })
|
13
11
|
end
|
14
12
|
|
15
13
|
task :vpc => :config_aws do |t, args|
|
@@ -22,7 +20,7 @@ task :describe_vpc => :config_aws do
|
|
22
20
|
Cfer.describe! 'vpc'
|
23
21
|
end
|
24
22
|
|
25
|
-
task :instance => :
|
23
|
+
task :instance => :vpc do |t, args|
|
26
24
|
key_pair = ask("Enter your EC2 KeyPair name: ")
|
27
25
|
|
28
26
|
Cfer.converge! 'instance',
|
@@ -48,10 +46,11 @@ task :converge => [:vpc, :instance]
|
|
48
46
|
# This task isn't really part of Cfer.
|
49
47
|
# It just makes it easier for me to release new versions.
|
50
48
|
task :release do
|
49
|
+
`git checkout master`
|
50
|
+
`git merge develop --no-ff -m 'Merge from develop for release'`
|
51
|
+
|
51
52
|
require_relative 'lib/cfer/version.rb'
|
52
53
|
|
53
|
-
`git checkout master`
|
54
|
-
`git merge develop --no-ff -m 'Merge from develop for release v#{Cfer::VERSION}'`
|
55
54
|
`git tag -m "Release v#{Cfer::VERSION}" #{Cfer::VERSION}`
|
56
55
|
end
|
57
56
|
|
data/cfer.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.name = "cfer"
|
8
8
|
spec.version = Cfer::VERSION
|
9
9
|
spec.authors = ["Sean Edwards"]
|
10
|
-
spec.email = ["stedwards87+
|
10
|
+
spec.email = ["stedwards87+cfer@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = %q{Toolkit for automating infrastructure using AWS CloudFormation}
|
13
13
|
spec.description = spec.summary
|
@@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_runtime_dependency 'highline'
|
31
31
|
spec.add_runtime_dependency 'table_print'
|
32
32
|
spec.add_runtime_dependency "rake"
|
33
|
+
spec.add_runtime_dependency "erubis"
|
33
34
|
|
34
35
|
spec.add_development_dependency "bundler"
|
35
36
|
spec.add_development_dependency "yard"
|
@@ -0,0 +1,56 @@
|
|
1
|
+
description 'Example stack template for a small EC2 instance'
|
2
|
+
|
3
|
+
# NOTE: This template depends on vpc.rb
|
4
|
+
|
5
|
+
# Include common template code that will be used for examples that create EC2 instances.
|
6
|
+
include_template 'common/instance_deps.rb'
|
7
|
+
|
8
|
+
resource :instance, "AWS::EC2::Instance",
|
9
|
+
# Set a creation policy so that the stack will wait for
|
10
|
+
# on-instance provisioning to complete before marking the instance
|
11
|
+
# as done.
|
12
|
+
:CreationPolicy => {
|
13
|
+
:ResourceSignal => {
|
14
|
+
:Count => 1
|
15
|
+
}
|
16
|
+
} do
|
17
|
+
# Chef provisioning depends on cfn-init, so set that up first.
|
18
|
+
# We will have the initial provisioning set up cfn-hup, install chef, and run our cookbooks.
|
19
|
+
# Cfn-hup will only rerun chef when the metadata changes.
|
20
|
+
cfn_init_setup signal: :instance,
|
21
|
+
cfn_init_config_set: [ :cfn_hup, :install_chef, :run_chef],
|
22
|
+
cfn_hup_config_set: [ :cfn_hup, :run_chef]
|
23
|
+
|
24
|
+
# Configure chef to generate a Berksfile that will download the AWS cookbook from the Chef supermarket.
|
25
|
+
# Set the run list to run the AWS cookbook, so our instance will have the AWS SDK available.
|
26
|
+
chef_solo version: 'latest',
|
27
|
+
node: {
|
28
|
+
cfer: {
|
29
|
+
demo: {
|
30
|
+
welcome: "Welcome to Cfer!"
|
31
|
+
}
|
32
|
+
},
|
33
|
+
run_list: 'recipe[ec2-demo]'
|
34
|
+
},
|
35
|
+
# We specify a berksfile inline, but you could read this from somewhere else in your repo too.
|
36
|
+
# This uses a simple cookbook to write a file, similar to the instance.rb example.
|
37
|
+
# Review this cookbook here: https://github.com/seanedwards/cfer-cookbook-demo
|
38
|
+
berksfile: <<-EOF
|
39
|
+
source "https://supermarket.chef.io"
|
40
|
+
cookbook 'ec2-demo', github: 'seanedwards/cfer-cookbook-demo', branch: 'master'
|
41
|
+
EOF
|
42
|
+
|
43
|
+
image_id Fn::ref(:ImageId)
|
44
|
+
instance_type Fn::ref(:InstanceType)
|
45
|
+
key_name Fn::ref(:KeyName)
|
46
|
+
|
47
|
+
network_interfaces [ {
|
48
|
+
AssociatePublicIpAddress: "true",
|
49
|
+
DeviceIndex: "0",
|
50
|
+
GroupSet: [ Fn::ref(:instancesg) ],
|
51
|
+
SubnetId: Fn::ref(:SubnetId)
|
52
|
+
} ]
|
53
|
+
end
|
54
|
+
|
55
|
+
output :instance, Fn::ref(:instance)
|
56
|
+
output :instanceip, Fn::get_att(:instance, :PublicIp)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# By not specifying a default value, a parameter becomes required.
|
2
|
+
# Specify this parameter by adding `--parameters KeyName:<ec2-keyname>` to your CLI options.
|
3
|
+
parameter :KeyName
|
4
|
+
|
5
|
+
# We define some more parameters the same way we did in the VPC template.
|
6
|
+
# Cfer will fetch the output values from the `vpc` stack we created earlier.
|
7
|
+
#
|
8
|
+
# If you created the VPC stack with a different name, you can overwrite these default values
|
9
|
+
# by adding `Vpc:<vpc_stack_name> to your `--parameters` option
|
10
|
+
parameter :Vpc, default: 'vpc'
|
11
|
+
parameter :VpcId, default: lookup_output(parameters[:Vpc], 'vpcid')
|
12
|
+
parameter :SubnetId, default: lookup_output(parameters[:Vpc], 'subnetid1')
|
13
|
+
|
14
|
+
# This is the Ubuntu 14.04 LTS HVM AMI provided by Amazon.
|
15
|
+
parameter :ImageId, default: 'ami-fce3c696'
|
16
|
+
parameter :InstanceType, default: 't2.nano'
|
17
|
+
|
18
|
+
# Define a security group to be applied to an instance.
|
19
|
+
# This one will allow SSH access from anywhere, and no other inbound traffic.
|
20
|
+
resource :instancesg, "AWS::EC2::SecurityGroup" do
|
21
|
+
group_description 'Wide-open SSH'
|
22
|
+
vpc_id Fn::ref(:VpcId)
|
23
|
+
|
24
|
+
# Parameter values can be Ruby arrays and hashes. These will be transformed to JSON.
|
25
|
+
# You could write your own functions to make stuff like this easier, too.
|
26
|
+
security_group_ingress [
|
27
|
+
{
|
28
|
+
CidrIp: '0.0.0.0/0',
|
29
|
+
IpProtocol: 'tcp',
|
30
|
+
FromPort: 22,
|
31
|
+
ToPort: 22
|
32
|
+
}
|
33
|
+
]
|
34
|
+
end
|
data/examples/instance.rb
CHANGED
@@ -2,42 +2,8 @@ description 'Example stack template for a small EC2 instance'
|
|
2
2
|
|
3
3
|
# NOTE: This template depends on vpc.rb
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
# Specify this parameter by adding `--parameters KeyName:<ec2-keyname>` to your CLI options.
|
8
|
-
parameter :KeyName
|
9
|
-
|
10
|
-
# We define some more parameters the same way we did in the VPC template.
|
11
|
-
# Cfer will interpret the default value by looking up the stack output named `vpcid`
|
12
|
-
# on the stack named `vpc`.
|
13
|
-
#
|
14
|
-
# If you created the VPC stack with a different name, you can overwrite these default values
|
15
|
-
# by adding `VpcId:@<vpc-stack-name>.vpcid SubnetId:@<vpc-stack-name>.subnetid1`
|
16
|
-
# to your `--parameters` option
|
17
|
-
parameter :VpcId, default: '@vpc.vpcid'
|
18
|
-
parameter :SubnetId, default: '@vpc.subnetid1'
|
19
|
-
|
20
|
-
# This is the Ubuntu 14.04 LTS HVM AMI provided by Amazon.
|
21
|
-
parameter :ImageId, default: 'ami-d05e75b8'
|
22
|
-
parameter :InstanceType, default: 't2.medium'
|
23
|
-
|
24
|
-
# Define a security group to be applied to an instance.
|
25
|
-
# This one will allow SSH access from anywhere, and no other inbound traffic.
|
26
|
-
resource :instancesg, "AWS::EC2::SecurityGroup" do
|
27
|
-
group_description 'Wide-open SSH'
|
28
|
-
vpc_id Fn::ref(:VpcId)
|
29
|
-
|
30
|
-
# Parameter values can be Ruby arrays and hashes. These will be transformed to JSON.
|
31
|
-
# You could write your own functions to make stuff like this easier, too.
|
32
|
-
security_group_ingress [
|
33
|
-
{
|
34
|
-
CidrIp: '0.0.0.0/0',
|
35
|
-
IpProtocol: 'tcp',
|
36
|
-
FromPort: 22,
|
37
|
-
ToPort: 22
|
38
|
-
}
|
39
|
-
]
|
40
|
-
end
|
5
|
+
# Include common template code that will be used for examples that create EC2 instances.
|
6
|
+
include_template 'common/instance_deps.rb'
|
41
7
|
|
42
8
|
# We can define extension objects, which extend the basic JSON-building
|
43
9
|
# functionality of Cfer. Cfer provides a few of these, but you're free
|
@@ -82,3 +48,4 @@ resource :instance, "AWS::EC2::Instance" do
|
|
82
48
|
end
|
83
49
|
|
84
50
|
output :instance, Fn::ref(:instance)
|
51
|
+
output :instanceip, Fn::get_att(:instance, :PublicIp)
|
data/examples/vpc.rb
CHANGED
@@ -49,7 +49,7 @@ resource :routetable, 'AWS::EC2::RouteTable' do
|
|
49
49
|
vpc_id Fn::ref(:vpc)
|
50
50
|
end
|
51
51
|
|
52
|
-
(1..
|
52
|
+
(1..2).each do |i|
|
53
53
|
resource "subnet#{i}", 'AWS::EC2::Subnet' do
|
54
54
|
# Other CloudFormation intrinsics, such as `Fn::Select` and `AWS::Region` are available as Ruby objects
|
55
55
|
# Inspecting these functions will reveal that they simply return a Ruby hash representing the same CloudFormation structures
|
data/lib/cfer.rb
CHANGED
@@ -20,22 +20,30 @@ module Cfer
|
|
20
20
|
module Core
|
21
21
|
end
|
22
22
|
|
23
|
+
%w{
|
24
|
+
DB
|
25
|
+
ASG
|
26
|
+
}.each do |acronym|
|
27
|
+
ActiveSupport::Inflector.inflections.acronym acronym
|
28
|
+
end
|
29
|
+
|
23
30
|
# The Cfer logger
|
24
31
|
LOGGER = Logger.new(STDERR)
|
25
32
|
LOGGER.level = Logger::INFO
|
26
|
-
LOGGER.formatter = proc { |severity,
|
27
|
-
msg =
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
LOGGER.formatter = proc { |severity, _datetime, _progname, msg|
|
34
|
+
msg =
|
35
|
+
case severity
|
36
|
+
when 'FATAL'
|
37
|
+
Rainbow(msg).red.bright
|
38
|
+
when 'ERROR'
|
39
|
+
Rainbow(msg).red
|
40
|
+
when 'WARN'
|
41
|
+
Rainbow(msg).yellow
|
42
|
+
when 'DEBUG'
|
43
|
+
Rainbow(msg).black.bright
|
44
|
+
else
|
45
|
+
msg
|
46
|
+
end
|
39
47
|
|
40
48
|
"#{msg}\n"
|
41
49
|
}
|
@@ -47,8 +55,8 @@ module Cfer
|
|
47
55
|
tmpl = options[:template] || "#{stack_name}.rb"
|
48
56
|
cfn = options[:aws_options] || {}
|
49
57
|
|
50
|
-
cfn_stack = Cfer::Cfn::Client.new(cfn.merge(stack_name: stack_name))
|
51
|
-
stack = Cfer::stack_from_file(tmpl, options.merge(client: cfn_stack))
|
58
|
+
cfn_stack = options[:cfer_client] || Cfer::Cfn::Client.new(cfn.merge(stack_name: stack_name))
|
59
|
+
stack = options[:cfer_stack] || Cfer::stack_from_file(tmpl, options.merge(client: cfn_stack))
|
52
60
|
|
53
61
|
begin
|
54
62
|
cfn_stack.converge(stack, options)
|
@@ -58,25 +66,36 @@ module Cfer
|
|
58
66
|
rescue Aws::CloudFormation::Errors::ValidationError => e
|
59
67
|
Cfer::LOGGER.info "CFN validation error: #{e.message}"
|
60
68
|
end
|
61
|
-
describe! stack_name, options
|
69
|
+
describe! stack_name, options unless options[:follow]
|
62
70
|
end
|
63
71
|
|
64
72
|
def describe!(stack_name, options = {})
|
65
73
|
config(options)
|
66
74
|
cfn = options[:aws_options] || {}
|
67
|
-
cfn_stack = Cfer::Cfn::Client.new(cfn.merge(stack_name: stack_name))
|
75
|
+
cfn_stack = options[:cfer_client] || Cfer::Cfn::Client.new(cfn.merge(stack_name: stack_name))
|
76
|
+
cfn_stack = cfn_stack.fetch_stack
|
68
77
|
|
69
78
|
Cfer::LOGGER.debug "Describe stack: #{cfn_stack}"
|
70
79
|
|
71
|
-
case options[:output_format]
|
80
|
+
case options[:output_format]
|
72
81
|
when 'json'
|
73
82
|
puts render_json(cfn_stack, options)
|
74
|
-
when 'table'
|
83
|
+
when 'table', nil
|
75
84
|
puts "Status: #{cfn_stack[:stack_status]}"
|
76
85
|
puts "Description: #{cfn_stack[:description]}" if cfn_stack[:description]
|
77
86
|
puts ""
|
78
|
-
|
79
|
-
|
87
|
+
def tablify(list, type)
|
88
|
+
list ||= []
|
89
|
+
list.map { |param|
|
90
|
+
{
|
91
|
+
:Type => type.to_s.titleize,
|
92
|
+
:Key => param[:"#{type}_key"],
|
93
|
+
:Value => param[:"#{type}_value"]
|
94
|
+
}
|
95
|
+
}
|
96
|
+
end
|
97
|
+
parameters = tablify(cfn_stack[:parameters] || [], 'parameter')
|
98
|
+
outputs = tablify(cfn_stack[:outputs] || [], 'output')
|
80
99
|
tp parameters + outputs, :Type, :Key, {:Value => {:width => 80}}
|
81
100
|
else
|
82
101
|
raise Cfer::Util::CferError, "Invalid output format #{options[:output_format]}."
|
@@ -86,7 +105,7 @@ module Cfer
|
|
86
105
|
def tail!(stack_name, options = {}, &block)
|
87
106
|
config(options)
|
88
107
|
cfn = options[:aws_options] || {}
|
89
|
-
cfn_client = Cfer::Cfn::Client.new(cfn.merge(stack_name: stack_name))
|
108
|
+
cfn_client = options[:cfer_client] || Cfer::Cfn::Client.new(cfn.merge(stack_name: stack_name))
|
90
109
|
if block
|
91
110
|
cfn_client.tail(options, &block)
|
92
111
|
else
|
@@ -143,7 +162,7 @@ module Cfer
|
|
143
162
|
|
144
163
|
def render_json(obj, options = {})
|
145
164
|
if options[:pretty_print]
|
146
|
-
puts JSON.pretty_generate(obj)
|
165
|
+
puts JSON.pretty_generate(obj, options)
|
147
166
|
else
|
148
167
|
puts obj.to_json
|
149
168
|
end
|