cfer 0.3.0 → 0.4.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 +4 -4
- data/.gitignore +1 -1
- data/README.md +39 -1
- data/Rakefile +1 -56
- data/cfer.gemspec +13 -14
- data/examples/common/instance_deps.rb +3 -3
- data/examples/instance.rb +15 -21
- data/lib/cfer.rb +83 -7
- data/lib/cfer/block.rb +42 -0
- data/lib/cfer/cfn/cfer_credentials_provider.rb +72 -0
- data/lib/cfer/cfn/client.rb +121 -18
- data/lib/cfer/cli.rb +40 -1
- data/lib/cfer/core/client.rb +11 -0
- data/lib/cfer/core/resource.rb +16 -18
- data/lib/cfer/core/stack.rb +85 -14
- data/lib/cfer/util/error.rb +8 -0
- data/lib/cfer/version.rb +7 -1
- data/lib/cferext/aws/auto_scaling/auto_scaling_group.rb +6 -0
- data/lib/cferext/aws/iam/policy.rb +30 -0
- data/lib/cferext/aws/iam/policy_generator.rb +54 -0
- metadata +84 -58
- data/examples/chef_instance.rb +0 -56
- data/lib/cferext/aws/auto_scaling/launch_configuration.rb +0 -15
- data/lib/cferext/aws/ec2/instance.rb +0 -15
- data/lib/cferext/provisioning.rb +0 -16
- data/lib/cferext/provisioning/cfn-bootstrap.rb +0 -186
- data/lib/cferext/provisioning/chef.rb +0 -75
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'cferext/provisioning'
|
2
|
-
|
3
|
-
require 'base64'
|
4
|
-
require 'yaml'
|
5
|
-
|
6
|
-
module CferExt::AWS::AutoScaling
|
7
|
-
class LaunchConfiguration < Cfer::Cfn::Resource
|
8
|
-
include CferExt::Provisioning
|
9
|
-
|
10
|
-
def initialize(name, type, options = {}, &block)
|
11
|
-
options[:Metadata] ||= {}
|
12
|
-
super(name, type, options, &block)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'cferext/provisioning'
|
2
|
-
|
3
|
-
require 'base64'
|
4
|
-
require 'yaml'
|
5
|
-
|
6
|
-
module CferExt::AWS::EC2
|
7
|
-
class Instance < Cfer::Cfn::Resource
|
8
|
-
include CferExt::Provisioning
|
9
|
-
|
10
|
-
def initialize(name, type, options = {}, &block)
|
11
|
-
options[:Metadata] ||= {}
|
12
|
-
super(name, type, options, &block)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/lib/cferext/provisioning.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
module CferExt::Provisioning
|
2
|
-
def cloud_config(options)
|
3
|
-
data = ::YAML.dump(cloud_init_data.stringify_keys)
|
4
|
-
user_data Cfer::Core::Fn::base64("#cloud-config\n##{data}")
|
5
|
-
end
|
6
|
-
|
7
|
-
def shell_init(script, options = {})
|
8
|
-
data = "#!#{options[:shell] || '/usr/bin/env bash'}\n#{cloud_init_data}"
|
9
|
-
user_data Cfer::Core::Fn::base64(data)
|
10
|
-
end
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
require_relative 'provisioning/cfn-bootstrap.rb'
|
15
|
-
require_relative 'provisioning/chef.rb'
|
16
|
-
|
@@ -1,186 +0,0 @@
|
|
1
|
-
module CferExt::Provisioning
|
2
|
-
|
3
|
-
def cfn_auth(name, options = {})
|
4
|
-
self[:Metadata]['AWS::CloudFormation::Authentication'] ||= {}
|
5
|
-
self[:Metadata]['AWS::CloudFormation::Authentication'][name] = options
|
6
|
-
end
|
7
|
-
|
8
|
-
def cfn_init_setup(options = {})
|
9
|
-
self[:Metadata]['AWS::CloudFormation::Init'] = {}
|
10
|
-
|
11
|
-
script = [ "#!/bin/bash -xe\n" ]
|
12
|
-
|
13
|
-
script.concat case options[:flavor]
|
14
|
-
when :redhat, :centos, :amazon
|
15
|
-
[
|
16
|
-
"rpm -Uvh https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.amzn1.noarch.rpm\n"
|
17
|
-
]
|
18
|
-
when :ubuntu, :debian, nil
|
19
|
-
[
|
20
|
-
"apt-get update --fix-missing\n",
|
21
|
-
"apt-get install -y python-pip\n",
|
22
|
-
"pip install setuptools\n",
|
23
|
-
"easy_install https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz\n",
|
24
|
-
]
|
25
|
-
end
|
26
|
-
|
27
|
-
script.concat [
|
28
|
-
"# Helper function\n",
|
29
|
-
"function error_exit\n",
|
30
|
-
"{\n",
|
31
|
-
]
|
32
|
-
|
33
|
-
if options[:signal]
|
34
|
-
script.concat [
|
35
|
-
"/usr/local/bin/cfn-signal",
|
36
|
-
" -s false",
|
37
|
-
" --resource '", options[:signal], "'",
|
38
|
-
" --stack ", Cfer::Cfn::AWS::stack_name,
|
39
|
-
" --region ", Cfer::Cfn::AWS::region,
|
40
|
-
"\n"
|
41
|
-
]
|
42
|
-
end
|
43
|
-
|
44
|
-
script.concat [
|
45
|
-
" exit 1\n",
|
46
|
-
"}\n"
|
47
|
-
]
|
48
|
-
|
49
|
-
|
50
|
-
script.concat [
|
51
|
-
"/usr/local/bin/cfn-init",
|
52
|
-
" --configsets '", Cfer::Core::Fn::join(',', options[:cfn_init_config_set]) || raise('Please specify a `cfn_init_config_set`'), "'",
|
53
|
-
" --stack ", Cfer::Cfn::AWS::stack_name,
|
54
|
-
" --resource ", @name,
|
55
|
-
" --region ", Cfer::Cfn::AWS::region,
|
56
|
-
" || error_exit 'Failed to run cfn-init'\n"
|
57
|
-
]
|
58
|
-
|
59
|
-
if options[:cfn_hup_config_set]
|
60
|
-
cfn_hup(options)
|
61
|
-
|
62
|
-
script.concat [
|
63
|
-
"/usr/local/bin/cfn-hup || error_exit 'Failed to start cfn-hup'\n"
|
64
|
-
]
|
65
|
-
end
|
66
|
-
|
67
|
-
if options[:signal]
|
68
|
-
script.concat [
|
69
|
-
"/usr/local/bin/cfn-signal",
|
70
|
-
" -s true",
|
71
|
-
" --resource '", options[:signal], "'",
|
72
|
-
" --stack ", Cfer::Cfn::AWS::stack_name,
|
73
|
-
" --region ", Cfer::Cfn::AWS::region,
|
74
|
-
"\n"
|
75
|
-
]
|
76
|
-
end
|
77
|
-
|
78
|
-
user_data Cfer::Core::Fn::base64(
|
79
|
-
Cfer::Core::Fn::join('', script)
|
80
|
-
)
|
81
|
-
end
|
82
|
-
|
83
|
-
def config_set(name)
|
84
|
-
{ "ConfigSet" => name }
|
85
|
-
end
|
86
|
-
|
87
|
-
def cfn_init_config_set(name, sections)
|
88
|
-
cfg_sets = cloudformation_init['configSets'] || {}
|
89
|
-
cfg_set = Set.new(cfg_sets[name] || [])
|
90
|
-
cfg_set.merge sections
|
91
|
-
cfg_sets[name] = cfg_set.to_a
|
92
|
-
cloudformation_init['configSets'] = cfg_sets
|
93
|
-
end
|
94
|
-
|
95
|
-
def cfn_init_config(name, options = {}, &block)
|
96
|
-
cfg = ConfigSet.new(cloudformation_init[name])
|
97
|
-
cfg.instance_eval(&block)
|
98
|
-
cloudformation_init[name] = cfg.to_h
|
99
|
-
end
|
100
|
-
|
101
|
-
private
|
102
|
-
|
103
|
-
class ConfigSet
|
104
|
-
def initialize(hash)
|
105
|
-
@config_set = hash || {}
|
106
|
-
end
|
107
|
-
|
108
|
-
def to_h
|
109
|
-
@config_set
|
110
|
-
end
|
111
|
-
|
112
|
-
def commands
|
113
|
-
@config_set['commands'] ||= {}
|
114
|
-
end
|
115
|
-
|
116
|
-
def files
|
117
|
-
@config_set['files'] ||= {}
|
118
|
-
end
|
119
|
-
|
120
|
-
def packages
|
121
|
-
@config_set['packages'] ||= {}
|
122
|
-
end
|
123
|
-
|
124
|
-
def command(name, cmd, options = {})
|
125
|
-
commands[name] = options.merge('command' => cmd)
|
126
|
-
end
|
127
|
-
|
128
|
-
def file(path, options = {})
|
129
|
-
files[path] = options
|
130
|
-
end
|
131
|
-
|
132
|
-
def package(type, name, versions = [])
|
133
|
-
packages[type] ||= {}
|
134
|
-
packages[type][name] = versions
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
def cloudformation_init(options = {})
|
139
|
-
raise "Set up cfn-init using cfn_init_setup first" unless self[:Metadata]['AWS::CloudFormation::Init']
|
140
|
-
self[:Metadata]['AWS::CloudFormation::Init']
|
141
|
-
end
|
142
|
-
|
143
|
-
|
144
|
-
def cfn_hup(options)
|
145
|
-
resource_name = @name
|
146
|
-
target_config_set = options[:cfn_hup_config_set] || raise('Please specify a `cfn_hup_config_set`')
|
147
|
-
|
148
|
-
cfn_init_config_set :cfn_hup, [ :cfn_hup ]
|
149
|
-
|
150
|
-
cfn_init_config(:cfn_hup) do
|
151
|
-
if options[:access_key] && options[:secret_key]
|
152
|
-
file '/etc/cfn/cfn-credentials', content: Cfer::Core::Fn::join('', [
|
153
|
-
"AWSAccessKeyId=", options[:access_key], "\n",
|
154
|
-
"AWSSecretKey=", options[:secret_key], "\n"
|
155
|
-
]),
|
156
|
-
mode: '000400',
|
157
|
-
owner: 'root',
|
158
|
-
group: 'root'
|
159
|
-
end
|
160
|
-
|
161
|
-
file '/etc/cfn/cfn-hup.conf', content: Cfer::Core::Fn::join('', [
|
162
|
-
"[main]\n",
|
163
|
-
"stack=", Cfer::Cfn::AWS::stack_name, "\n",
|
164
|
-
"region=", Cfer::Cfn::AWS::region, "\n",
|
165
|
-
"interval=", options[:interval] || 1, "\n"
|
166
|
-
]),
|
167
|
-
mode: '000400',
|
168
|
-
owner: 'root',
|
169
|
-
group: 'root'
|
170
|
-
|
171
|
-
file '/etc/cfn/hooks.d/cfn-init-reload.conf', content: Cfer::Core::Fn::join('', [
|
172
|
-
"[cfn-auto-reloader-hook]\n",
|
173
|
-
"triggers=post.update\n",
|
174
|
-
"path=Resources.#{resource_name}.Metadata.AWS::CloudFormation::Init\n",
|
175
|
-
"action=/usr/local/bin/cfn-init",
|
176
|
-
" -c '", Cfer::Core::Fn::join(',', target_config_set), "'",
|
177
|
-
" -s ", Cfer::Cfn::AWS::stack_name,
|
178
|
-
" --region ", Cfer::Cfn::AWS::region,
|
179
|
-
" -r #{resource_name}",
|
180
|
-
"\n",
|
181
|
-
"runas=root\n"
|
182
|
-
])
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
@@ -1,75 +0,0 @@
|
|
1
|
-
require 'erubis'
|
2
|
-
|
3
|
-
module CferExt::Provisioning
|
4
|
-
|
5
|
-
def install_chef(options = {})
|
6
|
-
setup_set = [ :install_chef ]
|
7
|
-
run_set = [ :run_chef ]
|
8
|
-
cfn_init_config :install_chef do
|
9
|
-
command :install_chef, "curl https://www.opscode.com/chef/install.sh | bash -s -- -v #{options[:version] || 'latest'}"
|
10
|
-
command :make_ohai_hints, 'mkdir -p /etc/chef/ohai/hints && touch /etc/chef/ohai/hints/ec2.json'
|
11
|
-
command :make_chefdir, 'mkdir -p /var/chef/cookbooks && mkdir -p /var/chef/data_bags'
|
12
|
-
end
|
13
|
-
|
14
|
-
if options[:berksfile]
|
15
|
-
cfn_init_config :install_berkshelf do
|
16
|
-
file '/var/chef/berkshelf.sh', content: <<-EOF.strip_heredoc
|
17
|
-
export BERKSHELF_PATH=/var/chef/berkshelf
|
18
|
-
|
19
|
-
# Some cookbooks have UTF-8, and cfn-init uses US-ASCII because of reasons
|
20
|
-
export LANG=en_US.UTF-8
|
21
|
-
export RUBYOPTS="-E utf-8"
|
22
|
-
|
23
|
-
# Berkshelf seems a bit unreliable, so retry these commands a couple times.
|
24
|
-
if [ -e Berksfile.lock ]
|
25
|
-
then
|
26
|
-
for i in {1..3}; do /opt/chef/embedded/bin/berks update && break || sleep 15; done
|
27
|
-
fi
|
28
|
-
for i in {1..3}; do /opt/chef/embedded/bin/berks vendor /var/chef/cookbooks -b /var/chef/Berksfile && break || sleep 15; done
|
29
|
-
EOF
|
30
|
-
command :install_berkshelf, '/opt/chef/embedded/bin/gem install berkshelf --no-ri --no-rdoc'
|
31
|
-
command :install_git, 'apt-get install -y git'
|
32
|
-
end
|
33
|
-
setup_set.append :install_berkshelf
|
34
|
-
end
|
35
|
-
|
36
|
-
if options[:berksfile]
|
37
|
-
cfn_init_config :run_berkshelf do
|
38
|
-
file '/var/chef/Berksfile', content: options[:berksfile].strip_heredoc
|
39
|
-
command :run_berkshelf, 'bash -l /var/chef/berkshelf.sh', cwd: '/var/chef'
|
40
|
-
end
|
41
|
-
run_set.prepend :run_berkshelf
|
42
|
-
end
|
43
|
-
|
44
|
-
cfn_init_config_set :install_chef, setup_set
|
45
|
-
cfn_init_config_set :run_chef, run_set
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
def chef_solo(options = {})
|
50
|
-
raise "Chef already configured on this resource" if @chef
|
51
|
-
@chef = true
|
52
|
-
|
53
|
-
chef_config = options[:node] || raise('`node` required when setting up chef')
|
54
|
-
|
55
|
-
install_chef(options)
|
56
|
-
|
57
|
-
cfn_init_config :run_chef do
|
58
|
-
file "/etc/chef/solo.rb", content: options[:solo_rb] || Cfer::Core::Fn::join("\n", [
|
59
|
-
"cookbook_path '/var/chef/cookbooks'",
|
60
|
-
"log_location '/var/log/chef-client.log'"
|
61
|
-
]),
|
62
|
-
owner: 'root',
|
63
|
-
group: 'root'
|
64
|
-
|
65
|
-
file "/etc/chef/config.json", content: chef_config.to_json,
|
66
|
-
owner: 'root',
|
67
|
-
group: 'root'
|
68
|
-
|
69
|
-
chef_cmd = 'chef-solo -c /etc/chef/solo.rb -j /etc/chef/config.json'
|
70
|
-
chef_cmd << " -o '#{options[:run_list].join(',')}'" if options[:run_list]
|
71
|
-
command :run_chef, chef_cmd
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|