cfndk 0.1.1.2 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +1 -1
  3. data/.gitignore +1 -0
  4. data/.rspec +2 -0
  5. data/Gemfile.lock +9 -5
  6. data/README.md +124 -10
  7. data/cfndk.gemspec +3 -0
  8. data/docker/Dockerfile +8 -0
  9. data/docker/build.sh +3 -0
  10. data/docker/cfndk.sh +14 -0
  11. data/lib/cfndk.rb +9 -0
  12. data/lib/cfndk/change_set_command.rb +14 -8
  13. data/lib/cfndk/command.rb +14 -6
  14. data/lib/cfndk/credential_provider_chain.rb +12 -42
  15. data/lib/cfndk/credential_resolvable.rb +10 -0
  16. data/lib/cfndk/diff.rb +38 -0
  17. data/lib/cfndk/global_config.rb +32 -2
  18. data/lib/cfndk/key_pair.rb +33 -1
  19. data/lib/cfndk/key_pair_command.rb +10 -3
  20. data/lib/cfndk/key_pairs.rb +12 -0
  21. data/lib/cfndk/stack.rb +58 -59
  22. data/lib/cfndk/stack_command.rb +26 -8
  23. data/lib/cfndk/stacks.rb +16 -0
  24. data/lib/cfndk/template_packager.rb +210 -0
  25. data/lib/cfndk/uuid.rb +10 -0
  26. data/lib/cfndk/version.rb +1 -1
  27. data/spec/cfndk_spec.rb +1 -1
  28. data/spec/cfndk_stack_create_spec.rb +365 -5
  29. data/spec/cfndk_stack_destroy_spec.rb +64 -0
  30. data/spec/cfndk_stack_update_spec.rb +86 -0
  31. data/spec/fixtures/big_vpc.yaml +533 -0
  32. data/spec/fixtures/lambda_function/index.js +4 -0
  33. data/spec/fixtures/lambda_function/lambda_function.json +4 -0
  34. data/spec/fixtures/lambda_function/lambda_function.yaml +28 -0
  35. data/spec/fixtures/nested_stack.json +35 -0
  36. data/spec/fixtures/nested_stack.yaml +20 -0
  37. data/spec/fixtures/serverless_function/index.js +4 -0
  38. data/spec/fixtures/serverless_function/serverless_function.json +4 -0
  39. data/spec/fixtures/serverless_function/serverless_function.yaml +21 -0
  40. data/spec/fixtures/stack.json +8 -0
  41. data/spec/fixtures/stack.template.json +39 -0
  42. data/spec/fixtures/stack.yaml +22 -0
  43. data/spec/fixtures/vpc.template.json +40 -0
  44. data/vagrant/Vagrantfile +89 -0
  45. metadata +80 -4
@@ -2,6 +2,8 @@ module CFnDK
2
2
  class Command < Thor
3
3
  include Thor::Actions
4
4
  include ConfigFileLoadable
5
+ include CredentialResolvable
6
+
5
7
  class << self
6
8
  def exit_on_failure?
7
9
  true
@@ -44,19 +46,25 @@ module CFnDK
44
46
  option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
45
47
  option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
46
48
  option :properties, type: :hash, aliases: 'p', default: {}, desc: 'Set property'
47
- option :stack_names, type: :array, desc: 'Target stack names'
49
+ option :stack_names, type: :array, aliases: 's', desc: 'Target stack names'
48
50
  option :keypair_names, type: :array, desc: 'Target keypair names'
49
51
  def create
50
52
  CFnDK.logger.info 'create...'.color(:green)
51
53
  data = load_config_data(options)
52
-
53
- credentials = CFnDK::CredentialProviderChain.new.resolve
54
+ credentials = resolve_credential(data, options)
55
+ global_config = CFnDK::GlobalConfig.new(data, options)
54
56
  stacks = CFnDK::Stacks.new(data, options, credentials)
55
57
  keypairs = CFnDK::KeyPairs.new(data, options, credentials)
56
58
 
59
+ global_config.pre_command_execute
60
+ stacks.pre_command_execute
57
61
  stacks.validate
62
+ keypairs.pre_command_execute
58
63
  keypairs.create
64
+ keypairs.post_command_execute
59
65
  stacks.create
66
+ stacks.post_command_execute
67
+ global_config.post_command_execute
60
68
  return 0
