Class: Putpaws::Provision::Runner
- Inherits:
-
Object
- Object
- Putpaws::Provision::Runner
- Defined in:
- lib/putpaws/provision/runner.rb
Overview
Orchestrates the provisioning commands:
ready (provision:init) ... interview + drafts
steady (provision:roles) ... create IAM roles from the reviewed drafts
ahead (provision:plan) ... dry-run
up (provision:up) ... build the rest, idempotent
Running steady IS the user's explicit confirmation of the drafts:
up never touches IAM and stops until the role ARNs are filled.
Constant Summary collapse
- ROLE_KEYS =
[:task_execution_role_arn, :task_role_arn, :codebuild_role_arn, :scheduler_role_arn]
- ROLE_DRAFTS =
{ task_execution_role_arn: 'role-task-execution.json', task_role_arn: 'role-task.json', codebuild_role_arn: 'role-codebuild.json', scheduler_role_arn: 'role-scheduler.json', }
Instance Attribute Summary collapse
-
#clients ⇒ Object
readonly
Returns the value of attribute clients.
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#io ⇒ Object
readonly
Returns the value of attribute io.
-
#prompt ⇒ Object
readonly
Returns the value of attribute prompt.
-
#state ⇒ Object
readonly
Returns the value of attribute state.
Instance Method Summary collapse
- #blank_role_keys ⇒ Object
- #devops_resources ⇒ Object
-
#initialize(config:, state: nil, clients: nil, prompt: nil, io: $stdout) ⇒ Runner
constructor
A new instance of Runner.
- #missing_devops_requirements ⇒ Object
- #plan ⇒ Object
- #service_resources ⇒ Object
-
#steady! ⇒ Object
putpaws steady: show each draft inline, confirm one by one, then apply it as-is and fill the ARN into provision.json. -
#steady_role_entries ⇒ Object
A role is managed by
steadywhen its ARN is blank (to be created) or when the filled ARN points at the draft's own role name (created by a previoussteady; kept updatable). - #up! ⇒ Object
Constructor Details
#initialize(config:, state: nil, clients: nil, prompt: nil, io: $stdout) ⇒ Runner
Returns a new instance of Runner.
37 38 39 40 41 42 43 |
# File 'lib/putpaws/provision/runner.rb', line 37 def initialize(config:, state: nil, clients: nil, prompt: nil, io: $stdout) @config = config @state = state || State.load(config) @clients = clients || AwsClients.new(region: config.region) @prompt = prompt @io = io end |
Instance Attribute Details
#clients ⇒ Object (readonly)
Returns the value of attribute clients.
36 37 38 |
# File 'lib/putpaws/provision/runner.rb', line 36 def clients @clients end |
#config ⇒ Object (readonly)
Returns the value of attribute config.
36 37 38 |
# File 'lib/putpaws/provision/runner.rb', line 36 def config @config end |
#io ⇒ Object (readonly)
Returns the value of attribute io.
36 37 38 |
# File 'lib/putpaws/provision/runner.rb', line 36 def io @io end |
#prompt ⇒ Object (readonly)
Returns the value of attribute prompt.
36 37 38 |
# File 'lib/putpaws/provision/runner.rb', line 36 def prompt @prompt end |
#state ⇒ Object (readonly)
Returns the value of attribute state.
36 37 38 |
# File 'lib/putpaws/provision/runner.rb', line 36 def state @state end |
Instance Method Details
#blank_role_keys ⇒ Object
45 46 47 |
# File 'lib/putpaws/provision/runner.rb', line 45 def blank_role_keys ROLE_KEYS.select{|k| Util.blank?(config.roles[k])} end |
#devops_resources ⇒ Object
74 75 76 77 78 79 80 |
# File 'lib/putpaws/provision/runner.rb', line 74 def devops_resources args = {config: config, state: state, clients: clients} [ Resources::LogGroup.new(log_group_name: config.build_log_group, output_key: :build_log_group, **args), Resources::CodebuildProject.new(**args), ] end |
#missing_devops_requirements ⇒ Object
82 83 84 85 86 |
# File 'lib/putpaws/provision/runner.rb', line 82 def missing_devops_requirements missing = [] missing << 'devops.source_repository (provision.json)' if Util.blank?(config.devops_settings[:source_repository]) missing end |
#plan ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/putpaws/provision/runner.rb', line 123 def plan io.puts "Service: #{config.service_name} (region: #{config.region}, account: #{config.account_id})" io.puts "" resources = steady_role_entries.reject{|e| e[:external]}.map{|e| e[:resource]} resources += service_resources resources += devops_resources if missing_devops_requirements.empty? resources.each do |r| p = r.plan print_action(p[:action].to_s.upcase, p[:kind], p[:name]) end if blank_role_keys.any? io.puts "[stop point] IAM roles are not created yet. Review the drafts, then run `putpaws steady`." end if missing_devops_requirements.any? io.puts "[stop point] Devops step is blocked. Fill in: #{missing_devops_requirements.join(', ')}" end check_ssm_parameters end |
#service_resources ⇒ Object
63 64 65 66 67 68 69 70 71 72 |
# File 'lib/putpaws/provision/runner.rb', line 63 def service_resources args = {config: config, state: state, clients: clients} [ Resources::SecurityGroup.new(**args), Resources::LogGroup.new(log_group_name: config.log_group, output_key: :log_group, **args), Resources::Cluster.new(**args), *config.preset.task_definitions.map{|entry| Resources::TaskDefinition.new(entry: entry, **args)}, Resources::Service.new(**args), ] end |
#steady! ⇒ Object
putpaws steady: show each draft inline, confirm one by one, then
apply it as-is and fill the ARN into provision.json.
Idempotent: re-run after editing drafts to update.
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/putpaws/provision/runner.rb', line 91 def steady! io.puts "Applying IAM roles from drafts in #{config.policies_dir}/" filled = {} steady_role_entries.each do |entry| if entry[:external] print_action('SKIP', 'IamRole', "#{config.roles[entry[:key]]} (external)") next end resource = entry[:resource] action = resource.plan[:action] if action == :skip print_action('SKIP', 'IamRole', resource.name) else io.puts "" io.puts "=== #{resource.draft_file} -> #{action.to_s.upcase} role: #{resource.name} ===" io.puts JSON.pretty_generate(resource.draft) unless prompt.yes?("Apply this content as role #{resource.name}?") io.puts "Skipped #{resource.name}" next end print_action(action.to_s.upcase, 'IamRole', resource.name) end outputs = resource.ensure! state.merge_resources!(outputs) filled[entry[:key]] = outputs[entry[:key]] end write_roles_to_provision_json!(filled) io.puts "Next: check with `putpaws ahead`, then build with `putpaws up`." end |
#steady_role_entries ⇒ Object
A role is managed by steady when its ARN is blank (to be created) or
when the filled ARN points at the draft's own role name (created by a
previous steady; kept updatable). An ARN with a different role name
is treated as external (org-managed) and never touched.
53 54 55 56 57 58 59 60 61 |
# File 'lib/putpaws/provision/runner.rb', line 53 def steady_role_entries args = {config: config, state: state, clients: clients} ROLE_KEYS.map do |key| resource = Resources::IamRole.new(roles_key: key, draft_file: ROLE_DRAFTS[key], **args) arn = config.roles[key] external = !Util.blank?(arn) && arn.split('/').last != resource.name {key: key, resource: resource, external: external} end end |
#up! ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/putpaws/provision/runner.rb', line 142 def up! if blank_role_keys.any? io.puts "[stop point] IAM roles are not ready: #{blank_role_keys.join(', ')}" io.puts "1. Review and edit the drafts in #{config.policies_dir}/" io.puts "2. Run `putpaws steady` to create the roles and fill their ARNs." io.puts " (or fill in existing role ARNs in provision.json yourself)" return end io.puts "Applying service step for #{config.service_name} (account: #{config.account_id}, region: #{config.region})" apply_resources(service_resources) state.mark_step!(:service, 'done') ConfigWriter.new(config: config, state: state, prompt: prompt, io: io).apply! if missing_devops_requirements.any? io.puts "[stop point] Devops step is not ready. Fill in: #{missing_devops_requirements.join(', ')}" io.puts "Then run `putpaws up` again." return end io.puts "Applying devops step" apply_resources(devops_resources) state.mark_step!(:devops, 'done') ConfigWriter.new(config: config, state: state, prompt: prompt, io: io).apply! io.puts "All steps completed." io.puts "Verify with: bundle exec putpaws #{config.service_name} ecs:run cmd='echo ok' wait=true" end |