aws-carb 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/README.md +31 -0
- data/Rakefile +1 -0
- data/aws-carb.gemspec +32 -0
- data/bin/carb +14 -0
- data/configs/config.yaml.example +24 -0
- data/lib/aws-carb/cli_argument_parser.rb +359 -0
- data/lib/aws-carb/config.rb +166 -0
- data/lib/aws-carb/helpers.rb +17 -0
- data/lib/aws-carb/monkey_patches.rb +78 -0
- data/lib/aws-carb/services/ec2.rb +97 -0
- data/lib/aws-carb/services/route53.rb +86 -0
- data/lib/aws-carb/user_data.rb +103 -0
- data/lib/aws-carb/version.rb +3 -0
- data/lib/aws-carb.rb +129 -0
- data/templates/basic.cloud-config.erb +84 -0
- metadata +204 -0
@@ -0,0 +1,78 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# monkeypatch shell spinner to fix some bugs..
|
4
|
+
|
5
|
+
module ShellSpinner
|
6
|
+
class Runner
|
7
|
+
def wrap_block(text = nil, colorize = true, &block)
|
8
|
+
with_message(text) { with_spinner(&block) }
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
# FIXME: better way to disable colours?
|
14
|
+
#colorize = colorize ? lambda { |s,c| s.colorize(c) } : lambda { |s,c| s }
|
15
|
+
#colorize.call(s, :red)
|
16
|
+
|
17
|
+
def with_message(text = nil, colorize = false)
|
18
|
+
begin
|
19
|
+
print "#{text}... " unless text.nil?
|
20
|
+
|
21
|
+
catch_user_output { yield }
|
22
|
+
|
23
|
+
print "done\n".colorize(:green) unless text.nil?
|
24
|
+
|
25
|
+
print user_output.colorize(:blue)
|
26
|
+
|
27
|
+
rescue Exception => e
|
28
|
+
print "\bfail\n".colorize(:red) unless text.nil?
|
29
|
+
|
30
|
+
print user_output.colorize(:blue)
|
31
|
+
|
32
|
+
re_raise_exception e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def ShellSpinner(text = nil, colorize = true, &block)
|
39
|
+
runner = ShellSpinner::Runner.new
|
40
|
+
|
41
|
+
runner.wrap_block(text, colorize, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
# override the output from optparse to be a bit more aesthetically pleasing
|
45
|
+
module Subcommands
|
46
|
+
def print_actions
|
47
|
+
subcommand_help = "#{'SUBCOMMAND'.colorize({:color => :white, :mode => :bold})}\n"
|
48
|
+
|
49
|
+
@commands.each_pair do |c, opt|
|
50
|
+
subcommand_help << "\n #{c} - #{opt.call.description}"
|
51
|
+
end
|
52
|
+
|
53
|
+
unless @aliases.empty?
|
54
|
+
subcommand_help << "\n\naliases: \n"
|
55
|
+
@aliases.each_pair { |name, val| subcommand_help << " #{name} - #{val}\n" }
|
56
|
+
end
|
57
|
+
|
58
|
+
subcommand_help << "\n\n help <command> - for more information on a specific command\n\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
def command *names
|
62
|
+
name = names.shift
|
63
|
+
|
64
|
+
@commands ||= {}
|
65
|
+
@aliases ||= {}
|
66
|
+
|
67
|
+
names.each { |n| @aliases[n.to_s] = name.to_s } if names.length > 0
|
68
|
+
|
69
|
+
opt = lambda do
|
70
|
+
OptionParser.new do |opts|
|
71
|
+
yield opts
|
72
|
+
opts.banner << "OPTIONS"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
@commands[name.to_s] = opt
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module AWSCarb
|
4
|
+
module Services
|
5
|
+
class Ec2
|
6
|
+
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
attr_reader :instance
|
10
|
+
|
11
|
+
def client(config)
|
12
|
+
@config = config
|
13
|
+
@instance = nil
|
14
|
+
|
15
|
+
ShellSpinner "# configuring ec2 session", false do
|
16
|
+
begin
|
17
|
+
@client = AWS::EC2.new(config[:ec2])
|
18
|
+
@client.regions[@config.find_with_context(:region, :ec2)]
|
19
|
+
puts
|
20
|
+
rescue => e
|
21
|
+
puts "error: failed to create ec2 session, check that you're using a valid region!"
|
22
|
+
die e
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_instance
|
28
|
+
|
29
|
+
instance = nil
|
30
|
+
|
31
|
+
ShellSpinner "# creating instance", false do
|
32
|
+
|
33
|
+
# FIXME: this is naff
|
34
|
+
|
35
|
+
begin
|
36
|
+
allowed_ec2_parameters = [
|
37
|
+
:count,
|
38
|
+
:iam_instance_profile,
|
39
|
+
:block_device_mappings,
|
40
|
+
:virtual_name,
|
41
|
+
:device_name,
|
42
|
+
:ebs,
|
43
|
+
:snapshot_id,
|
44
|
+
:volume_size,
|
45
|
+
:delete_on_termination,
|
46
|
+
:volume_type,
|
47
|
+
:iops,
|
48
|
+
:no_device,
|
49
|
+
:monitoring_enabled,
|
50
|
+
:availability_zone,
|
51
|
+
:image_id,
|
52
|
+
:key_name,
|
53
|
+
:key_pair,
|
54
|
+
:security_groups,
|
55
|
+
:security_group_ids,
|
56
|
+
:user_data,
|
57
|
+
:instance_type,
|
58
|
+
:kernel_id,
|
59
|
+
:ramdisk_id,
|
60
|
+
:disable_api_termination,
|
61
|
+
:instance_initiated_shutdown_behavior,
|
62
|
+
:subnet,
|
63
|
+
:private_ip_address,
|
64
|
+
:dedicated_tenancy,
|
65
|
+
:ebs_optimized,
|
66
|
+
]
|
67
|
+
|
68
|
+
ec2_config = {}
|
69
|
+
|
70
|
+
allowed_ec2_parameters.each do |param|
|
71
|
+
ec2_config[param] = @config[:ec2][param] if @config[:ec2][param]
|
72
|
+
end
|
73
|
+
|
74
|
+
@instance = @client.instances.create(ec2_config)
|
75
|
+
rescue => e
|
76
|
+
puts "# failed to create new ec2 instance:"
|
77
|
+
die e
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
puts
|
82
|
+
|
83
|
+
ShellSpinner "# awaiting build completion", false do
|
84
|
+
sleep 1 until @instance.status != :pending
|
85
|
+
end
|
86
|
+
|
87
|
+
puts
|
88
|
+
|
89
|
+
ShellSpinner "# awaiting running state", false do
|
90
|
+
sleep 1 until @instance.status == :running
|
91
|
+
end
|
92
|
+
|
93
|
+
puts
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module AWSCarb
|
4
|
+
# named so as not to clash with AWS module from aws-sdk
|
5
|
+
module Services
|
6
|
+
class Route53
|
7
|
+
|
8
|
+
include Singleton
|
9
|
+
|
10
|
+
def client(config)
|
11
|
+
@config = config
|
12
|
+
|
13
|
+
begin
|
14
|
+
ShellSpinner "# configuring route53 session", false do
|
15
|
+
@client = ::AWS::Route53.new(@config[:route53])
|
16
|
+
end
|
17
|
+
|
18
|
+
puts
|
19
|
+
rescue => e
|
20
|
+
puts "error: failed to create route53 session"
|
21
|
+
die e
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def check_hostname_and_domain_availability
|
26
|
+
|
27
|
+
ShellSpinner "# checking to see if hostname and domain have been configured", false do
|
28
|
+
|
29
|
+
if @config[:route53].andand[:new_dns_records]
|
30
|
+
|
31
|
+
else
|
32
|
+
debug "# skipping route53 check since either hostname or domain wasn't found:"
|
33
|
+
debug "hostname not found" if hostname.nil?
|
34
|
+
debug "domain not found" if domain.nil?
|
35
|
+
debug
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
puts
|
40
|
+
|
41
|
+
return unless @config[:route53].andand[:new_dns_records]
|
42
|
+
|
43
|
+
ShellSpinner "# checking to see if record exists", false do
|
44
|
+
begin
|
45
|
+
record_sets = @client.hosted_zones[@config[:route53][:zone]].resource_record_sets
|
46
|
+
|
47
|
+
@config[:route53][:new_dns_records].each_value do |record|
|
48
|
+
die "error: record already exists: #{record[:alias]}" if record_sets[record[:alias], 'CNAME'].exists?
|
49
|
+
end
|
50
|
+
rescue => e
|
51
|
+
puts "# could not check to see if DNS records exist:"
|
52
|
+
die e
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
puts
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_records(ec2)
|
60
|
+
if @config[:route53][:new_dns_records].nil?
|
61
|
+
debug "# skipping creation of new records on route53"
|
62
|
+
debug
|
63
|
+
return
|
64
|
+
end
|
65
|
+
|
66
|
+
ShellSpinner "# updating route53 with new CNAMES for host", false do
|
67
|
+
|
68
|
+
@config[:route53][:new_dns_records][:public][:target] = ec2.instance.public_dns_name
|
69
|
+
@config[:route53][:new_dns_records][:private][:target] = ec2.instance.private_dns_name
|
70
|
+
|
71
|
+
record_sets = @client.hosted_zones[@config[:route53][:zone]].resource_record_sets
|
72
|
+
|
73
|
+
@config[:route53][:new_dns_records].each do |record_scope, record|
|
74
|
+
new_record = record_sets[record[:alias], 'CNAME']
|
75
|
+
|
76
|
+
raise "error: '#{record_scope}' record already exists: #{record[:alias]}" if new_record.exists?
|
77
|
+
|
78
|
+
record_sets.create(record[:alias], 'CNAME', :ttl => @config[:route53][:ttl], :resource_records => [{:value => record[:target]}])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
puts
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
module AWSCarb
|
4
|
+
class UserData
|
5
|
+
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
attr_accessor :combined_user_data
|
9
|
+
|
10
|
+
def create(config)
|
11
|
+
user_data_template_resolved = resolve_template(config)
|
12
|
+
@combined_user_data = combine_user_data(config, user_data_template_resolved)
|
13
|
+
@user_data_template = nil
|
14
|
+
@resolved_template = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def resolve_template(config)
|
18
|
+
|
19
|
+
# FIXME: blank templates / empty templates / no template should work..
|
20
|
+
|
21
|
+
return nil unless config[:ec2] and config[:user_data_template][:file]
|
22
|
+
|
23
|
+
ShellSpinner "# loading template", false do
|
24
|
+
begin
|
25
|
+
template_file = config[:user_data_template][:file]
|
26
|
+
|
27
|
+
raise ArgumentError, "no such file: #{template_file}" unless File.exist?(template_file)
|
28
|
+
|
29
|
+
@user_data_template = File.read(template_file)
|
30
|
+
rescue => e
|
31
|
+
puts "# unable to open template file:"
|
32
|
+
die e
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
puts
|
37
|
+
|
38
|
+
ShellSpinner "# parsing template" do
|
39
|
+
begin
|
40
|
+
@resolved_template = Erubis::Eruby.new(@user_data_template).result(config[:user_data_template_variables])
|
41
|
+
rescue => e
|
42
|
+
puts "# failed to resolve variables in user_data_template:"
|
43
|
+
ap e.class
|
44
|
+
die e
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
puts
|
49
|
+
|
50
|
+
return @resolved_template
|
51
|
+
end
|
52
|
+
|
53
|
+
def combine_user_data(config, user_data_template_resolved)
|
54
|
+
|
55
|
+
# if user_data_template and user_data are supplied then combine them, otherwise just
|
56
|
+
# use user_data (which is empty by default)
|
57
|
+
begin
|
58
|
+
if config[:ec2].andand[:user_data]
|
59
|
+
user_data = config[:ec2][:user_data]
|
60
|
+
end
|
61
|
+
|
62
|
+
if ! user_data_template_resolved.nil? and ! user_data.nil?
|
63
|
+
puts "# combining user_data with user_data_template"
|
64
|
+
user_data = user_data_template_resolved + user_data
|
65
|
+
puts
|
66
|
+
elsif ! user_data_template_resolved.nil? and user_data.nil?
|
67
|
+
debug "# no raw user_data parsed in"
|
68
|
+
user_data = user_data_template_resolved
|
69
|
+
debug
|
70
|
+
elsif user_data.nil?
|
71
|
+
debug "# no user_data or user_data_template specified on the command line"
|
72
|
+
user_data = ""
|
73
|
+
debug
|
74
|
+
else
|
75
|
+
debug "# using user_data from cli argument"
|
76
|
+
debug
|
77
|
+
end
|
78
|
+
|
79
|
+
rescue => e
|
80
|
+
puts "# failed to combine user_data!"
|
81
|
+
die e
|
82
|
+
end
|
83
|
+
|
84
|
+
return user_data
|
85
|
+
end
|
86
|
+
|
87
|
+
def display
|
88
|
+
return if @combined_user_data.nil?
|
89
|
+
|
90
|
+
puts "# --- beginning of user_data ---"
|
91
|
+
puts
|
92
|
+
begin
|
93
|
+
puts @combined_user_data
|
94
|
+
rescue => e
|
95
|
+
puts "error: could not display user_data!"
|
96
|
+
puts e
|
97
|
+
end
|
98
|
+
puts
|
99
|
+
puts "# --- end of user_data ---"
|
100
|
+
puts
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/aws-carb.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'aws-sdk'
|
4
|
+
require 'yaml'
|
5
|
+
require 'erubis'
|
6
|
+
require 'awesome_print'
|
7
|
+
require 'securerandom'
|
8
|
+
require 'shell-spinner'
|
9
|
+
require 'active_support/core_ext/string/strip'
|
10
|
+
require 'active_support/core_ext/hash/keys'
|
11
|
+
require 'ostruct'
|
12
|
+
require 'subcommand'
|
13
|
+
require 'singleton'
|
14
|
+
require 'andand'
|
15
|
+
require 'colorize'
|
16
|
+
|
17
|
+
# module is broken up into:
|
18
|
+
#
|
19
|
+
# AWSCarb.* - main methods
|
20
|
+
# AWSCarb::CliArugmentParser - argument parsing
|
21
|
+
# AWSCarb::Config - argument checking / config checking
|
22
|
+
# AWSCarb::UserData - parse user data template and possibly combine with user_data cli arg
|
23
|
+
# AWSCarb::Services::Ec2 - build an ec2 instance
|
24
|
+
# AWSCarb::Services::Route53 - create dns records in route53
|
25
|
+
#
|
26
|
+
|
27
|
+
if ! $stdout.tty?
|
28
|
+
String.class_eval do
|
29
|
+
def colorize(args)
|
30
|
+
self
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module AWSCarb
|
36
|
+
def self.banner
|
37
|
+
banner = <<-HEREDOC.strip_heredoc
|
38
|
+
|
39
|
+
:::::::: ::: ::::::::: :::::::::
|
40
|
+
:+: :+: :+: :+: :+: :+: :+: :+:
|
41
|
+
+:+ +:+ +:+ +:+ +:+ +:+ +:+
|
42
|
+
+#+ +#++:++#++: +#++:++#: +#++:++#+
|
43
|
+
+#+ +#+ +#+ +#+ +#+ +#+ +#+
|
44
|
+
#+# #+# #+# #+# #+# #+# #+# #+#
|
45
|
+
######## ### ### ### ### #########
|
46
|
+
|
47
|
+
- cloudinit and route53 bootstrap -
|
48
|
+
|
49
|
+
HEREDOC
|
50
|
+
|
51
|
+
indent = ' ' * 6
|
52
|
+
|
53
|
+
puts banner.each_line.map { |line| indent + line }
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.run
|
57
|
+
|
58
|
+
#
|
59
|
+
# configuration
|
60
|
+
#
|
61
|
+
|
62
|
+
# parse cli args
|
63
|
+
cli_arguments = CliArgumentParser.parse
|
64
|
+
|
65
|
+
# display banner on successful cli argument parsing..
|
66
|
+
banner
|
67
|
+
|
68
|
+
# create a configuration based on our various data sources..
|
69
|
+
@config = Config.instance
|
70
|
+
@config.create(cli_arguments)
|
71
|
+
@config.display if $GLOBAL_VERBOSE
|
72
|
+
|
73
|
+
# load erb template and parse the template with user_data_template_variables
|
74
|
+
# then merge user_data template with raw user_data (if provided) -
|
75
|
+
# end up single user_data ready to pass into ec2 instance..
|
76
|
+
@user_data = UserData.instance
|
77
|
+
@user_data.create(@config)
|
78
|
+
@user_data.display if @config[:user_data_template][:file] and ($GLOBAL_VERBOSE or @config[:show_parsed_template])
|
79
|
+
|
80
|
+
#
|
81
|
+
# aws interaction
|
82
|
+
#
|
83
|
+
|
84
|
+
if @config[:route53].andand[:new_dns_records]
|
85
|
+
@route53 = Services::Route53.instance
|
86
|
+
@route53.client(@config)
|
87
|
+
@route53.check_hostname_and_domain_availability
|
88
|
+
end
|
89
|
+
|
90
|
+
## initialize ec2 object with credentials
|
91
|
+
@ec2 = Services::Ec2.instance
|
92
|
+
@ec2.client(@config)
|
93
|
+
@ec2.create_instance
|
94
|
+
|
95
|
+
if @config[:route53].andand[:new_dns_records]
|
96
|
+
@route53.create_records(@ec2)
|
97
|
+
end
|
98
|
+
|
99
|
+
#
|
100
|
+
# summary
|
101
|
+
#
|
102
|
+
|
103
|
+
show_instance_details
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.show_instance_details
|
107
|
+
puts <<-HEREDOC.strip_heredoc
|
108
|
+
# instance details:
|
109
|
+
id: #{@ec2.instance.id}
|
110
|
+
public ip: #{@ec2.instance.public_ip_address}
|
111
|
+
public aws fqdn: #{@ec2.instance.public_dns_name}
|
112
|
+
private ip: #{@ec2.instance.private_ip_address}
|
113
|
+
private aws fqdn: #{@ec2.instance.private_dns_name}
|
114
|
+
HEREDOC
|
115
|
+
|
116
|
+
unless @config[:route53][:new_dns_records].nil?
|
117
|
+
puts <<-HEREDOC.strip_heredoc
|
118
|
+
public fqdn: #{@config[:route53][:new_dns_records][:public][:alias]}
|
119
|
+
private fqdn: #{@config[:route53][:new_dns_records][:private][:alias]}
|
120
|
+
HEREDOC
|
121
|
+
end
|
122
|
+
|
123
|
+
puts <<-HEREDOC.strip_heredoc
|
124
|
+
|
125
|
+
# connect:
|
126
|
+
ssh #{@ec2.instance.dns_name} -l ubuntu
|
127
|
+
HEREDOC
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#cloud-config
|
2
|
+
|
3
|
+
# the above line is required by cloud init
|
4
|
+
|
5
|
+
<%- if defined?(hostname) %>
|
6
|
+
hostname: <%= hostname %>
|
7
|
+
fqdn: <%= hostname -%>.<%= domain %>
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%- if defined?(ssh_keys) %>
|
11
|
+
ssh_authorized_keys:
|
12
|
+
<% ssh_keys.each do |key| %>
|
13
|
+
- <%= key %>
|
14
|
+
<% end %>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
bootcmd:
|
18
|
+
- echo "deb http://<%= repository_server -%>/debian/ <%= debian_distro -%> main" >> /etc/apt/<%= apt_source_name -%>.list.d/<% apt_source_name -%>.list
|
19
|
+
|
20
|
+
package_upgrade: true
|
21
|
+
|
22
|
+
manage_etc_hosts: true
|
23
|
+
|
24
|
+
packages:
|
25
|
+
- puppet
|
26
|
+
- facter
|
27
|
+
- lsb-release
|
28
|
+
|
29
|
+
# required by aws-sdk
|
30
|
+
- ruby1.9.1
|
31
|
+
- ruby1.9.1-dev
|
32
|
+
- libxml2-dev
|
33
|
+
- build-essential
|
34
|
+
|
35
|
+
# required by awscli
|
36
|
+
- python-pip
|
37
|
+
|
38
|
+
|
39
|
+
puppet:
|
40
|
+
conf:
|
41
|
+
main:
|
42
|
+
logdir: /var/log/puppet
|
43
|
+
vardir: /var/lib/puppet
|
44
|
+
rundir: /var/run/puppet
|
45
|
+
ssldir: /etc/puppet/ssl
|
46
|
+
confdir: /etc/puppet
|
47
|
+
pluginsync: true
|
48
|
+
factpath: /var/lib/puppet/lib/facter:/var/lib/puppet/facts
|
49
|
+
agent:
|
50
|
+
server: <%= puppet_master %>
|
51
|
+
ca_server: <%= ca_server %>
|
52
|
+
configtimeout: 600
|
53
|
+
preferred_serialization_format: marshal
|
54
|
+
|
55
|
+
runcmd:
|
56
|
+
- service puppet stop
|
57
|
+
- puppet agent --onetime --no-daemonize -v > /var/log/puppet-initial_run.log
|
58
|
+
- update-alternatives --set ruby /usr/bin/ruby1.9.1
|
59
|
+
- update-alternatives --set gem /usr/bin/gem1.9.1
|
60
|
+
|
61
|
+
# building the native extensions for this gem takes a long time,
|
62
|
+
# if you reboot the machine soon after machine creation
|
63
|
+
# then this gem may not have finished installing and your
|
64
|
+
# DNS will not get updated on boot.
|
65
|
+
- gem install aws-sdk facter --no-ri --no-rdoc
|
66
|
+
|
67
|
+
# script to update route53 dynamic dns configuration on boot..
|
68
|
+
|
69
|
+
- pip install awscli
|
70
|
+
|
71
|
+
# filthy hack..
|
72
|
+
- mkdir /root/.aws
|
73
|
+
- echo '[profile s3]' >> /root/.aws/config
|
74
|
+
- echo 'aws_access_key_id = <%= s3_access_key_id %>' >> /root/.aws/config
|
75
|
+
- echo 'aws_secret_access_key = <%= s3_secret_access_key %>' >> /root/.aws/config
|
76
|
+
- echo 'region = <%= s3_region %>' >> /root/.aws/config
|
77
|
+
|
78
|
+
# update route53 on boot
|
79
|
+
# available at: https://github.com/roobert/route53-dynamic_dns_update
|
80
|
+
- aws s3 --profile s3 cp --region us-east-1 s3://<%= s3_bucket -%>.cloudinit/aws-route53.conf /etc/aws-route53.conf
|
81
|
+
- aws s3 --profile s3 cp --region us-east-1 s3://<%= s3_bucket -%>.cloudinit/route53-dynamic_dns_update.rb /usr/local/bin/route53-dynamic_dns_update.rb
|
82
|
+
- chmod 400 /etc/aws-route53.conf
|
83
|
+
- chmod 755 /usr/local/bin/route53-dynamic_dns_update.rb
|
84
|
+
- echo '/usr/local/bin/route53-dynamic_dns_update.rb' > /etc/rc.local
|