61
69
  rescue => e
62
70
  CFnDK.logger.error "#{e.class}: #{e.message}".color(:red)
@@ -73,8 +81,8 @@ module CFnDK
73
81
  def destroy
74
82
  CFnDK.logger.info 'destroy...'.color(:green)
75
83
  data = load_config_data(options)
84
+ credentials = resolve_credential(data, options)
76
85
 
77
- credentials = CFnDK::CredentialProviderChain.new.resolve
78
86
  stacks = CFnDK::Stacks.new(data, options, credentials)
79
87
  keypairs = CFnDK::KeyPairs.new(data, options, credentials)
80
88
 
@@ -97,14 +105,14 @@ module CFnDK
97
105
  desc 'report', 'Report stack'
98
106
  option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
99
107
  option :uuid, type: :string, aliases: 'u', default: ENV['CFNDK_UUID'] || nil, desc: 'Use UUID'
100
- option :stack_names, type: :array, desc: 'Target stack names'
108
+ option :stack_names, type: :array, aliases: 's', desc: 'Target stack names'
101
109
  option :types, type: :array, default: %w(tag output parameter resource event), desc: 'Report type'
102
110
  def report
103
111
  CFnDK.logger.info 'report...'.color(:green)
104
112
 
105
113
  data = load_config_data(options)
114
+ credentials = resolve_credential(data, options)
106
115
 
107
- credentials = CFnDK::CredentialProviderChain.new.resolve
108
116
  stacks = CFnDK::Stacks.new(data, options, credentials)
109
117
  stacks.report
110
118
  return 0
@@ -1,12 +1,14 @@
1
1
  module CFnDK
2
2
  class CredentialProviderChain
3
- def initialize(config = nil)
4
- @config = config
3
+ def initialize(profile = nil)
4
+ @profile = profile
5
5
  end
6
6
 
7
7
  def resolve
8
8
  providers.each do |method_name, options|
9
- provider = send(method_name, options.merge(config: @config))
9
+ CFnDK.logger.debug "resolving: #{method_name}"
10
+ provider = send(method_name, options)
11
+ CFnDK.logger.debug "resolved: #{method_name}" if provider && provider.set?
10
12
  return provider if provider && provider.set?
11
13
  end
12
14
  nil
@@ -16,30 +18,17 @@ module CFnDK
16
18
 
17
19
  def providers
18
20
  [
19
- [:static_credentials, {}],
20
21
  [:env_credentials, {}],
21
22
  [:assume_role_credentials, {}],
22
- [:shared_credentials, {}],
23
- [:process_credentials, {}],
23
+ [:shared_credentials, {profile: @profile}],
24
24
  [:instance_profile_credentials, {
25
- retries: @config ? @config.instance_profile_credentials_retries : 0,
26
- http_open_timeout: @config ? @config.instance_profile_credentials_timeout : 1,
27
- http_read_timeout: @config ? @config.instance_profile_credentials_timeout : 1,
25
+ retries: 0,
26
+ http_open_timeout: 1,
27
+ http_read_timeout: 1,
28
28
  }],
29
29
  ]
30
30
  end
31
31
 
32
- def static_credentials(options)
33
- if options[:config]
34
- ::Aws::Credentials.new(
35
- options[:config].access_key_id,
36
- options[:config].secret_access_key,
37
- options[:config].session_token)
38
- else
39
- nil
40
- end
41
- end
42
-
43
32
  def env_credentials(options)
44
33
  key = %w(AWS_ACCESS_KEY_ID AMAZON_ACCESS_KEY_ID AWS_ACCESS_KEY)
45
34
  secret = %w(AWS_SECRET_ACCESS_KEY AMAZON_SECRET_ACCESS_KEY AWS_SECRET_KEY)
@@ -55,8 +44,8 @@ module CFnDK
55
44
  end
56
45
 
57
46
  def shared_credentials(options)
58
- if options[:config]
59
- ::Aws::SharedCredentials.new(profile_name: options[:config].profile)
47
+ if options[:profile]
48
+ ::Aws::SharedCredentials.new(profile_name: options[:profile])
60
49
  else
61
50
  ::Aws::SharedCredentials.new(
62
51
  profile_name: ENV['AWS_PROFILE'].nil? ? 'default' : ENV['AWS_PROFILE'])
@@ -65,29 +54,10 @@ module CFnDK
65
54
  nil
