class CfnDslPipeline::Pipeline
Main pipeline
Interface to cfn_nag auditing
Interface to cfndsl
Interface to AWS SDK syntax checks
Dump stack parameters based on template
Attributes
base_name[RW]
input_filename[RW]
options[RW]
output_dir[RW]
output_file[RW]
output_filename[RW]
s3_client[RW]
syntax_report[RW]
template[RW]
Public Class Methods
new(output_dir, options)
click to toggle source
# File lib/cfndsl-pipeline.rb, line 44 def initialize(output_dir, options) self.input_filename = '' self.output_file = nil self.template = nil self.options = options || nil self.syntax_report = [] FileUtils.mkdir_p output_dir abort "Could not create output directory #{output_dir}" unless Dir[output_dir] self.output_dir = output_dir end
Public Instance Methods
build(input_filename, cfndsl_extras)
click to toggle source
# File lib/cfndsl-pipeline.rb, line 55 def build(input_filename, cfndsl_extras) abort "Input file #{input_filename} doesn't exist!" unless File.file?(input_filename) self.input_filename = input_filename.to_s self.base_name = File.basename(input_filename, '.*') self.output_filename = File.expand_path("#{output_dir}/#{base_name}.yaml") exec_cfndsl cfndsl_extras exec_syntax_validation if options.validate_syntax exec_dump_params if options.dump_deploy_params exec_cfn_nag if options.validate_cfn_nag end
exec_cfn_nag()
click to toggle source
# File lib/exec_cfn_nag.rb, line 10 def exec_cfn_nag puts 'Auditing template with cfn-nag...' configure_cfn_nag_logging cfn_nag = CfnNag.new(config: options.cfn_nag) result = cfn_nag.audit(cloudformation_string: template) save_report result display_report result show_summary result end
exec_cfndsl(cfndsl_extras)
click to toggle source
# File lib/exec_cfndsl.rb, line 10 def exec_cfndsl(cfndsl_extras) puts 'Generating CloudFormation template...' model = CfnDsl.eval_file_with_extras(@input_filename.to_s, cfndsl_extras, (options.debug_cfndsl ? STDOUT : nil)) @template = JSON.parse(model.to_json).to_yaml File.open(@output_filename, 'w') do |file| file.puts @template end @output_file = File.open(@output_filename) puts "#{@output_file.size} bytes written to #{@output_filename}" end
exec_dump_params()
click to toggle source
# File lib/params.rb, line 8 def exec_dump_params param_filename = "#{output_dir}/#{base_name}.params" puts "Deploy parameters written to #{param_filename}" param_file = File.open(File.expand_path(param_filename), 'w') syntax_report['parameters'].each do |param| param_file.puts "#{param['parameter_key']}=#{param['default_value']}" end end
exec_syntax_validation()
click to toggle source
# File lib/exec_syntax.rb, line 16 def exec_syntax_validation puts 'Validating template syntax...' if options.estimate_cost || (output_file.size > 51_200) puts 'Filesize is greater than 51200, or cost estimation required. Validating via S3 bucket ' uuid = UUID.new bucket = determine_bucket object_name = uuid.generate.to_s upload_template(bucket, object_name) self.syntax_report = s3_validate_syntax(bucket, object_name) estimate_cost(bucket_name, object_name) unless options.validation_bucket puts 'Deleting temporary S3 bucket...' bucket.delete! end else self.syntax_report = local_validate_syntax end save_syntax_report end
Private Instance Methods
configure_cfn_nag_logging()
click to toggle source
# File lib/exec_cfn_nag.rb, line 22 def configure_cfn_nag_logging CfnNagLogging.configure_logging([:debug]) if options.debug_audit end
determine_bucket()
click to toggle source
# File lib/exec_syntax.rb, line 38 def determine_bucket if options.validation_bucket bucket_name = options.validation_bucket puts "Using existing S3 bucket #{bucket_name}..." bucket = s3_client.bucket(options.validation_bucket) else bucket_name = "arch-code-#{uuid.generate}" puts "Creating temporary S3 bucket #{bucket_name}..." bucket = s3_client.bucket(bucket_name) bucket.create end bucket end
display_report(result)
click to toggle source
# File lib/exec_cfn_nag.rb, line 26 def display_report(result) ColoredStdoutResults.new.render( [ { filename: @base_name.to_s, file_results: result } ] ) end
estimate_cost(bucket, object_name)
click to toggle source
# File lib/exec_syntax.rb, line 67 def estimate_cost(bucket, object_name) return unless options.estimate_cost puts 'Estimate cost of template...' client = Aws::CloudFormation::Client.new(region: options.aws_region) costing = client.estimate_template_cost(template_url: "https://#{bucket.url}/#{object_name}") puts "Cost Calculator URL is: #{costing.url}" end
local_validate_syntax()
click to toggle source
# File lib/exec_syntax.rb, line 84 def local_validate_syntax puts 'Validating template syntax locally...' client = Aws::CloudFormation::Client.new(region: options.aws_region) client.validate_template(template_body: template) end
s3_validate_syntax(bucket, object_name)
click to toggle source
# File lib/exec_syntax.rb, line 76 def s3_validate_syntax(bucket, object_name) return unless options.validate_syntax puts 'Validating template syntax in S3 Bucket...' client = Aws::CloudFormation::Client.new(region: options.aws_region) client.validate_template(template_url: "https://s3.amazonaws.com/#{bucket.url}/#{object_name}") end
save_report(result)
click to toggle source
# File lib/exec_cfn_nag.rb, line 37 def save_report(result) return unless options.save_audit_report report_data = Capture.capture do SimpleStdoutResults.new.render( [ { filename: @base_name.to_s, file_results: result } ] ) end filename = "#{output_dir}/#{base_name}.audit" File.open(File.expand_path(filename), 'w').puts report_data['stdout'] puts "Saved audit report to #{filename}" end
save_syntax_report()
click to toggle source
# File lib/exec_syntax.rb, line 52 def save_syntax_report return unless options.save_syntax_report report_filename = "#{output_dir}/#{base_name}.report" puts "Syntax validation report written to #{report_filename}" File.open(File.expand_path(report_filename), 'w').puts syntax_report.to_hash.to_yaml end
show_summary(result)
click to toggle source
# File lib/exec_cfn_nag.rb, line 55 def show_summary(result) if result[:failure_count].positive? puts "Audit failed. #{result[:failure_count]} error(s) found ( ಠ ʖ̯ ಠ) ".red elsif result[:violations].count.positive? puts "Audit passed with #{result[:warning_count]} warnings. (._.) ".yellow else puts 'Audit passed! ヽ( ゚ヮ゚)/ ヽ(´ー`)ノ'.green end end
upload_template(bucket, object_name)
click to toggle source
# File lib/exec_syntax.rb, line 60 def upload_template(bucket, object_name) puts 'Uploading template to temporary S3 bucket...' object = bucket.object(object_name) object.upload_file(output_file) puts "https://s3.amazonaws.com/#{bucket_name}/#{object_name}" end