66
55
  end
67
56
 
68
- def process_credentials(options)
69
- profile_name = options[:config].profile if options[:config]
70
- profile_name ||= ENV['AWS_PROFILE'].nil? ? 'default' : ENV['AWS_PROFILE']
71
-
72
- config = ::Aws.shared_config
73
- if config.config_enabled? && process_provider = config.credentials_process(profile_name)
74
- ::Aws::ProcessCredentials.new(process_provider)
75
- else
76
- nil
77
- end
78
- rescue ::Aws::Errors::NoSuchProfileError
79
- nil
80
- end
81
-
82
57
  def assume_role_credentials(options)
83
58
  if ::Aws.shared_config.config_enabled?
84
59
  profile = nil
85
60
  region = nil
86
- if options[:config]
87
- profile = options[:config].profile
88
- region = options[:config].region
89
- assume_role_with_profile(options[:config].profile, options[:config].region)
90
- end
91
61
  assume_role_with_profile(profile, region)
92
62
  else
93
63
  nil
@@ -106,7 +76,7 @@ module CFnDK
106
76
  ::Aws.shared_config.assume_role_credentials_from_config(
107
77
  profile: prof,
108
78
  region: region,
109
- chain_config: @config
79
+ chain_config: nil
110
80
  )
111
81
  end
112
82
  end
@@ -0,0 +1,10 @@
1
+ module CFnDK
2
+ module CredentialResolvable
3
+ private
4
+
5
+ def resolve_credential(data, option)
6
+ global_config = CFnDK::GlobalConfig.new(data, option)
7
+ CFnDK::CredentialProviderChain.new(global_config.profile).resolve
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,38 @@
1
+ module CFnDK
2
+ FORMAT = :unified
3
+ LINES = 3
4
+
5
+ def self.diff(data_old, data_new)
6
+ result = ''
7
+
8
+ file_length_difference = 0
9
+
10
+ data_old = data_old.split($/).map { |e| e.chomp }
11
+ data_new = data_new.split($/).map { |e| e.chomp }
12
+
13
+ diffs = Diff::LCS.diff(data_old, data_new)
14
+ diffs = nil if diffs.empty?
15
+
16
+ return '' unless diffs
17
+
18
+ oldhunk = hunk = nil
19
+
20
+ diffs.each do |piece|
21
+ begin
22
+ hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, LINES, file_length_difference)
23
+ file_length_difference = hunk.file_length_difference
24
+
25
+ next unless oldhunk
26
+ next if LINES.positive? and hunk.merge(oldhunk)
27
+
28
+ result << oldhunk.diff(FORMAT) << "\n"
29
+ ensure
30
+ oldhunk = hunk
31
+ end
32
+ end
33
+
34
+ last = oldhunk.diff(FORMAT)
35
+ last << "\n" if last.respond_to?(:end_with?) && !last.end_with?("\n")
36
+ result << last
37
+ end
38
+ end
@@ -1,16 +1,46 @@
1
1
  module CFnDK
2
2
  class GlobalConfig
3
- attr_reader :timeout_in_minutes, :s3_template_bucket, :s3_template_hash, :region, :role_arn
3
+ attr_reader :timeout_in_minutes, :s3_template_bucket, :s3_template_hash, :region, :role_arn, :package, :profile, :pre_command, :post_command
4
4
  def initialize(data, option)
5
5
  @timeout_in_minutes = 1
6
6
  @s3_template_bucket = 'cfndk-templates'
7
- @s3_template_hash = SecureRandom.uuid
7
+ @s3_template_hash = Uuid.instance.uuid
8
8
  @region = ENV['AWS_REGION'] || 'us-east-1'
9
+ @package = false
10
+ @profile = ENV['AWS_PROFILE'] || nil
9
11
  return unless data['global'].is_a?(Hash)
10
12
  @timeout_in_minutes = data['global']['timeout_in_minutes'] || 1
11
13
  @s3_template_bucket = data['global']['s3_template_bucket'] || 'cfndk-templates'
12
14
  @region = data['global']['region'] || ENV['AWS_REGION'] || 'us-east-1'
15
+ @package = data['global']['package'] === 'true' ? true : false
13
16
  @role_arn = data['global']['role_arn'] || nil
17
+ @profile = ENV['AWS_PROFILE'] || data['global']['default_profile'] || nil
18
+ @pre_command = data['global']['pre_command'] || nil
19
+ @post_command = data['global']['post_command'] || nil
20
+ end
21
+
22
+ def pre_command_execute
23
+ if @pre_command
24
+ CFnDK.logger.info(('execute global pre command: ' + @pre_command).color(:green))
25
+ IO.popen(@pre_command, :err => [:child, :out]) do |io|
26
+ io.each_line do |line|
27
+ CFnDK.logger.info((line).color(:green))
28
+ end
29
+ end
30
+ raise 'global pre command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @pre_command if $?.exitstatus != 0
31
+ end
32
+ end
33
+
34
+ def post_command_execute
35
+ if @post_command
36
+ CFnDK.logger.info(('execute global post command: ' + @post_command).color(:green))
37
+ IO.popen(@post_command, :err => [:child, :out]) do |io|
38
+ io.each_line do |line|
39
+ CFnDK.logger.info((line).color(:green))
40
+ end
41
+ end
42
+ raise 'global post command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @post_command if $?.exitstatus != 0
43
+ end
14
44
  end
15
45
  end
16
46
  end
@@ -1,17 +1,22 @@
1
1
  module CFnDK
2
2
  class KeyPair
3
- attr_reader :key_file
3
+ attr_reader :key_file, :enabled, :pre_command, :post_command
4
4
  def initialize(name, data, option, global_config, credentials)
5
5
  @global_config = global_config
6
6
  @name = name
7
7
  data = {} unless data
8
8
  @key_file = data['key_file'] || nil
9
9
  @region = data['region'] || @global_config.region
10
+ @pre_command = data['pre_command'] || nil
11
+ @post_command = data['post_command'] || nil
12
+ @enabled = true
13
+ @enabled = false if data['enabled'] === false
10
14
  @option = option
11
15
  @client = Aws::EC2::Client.new(credentials: credentials, region: @region)
12
16
  end
13
17
 
14
18
  def create
19
+ return unless @enabled
15
20
  CFnDK.logger.info(('creating keypair: ' + name).color(:green))
16
21
  key_pair = @client.create_key_pair(
17
22
  key_name: name
@@ -22,6 +27,7 @@ module CFnDK
22
27
  end
23
28
 
24
29
  def destroy
30
+ return unless @enabled
25
31
  if exists?
26
32
  CFnDK.logger.info(('deleting keypair: ' + name).color(:green))
27
33
  @client.delete_key_pair(
@@ -51,6 +57,32 @@ module CFnDK
51
57
  @name
52
58
  end
53
59
 
60
+ def pre_command_execute
61
+ return unless @enabled
62
+ if @pre_command
63
+ CFnDK.logger.info(('execute pre command: ' + @pre_command).color(:green))
64
+ IO.popen(@pre_command, :err => [:child, :out]) do |io|
65
+ io.each_line do |line|
66
+ CFnDK.logger.info((line).color(:green))
67
+ end
68
+ end
69
+ raise 'pre command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @pre_command if $?.exitstatus != 0
70
+ end
71
+ end
72
+
73
+ def post_command_execute
74
+ return unless @enabled
75
+ if @post_command
76
+ CFnDK.logger.info(('execute post command: ' + @post_command).color(:green))
77
+ IO.popen(@post_command, :err => [:child, :out]) do |io|
78
+ io.each_line do |line|
79
+ CFnDK.logger.info((line).color(:green))
80
+ end
81
+ end
82
+ raise 'post command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @post_command if $?.exitstatus != 0
83
+ end
84
+ end
85
+
54
86
  private
55
87
 
56
88
  def create_key_file(key_pair)
@@ -2,6 +2,8 @@ module CFnDK
2
2
  class KeyPairCommand < Thor
3
3
  include SubcommandHelpReturnable
4
4
  include ConfigFileLoadable
5
+ include CredentialResolvable
6
+
5
7
  class_option :verbose, type: :boolean, aliases: 'v', desc: 'More verbose output.'
6
8
  class_option :color, type: :boolean, default: true, desc: 'Use colored output'
7
9
  class_option :config_path, type: :string, aliases: 'c', default: "#{Dir.getwd}/cfndk.yml", desc: 'The configuration file to use'
@@ -13,10 +15,15 @@ module CFnDK
13
15
  def create
14
16
  CFnDK.logger.info 'create...'.color(:green)
15
17
  data = load_config_data(options)
16
-
17
- credentials = CFnDK::CredentialProviderChain.new.resolve
18
+ credentials = resolve_credential(data, options)
19
+ global_config = CFnDK::GlobalConfig.new(data, options)
18
20
  keypairs = CFnDK::KeyPairs.new(data, options, credentials)
21
+
22
+ global_config.pre_command_execute
23
+ keypairs.pre_command_execute
19
24
  keypairs.create
25
+ keypairs.post_command_execute
26
+ global_config.post_command_execute
20
27
  return 0
21
28
  rescue => e
22
29
  CFnDK.logger.error "#{e.class}: #{e.message}".color(:red)
@@ -31,8 +38,8 @@ module CFnDK
31
38
  def destroy
32
39
  CFnDK.logger.info 'destroy...'.color(:green)
33
40
  data = load_config_data(options)
41
+ credentials = resolve_credential(data, options)
34
42
 
35
- credentials = CFnDK::CredentialProviderChain.new.resolve
36
43
  keypairs = CFnDK::KeyPairs.new(data, options, credentials)
37
44
 
38
45
  if options[:force] || yes?('Are you sure you want to destroy? (y/n)', :yellow)
@@ -21,6 +21,18 @@ module CFnDK
21
21
  end
22
22
  end
23
23
 
24
+ def pre_command_execute
25
+ @keypairs.each_value do |keypair|
26
+ keypair.pre_command_execute
27
+ end
28
+ end
29
+
30
+ def post_command_execute
31
+ @keypairs.each_value do |keypair|
32
+ keypair.post_command_execute
33
+ end
34
+ end
35
+
24
36
  private
25
37
 
26
38
  def prepare_keypairs(data)
@@ -1,6 +1,6 @@
1
1
  module CFnDK
2
2
  class Stack
3
- attr_reader :template_file, :parameter_input, :capabilities, :depends, :timeout_in_minutes, :region, :role_arn
3
+ attr_reader :template_file, :parameter_input, :capabilities, :depends, :timeout_in_minutes, :region, :role_arn, :package, :enabled, :pre_command, :post_command
4
4
  def initialize(name, data, option, global_config, credentials)
5
5
  @global_config = global_config
6
6
  @name = name
@@ -10,16 +10,23 @@ module CFnDK
10
10
  @depends = data['depends'] || []
11
11
  @region = data['region'] || @global_config.region
12
12
  @role_arn = @global_config.role_arn
13
+ @package = data['package'] || @global_config.package
14
+ @pre_command = data['pre_command'] || nil
15
+ @post_command = data['post_command'] || nil
16
+ @enabled = true
17
+ @enabled = false if data['enabled'] === false
13
18
  @timeout_in_minutes = data['timeout_in_minutes'] || @global_config.timeout_in_minutes
14
19
  @override_parameters = data['parameters'] || {}
15
20
  @option = option
16
21
  @client = Aws::CloudFormation::Client.new(credentials: credentials, region: @region)
17
22
  @s3_client = Aws::S3::Client.new(credentials: credentials, region: @region)
18
23
  @sts_client = Aws::STS::Client.new(credentials: credentials, region: @region)
24
+ @tp = CFnDK::TemplatePackager.new(@template_file, @region, @package, @global_config, @s3_client, @sts_client)
19
25
  end
20
26
 
21
27
  def create
22
28
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
29
+ return unless @enabled
23
30
  CFnDK.logger.info(('creating stack: ' + name).color(:green))
24
31
  CFnDK.logger.debug('Name :' + name)
25
32
  CFnDK.logger.debug('Parametres :' + parameters.inspect)
@@ -44,10 +51,11 @@ module CFnDK
44
51
  tags: tags,
45
52
  }
46
53
  hash[:role_arn] = @role_arn if @role_arn
47
- if large_template?
48
- hash[:template_url] = upload_template_file()
54
+
55
+ if @tp.large_template?
56
+ hash[:template_url] = @tp.upload_template_file()
49
57
  else
50
- hash[:template_body] = template_body()
58
+ hash[:template_body] = @tp.template_body()
51
59
  end
52
60
  @client.create_stack(
53
61
  hash
@@ -56,6 +64,7 @@ module CFnDK
56
64
 
57
65
  def wait_until_create
58
66
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
67
+ return unless @enabled
59
68
  CFnDK.logger.info(('waiting create stack: ' + name).color(:green))
60
69
  begin
61
70
  @client.wait_until(
@@ -76,6 +85,7 @@ module CFnDK
76
85
 
77
86
  def update
78
87
  return false if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
88
+ return unless @enabled
79
89
  CFnDK.logger.info(('updating stack: ' + name).color(:green))
80
90
  CFnDK.logger.debug('Name :' + name)
81
91
  CFnDK.logger.debug('Parametres :' + parameters.inspect)
@@ -89,10 +99,10 @@ module CFnDK
89
99
  capabilities: capabilities,
90
100
  }
91
101
  hash[:role_arn] = @role_arn if @role_arn
92
- if large_template?
93
- hash[:template_url] = upload_template_file()
102
+ if @tp.large_template?
103
+ hash[:template_url] = @tp.upload_template_file()
94
104
  else
95
- hash[:template_body] = template_body()
105
+ hash[:template_body] = @tp.template_body()
96
106
  end
97
107
  @client.update_stack(
98
108
  hash
@@ -111,6 +121,7 @@ module CFnDK
111
121
 
112
122
  def wait_until_update
113
123
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
124
+ return unless @enabled
114
125
  CFnDK.logger.info(('waiting update stack: ' + name).color(:green))
115
126
  @client.wait_until(
116
127
  :stack_update_complete,
@@ -124,6 +135,7 @@ module CFnDK
124
135
 
125
136
  def destroy
126
137
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
138
+ return unless @enabled
127
139
  if exits?
128
140
  CFnDK.logger.info(('deleting stack: ' + name).color(:green))
129
141
  CFnDK.logger.debug('Name :' + name)
@@ -142,6 +154,7 @@ module CFnDK
142
154
 
143
155
  def wait_until_destroy
144
156
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
157
+ return unless @enabled
145
158
  return unless exits?
146
159
  CFnDK.logger.info(('waiting delete stack: ' + name).color(:green))
147
160
  @client.wait_until(
@@ -156,6 +169,7 @@ module CFnDK
156
169
 
157
170
  def create_change_set
158
171
  return nil if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
172
+ return unless @enabled
159
173
  CFnDK.logger.info(('creating change set: ' + change_set_name).color(:green))
160
174
  CFnDK.logger.debug('Parametres :' + parameters.inspect)
161
175
  CFnDK.logger.debug('Capabilities:' + capabilities.inspect)
@@ -183,10 +197,10 @@ module CFnDK
183
197
  tags: tags,
184
198
  }
185
199
  hash[:role_arn] = @role_arn if @role_arn
186
- if large_template?
187
- hash[:template_url] = upload_template_file()
200
+ if @tp.large_template?
201
+ hash[:template_url] = @tp.upload_template_file()
188
202
  else
189
- hash[:template_body] = template_body()
203
+ hash[:template_body] = @tp.template_body()
190
204
  end
191
205
  @client.create_change_set(
192
206
  hash
@@ -204,6 +218,7 @@ module CFnDK
204
218
 
205
219
  def wait_until_create_change_set
206
220
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
221
+ return unless @enabled
207
222
  return unless exits?
208
223
  CFnDK.logger.info(('waiting create change set: ' + change_set_name).color(:green))
209
224
  @client.wait_until(
@@ -229,6 +244,7 @@ module CFnDK
229
244
 
230
245
  def execute_change_set
231
246
  return nil if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
247
+ return unless @enabled
232
248
  if available_change_set?
233
249
  CFnDK.logger.info(('executing change set: ' + change_set_name).color(:green))
234
250
  @client.execute_change_set(
@@ -245,6 +261,7 @@ module CFnDK
245
261
 
246
262
  def delete_change_set
247
263
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
264
+ return unless @enabled
248
265
  CFnDK.logger.info(('deleting change set: ' + change_set_name).color(:green))
249
266
  @client.delete_change_set(
250
267
  stack_name: name,
@@ -255,6 +272,7 @@ module CFnDK
255
272
 
256
273
  def report_change_set
257
274
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
275
+ return unless @enabled
258
276
  CFnDK.logger.info('*****************************************************'.color(:green))
259
277
  CFnDK.logger.info(('change set: ' + change_set_name).color(:green))
260
278
  CFnDK.logger.info('*****************************************************'.color(:green))
@@ -318,13 +336,14 @@ module CFnDK
318
336
 
319
337
  def validate
320
338
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
339
+ return unless @enabled
321
340
  CFnDK.logger.info(('validate stack: ' + name).color(:green))
322
341
  CFnDK.logger.debug('Name :' + @name)
323
342
  hash = {}
324
- if large_template?
325
- hash[:template_url] = upload_template_file()
343
+ if @tp.large_template?
344
+ hash[:template_url] = @tp.upload_template_file()
326
345
  else
327
- hash[:template_body] = template_body()
346
+ hash[:template_body] = @tp.template_body()
328
347
  end
329
348
  @client.validate_template(
330
349
  hash
@@ -373,6 +392,7 @@ module CFnDK
373
392
 
374
393
  def report
375
394
  return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
395
+ return unless @enabled
376
396
  CFnDK.logger.info('*****************************************************'.color(:green))
377
397
  CFnDK.logger.info(('stack: ' + name).color(:green))
378
398
  CFnDK.logger.info('*****************************************************'.color(:green))
@@ -484,14 +504,6 @@ module CFnDK
484
504
  [@name, @option[:change_set_uuid]].compact.join('-')
485
505
  end
486
506
 
487
- def template_body
488
- File.open(@template_file, 'r').read
489
- end
490
-
491
- def large_template?
492
- File.size(@template_file) > 51200
493
- end
494
-
495
507
  def parameters
496
508
  json = JSON.load(open(@parameter_input).read)
497
509
  json['Parameters'].map do |item|
@@ -503,49 +515,36 @@ module CFnDK
503
515
  end.compact
504
516
  end
505
517
 
506
- private
507
-
508
- def upload_template_file
509
- begin
510
- @s3_client.head_bucket(bucket: bucket_name)
511
- rescue Aws::S3::Errors::NotFound, Aws::S3::Errors::Forbidden
512
- @s3_client.create_bucket(bucket: bucket_name)
513
- CFnDK.logger.info('Creatt S3 bucket: ' + bucket_name)
514
- @s3_client.put_bucket_lifecycle_configuration(
515
- bucket: bucket_name,
516
- lifecycle_configuration: {
517
- rules: [
518
- {
519
- expiration: {
520
- days: 1,
521
- },
522
- status: 'Enabled',
523
- id: 'Delete Old Files',
524
- prefix: '',
525
- abort_incomplete_multipart_upload: {
526
- days_after_initiation: 1,
527
- },
528
- },
529
- ],
530
- }
531
- )
518
+ def pre_command_execute
519
+ return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
520
+ return unless @enabled
521
+ if @pre_command
522
+ CFnDK.logger.info(('execute pre command: ' + @pre_command).color(:green))
523
+ IO.popen(@pre_command, :err => [:child, :out]) do |io|
524
+ io.each_line do |line|
525
+ CFnDK.logger.info((line).color(:green))
526
+ end
527
+ end
528
+ raise 'pre command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @pre_command if $?.exitstatus != 0
532
529
  end
533
- key = [@global_config.s3_template_hash, @template_file].compact.join('/')
534
- @s3_client.put_object(
535
- body: template_body,
536
- bucket: bucket_name,
537
- key: key
538
- )
539
- url = "https://s3.amazonaws.com/#{bucket_name}/#{key}"
540
- CFnDK.logger.info('Put S3 object: ' + url)
541
- url
542
530
  end
543
531
 
544
- def bucket_name
545
- resp = @sts_client.get_caller_identity({})
546
- resp.account + '-' + @region + '-' + @global_config.s3_template_bucket
532
+ def post_command_execute
533
+ return if @option[:stack_names].instance_of?(Array) && !@option[:stack_names].include?(@name)
534
+ return unless @enabled
535
+ if @post_command
536
+ CFnDK.logger.info(('execute post command: ' + @post_command).color(:green))
537
+ IO.popen(@post_command, :err => [:child, :out]) do |io|
538
+ io.each_line do |line|
539
+ CFnDK.logger.info((line).color(:green))
540
+ end
541
+ end
542
+ raise 'post command is error. status: ' + $?.exitstatus.to_s + ' command: ' + @post_command if $?.exitstatus != 0
543
+ end
547
544
  end
548
545
 
546
+ private
547
+
549
548
  def colored_status(str)
550
549
  case str
551
550
  when 'CREATE_FAILED' then